-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
fix: revoke Blob URLs created by p5.File #9155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a65b6ed
e470281
fb43ab1
efe21f2
6cbdcea
0ddce5e
0cb3783
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1822,9 +1822,10 @@ function dom(p5, fn) { | |
| fn.createFileInput = function (callback, multiple = false) { | ||
| // p5._validateParameters('createFileInput', arguments); | ||
|
|
||
| const pInst = this; | ||
| const handleFileSelect = function (event) { | ||
| for (const file of event.target.files) { | ||
| File._load(file, callback); | ||
| File._load(file, callback, pInst); | ||
|
Comment on lines
+1825
to
+1828
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per the above, this should not be necessary. |
||
| } | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,51 @@ class File { | |
| this.name = file.name; | ||
| this.size = file.size; | ||
| this.data = undefined; | ||
| this._isBlobUrl = false; | ||
| } | ||
|
|
||
| /** | ||
| * Revokes the Blob URL associated with this file, if one was created. | ||
| * | ||
| * When video or audio files are loaded via | ||
| * <a href="#/p5/createFileInput">createFileInput()</a> or | ||
| * <a href="#/p5.Element/drop">myElement.drop()</a>, p5 creates a Blob URL | ||
| * pointing to the media in browser memory. Calling `revoke()` releases that | ||
| * resource immediately instead of waiting for the sketch to be removed. | ||
| * | ||
| * @method revoke | ||
| * @for p5.File | ||
| * | ||
| * @example | ||
| * // Load a video file and release its URL when replacing it. | ||
| * let video; | ||
| * let previousFile; | ||
| * | ||
| * function setup() { | ||
| * createCanvas(100, 100); | ||
| * createFileInput(handleFile); | ||
| * } | ||
| * | ||
| * function handleFile(file) { | ||
| * if (file.type === 'video') { | ||
| * if (video) { | ||
| * video.remove(); | ||
| * previousFile.revoke(); | ||
| * } | ||
| * | ||
| * video = createVideo(file.data); | ||
| * previousFile = file; | ||
| * } | ||
| * } | ||
| */ | ||
| revoke() { | ||
| if (this._isBlobUrl && this.data) { | ||
| URL.revokeObjectURL(this.data); | ||
| if (this._pInst && this._pInst._blobUrls) { | ||
| this._pInst._blobUrls.delete(this.data); | ||
| } | ||
| this._isBlobUrl = false; | ||
| } | ||
|
Comment on lines
+26
to
+67
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It needs to be clearer when and why a user might want to revoke a URL object manually like this and what the consequence of this would be. |
||
| } | ||
|
|
||
| static _createLoader(theFile, callback) { | ||
|
|
@@ -42,16 +87,20 @@ class File { | |
| return reader; | ||
| } | ||
|
|
||
| static _load(f, callback) { | ||
| static _load(f, callback, pInst) { | ||
| // Text or data? | ||
| // This should likely be improved | ||
| if (/^text\//.test(f.type) || f.type === 'application/json') { | ||
| File._createLoader(f, callback).readAsText(f); | ||
| } else if (!/^(video|audio)\//.test(f.type)) { | ||
| File._createLoader(f, callback).readAsDataURL(f); | ||
| } else { | ||
| const file = new File(f); | ||
| const file = new File(f, pInst); | ||
| file.data = URL.createObjectURL(f); | ||
| file._isBlobUrl = true; | ||
| if (pInst && pInst._blobUrls) { | ||
| pInst._blobUrls.add(file.data); | ||
| } | ||
| callback(file); | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be on the p5 instance? Can it not be fully handled by
p5.Fileitself? For cleaning up when the sketch is removed, use theremovelifecycle hook which is designed for this kind of use.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@limzykenneth Thanks for the feedback! I looked through the lifecycle code and I think I understand the direction now: move the Blob URL cleanup into
p5.Fileand use the existingremovelifecycle hook, rather than keeping_blobUrlson the p5 instance.The one thing I'm still unsure about is how you'd like the
Fileto keep track of which p5 instance it belongs to. Right now_load()getspInstexplicitly for that, but from your comment ondom.js, it sounds like you'd prefer not to pass it through like this.I could move the cleanup into a single
removehook, but I don't want to introduce another registry or ownership mechanism if there's already a pattern in p5.js that I'm missing.Is there a particular approach you had in mind for handling the per-instance cleanup here?