Re: Out of order JS file execution in WebKit
Werner Thie <[email protected]> Wed, 14 Apr 2010 16:30:39 +0200
| Newsgroups | gmane.comp.python.quotient.dev |
|---|---|
| Organization | THIEngineering AG |
| Message-ID | <[email protected]> |
On 13.04.2010 03:56, [email protected] wrote: > On 12 Apr, 06:53 pm, [email protected] wrote: >> This definitely makes sense. I got the sinking feeling that I'm loosing >> this really great and simple extension of JS and the whole nevow/athena >> LivePage ecosystem too when I encountered this WebKit problem first. If >> you could elaborate on where to bring in the wrapper func you proposed >> I >> would be more than happy. > > So, a few tips to get started: > > Athena already keeps track of any widget which has been dropped into the > page somehow but for which the javascript object hasn't yet been > initialized. The reasons for this are a bit obscure, but the result is > Nevow.Athena.Widget._waitingWidgets. If you search for _waitingWidgets > in Nevow/nevow/js/Nevow/Athena/__init__.js, you'll find a couple > functions which interact with this. One, _widgetNodeAdded, gets called > from the DOM when a new widget appears in it that needs to be > initialized. Then, some time later, _instantiateWidgets gets called and > goes over _waitingWidgets instantiating the things that need to be > instantiated. > > That's all interesting because it's _sort of_ like what you might want > to happen with modules. Keep track of which ones have been loaded but > are waiting on dependencies before actually being evaluated, and then at > some later point actually doing the evaluation. > > _waitingWidgets triggers the "later point" using a timer event, which > sucks, but there was probably some reason for it. Fortunately, for > module loading, it's not necessary to resort to timing. Instead, the > event will be that some /other/ javascript module was finally loaded and > evaluated. > > Next, in Nevow/nevow/athena.py, there's MappingResource. This is the > thing that's supposed to be used to actually serve up the source of the > JavaScript modules. > > If you change what its `resourceFactory` method returns, then you're > changing what javascript is served up when a browser tries to load > athena modules. As a first stab, you could try loading up the contents > of the named file yourself, mangling it somehow, and returning it in a > static.Data. > > Ultimately it would be nice if Athena's javascript weren't tied to files > on disk, but that's a concern for later on I think. > > As for the actual mangling itself, it may be a simple matter of wrapping > the entire module source in some boilerplate for deferring evaluation > and setting up the necessary triggers. As far as the wrapping goes, I'm > really just talking about simple string manipulation. Like: > > moduleSource = """ > setupSomeState("%(moduleName)s, function() { > %(moduleBody)s > }); > """ % {'moduleName': whateverName, 'moduleBody': originalJSSource} > > Nothing fancier than that. I think it should work. Perhaps the only > tricky bit is that the module name may not be immediately easily > accessible, but I'm sure there's a way to deal with that. > > Hope this helps, > Jean-Paul > > _______________________________________________ > Divmod-dev mailing list > [email protected] > http://divmod.org/cgi-bin/mailman/listinfo/divmod-dev Hello Jean-Paul I decided to do a first go around with handcrafted wrapper code for the JS modules in question like you suggested and it worked no problem. Filling the boilerplate with content seems to me a little bit more of a challenge, because after some debugging in the MappingResource I don't yet see a way to get at the information in the import statements without reparsing the file (which I assume is a no go). Do you have a suggestion on how to proceed? Thxs, Werner modulesWaiting = {}; function moduleLoaded(module) { modulesWaiting[module] = null; Divmod.debug("moduleLoaded", "loaded module: " + module); } function waitForModules(module, f) { modulesWaiting[module] = f; for (var m in modulesWaiting) { if (modulesWaiting[m]) modulesWaiting[m](); } } //// boilerplate wrapper code //waitForModules(%(modulename)s, function() { // var deps = [%(depsFromImport)s]; //comma separated list of modules // var loaded = true; // for (var i=0; i<deps.length; i++) // loaded = loaded && (deps[i] != null); // if (loaded) { // //here comes the source, Luke // // moduleLoaded(%(modulename)s); // } //});