Dynamically created elements get ignored
If one dynamically creates a canvas element with a datasrc attribute set (after the page has been loaded) it will be ignored, i.e. they do not get automatically initialised.
Automatic initialisation of such canvas elements is currently done through an event listener attached to the DOMContentLoaded event. To support automatic initialisation of dynamically created elements an additional listener for the DOMNodeInserted event is required.
In my quick tests, simply calling the existing automatic initialisation routine on a listener for DOMNodeInserted worked, however I suspect a production-quality solution should be more careful to ensure it only initialises new canvas elements and does not re-initialise existing elements.
Comments and changes to this ticket
I'm pretty new to Processing.js at the moment, and I ran across this bug owing to the nature of how I was trying to use it.
So, in reality, I'm not actually programatically dynamically creating a single DOM canvas element - I have a view which contains a canvas element amongst many other things. (It could of course contain many of them.)
I'm sure you're right that I could manually init a new Processing, however I have not yet found documentation that tells me how to use Processing.js or the Processing object; the "Reference" section of the website only documents the Processing language, which left me with examples as my guide. I assumed that if Processing.js adds support for a datasrc attribute on a canvas tag, then it adds support for a datasrc attribute...
It seems to me that listening for DOMNodeInserted, if done correctly, shouldn't be harmful and would simplify the use of Processing.js in dynamic circumstances.
I'm not overly familiar with these DOM events, and haven't delved into the Processing.js code very deeply yet. I suspect that Processing.js might need to keep track of the canvas elements it's handling (which it might already do), which may mean that it should also listen for DOMNodeRemovedFromDocument to help ensure it doesn't leak when canvas elements are removed from the DOM.
On a closely related vein, it would also be sensible to listen for DOMAttrModified to check whether the datasrc has changed on a canvas.
For now, probably the best way will be to call Processing(canvas, code) function to initialize canvas as a processing object.
The attached fix adds following methods to the Processing object/function:
Processing.inline(scriptOrItsId) – inlines surface that runs declared HTMLScriptElement code
Processing.importAndInline(url) – inlines surface that runs remote code
Processing.injectIn(elementOrItsId, scriptOrItsId) – creates surface inside HTMLElement and replace its content, runs declared HTMLScriptElement code there
Processing.importAndInjectIn(elementOrItsId, url) – creates surface inside HTMLElement and replace its content, runs remote code there
Processing.attachTo(canvasOrItsId, scriptOrItsId) – uses HTMLCanvas as a surface and runs declared HTMLScriptElement code there
Processing.importAndAttachTo(elementOrItsId, url) – uses HTMLCanvas as a surface and runs remote code there
This is a preliminary work. Known issue: when a surface (e.g. ) is running by the Processing.js is removed from the document, the cleanup must be performed.
Wouldn't listening for DOMNodeInserted / DOMNodeRemovedFromDocument / DOMAttrModified have a pretty large cost, even if we don't do anything with it most of the times it is called?
I wouldn't be willing to sacrifice performance of every node I insert into my documents (especially for Ajax applications where hundreds of divs are constantly being inserted/removed. If we're going to support this, I would suggest we make it opt-in with a method like
documentif that actually works).
- Assigned user set to David Humphrey
I'd like to close this ticket, especially with 1.2 introducing loadSketchFromSources() - any dynamically created canvas can immediately be populated by creating it as a normal canvas and instead of setting its "data-processing-sources" attribute with a string "file1.pde file2.pde ..." calling loadSketchFromSource(newCanvas, dataProcessingoSourcesString.split(" ")).
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »