Skip to content
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

Allow the embedder to specify p5 addon libraries to load #53

Open
toolness opened this issue Apr 16, 2016 · 9 comments
Open

Allow the embedder to specify p5 addon libraries to load #53

toolness opened this issue Apr 16, 2016 · 9 comments

Comments

@toolness
Copy link
Owner

Might be nice for tutorials that want to use p5.sound, p5.dom, et cetera.

@toolness
Copy link
Owner Author

Hmm, so this might actually be a bit trickier than I thought... In preview-frame.ts, we're loading the p5.js script asynchronously, but we're also counting on it to notice the setup/draw functions in an inline <script> tag, and then immediately activate global mode and start the sketch itself.

The challenge with adding p5 add-on libraries is that they need to be added after the main p5 script is loaded (or else their calls to e.g. p5.prototype.registerPreloadMethod() will fail), but before the sketch executes.

Normally this is just done by adding another <script> tag to one's HTML file, but because the preview widget is doing things dynamically and loading things asynchronously, that's hard. By the time the main p5 library has loaded, document.readyState will likely be complete, so it'll immediately check for the existence of draw/render to start up a sketch in global mode. If it finds them, it'll immediately start the sketch--giving us no time to load more add-on libraries; if it doesn't find them, our "chance" to use global mode has passed us by, as there's no documented way for us to start p5 global mode explicitly.

There might be a few ways to work around this:

  1. We could have the preview frame create yet another iframe within it, whose HTML document it dynamically creates via document.write(). This way it could write out all the script tags at once and loading/execution would proceed as expected.
  2. We could write a bunch of mangly code to convert the user's sketch to use p5 instance mode, which we then activate manually once we've loaded all the add-on libraries. This code would probably crib from the mangly code in the p5 website's render.js... However, we'd have to be very careful to preserve line numbers so that errors would still be helpful. The mangly code would also be tightly coupled to p5, so as e.g. new global event-handling methods like mouseClicked are added--or new ones are introduced by add-on libraries--the mangly code would become out-of-date. I really don't like this option.
  3. We could add a documented/supported mechanism to p5 that allows environments like the widget to instantiate p5 global mode explicitly, after all dependencies have been loaded and such. I think there's actually a "hacky" way to go about doing this--iirc, just calling new p5() without any arguments will actually do it--but we'd want to make sure it's actually documented, so that it continues to be supported going forward.

I think I like options 1 and 3. Option 2 is right out.

@kaganjd does any of this make sense? It's a lot more complicated than I thought it'd be, but I think we can still do it! (Sorry I said it'd be easy, though... 😣)

@kaganjd
Copy link
Contributor

kaganjd commented Aug 25, 2016

@toolness I've been thinking about option 1. Just to make sure I'm on the right track, are you saying that instead of the loadP5 function in preview-frame.js [1], we'd have something like a writeToIframe() function that writes preview-frame.html? [2]

[1]

function loadP5(version: string, cb?: () => void) {

[2] https://gist.github.com/kaganjd/fef5209591233473c2cd7a8e796997be

@toolness
Copy link
Owner Author

Yep! Or slightly more accurately, creates an iframe within preview-frame.html that it writes to. I think that there will ultimately be a ridiculous number of iframes here:

  • Web page in user's browser
    • Embedded p5 widget frame (p5-widget.html)
      • Preview frame (preview-frame.html)
        • Dynamically-created iframe written to via document.write()

It's important to note that in an ideal scenario, we'd actually host preview-frame.html on a separate domain to prevent cross-site scripting attacks (see #57). We'd like to do that eventually, which is why we want preview-frame.html to actually exist (otherwise one could argue that we should simplify the situation and remove preview-frame.html from this picture entirely).

Ummm I think that's one way forward, at least. Wanna make a protoype? 😁

@toolness
Copy link
Owner Author

Blergh now I am starting to wonder if there are other ways to do this without making yet another iframe. I think we actually re-create the preview frame every time the user changes their code, in which case we could potentially just deliver all the required information through querystring arguments... Arg, why is this so hard.

Sorry about this, I really thought it'd be a lot easier!

@kaganjd
Copy link
Contributor

kaganjd commented Aug 27, 2016

Maybe Javascript promises could be useful here? I'll start looking into
that. And qs arguments :)

@jaredhirsch
Copy link

I don't have a lot of p5 experience, but just in straight front-end programming terms, option 3 sounds like the least amount of work 👍

Changing the semantics of new p5() seems unlikely, which is good. And, if that change does happen, I guess p5.js-widget could hang back with the last working p5 version until option 1 or 2 gets implemented.

@toolness
Copy link
Owner Author

Good point @6a68 ! Thanks for the feedback.

@JunShern
Copy link

Hi @toolness, did you get anywhere on this? I'm working on a tutorial for p5.sound right now and would love to use your widget for this (it would be very helpful to have p5.dom as well).

I suppose that based on your answer about the script loading order, something simple like adding the add-on library urls to the loadScripts part of the code won't work?

@ghost
Copy link

ghost commented Oct 29, 2018

Hi @toolness, Just LOVE your p5.js-widget! I wonder if anyone found an answer to how to add on p5.dom to it?
I would like to use the createSlider on some tutorials.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants