Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On Thu, 15 Jan 2015, Boris Zbarsky wrote: It doesn't match _all_ implementations, certainly. OK, but have you bothered to find out why? The usual reason is just that there was no spec initially, and that the relevant implementations haven't bothered to fix it since the spec was written. Per the HTML spec, there's two ways that WindowProxy can change. One is session history traversal. That can never happen with JS on the stack Are you sure, given showModalDialog? I'm assuming that showModalDialog() is dead. showModalDialog() breaks every assumption under the sun and is generally bad news. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On Thu, 4 Dec 2014, Boris Zbarsky wrote: On 12/4/14, 1:36 PM, Travis Leithead wrote: In IE's implementation, the window proxy has no storage as a typical JS var--it's only a semi-intelligent forwarder to its companion inner window. That's an IE implementation detail. It's more than that. It's how the HTML spec defines WindowProxy. So when a script does: Object.defineProperty(frames[0], foo, { value: true; }); It is defining a property on frames[0]. The fact that this is actually a proxy for some other object (the global inside that iframe) is somewhat of an implementation detail, again. According to the HTML spec, all operations that would be performed on the WindowProxy object must be performed on the Window object of the browsing context's active document instead. So the above would set a property on the underlying Window object, not the WindowProxy. This isn't about appearance. The relevant spec invariant for [[GetOwnProperty]], for example, is: If P’s attributes other than [[Writable]] may change over time or if the property might disappear, then P’s [[Configurable]] attribute must be true. And Object.getOwnPropertyDescriptor is clearly defined to invoke [[GetOwnProperty]]. So when a page does Object.getOwnPropertyDescriptor(window, foo) this is invoking the window proxy's [[GetOwnProperty]]. ...but the window proxy's [[GetOwnProperty]] just forwards that straight to the Window's [[GetOwnProperty]]. The property is on the Window, not the WindowProxy. It can't disappear from the Window. The invariant is thus maintained. There is no way to directly query the WindowProxy. To all intents and purposes, it's not a real object. It's a reference to another object, which happens to change during navigation. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On Wed, 14 Jan 2015, Boris Zbarsky wrote: On 1/14/15 3:17 PM, Ian Hickson wrote: It's more than that. It's how the HTML spec defines WindowProxy. The point is, the HTML spec's definition is not expressible in ES terms. So how do go about bridging this gap? I don't understand what you mean by expressible in ES terms. It's expressed in English. According to the HTML spec, all operations that would be performed on the WindowProxy object must be performed on the Window object of the browsing context's active document instead. So the above would set a property on the underlying Window object, not the WindowProxy. It would call the [[DefineOwnProperty]] trap of the WindowProxy. That then forwards to the Window, yes? No. WindowProxy isn't an ES Proxy. (The term WindowProxy predates ES Proxy). When you have a WindowProxy object, it acts exactly like the Window object to which it currently points. It is indistinguishable from the Window object. When the WindowProxy changes what it's pointing at, it's exactly as if the browser had reached in and changed every WindowProxy that pointed to the former and made it point to the latter. ...but the window proxy's [[GetOwnProperty]] just forwards that straight to the Window's [[GetOwnProperty]]. Yes, but since which window it forwards to changes you get an invariant violation for the WindowProxy object itself. I don't understand how that follows. The property is on the Window, not the WindowProxy. It can't disappear from the Window. The invariant is thus maintained. I think you misunderstand what the invariant is. Maybe. Please elaborate. There is no way to directly query the WindowProxy. It doesn't matter. The user sees the WindowProxy, not the Window. No. What the author has is a WindowProxy, but in every sense it acts like a Window. (Which Window it acts like changes occasionally.) After you navigate, you still have the same WindowProxy (e.g. .contentWindow returns something that is === to the thing you had before you navigated). You have no way to actually test this. Since every reference to the old Window is now a reference to the new Window, you have no way to test if the WindowProxy references something new. It's just like if the browser had reached in and changed all your references from under you. But properties it claimed to have that were non-configurable are now gone. That is precisely a violation of the invariants. Suppose you have this code: // part 1 let a = {}; let b = {}; let c = a; // part 2 c.foo = 1; // part 3 c = b; // part 4 console.log(c.foo); Is it surprising that the log doesn't log 1? This is what is going on here, except that part 3 is done by the browser. To all intents and purposes, it's not a real object. It looks like an object and quacks like an object. It looks and quacks like a Window. It's a reference to another object JS doesn't have such a type in the language, sadly, so we can't model it that way for consumers. It turns out that it does have such a type. WindowProxy is it. I agree that that makes it a special snowflake. On Wed, 14 Jan 2015, Mark S. Miller wrote: Boris has this exactly right. Further, a malicious proxy handler can leverage the presence of a single object that violates these invariants into the creation of arbitrary other proxies objects that also violate these invariants. The key is that the enforcement of the invariants relies on the proxy's target being constrained by these invariants. See http://research.google.com/pubs/pub40736.html If you're exposing your Window object to untrusted code you are so far beyond losing that this is the least of your concerns. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
above if I do |var d = c;| then the d won't change in part 3. If in the code above you do var d = c, then add d = b to part 3 to simulate what the browser does. Having an object with sane internal methods here is really much simpler than magic update all the references behavior. But again, I've said this to you numerous times. I'm not actually proposing updating all the references. That's just a convenient way to think about it that is isomorphic in behaviour to what is specced. What is specced is just that you have a placeholder pseudo-object that forwards all behaviour to an underlying object, where which object it's forwarding to can change over time. Let me try it again: the fact that the definition in the HTML spec has not lead to interop is not an accident. It's not something browsers can sanely achieve interop on because it involves handwavy magic that they are extremely likely to interpret differently. On the other hand, defining a single object with internal methods that do what you want would be _very_ clear to an DOM or JS engine implementor. I have asked before, but would like to reiterate: If there is any behaviour that is underdefined by the HTML spec's current prose, please tell me, so that I can spec it. It looks and quacks like a Window. No, it, doesn't, see above. It is literally indistinguishable from _a_ Window in every way at all times. That's the whole point. Which Window it appears to be indistinguishable from at any particular time varies over time. It turns out that it does have such a type. WindowProxy is it. I agree that that makes it a special snowflake. My point is that this special snowflake is unnecessary and confusing. Well it predates all the ES6 stuff we're talking about here by several years, so I'd argue that the confusion doesn't stem from WindowProxy. I also don't really agree that it's confusing. It's really simple to explain, certainly much simpler than anything involving ES proxies and so forth. It's one sentence in the spec, and as far as I'm aware, it doesn't leave anything undefined. I also disagree that what the spec says doesn't match implementations. I think it matches implementations pretty darn closely. I mean, in particular, it matches exactly what Travis described as IE's implementation. (This is not an accident; matching implementations was one of the main goals of the HTML spec, and at the time this was specced, IE was by far the biggest UA out there.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Event loops in navigated-away-from windows
On Sat, 27 Sep 2014, Anne van Kesteren wrote: Well, I for one find it confusing that while HTML had a fairly worked out event loop concept, ECMAScript added another and now I somehow mentally need to integrate them. It would be way clearer if ECMAScript just queued tasks/jobs/microtasks to the Host so we'd keep a single concept of a loop. Allen and I discussed how they should be integrated, and the long and short of it is that there's only one event loop; HTML just interrupts the ES6 loop at NextJob step 4 (the implementation defined manner), and resumes the HTML event loop, and when the HTML event loop needs to resume running code, it resumes the NextJob algorithm. That and a few other hooks ensures that all the jobs end up as tasks and all the ordering semantics are preserved. The discussion was at: http://esdiscuss.org/topic/the-initialization-steps-for-web-browsers I haven't yet done this in HTML because I'm waiting for Allen to make the changes he talked about in that thread; this is being tracked here: https://bugs.ecmascript.org/show_bug.cgi?id=3138 Once that's done I can update HTML. (I don't want to update HTML before, because otherwise I'll have to do it twice.) The HTML bug for this is: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981 I certainly wouldn't object to the ES spec's event loop algorithms being turned inside out (search for RunCode on the esdiscuss thread above for an e-mail where I propose this) but that would be purely an editorial change, it wouldn't change the implementations. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Event loops in navigated-away-from windows
On Mon, 29 Sep 2014, Anne van Kesteren wrote: On Mon, Sep 29, 2014 at 8:18 PM, Ian Hickson i...@hixie.ch wrote: I certainly wouldn't object to the ES spec's event loop algorithms being turned inside out (search for RunCode on the esdiscuss thread above for an e-mail where I propose this) but that would be purely an editorial change, it wouldn't change the implementations. The proposed setup from Allen will start failing the moment ECMAScript wants something more complicated with its loop. At that point you'll have to propose another set of hacks to make the integration with HTML work again. And given this integration is so weird, I doubt implementations will match it as written. Seems more likely they'll implement the more straightforward alternative. (Also, the proposed setup does seem to require exactly that kind of mental integration I was worried about. With HTML hijacking the ES loop to do its bidding.) Certainly editorially I would much rather have the inside out version of the spec hooks that I mentioned in my earlier e-mail, yes. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Loader proposed changes
On Wed, 10 Sep 2014, Rob Sayre wrote: On Fri, Aug 29, 2014 at 2:23 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 29 Aug 2014, David Herman wrote: It's still not completely clear to me what your use cases are, so I'm not sure exactly how much user-visible API you need. My goal is to avoid browsers having to implement two dependency systems (one for ES modules, one for HTML imports). Is that a goal? Browsers have a lot of dependency systems, not just two. My hope is that we can explain all the dependency systems (HTML documents that have subresources like scripts and style sheets and so on, @imports and images and so on in CSS, HTML imports, ES6 modules, etc) using the same underlying infrastructure. This would enable authors to extend browser behaviours using a common set of primitives. I must admit though that while I initially assumed that this would be an obvious goal that browser vendors would all be eager to reach, I have yet to see anyone indicate that they're interested in this. So maybe it is in fact not a goal. I don't know. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Loader proposed changes
On Thu, 11 Sep 2014, Brendan Eich wrote: Ian Hickson wrote: I must admit though that while I initially assumed that this would be an obvious goal that browser vendors would all be eager to reach, I have yet to see anyone indicate that they're interested in this. So maybe it is in fact not a goal. I don't know. I think it must be a non-goal for competing browser vendors. For a new browser, esp. bootstrapped in JS, it's a no-brainer. This suggest going bottom-up, not top-down: try to unify two, then three, subsystems. Don't multiply risk of independent events into a tiny odds ratio. I don't understand how to do this in a backwards-compatible way. If we slowly expose more and more resource loads to the ES module loader, then pages that rely on what resources are passed to the ES module loader will fail each time we add more. (As a trivial example, consider a page whose fetch hook does nothing, but where the page actually doesn't load any scripts so it doesn't matter. If we then add style sheets in a later verison, suddenly no sheets load and the page is unstyled, breaking the page.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Loader proposed changes
On Thu, 11 Sep 2014, Brendan Eich wrote: It may be that you have to keep compatibility, which means larger API surface over time, new more-unified and old less-unified subsystems coexisting. That's how the Web has grown in other areas. Original DOM didn't reflect all elements; in the '90s things evolved in layers. I don't really understand what this would look like for the ES6 loader. Would we have different hooks for each kind of module? Or...? Nevertheless if you can't get implementors on side, that's a strong signal. Indeed. I don't really mind either way, for the record; I really assumed (in part from talking with Chrome people and others in #whatwg) that this was an obvious win and would be uncontroversial, especially with the recent focus on explaining the platform via ES-exposed primitives. Obviously for me it'd be a lot simpler if we didn't integrate things like this; it would let me spec a dependency system people are asking for for subresources of HTML documents without having to worry about integrating with CSS and ES6. :-) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Loader proposed changes
On Fri, 29 Aug 2014, David Herman wrote: It's still not completely clear to me what your use cases are, so I'm not sure exactly how much user-visible API you need. My goal is to avoid browsers having to implement two dependency systems (one for ES modules, one for HTML imports). But if you are trying to reflect the browser's fetching policies and priorities based on different types of assets, then you are looking for a layer in between ServiceWorker and module loader -- call it an asset manager or resource manager. Right. But that kind of system will have dependencies to track, including dependencies between ES6 modules, and on ES6 modules from other things, and from ES6 modules to other things. I don't understand how to make that work if we're not able to have a single dependency system. I'd be happy to discuss this with you and see if we can flesh out the use cases and requirements to get a better handle on the problem space. I would love that. Where and when? You may also find the following helpful in explaining things I'm looking at at the moment related to this: http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Aug/0177.html -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ES6 Loader proposed changes
Here are the changes that would be needed to make the ES6 loader infrastructure underpin the Web platform's loader infrastructure (basically, placing the ES6 loader the management layer between the Web platform APIs on top, and Service Workers underneath). The ES6 module loader mechanism is very explicitly and specifically specified. It provides hooks that the UA can plug into, e.g. to actually dispatch loads, and it tracks the load state of each resource it is informed about, including what other resources that resource depends upon. If we can reuse this for the rest of the Web platform, it gives authors a really uniform API for all loading operations. * Some document types are incrementally parsed, meaning that their dependencies are discovered before the fetch hook has finished. For these, it would be helpful if the dependencies could be reported to the ES6 machinery before the fetch hook finishes. (Right now, [[Dependencies]] is initialised as a response to the instantiate hook, at the end of the module load.) * Ideally, it would be possible to provide the dependencies even earlier, e.g. at LoadModule() time, before the normalize hook, for the case where a custom module loader has a JSON file describing the dependency tree, or if, in future, HTML grows dependency information (the latter is likely). * It is possible to mutate the DOM, including the URL of resources that a document depends on. For example, you can have an img src=foo.png element, and dynamically change that attribute to have the value bar.jpeg instead. To manage this, the [[Dependencies]] list needs to be mutable. * Some loads have metadata other than dependencies, too. For example, anything loaded in CSS via the @import rule will always be parsed as CSS, even if it has already been referenced as an HTML file or ES6 module or PNG image elsewhere before: the load has the metadata treat as CSS and don't dedupe. Similarly, link rel=stylesheet rules can have media queries attached to them. It would therefore be helpful if, rather than just a name, you could pass LoadModule() some metadata that would be passed along to all the hooks. With the above changes, I think we could make ES6 modules underpin the entire Web dependency management system without needing to invent and expose yet another API, and without needing to redundantly manage the dependency tree. If we reuse the ES6 module loader to manage all HTML document resources, it would also trivially allow custom module loaders to allow ES6 modules to refer to other resource types without those module loaders needing to redundantly reimplement parts of the browser infrastructure (e.g. they could just hook into existing CSS style sheet loads rather than having to do separately load style sheets mentioned in ES6 modules). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
On Fri, 22 Aug 2014, Marius Gundersen wrote: One way to do this would be to predeclare the modules, as in: script type=module src=a.js id=a needs=c load-policy=when-needed /script script type=module src=b.js id=b needs=c load-policy=when-needed /script script type=module src=c.js id=c load-policy=when-needed /script All of these scripts would need to be empedded in every page Only the ones that are needed. But actually it's not that bad. These dependencies can all be listed in an HTML import, which is then marked as heavily cachable. This ends up being just as cheap to pass to the server as a JSON file of the dependencies. Pre-fetching dependencies seems like it could most easily be implemented using ServiceWorkers[1]. A simple build tool, given a set of modules, can generate a JSON file with each module id (URI) and its dependencies (list of URIs). This JSON file would contain the entire dependency forrest from all roots to all leaves, and could be made available on the webserver for the ServiceWorker to download. That wouldn't let you do preparsing, which is a big part of the reason to want to prefetch resources. (ServiceWorkers are an important part of the upcoming revolution in resource loading on the Web, but dependency handling is at a different level, namely, the ES6 loader level.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Strawman proposal: new `is` operator
On Sun, 24 Aug 2014, Isiah Meadows wrote: One big question I have is whether a different keyword should be used (`isa`, etc), given its use as a keyword synonym to `===` in many compile-to-JS languages, most notably CoffeeScript. is is used to mean is an instance of or an instance of a subclass of in C# and modern Pascals, FWIW. Perl uses isa for this. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
On Thu, 21 Aug 2014, C. Scott Ananian wrote: On Thu, Aug 21, 2014 at 11:54 AM, John Barton johnjbar...@google.com wrote: Where? The Load Request records imply a dependency graph. Are these maintained though out the life of the page? I don't see any existing reason to expect these are maintained. Ian's proposal (well, mutation in general) certainly implies that these (or an appropriate summary) should be maintained. Again, possibly you can drop parts of the graph from memory once all requests have been fulfilled... but I think that's an implementation optimization. The simplest spec would just stipulate a persistent dependency graph. I'd guess that you'd want to restrict arbitrary reads of the graph in order to allow the optimization. Write-only access would be best. I don't think we need to maintain the dependency graph beyond the link stage. Once something is linked, it doesn't really matter if the dependency is still true or not, since it doesn't make any difference -- it can't block the load any more. So I'm happy with the way the ES6 spec discards the dependency information. The important change IMHO is that the dependency information be maintained from earlier in the cycle, and be mutable (write-only would be fine, assuming you can remove dependencies; there's no need, IMHO, to expose the actual dependency chain to script). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
we can just use build tools and browsers. Actually, modulo the changes described above, the ES6 loader already does all this. Huh? How do you plan to parse the modules to obtain dependencies without sending them to the browser? You send them to the browser, just not in the module itself. It just doesn't quite handle it at the level of pre-emptive declaration of dependencies. But suppose you had two modules A, B, and C. A and B depend on C. With ES6 today, when A is loaded, it loads C. If late you load B, B doesn't reload C; it just links into it. So this is all already supported. All that's needed is a way to tell the ES6 system to get C before it has even received A. You've really lost me now. I thought your goal was to avoid sending C over the network. Now you want to send it without even seeing A? Not sending C over the network at all wouldn't work, since it would mean A doesn't have its dependencies available. I don't follow. The idea is that authors be able to predeclare (relevant parts of) the dependency tree such that when a node in that tree is needed, e.g. A in the example above, all the relevant nodes can be fetched in parallel, e.g. A and C in the example above, rather than in a serialised manner, e.g. first fetching A, then parsing it, then fetching C. One way to do this would be to predeclare the modules, as in: script type=module src=a.js id=a needs=c load-policy=when-needed /script script type=module src=b.js id=b needs=c load-policy=when-needed /script script type=module src=c.js id=c load-policy=when-needed /script ... // in some script or event handler or some such document.scripts.a.load(); // a is now needed, a and c get fetched in // parallel with only one RTT. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
this information to the client currently, in a custom format. So it would not be that much of a stretch to imagine them putting it in an HTML import, say. Something that would allow them to have the dependency chain, without blocking the initial page load. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Wed, 20 Aug 2014, John Barton wrote: The reverse case, where a img depends on a script, is not a use case. Why not? What if the image has an onmouseover handler that calls an API function defined in a module, for instance? Then the page depends on the onmouseover handler code and it has a dependency on the module. Images are leaf nodes in the dependency tree. Can you show me the markup for how you would like this to work? I'm not sure I follow what your vision is here. Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? import './latter'; It's a solved problem for scripts. The key part of my question was non-loaded. The import bit is in the script. The script isn't loaded yet, so we can't rely on it. script System.import('./former').then((former) = { // do stuff with former, knowing './former' imported './latter'. }); /script This results in multiple RTTs. If you don't want multiple round trips, import from a bundle. That doesn't work; see the discussion in this e-mail: https://mail.mozilla.org/pipermail/es-discuss/2014-August/038853.html Also, this doesn't wait until former is needed before loading it. But the mechanisms for knowing need are not available to any one at this point. Right. I'm trying to set up the groundwork to add such features to HTML. I think you are imagining a magical trigger that does not exist. That more or less summarises my job, yeah. :-) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Wed, 20 Aug 2014, John Barton wrote: On Wed, Aug 20, 2014 at 3:23 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 20 Aug 2014, John Barton wrote: The reverse case, where a img depends on a script, is not a use case. Why not? What if the image has an onmouseover handler that calls an API function defined in a module, for instance? Then the page depends on the onmouseover handler code and it has a dependency on the module. Images are leaf nodes in the dependency tree. Can you show me the markup for how you would like this to work? I'm not sure I follow what your vision is here. script System.import('jquery').then(() = { $(document).ready(() = { $(img.a).hover(() = { $(this).stop().animate({opacity: 0}, slow); }, () = { $(this).stop().animate({opacity: 1}, slow); }); }); }); /script Here the page depends upon a mouseover handler which depends upon jquery. The handler and the page depend upon the image. This doesn't do what I was describing. I apologise for being unclear. The idea is that the jQuery module in this world doesn't get loaded until it is needed. When the user hovers over the image, then the jQuery module is loaded and used, but until then, nothing needs jQuery so it's not loaded. (Or replace jQuery with whatever it is that's special to this image; the precise library doesn't matter.) If you don't want multiple round trips, import from a bundle. That doesn't work; see the discussion in this e-mail: https://mail.mozilla.org/pipermail/es-discuss/2014-August/038853.html So I answered on another thread. Ah, looks like your e-mail got caught by my spam filters. I'll continue to respond there. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
On Wed, Aug 20, 2014 at 4:06 PM, John Barton johnjbar...@google.com wrote: On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: This just doens't work. Suppose the dependency graph looks like this: Feature A -- Dependency A1 \__\ Dependency\ Feature B -- Dependency B1 / /AB -- Dependency D Feature C -- Dependency C1 --- Dependency C2 / All of A, B, and C are to be fetched on-demand-only, to avoid using up too much bandwidth. All the files here are non-trivial in size. How do you package this? If you make a package for A, a package for B, and a package for C, then you'll have redundant content in the packages, and when the client asks for B after already having asked for A, the amount of content sent back will be greater than necessary and therefore it'll be slower than necessary. If you create multiple packages such that you group as much as possible into each package as possible without overlap, then you still end up with multiple resources to download when you need any of A, B, or C. Basically, it boils down to: Package A \__\ Package\ Package B / /AB -- Package D Package C - / ...and then you're back to the problem I asked about. If you don't have server-side support, then to avoid round-trips the client needs to know about the dependencies before it makes the first request. It can't wait til it receives the packages to discover the dependencies because if you do that then you're serialising your RTTs instead of pipelining them. I assume you are imagining a densely connected graph with random access to any of the roots. I'm not quite sure what that means. I mean a world where different otherwise unrelated leaf modules or resources depend on common shared dependencies. I expect that real life pages have well partitioned graphs (widgets) that share some dense parts (utilities) and simple access patterns -- main page, utilities, a set of widgets. I doubt that the Web is that convenient. On some well-designed sites it might work out that way. Consider a site like Google+, though. However well-designed it is, it fundamentally has a lot of common files used by lots of intermediate shared files used by lots of leaf modules (and a lot more depth while we're at it). What exactly is needed depends on what posts are displayed, the user's preferences with respect to features like Hangouts, etc. It's a complicated graph. But sure, it would be great to have a complete solution if it's not a lot more complex. I don't think it should be particularly complex. It only requires some minor changes. One is that we need to be able to declare dependencies ahead of the instantiate hook. Another (a subset, really) is that we need to be able to declare dependencies for ES6 modules as well as letting the ES6 infrastructure discover them automatically. Finally, it would be ideal if we could also adjust those dependencies on the fly, since if we're reflecting dependencies described in the mutable DOM structure, it might be mutated. I guess you're proposing the send the dependency graph to the browser, then when a new root is needed, the stored graph is compared with the currently-loaded modules. The additional modules needed are then requested as a group. Up to this point we can just use build tools and browsers. Actually, modulo the changes described above, the ES6 loader already does all this. It just doesn't quite handle it at the level of pre-emptive declaration of dependencies. But suppose you had two modules A, B, and C. A and B depend on C. With ES6 today, when A is loaded, it loads C. If late you load B, B doesn't reload C; it just links into it. So this is all already supported. All that's needed is a way to tell the ES6 system to get C before it has even received A. How will we tell the server send me this list of files all in one response? HTTP pipelining does this today, that's a solved problem. -- Ian Hickson ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ES6 module loader issues: preloading, and CSS imports
(For some reason, e-mails containing the following text have failed to make it to the es-discuss list. Not sure what's going on with that. Anyway, this is a new e-mail that contains more or less the same contents but changed a bit in case there's some filter or bug that the last e-mails were hitting.) It would be helpful if there was a way that the module _execution_ (after it's been parsed and dependencies have been extracted) could be delayed by the loader. Suppose a page is loading and has reached a quiescent state, and so the browser thinks ok, time to preload some scripts. It might start with one script, and then find that it imports another, and would then fetch that one. But it doesn't want to actually execute anything, because the scripts haven't been invoked yet. Since ES6 does all the heavy lifting of finding the imports in the source code and setting up all the linking, it would be good if the browser could rely on that but just put a stop to the final execution step until such time as the resource is actually needed. Doing this in the fetch or translate hooks wouldn't work because we need the instantiate hook to do its dependency tracking bit first. It's possible, based on this and earlier e-mails about how to change dependencies, that really what we need is a new hook that splits instantiate in half -- half for handling dependencies, and half for handling execution. That might also enable the instantiate hook to change to not return a weird object or undefined. It would similarly address the how do I add out-of-band dependencies issue I mentioned earlier. Combined with changing where dependencies are first initialised, this would address most of the dependency issues I've raised, I think. This would also allow for ES6 import syntax to be used inline to declare some dependencies, as in the case of an inline script marked as being on-demand containing something like: import jquery; import jquery/animations; import myapp/logic; If the browser could notice that this was an inline script and have the ES6 module system pre-parse it to discover the imports, it could preload them and then when the script element's execute() or load() method (whatever we end up calling it) is invoked it could just unblock the execution and immediately have the scripts run. Assuming we use the ES6 module loader to handle all the loads in an HTML document, in the Web context, there are also some interesting questions to resolve around the issue of de-duping. Suppose you had an inline style element markup containing: @import http://example.com/foo.x;; ...followed by an external script element src= pointing to: http://example.com/foo.x This causes foo.x to be evaluated once as a style sheet, and once as a script. In the new world, though, if every load goes through the ES6 module system, how do we distinguish them in the module registry? Similarly, consider the reverse case of an inline script module saying: import http://example.com/foo.x;; ...followed by an inline style block saying: @import http://example.com/foo.x;; After the module's import, foo.x is in the registry as an ES6 module. But the semantics of the @import rule are that it must be interpreted as CSS, so that doesn't work. It would be great if it was possible to attach metadata to the key that is used in the registry that would be part of the registry key but not exposed in the module API. For example, @import could tag all its modules as CSS, so that the above would be keyed as {http://example.com/foo.x;, CSS}. Regular imports wouldn't key anything, so that in the case of an inline CSS block followed by an inline ES6 module both importing the same file, the second import would find the pre-existing CSS import rather than try to introduce a new one. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Mon, 18 Aug 2014, John Barton wrote: Your examples use script. I just don't think now that we should use the same solution for HTML. We should analyze the HTML requirements and design a solution. If the result is similar to script then we can reuse. That's what I've been doing. My conclusion is that it's very similar, and just requires a few changes to the ES6 module loader design, those I've been describing. The alternative is that we end up with two very similar dependency systems which interact (because people want to have scripts depend on HTML features and vice versa). This does not seem like a win to me. But in the case of image tags we already know exactly which image the HTML depends upon. But other elements might depends on the img, and that we don't know. (For example, a graphical game might need some sprite assets to be loaded before it can start up. So its script might be marked as depending on an img element that loads that image. Or the script contents might have an import statement that refers to that image.) Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? import './latter'; It's a solved problem for scripts. The key part of my question was non-loaded. The import bit is in the script. The script isn't loaded yet, so we can't rely on it. Discussing HTML dependency loading and ES dependency loading together makes a lot of sense -- up to a point. But requiring specs and implementations to converge does not seem good to me now. It seems really good to me, given the alternative. But I'll defer to the rest of the JS spec community to make that decision, since it requires changes to the ES6 spec if we're going to do it. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ES6 module loader and de-duping across language semantics
Assuming we use the ES6 module loader to handle all the loads in an HTML document, in the Web context, there are some interesting questions to resolve around the issue of de-duping. Suppose you had this markup snippet: style @import http://example.com/foo.x;; /style script href=http://example.com/foo.x;/script This causes foo.x to be evaluated once as a style sheet, and once as a script. In the new world, though, if every load goes through the ES6 module system, how do we distinguish them in the module registry? Similarly, consider this case: script type=module import http://example.com/foo.x;; /script style @import http://example.com/foo.x;; /style After the module's import, foo.x is in the registry as an ES6 module. But the semantics of the @import rule are that it must be interpreted as CSS, so that doesn't work. It would be great if it was possible to attach metadata to the key that is used in the registry that would be part of the registry key but not exposed in the module API. For example, @import could tag all its modules as CSS, so that the above would be keyed as {http://example.com/foo.x;, CSS}. Regular imports wouldn't key anything, so that in this case: style @import http://example.com/foo.x;; /style script type=module import http://example.com/foo.x;; /script ...the second import would find the pre-existing CSS import rather than try to introduce a new one. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Delaying execution of modules in the loader
It would be helpful if there was a way that the module _execution_ (after it's been parsed and dependencies have been extracted) could be delayed by the loader. Suppose a page is loading and has reached a quiescent state, and so the browser thinks ok, time to preload some scripts. It might start with one script, and then find that it imports another, and would then fetch that one. But it doesn't want to actually execute anything, because the scripts haven't been invoked yet. Since ES6 does all the heavy lifting of finding the imports in the source code and setting up all the linking, it would be good if the browser could rely on that but just put a stop to the final execution step until such time as the resource is actually needed. This would also allow for ES6 import syntax to be used inline to declare some dependencies, as in: script type=module when-needed import jquery; import jquery/animations; import myapp/logic; /script If the browser could notice that this was an inline script and have the ES6 module system pre-parse it to discover the imports, it could preload them and then when the script element's execute() method is invoked it could just unblock the execution and immediately have the scripts run. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies found during the load (before instantiation)
On Mon, 18 Aug 2014, John Barton wrote: On Mon, Aug 18, 2014 at 10:55 AM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, Ian Hickson wrote: One of the problems I'm running into when it comes to trying to integrate ES6 modules with HTML and new HTML-based dependency features is the way that I can't tell ES about dependencies I know about before the data is actually fetched and instantiated. Another example of where we have something like this is HTML imports. The fetch hook for HTML imports needs to actually be the hook that does all the parsing, since HTML loads incrementally. (For HTML imports, the translate and instantiate hooks are essentially no-ops.) This means that the in-band dependencies for HTML imports are found during the fetch hook, and need to be set up right away. For example, if an HTML import contains a script type=module block, that inline module needs to be added as dependency of the import itself (so that the import's 'load' event doesn't fire until all internal modules are loaded). It it contains an img src= element, that needs to be added as a dependency as its loading. This is similar to the instantiate hook adding dependencies, except that it has to happen earlier due to the incremental parsing. Can we explore the opposite question: how much does the HTML dependency problem really overlap the ES dependency problem? As far as I can tell they're the same problem. At the simplest level, if we want it to be possible for one inline module to reference another inline module, then they're in fact exactly the same. Similarly if an HTML import contains a module and another HTML import contains a module, and they need to reference each other, then they're the same problem. HTML imports can also import style sheets and images and so on. Images can be imported by HTML documents that aren't imports. The transitive closure of the problem that includes ES6 Modules being downloaded is the entire Web platform's loading mechanism. Plus, if we want to make sure that ES6 module loading participates in the Web platform's Service Workers and Fetch infrastructures, they need to be implemented in a manner consistent with other loads. The alternative is a lot of redundant code. I could be wrong, maybe browser vendors really do want to write dependency systems twice. I haven't heard one way or the other from browser vendors in this thread, so it's hard to tell. To the first approximation these are the same problem: given the root of graph, load all of the nodes of the graph. The solution to this generic problem is well known and the code, while not trivial, is not very complex. As soon as we go beyond this first level, the problems diverge. In fact I think your posts make the case that the character of these problems differ on so many points that code reuse is unlikely and algorithm reuse unwise. I disagree. The problems seem very similar and more than just reuse code, they can just be the same code. There's actually very few problems that need changes to the module loading mechanism, and all those problems would benefit ES6 modules alone, as far as I can tell. In particular the reason we -- 'we' being you and me -- can't understand the ES spec is (evidently) that it supports loading a graph of mixed nodes (ES and legacy) with different assumptions about circular references. I think I have a pretty clear grip on the ES6 module spec at this point, FWIW. I just think a few things need tweaking to support the Web. HTML is unlikely to have the identical requirements on circular references and it's legacy (script tags, document.write, mutable declarations, HTML imports) has quite different issues. The ES6 module system is mostly already generic enough to handle most of these cases. The problems are mostly around needing more control over metadata (to distinguish CSS loads from ES loads, e.g. -- or indeed, to distinguish ES Module loads from legacy ES async script loads), needing to be able to manage dependencies for a load before its instantiate hook (useful for legacy JS module loaders, and for making it possible to preload ES6 modules), and needing to be able to delay execution (e.g. so that ES6 modules can be preparsed but not executed until needed). It seems to me that a better design for HTML dependency loading would integrate with the ES Loader rather than attempt to mutate it. I don't understand the difference. How do I integrate without duplicating requirements (e.g. having to manage the dependency tree twice) if the ES6 module loader doesn't support the requirements? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es
Re: Referencing modules loaded by HTML Imports.
On Mon, 18 Aug 2014, John Barton wrote: On Mon, Aug 18, 2014 at 2:06 PM, Ian Hickson i...@hixie.ch wrote: Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. If they share a Window object then they should share a Loader, but they may have different baseURLs. So for you example above we write eg. import {b} from ./b; because the scripts in the HTML import will have names relative to the same default baseURL as the main document. I don't understand. Why would b refer to a script in the module? Suppose you have two imports in index.html: link rel=import href=foo.html link rel=import href=bar.html ...and foo.html and bar.html both have this structure: !DOCTYPE HTML script type=module id=mod1 ... /script script type=module id=mod2 ... /script How should an import statement in index.html refer to the id=mod1 module in foo.html? How about the id=mod1 module in bar.html? How about the id=mod2 module in bar.html? (All the files are in the same directory.) I think we could also imagine that such an import declaration could be used without the HTML Import declaration. The fetch() call will ask for baseURL/foo/b.js and the server will say hey that's in an HMTL Import and serve text/html. The fetch() hook will have to detect this and process the HTML Import, then continue with the loading process. That's basically what everything I've been e-mailing the list about is intended to support. On Mon, 18 Aug 2014, Matthew Robb wrote: Would there be any problems treating the html import as a virtual module itself. Giving all scripts inside the sub document the module context object as its this binding? Then to do any additional loading you'd need to do this.import(). I'm not sure what this means. Presumably though the browser should take care of this, the author shouldn't have to call this.import() or anything manually. On Tue, 19 Aug 2014, John Barton wrote: OTOH, I think System.import() is clearer. Not sure how this applies here. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Mon, 18 Aug 2014, John Barton wrote: (For example, a graphical game might need some sprite assets to be loaded before it can start up. So its script might be marked as depending on an img element that loads that image. Or the script contents might have an import statement that refers to that image.) Supporting this case seems straight-forward and can be done entirely by the browser Loader implementation using hooks. That is my hope, yes. The reverse case, where a img depends on a script, is not a use case. Why not? What if the image has an onmouseover handler that calls an API function defined in a module, for instance? Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? import './latter'; It's a solved problem for scripts. The key part of my question was non-loaded. The import bit is in the script. The script isn't loaded yet, so we can't rely on it. script System.import('./former').then((former) = { // do stuff with former, knowing './former' imported './latter'. }); /script This results in multiple RTTs. Also, this doesn't wait until former is needed before loading it. Here we are expressing the dependency of the HTML file on the non-loaded file './former' and it depends on the non-loaded file './latter'. But you don't know that it depends on ./latter until you've fetched ./former, by which time it's too late. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 module loader issues: preloading, and CSS imports
(a la System.JS) to do your own thing if needed. The registry I'm talking about is the Web browser's built-in registry. If that's not the same as the ES6 module registry, then we've presumably failed somewhere since that means you can't get to the ES6 one. :-) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Delaying execution of modules in the loader
On Tue, 19 Aug 2014, Guy Bedford wrote: The loader is designed to enable deferred execution, but there isn't an easy hook to allow this that I know of. System.define is the only load function that does not ensure execution. The others (System.import, System.load, System.module), run an EnsureEvaluated call to run the scripts. It could certainly be worth considering a new load function that runs the hook cycles but does not evaluate - System.preload for example. The implementation is trivial as well. Oh, interesting. You mean that just calling LoadModule() doesn't actually trigger any code to execute? That would solve my problem, I just wouldn't call EnsureEvaluated() until I needed the modules. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Various Loader-related e-mails
of dependency declaration already specified in their JS files. Maybe not hundreds, but maybe dozens. Also, not all these dependencies are written in their JS files. Also, it turns out that people will do lots of things to make their pages quicker, and it's a lot easier, in many cases, to adjust their markup than to adjust their server configuration. But the JS ones are written in JS files. And the non-JS ones are written somewhere. Inventing a mechanism that causes devs to duplicate all of this info is crazy. The mechanism I'm working on here can be used for just the non-JS dependencies if you don't want to use it to do the JS ones in your projects. That's fine. Just to be clear: I think dependency loading web pages is an awesome direction. Using a duplicate declarative solution? Not so much. If we want to avoid duplicating the dependencies, we need to hoist them out of the scripts. Declaring the dependencies in the scripts is too late. I'd be happy to make it possible for dependencies declared in HTML to cause linking to happen. In fact, I'm not really sure how to avoid it: there isn't really a way, as far as I can tell, for me to add a dependency to the ES6 module system without it affecting the linking. And if you allow a tool running on the server (eg a build) then its the same as bundling with an extra unnecessary round trip. The tool is likely to not be running on the server, but on the developent machine. It's unfortunate, and I don't really understand it, but it's a fact of life on the Web that many authors have only minimal control over their servers. Many is now most. This what success looks like: browser page devs no longer work on servers. We have to design for this case. I'm glad you agree with the goal. How do we get there? You can specify dependencies in `instantiate()` returns. That is not before the load; q.v. the subject line of this e-mail. The list is known before the load and it is placed into the ES6 dependency system by returning an object from `instantiate()`; this is the way that bundling works as far as I understand it. The instantiate hook is run after the load. The load happens in the fetch hook. Ideally, we'd have all the dependencies figure out by the locate hook; in some cases I really would like to be able to list the dependencies even before the normalize hook, e.g. in a _previous_ load's instantiate hook. Is there some way we can adjust the spec to do that? On Fri, 15 Aug 2014, Kevin Smith wrote: I think it would be reasonable for us to say that all the dependency declaration mechanisms are equivalent in that they all cause the target dependency to be executed (whatever that means in the context). OK. The instantiate hook allows you to specify arbitrary dependencies, but only if the module in question is not coming from ES6 source code. There's currently no way to say: instantiate this module from source as a normal ES6 module, but add A, B, and C to the dependency list. AFAIK, anyway. Right. Is there some way we can adjust the spec to allow this? This might need careful management around some resource types, though. In particular, CSS imports don't de-dupe, so we'd have to say what it means if you do: style depends-on=my-other-stylesheet @import url(my-other-stylesheet); /style Does this cause my-other-stylesheet to be loaded twice? This is from your other post, right? There are a number of issues around @import. If you're going to use the ES module loader as a general dependency management framework, then each resource will need to have a corresponding ES module image. Can you elaborate on image? What if the corresponding ES module for a stylesheet, instead of initializing and exposing a stylesheet object, exposed a factory function for creating stylesheet objects? Could you elaborate on this? It seems reasonable, except that I really need the StyleSheet object to be created earlier than the instantiate hook since that's the likely place that the Fetch request initialisation options would be exposed for CSS. On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 3:06 PM, Ian Hickson i...@hixie.ch wrote: Suppose you have an HTML import foo.html that declares two modules: script type=module id=a ... /script script type=module id=b ... /script As we noted in another thread, Web devs no longer control servers. And servers no longer allow inline script (for the most part going forward). So I don't see this feature as worth investing effort in. (I don't like it either, but it is what it is). While this might be true for top-level browsing contexts (though I doubt it), it's certainly not going to be true for HTML imports. One of the main goals of HTML imports is to make it possible to mash style sheets and ES6 modules together into a single resource using style
Modules and dependencies found during the load (before instantiation)
On Wed, 13 Aug 2014, Ian Hickson wrote: One of the problems I'm running into when it comes to trying to integrate ES6 modules with HTML and new HTML-based dependency features is the way that I can't tell ES about dependencies I know about before the data is actually fetched and instantiated. Another example of where we have something like this is HTML imports. The fetch hook for HTML imports needs to actually be the hook that does all the parsing, since HTML loads incrementally. (For HTML imports, the translate and instantiate hooks are essentially no-ops.) This means that the in-band dependencies for HTML imports are found during the fetch hook, and need to be set up right away. For example, if an HTML import contains a script type=module block, that inline module needs to be added as dependency of the import itself (so that the import's 'load' event doesn't fire until all internal modules are loaded). It it contains an img src= element, that needs to be added as a dependency as its loading. This is similar to the instantiate hook adding dependencies, except that it has to happen earlier due to the incremental parsing. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Mon, 18 Aug 2014, John Barton wrote: On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 3:41 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. Maybe I'm misunderstanding the ES6 loader spec. What's the Load Record [[Dependencies]] list? The dependencies for the Load. Once the load is complete the record is not needed. How about if the dependencies are changed during the load? For example: script id=a src=a.js load-policy=when-needed/script This seems like an unfortunate design choice Can you elaborate? What would a better design be? I'm certainly not married to this approach. Fundamentally, though, if the problem is how to mark HTML elements as load on demand with a dependency tree, I don't see many options beyond putting things in HTML attributes or elements. (I use scripts in the example above, but the problem applies equally to images or other non-script features, and the use cases for them apply even with scripting disabled. For example, marking images as load on demand so that they don't load until the user scrolls down, with some images needing particular style sheets that are also to not load until you scroll down to the relevant image.) script id=b src=b.js load-policy=when-needed/script script id=c needs=a ... /script script // at this point, the script with id=c is blocked waiting for a.js to // load. Let's change its dependencies: document.scripts.c.needs = 'b'; ...which leads to exotic quirks like this. Well, the DOM is mutable. If we hook something into the DOM, we have to define what happens when it mutates. // now the script needs to trigger b.js to load // a.js' load can be deprioritised (or canceled, if network is at a // premium), and no longer blocks the script from loading /script System.import already supports dynamic loading with runtime dependency selection. If you have a problem with it let's discuss that before redesigning it. I'm not sure I follow. Can you elaborate? How would you use System.import() to mark e.g. an image as dependent on a style sheet when scripting is disabled? Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Referencing modules loaded by HTML Imports.
On Mon, 18 Aug 2014, John Barton wrote: On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: To avoid overly spamming the list I've coallesced my responses to various threads over the weekend into this one e-mail. I really think this makes the discussion more difficult to follow and certainly more difficult to participate in. Apologies, I'm not familiar with this lists' conventions. Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. Separate document implies separate JS global: each needs its own Loader. So the rest of the questions aren't needed. HTML imports definitely need to expose modules across documents. Are you saying this requires changes to ES6 to support? What changes would we need? You need to give more details about such requirements. What is the runtime relationship between Imports and other documents? I assume the Import is providing some state that ends up in the importer but then you are saying these are different documents. HTML imports and regular documents share a Window object, but have separate Documents objects. You can find out more about them here: http://w3c.github.io/webcomponents/spec/imports/ They are shortly to be merged into the HTML spec proper; doing so is mostly just blocked on my work trying to integrate HTML with ES6's module loader so that we don't end up with multiple redundant dependency systems. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Thu, 14 Aug 2014, John Barton wrote: But since the only way the client can know that it needs a.js and jquery.js is if the server tells it [...] There's at least four ways this can happen: - the server tells the browser that it needs file a.js when the server is sending index.html, then tells the browser that it needs query.js when it is sending a.js, and the server doesn't preemptively send anything. - the server sends the browser all three files at once, preemptively. - the server tells the browser that it needs file a.js when sending index.html, then when a.js is requested, it preemptively sends jquery.js at the same time as telling the browser that it'l need it. - the server tells the browser that it needs files a.js and jquery.js at the same time as when it is sending index.html, and the server doesn't preemptively send anything. The first is too slow, since it requires one RTT per file. It's what we have now, and what ES6 modules describe in the absence of server support. The second is too slow, because it implies sending resources that aren't needed, possibly using up bandwidth that could be used for other purposes. It's something that can be supported by packaging and other solutions already being developed, if people want it. The second and third require server-side support beyond what many authors will be able to do. HTTP2 can provide this if people want it, I believe. The fourth is what I'm looking at. The fourth consists of the server having no built-in knowledge except what is in-band in the HTML file, namely, predeclared dependency trees. The key is just that the client can request all the files it's going to need at one time, so that, even without server support, the client doesn't wait more than one total RTT. Wait, you claimed earlier that without server support it's extra round trips. Now without server support it's no extra round trips. Which one ;-) As specced in ES6, it's one extra round trip per depth in the dependency chart; with predeclared dependencies, which is what I would like the ES6 module system to enable me to support in the HTML spec, it would be one RTT per branch of the dependency tree that is activated at once. If you meant suppose we had magic file on the server which listed dependencies and a Loader that read that file, then we can succeed by building the magic file and don't need server code changes. Well, the file wouldn't be magic. It'd just be a predeclared dependencies in the HTML file, something that authors have long asked for, at least on the WHATWG list. That's what bundling does: builds a magic file and ships all of the required modules in dependency order to the server. It even skips the step where the list it built and just sends the all the dependencies. Could we have better tools that allowed finer grained control over the bundle size vs trips? Sure. Ok, great. That's all I'm asking for. Actually I'm asking for less than that, I'm asking if the ES6 module system could be slightly adjusted so that this finer-grained control could be implemented on top of it without duplicating the dependency management (which is what you have to do now if you manually call LoadModule() on the dependencies early). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Fri, 15 Aug 2014, Kevin Smith wrote: Can you elaborate on this, just so I'm sure I understand it right? The execution order is determined by a depth-first traversal of the dependency graph starting with the node being loaded, where edges are ordered. So adding edges can have an effect on the traversal ordering. Execution order is in general not fixed, though, since the user can initiate loads of different parts of the graph at arbitrary times. Just something to consider. Ok, cool, that's what I thought. Thanks. 2) The ability to prefetch resources, given a URL which is currently loading. As Juan pointed out (and I forgot) this can be done with Loader.prototype.load. The problem with doing this is that it requires that the dependency tree be redundantly managed in two places: once on the HTML side, and once on the ES6 side. I would really like to avoid browsers having to implement two more or less identical dependency systems. I think there's an important distinction here. Let's say that you have this dependency chain: A - B - C So A depends on both B and C. Let's say that the user has declaratively indicated that A also depends on some other resource D, but A doesn't *actually* depend on D. How should things be modeled in that case? Would it make sense to add an edge from A to D? If D is an actual dependency, then you would want to execute/initialize it before A. On the other hand, if it's just a likely dependency, then you might want to load it (and it's dependencies) without initializing it, using `Loader.prototype.load`, or perhaps some other mechanism. Ah, I see. I think it would be reasonable for us to say that all the dependency declaration mechanisms are equivalent in that they all cause the target dependency to be executed (whatever that means in the context). This might need careful management around some resource types, though. In particular, CSS imports don't de-dupe, so we'd have to say what it means if you do: style depends-on=my-other-stylesheet @import url(my-other-stylesheet); /style Does this cause my-other-stylesheet to be loaded twice? But that's probably out of scope for this list. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Normalize hook default Web behaviour
Hello again, I'm looking at what the default behaviour of the Web's normalize hook should be. I've read through the links people have posted about this before, e.g. [1], but they tend to focus on the behaviour for sensible inputs and ES6-only inputs, so I'm not sure the following cases are really covered by those. The first case is around normalization vs location. Suppose a page has this markup: base href=http://example.com/; script type=module href=http://example.com/foo.js;/script script type=module import foo; /script Do we want foo.js to be downloaded and executed once, or twice? Second case: import test/; What should that do: throw in the normalize hook? import the file at http://example.com/test.js;? import the file at http://example.com/test/.js;? import the file at http://example.com/test/default.js;? Third case: empty string. What should get imported, if anything, if you do something like this?: import ; Fourth case: Suppose the referrer name is foo/bar, the base URL is http://example.com/baz/;, and a module tries to import ../../../quux. What should get imported? http://example.com/baz/quux.js;, because you only apply the ../ resolution to the referrer name, and trim leading ../s. http://example.com/quux.js;, because you apply the ../ resolution to the referrer name and the base URL, and trim leading ../s. nothing, throw an exception because the ..s go beyond the referrer name's root. nothing, throw an exception because the ..s go beyond the domain root when normalised. [1] https://github.com/dherman/web-modules/blob/master/browser-loader/requirements.md -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 9:43 AM, Ian Hickson i...@hixie.ch wrote: On Thu, 14 Aug 2014, John Barton wrote: But since the only way the client can know that it needs a.js and jquery.js is if the server tells it [...] There's at least four ways this can happen: - the server tells the browser that it needs file a.js when the server is sending index.html, then tells the browser that it needs query.js when it is sending a.js, and the server doesn't preemptively send anything. - the server sends the browser all three files at once, preemptively. - the server tells the browser that it needs file a.js when sending index.html, then when a.js is requested, it preemptively sends jquery.js at the same time as telling the browser that it'l need it. - the server tells the browser that it needs files a.js and jquery.js at the same time as when it is sending index.html, and the server doesn't preemptively send anything. The first is too slow, since it requires one RTT per file. It's what we have now, and what ES6 modules describe in the absence of server support. The second is too slow, because it implies sending resources that aren't needed, possibly using up bandwidth that could be used for other purposes. It's something that can be supported by packaging and other solutions already being developed, if people want it. The second method is faster than your method. It results in the same three file transfer in one less round trip. The second method does not imply sending any more or less resources than any other method listed. The second is too slow because there's lots of other files involved in practice, for example the default style sheet, the scripts that are needed straight away, the Web components that are needed straight away, all the default images, etc. The whole point of the discussion in this thread is that we're talking about files that are not needed straight away, and how to obtain them promptly once they are needed. The second and third require server-side support beyond what many authors will be able to do. HTTP2 can provide this if people want it, I believe. The fourth is what I'm looking at. The fourth consists of the server having no built-in knowledge except what is in-band in the HTML file, namely, predeclared dependency trees. By humans writing markup? That's not happening, at least not for more than trivial programs. It turns out that on the Web, there are lots of trivial programs. When you have trillions of Web pages, even the smallest of fractions ends up being significant numbers of pages. No one is going to write hundreds of lines of dependency declaration already specified in their JS files. Maybe not hundreds, but maybe dozens. Also, not all these dependencies are written in their JS files. Also, it turns out that people will do lots of things to make their pages quicker, and it's a lot easier, in many cases, to adjust their markup than to adjust their server configuration. And if you allow a tool running on the server (eg a build) then its the same as bundling with an extra unnecessary round trip. The tool is likely to not be running on the server, but on the developent machine. It's unfortunate, and I don't really understand it, but it's a fact of life on the Web that many authors have only minimal control over their servers. If you meant suppose we had magic file on the server which listed dependencies and a Loader that read that file, then we can succeed by building the magic file and don't need server code changes. Well, the file wouldn't be magic. It'd just be a predeclared dependencies in the HTML file, something that authors have long asked for, at least on the WHATWG list. You mean devs re-writing the same declarations they used in JS in HTML? Do these authors write modular JS? I am very skeptical. Currently, many of these developers don't write modular JS, no. However, my work here is intended to make it possible to use the ES6 module loading system even with legacy scripts, and to be able to declare dependencies for them too, so it's actually not a concern if it's not ES6 modules that they are writing. Indeed it might not be script at all. Declaring dependencies just between style sheets, HTML imports, images, and other resources will similarly require a dependency system, and if we reuse ES6's rather than require all browsers to implement two or more dependency systems, then the requirements for those non-script cases end up applying to ES6 modules. That's what bundling does: builds a magic file and ships all of the required modules in dependency order to the server. It even skips the step where the list it built and just sends the all the dependencies. Could we have better tools that allowed finer grained control over the bundle size
Importing modules inside HTML imports
Suppose you have an HTML import foo.html that declares two modules: script type=module id=a ... /script script type=module id=b ... /script How should they refer to each other? For example, if module id=b wants to import module id=a? I suppose the logical way is like this: import #a; Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. The logical way to do it would be: import foo.html#a; ...but that means that #a and foo.html#a should resolve to the same canonical string in the normalize hook. Presumably then, that's the full absolute URL? And we look up the document in the import list? But what if the import hasn't been instantiated yet? Should normalize just wait until it has been? (Otherwise, the module registry won't have the module and so locate will be called and locate won't have any idea what to do with that URL.) None of this is very compelling. Is there some expected way to do this that I haven't thought of? (Similar questions apply to referencing other things in imports, e.g. style sheets, images, etc.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Changing dependencies
ES6 modules are immutable, but some things on the Web platform that might have dependencies can have those dependencies change over time. For example, CSS style sheets have a mutable object model, and one of the things in that object model is their list of @imports, so you can dynamically change a style sheet's dependencies. Assuming we are implementing all CSS loads through the ES6 module loader system, what's the appropriate way in which I should spec reactions to changes to a CSS object's @import rules? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies
On Fri, 15 Aug 2014, John Barton wrote: The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. Maybe I'm misunderstanding the ES6 loader spec. What's the Load Record [[Dependencies]] list? (If ES6 isn't maintaining the dependency tree, then this would make my life a lot easier, since I could maintain all the dependency information outside of the Web's default Loader, without having to worry about browsers having to implement duplicate logic. So if I have indeed misinterpreted the spec to that extent, that would be very good to know!) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 3:52 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 2:59 PM, Ian Hickson i...@hixie.ch wrote: Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script Your example will just work if you just use script type=module import a; // ... /script When this module is compiled the other two will be loaded and compiled. That assumes that you have some sort of server-side support so that the server knows that when you request a, it should send a.js and jquery.js, which is an assumption that will work for some people but not [...] No, the loader just requests each of these when it needs them. Right. What I'm trying to do is have the loader load them _before_ it needs them. Without server-side support, on-demand loading looks like this: Client Server || 0ms |-_ | Client finds it needs a.js | -_| |-_ | | -_| Server sends back a.js | _- | | _- | | _- | 200ms |-_ | Client finds it needs jquery.js | -_| |-_ | | -_| Server sends back jquery.js | _- | | _- | | _- | 400ms |- | Client runs the scripts ...whereas if the client is aware of the dependencies early, it can do: Client Server || 0ms |-_ | Client finds it needs a.js and jquery.js | -_| |-_ | | -_| Server sends back a.js and jquery.js | _- | | _- | | _- | 200ms |- | Client runs the scripts ...which is a lot faster. everyone. One of the big pieces of feedback I am dealing with on the HTML side is a request for a way to predeclare the dependency graph to avoid this problem (so that the browser knows to request a.js and jquery.js at Actually I guess you mean avoid multi-pass requests for the entire dependency graph. I'm not sure what that means. But if that means the same thing, then sure. The key is just that the client can request all the files it's going to need at one time, so that, even without server support, the client doesn't wait more than one total RTT. (If you don't have either server-side support or client-side dependency predeclaration, you end up having to discover the dependency chart at runtime, which is a huge latency loss.) Well, as they said back when I worked on a dairy, you've step in it. This issue is at the root of the split between commonjs (modules for node, synchronous loading) and requirejs (modules for browser, prebuilt into bundles to avoid latency). The ES module system attempts to solve this by providing an asynchronous API (eg System.import()) and a proposal, to support server side dependency bundling in HTTP++. The workaround we have now is to pre-build bundles and use the locate() function to map module ids into bundles. That is basically the requirejs solution (with a much better programmer API). I predict node will extend their System to include a synchronous API. Then the circle will be complete. To be sure this is a difficult or even fundamental problem. I respect all efforts to solve this problem; don't believe anyone who says the solution is simple. Relying on packages doesn't really scale, unfortunately. When you have thousands of modules, as e.g. Google+ does, some of which are script and some are style sheets and some are sprite sheets and some are Web components and so on, you really need to be able to tell the server we need these files, and you need to be able to do this without having to discover the dependencies once you've fetched the first batch of files. On Thu, 14 Aug 2014, Juan Ignacio Dopazo wrote: For prefetching we're calling LoadModule() for all the dependencies we want to prefetch in the Fetch or Locate hooks. For example, Systemjs has a System.depCache option which allows you to define dependencies ahead of time. Here's the hook implementation: https://github.com/systemjs/systemjs/blob/master/lib/extension-depCache.js. Interesting, ok. So basically you have to manage the dependency tree outside of the ES6 Loader mechanism proper? I'm really hoping we can find a way to avoid the redundancy of having two mechanisms managing dependencies. On Wed, 13 Aug 2014, Kevin Smith wrote: I see two related abilities here, and I'm not quite sure if you want one of them or both: 1) The ability to add nodes (and edges) to the dependency graph as the graph is traversed by load operations. For example, the user might declaratively
Modules and dependencies known before the load
One of the problems I'm running into when it comes to trying to integrate ES6 modules with HTML and new HTML-based dependency features is the way that I can't tell ES about dependencies I know about before the data is actually fetched and instantiated. The problem can essentially be summarised by this line from the definition of ProcessLoadDependencies(): # The ProcessLoadDependencies abstract operation is called after one # module has nearly finished loading. It starts new loads as needed to # load the module's dependencies. Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script ...where uses is some hypothetical markup for telling the browser about dependencies ahead of time (the assumption being that anims.js contains a line like 'import jquery;'), and where whenneeded is some attribute that tells the browser to not bother starting the whole loading process until the resource is needed. In this example, the first two scripts do nothing at first. Then the third one is parsed, PromiseOfStartLoadPartwayThrough() is called with the contents of the element as the source, and eventually the ES system learns that it wants module a. Here, the normalize and locate hooks work together to determien that the element with id=a is what we're looking for. (Maybe it should be import #a, to distinguish a package name from an ID, but that's a topic for another e-mail.) At this point, I want to tell the ES6 module that: (a) we need to set off a load for that second script element, and (b) once we have that script element's file, it's probably going to want to import jquery, and therefore, we should also set off a load for that first script element with id=jquery. Right now, I don't see any way to do (b). ProcessLoadDependencies() is called after instantiate is done (by InstantiateSucceeded()), and it is the first time the ES6 module system tries to load anything. Ideally I think we should adjust the ES6 module system to support loading and compiling code (though not necessarily executing it) for dependencies at or around the fetch hook. Failing that, I guess we can also just do that at the HTML level. Will that just work? I'm not able to follow the ES spec closely enough to determine if, when ProcessLoadDependencies() is called for a and finds it needs jquery, it will properly link to the as-yet-not-loaded-but- already-in-progress-load for jquery. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 2:59 PM, Ian Hickson i...@hixie.ch wrote: Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script Your example will just work if you just use script type=module import a; // ... /script When this module is compiled the other two will be loaded and compiled. That assumes that you have some sort of server-side support so that the server knows that when you request a, it should send a.js and jquery.js, which is an assumption that will work for some people but not everyone. One of the big pieces of feedback I am dealing with on the HTML side is a request for a way to predeclare the dependency graph to avoid this problem (so that the browser knows to request a.js and jquery.js at the same time). People apparently have huge difficulties even getting their servers configured to send the right MIME types, let alone getting the servers to know about dependencies. (If you don't have either server-side support or client-side dependency predeclaration, you end up having to discover the dependency chart at runtime, which is a huge latency loss.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Dependencies for non-ES modules
Suppose an ES6 module loads a CSS file as an import, and that CSS file has an @import rule of its own. The CSS @import rule semantics are such that the file must be interpreted as CSS. It's not an open-ended import like ES6. Also, the load must not be deduped; each style sheet that is @imported will create a new independent CSSStyleSheet object. I'm not sure how to implement this using the ES6 Loader (should the ES6 loader even be used for this? It seems like it should, in case we later support CSS referencing ES6 modules, e.g. for Web Components). How do I mark a dependency with metadata? If I return an object in the deps field of the instantiate hook's result object, and then pass that through the normalize hook, the GetOrCreateLoad() function applies ToString() to it, so I can't pass any metadata through to fetch, where I need it. (If I translate the metadata in the object passed in deps in the normalize hook, that string gets exposed as the module name, which is rather suboptimal.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Wed, 13 Aug 2014, Kevin Smith wrote: Ideally I think we should adjust the ES6 module system to support loading and compiling code (though not necessarily executing it) for dependencies at or around the fetch hook. It seems like it should be possible, in principle, to add dependencies to a load record at any time prior the instantiate hook resolving. After all, the effect of the instantiate hook is to make the dependency list completely arbitrary. Would that solve the issue from your point of view? If I understand what you're saying correctly, then yes (assuming that those dependencies are also acted upon promptly, rather than only after fetch has returned). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Adding out-of-band dependencies for a module
On Tue, 12 Aug 2014, David Herman wrote: On Aug 11, 2014, at 5:06 PM, Ian Hickson i...@hixie.ch wrote: So I'm trying to figure out how to spec the HTML spec's Loader. We should coordinate -- I've been actively working on this (not the spec per se, but the design) with people engaged in the JS modules work. The HTML default loader design has some requirements that touch on existing JS ecosystems and practices, so we need to be sure we don't spec it in isolation. I've been chatting with people on #whatwg about this; I encourage you to join us! One of the things that we're likely to add as part of this is a generic dependency system. You've mentioned this to me before, but I'm afraid I haven't seen any clear rationale written up anywhere, nor a good description of what this means. I'm working on a more detailed description to send to the WHATWG list. I hope to be able to send something soon. One thing it might mean is a resource-fetching dependency system, meaning that for any two elements A and B that require fetching a network resource, you can state that A depends on B, meaning that whenever A's resource is fetched, B's resource should be fetched too and the system should not consider A's fetch complete until B's fetch is complete. If that's what you mean, I'm skeptical that an attribute is the right level for programmers to express this kind of resource grouping. We probably need a variety of approaches, sure. The attribute in my earlier mail is just a strawman; whatever the approach, if we end up with a way of saying if you find that you need this module then you should also make sure to apply this style sheet then the problem I described exists. I'm just trying to figure out how that should be specced. In particular, HTTP2 and the TAG's work on package management are better approaches to grouping network resources than scattering dependency attributes across a DOM tree. I'm not familiar with the TAG's work (do you have a reference?). HTTP2's new features are somewhat orthogonal to the issue of saying what resources should be activated together, though. (Also, many people won't be using HTTP2, especially the server-cleverness aspects of HTTP2, for a long time, but may still want to be able to declare dependencies.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Understanding the 'normalize' Loader hook
Assume my script is http://example.com/test.js, and assume that there is no extra information (nobody has registered any module names or anything like that). If I do: import a; import ./a; import /a; import //example.com/a; import http://example.com/a; ...am I supposed to end up with the same normalized name for all five? How many entries in [[Modules]] should this result in? (I understand that the answer depends on the default loader; what I'm asking is, what should the default loader's behaviour be.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, 12 Aug 2014, John Barton wrote: See the implemention in es6-module-loader: https://github.com/ModuleLoader/es6-module-loader/blob/master/lib/system.js#L117 Ah, fascinating. So basically: - normalize does relative URL logic based on the current base URL and the referrer (i.e. the URL of the script doing the importing). - locate resolves that URL and adds .js (only if the last segment is part of the path part of the URL and doesn't contain a .?). Is that more or less right? (There's also the loader.paths stuff. Why is that in locate rather than normalize?) (BTW, I noticed that both in that code above and in the spec, referrer is consistently misspelt as referer, the HTTP way.) I'm exploring some ways that the module system could be extended on the Web platform. One thing that some people have asked for is ways to declaratively import stylesheets and the like from inside script, as in: import sprites from images.png; ...where sprites gives you access to an Image element (img). For some cases, e.g. style sheets, you really want to provide more information than just a name, so we'd presumably have the import statement use an element's ID to do the lookup, as in: link rel=stylesheet href=foo.css id=foo-styles ... import styles from foo-styles; // gets us a reference to the link // element somehow Presumably, the way this works is the locate hook returns the actual HTMLLinkElement. But what does the normalize hook return? It can't return a URL, since then locate and fetch won't know to not fetch anything. Is there any way to return out-of-band data with the normalized name? (Really I think normalize and locate should probably be one hook, which returns either a URL or an object. Having them split, especially with the caching happening off a key in the middle, is quite difficult to map to the Web platform.) One option that jorendorff suggested in #whatwg is that if you want to refer to a local ID, you use #foo, as in: import styles from #foo-styles; This kind of approach has historically been problematic (see the history of usemap= for example), but I don't see a better solution. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, 12 Aug 2014, David Herman wrote: This is part of the design work we're actively working on. I'd ask you to hold off until we have some more information for you. I'll keep you posted -- we should have some more details for you soon. Where is the design work happening? I'd love to be part of it, since this directly impacts the rest of the work I'm doing on the HTML spec right now. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, 12 Aug 2014, John Barton wrote: On Tue, Aug 12, 2014 at 2:45 PM, Ian Hickson i...@hixie.ch wrote: On Tue, 12 Aug 2014, John Barton wrote: See the implemention in es6-module-loader: https://github.com/ModuleLoader/es6-module-loader/blob/master/lib/system.js#L117 Ah, fascinating. So basically: - normalize does relative URL logic based on the current base URL and the referrer (i.e. the URL of the script doing the importing). I would expect that normalized names to be platform independent. Sure. I'm talking specifically about the Web platform here. - locate resolves that URL and adds .js This step is platform dependent, it produces an address from a name. Right. (only if the last segment is part of the path part of the URL and doesn't contain a .?). No such restriction is applied in our code. Sure. What do we want for the default Web loader though? Is that more or less right? (There's also the loader.paths stuff. Why is that in locate rather than normalize?) Because the paths processing can produce arbitrary addresses (to cache, CDN, I guess) Sure but presumably if someone explicitly puts in the long URL, they still don't want it to cause a second load, right? I mean, if you do: loader.paths = { 'foo': 'scripts/foo', }; // in a different module import foo; // in a different module import scripts/foo; ...surely you want just one module loaded. No? Come to think of it, maybe you actually just want one loaded even if someone does: import scripts/foo.js; ...or even: // assuming the base URL the whole time has been // http://www.example.com/ import http://www.example.com/scripts/foo.js;; Is there any time we'd want all those imports to result in separate module loads? I'm exploring some ways that the module system could be extended on the Web platform. You might look at Guy Bedford's experiment on loader plugins https://github.com/systemjs/systemjs that follow the path laid down by Jame Burke in requirejs http://requirejs.org/docs/api.html#plugins Same basic idea, yeah. It's unfortunate, IMHO, that we have to have special syntax to get something from the normalize hook to the locate hook. It means it gets exposed in the name of the Module, and it means that if your syntax has any redundancy (e.g. the way the loader plugins SystemJS can infer the plugin type before the ! or have it explicitly given after the !) you can end up with duplicates you didn't intend. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, 12 Aug 2014, David Herman wrote: On Aug 12, 2014, at 2:46 PM, Ian Hickson i...@hixie.ch wrote: On Tue, 12 Aug 2014, David Herman wrote: This is part of the design work we're actively working on. I'd ask you to hold off until we have some more information for you. I'll keep you posted -- we should have some more details for you soon. Where is the design work happening? I'd love to be part of it, since this directly impacts the rest of the work I'm doing on the HTML spec right now. Right now what I've been doing is working with various stakeholders gathering requirements and constraints and beginning to sketch out what the solution space looks like. This includes people working on userland loader implementations, people in the Node community and browser development communities, people working on the JS modules design and spec, and people working on WC and HTML imports. Most of that has been in one-off discussions e.g. at the last TC39 face-to-face. I'll be filling out https://github.com/dherman/web-modules/tree/master/browser-loader with our progress. I don't want to block you and I'm happy to include you in these discussions, but there are enough stakeholders that it's not going to work to make everyone come to #whatwg at this stage. Cool, ok. (I wouldn't expect to do any real development work in an IRC channel, FWIW. That's just where I've been bouncing ideas off people. The real work for HTML happens on the WHATWG mailing list.) What's the expected output here? Are you hoping to write the spec for the Web's default loader? Or the spec for the spec? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Adding out-of-band dependencies for a module
On Tue, 12 Aug 2014, Rick Waldron wrote: On Mon, Aug 11, 2014 at 8:06 PM, Ian Hickson i...@hixie.ch wrote: One of the things that we're likely to add as part of this is a generic dependency system. Authors have long asked to be able to do things like define that their scripts depend on CSS or images or whatnot. If we introduce a global attribute for this is HTML, say needs=, then it will be possible to do something like: script type=module needs=foo href=foo.js/script ...where foo is an ID to some other element. So far so good. Unless the module has 1 dependency. That's no problem, we just define the attribute as taking a space-separated list of IDs. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Adding out-of-band dependencies for a module
So I'm trying to figure out how to spec the HTML spec's Loader. One of the things that we're likely to add as part of this is a generic dependency system. Authors have long asked to be able to do things like define that their scripts depend on CSS or images or whatnot. If we introduce a global attribute for this is HTML, say needs=, then it will be possible to do something like: script type=module needs=foo href=foo.js/script ...where foo is an ID to some other element. So far so good. However, I don't see how to actually add these dependencies to the Load Record's [[LinkSets]]. In the instantiate hook, I can either override the behaviour entirely (providing my own dependency list, but also having to evaluate the code myself and return an eventual Module), or I can return undefined and let the ES spec handle all of it, with no way to add explicit dependencies. I guess since the HTML spec is going to be calling both LoadModule() and EnsureEvaluated() for each module declared by script type=module, one solution is just to handle these myself, and not call EnsureEvaluated() until all the dependencies are ready as well as the LoadModule() promise being resolved. In that the expected behaviour? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
/multipage/webappapis.html#jump-to-a-code-entry-point The line that calls [[Call]] is Make the appropriate script execution environment specified by context execute the s's code entry-point. I can't actually mention [[Call]] explicitly because it might not be JavaScript that I'm executing. I'm hoping we can more explicitly glue this together at some point, maybe with WebIDL defining a generic term that is then explicitly mapped to [[Call]] in the ECMAScript/WebIDL binding in the WebIDL spec. BTW, I'm also assuming that a batch of events would be handled as a single ES job and that the abstract operation for that job would sequence through setup the the script settings for each event handler and then call it. Nah, that's all handled by the DOM spec. It can't be all a single ES job because, if nothing else, it could be interleaving ES and non-ES handlers. Finally, and a bit of an aside, I find it somewhat confusing that there are entities you call objects (for example, script settings objects) that don't seem to actually need to be exposed as ECMAScript objects. Unfortunately the English language has too few nouns. :-) This problem occurs all the time. For example, ES uses the term element for things that aren't HTML Elements; CSS uses properties for things that aren't JS properties; the word attribute is used for both WebIDL attributes and HTML content attributes, which are distinct even though there's usually a 1:1 mapping between them; the term media type means something different in a MIME context than a CSS context, the term selector is used in the ES grammar to mean something unrelated to CSS Selectors; the word resource means something different in almost every Web spec; the word character sometimes means multiple different things within a single spec (and rarely does it mean what it sounds like it means -- ES is a particularly prominent offender in that realm!); the terms user and author mean different things in different specs, etc... As far as object goes, you can pretend that all things called objects in the HTML spec are ES Objects of one kind or another, and it's just that some of them aren't exposed to author script. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Manipulation of the execution context stack
On Mon, 21 Jul 2014, Allen Wirfs-Brock wrote: I just added and remove it from the execution context stack to the text NewJob step 2 to make it explicit that suspending the running execution context also removes it from the stack. Cool, thanks. That fixes the problem. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Mon, 21 Jul 2014, Allen Wirfs-Brock wrote: So if there is no ES code to execution prior to that first user action then you might defer the whole 8.5 initialization process until then. Well, loading an HTML file involves manipulating the Window global object, so I need the realm initialised before I start that. However, if there is some other way to acquire and execute ES code prior to such a user action (for example, FF chrome code, a startup script, etc.) when you would have to do 8.5 initialization earlier. You might use the first Realm for that code or you might use the first Realm as sort of system utility realm, if you have a use for such a thing. Those are out of scope of the HTML spec. I think the realm created by 8.5, in the context of HTML, will never be used. (I expect implementations just won't create one, in practice, but that's an implementation detail.) It sounds like I need to give InitializeFirstRealm a better name, such as InitializeHostDefinedRealm. [...] Again, walking through this I can see that I should probably do a little refactoring to make these steps clearer. Thanks, that would be great. For each script that is ready to be processed (the source code has been retrieved) you just enqueue a PendingJob record for a ScriptEvaluationJob (15.1.9) with the realm for the job set to the realm that the script runs within. Do you have any opinion on how I should handle attribute event handlers? They are conceptually FunctionBodys with specific parameters, and they are parsed the first time they are invoked, but can be reinvoked later without being reparsed. Currently the HTML spec hand-waves this using code entry points but those don't really map to anything in ES. These are the relevant algorithms: Parsing: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#getting-the-current-value-of-the-event-handler Execution: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#the-event-handler-processing-algorithm How should I map this to ES6? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Tue, 10 Jun 2014, Ian Hickson wrote: On Tue, 10 Jun 2014, Allen Wirfs-Brock wrote: By an ECMAScript Environment (and this is what Ecma-262 defines, although it doesn't actually use that name) I mean a heap of ECMAScript objects (and related values) that may directly reference (point to) each other and a single thread of execution of ECMAScript code. The environment may include multiple global objects. Ok. Sounds like that mays to an event loop, on the HTML side. That should be quite workable. I'll invoke 8.5 when I create an event loop (with zero scripts), and I'll invoke CreateRealm() and then 8.5.1 when I create a Window. So I started trying to figure out how this would work, but I'm still having trouble (sorry). When an event loop is created, we invoke the algorithm in 8.5 Initialization, with step 7 set to obtain zero scripts, right?. Now, the user opens a tab or something, and so a Window object needs to be created. What do I do, exactly? Do I need to create a new realm? New execution context? Both? Do I basically do steps 1-5 of the Initialization steps again? I guess I do nothing else until I see a script; then what do I do? do I create a PendingTask record for the execution of the script, push it to the front of the Task Queue, and let 9.5's NextTask call procede with this new task? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Manipulation of the execution context stack
8.5 Initialization step 4 says Push newContext onto the execution context stack, and step 8 calls NextTask. 8.4.2 NextTask suspends the running execution context in step 2, then in step 3 asserts The execution context stack is now empty. However, I can't find anything in the prose around suspension that actually pops the execution context stack. Am I missing something? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Mon, 21 Jul 2014, Ian Hickson wrote: On Tue, 10 Jun 2014, Ian Hickson wrote: On Tue, 10 Jun 2014, Allen Wirfs-Brock wrote: By an ECMAScript Environment (and this is what Ecma-262 defines, although it doesn't actually use that name) I mean a heap of ECMAScript objects (and related values) that may directly reference (point to) each other and a single thread of execution of ECMAScript code. The environment may include multiple global objects. Ok. Sounds like that mays to an event loop, on the HTML side. That should be quite workable. I'll invoke 8.5 when I create an event loop (with zero scripts), and I'll invoke CreateRealm() and then 8.5.1 when I create a Window. So I started trying to figure out how this would work, but I'm still having trouble (sorry). When an event loop is created, we invoke the algorithm in 8.5 Initialization, with step 7 set to obtain zero scripts, right?. Now, the user opens a tab or something, and so a Window object needs to be created. What do I do, exactly? Do I need to create a new realm? New execution context? Both? Do I basically do steps 1-5 of the Initialization steps again? I guess I do nothing else until I see a script; then what do I do? do I create a PendingTask record for the execution of the script, push it to the front of the Task Queue, and let 9.5's NextTask call procede with this new task? Here's my best guess about how to integrate HTML and ES. So far I've only attempted to describe script execution, but the rest should follow pretty straight-forwardly in theory. When an event loop is created, invoke the algorithm in 8.5 Initialization. Step 7 should obtain zero scripts. This results in 8.4.2 NextTask being invoked. 8.4.2 NextTask is adjusted as follows: The implementation defined unhandled exception processing in step 1 must be the report an error logic in the HTML spec. The implementation defined manner for selecting a non-empty Task Queue in step 4 is to return execution to the calling algorithm; subsequent logic in the HTML spec will then resume the NextTask algorithm when a new task has been primed. When a Window or Worker is created, run 8.5 Initialization steps 1-6, except that in 8.5.1 InitializeFirstRealm, this implementation requires use of an exotic object object to serve as realm’s global object, namely, the Window or WorkerGlobalScope object. Then, suspend the execution context. Stash the realm in the script settings object for the Window. When you load a script, the browser fetches the file, gets the body, decodes it to Unicode, and then creates a PendingTask record whose [[Task]] is ScriptEvaluationTask, whose [[Arguments]] consists of a list with one member, the Unicode characters obtained earlier, and the [[Realm]] is the object stashed in the script settings object. That record is put in the Task Queue, and then the NextTask algorithm is resumed. Does anyone see anything problematic here? Does it look ok? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Manipulation of the execution context stack
On Mon, 21 Jul 2014, Allen Wirfs-Brock wrote: On Jul 21, 2014, at 11:23 AM, Ian Hickson wrote: 8.5 Initialization step 4 says Push newContext onto the execution context stack, and step 8 calls NextTask. 8.4.2 NextTask suspends the running execution context in step 2, then in step 3 asserts The execution context stack is now empty. However, I can't find anything in the prose around suspension that actually pops the execution context stack. Am I missing something? A job (task in the version you're looking at) Is there a more up to date version I can look at? I couldn't quite work out what the canonical file to look at was. I've been using this: http://people.mozilla.org/~jorendorff/es6-draft.html is always initialized (by NextJob) with an empty execution context stack. What step in NextJob does this? It seems that step 3 asserts it, but step 1 doesn't seem to affect the stack, and step 2 refers to the suspend prose, which seems mostly non-normative (I can't quite tell it's normative status -- there's no step-by-step algorithms, which seems to be the way the ES spec indications normativity, but there's no RFC2119-style prose either, so I can't tell the descriptive statements in that section from the prescriptive ones). NextJob creates a root execution context and then transfers control (a goto, not a call) As phrased it's more like a tail-call, but the three are black-box indistinguishable at the spec level, so that's somewhat academic. [...] We are essentially faking up an initial current job state that NextJob can switch out of when scheduling the first real job. I guess what I'm saying is that it's not clear to me where the switch out step happens. Do you have a pointer? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Manipulation of the execution context stack
On Mon, 21 Jul 2014, Allen Wirfs-Brock wrote: Is there a more up to date version I can look at? I couldn't quite work out what the canonical file to look at was. I've been using this: I just release a new PDF draft Friday at http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#july_18_2014_draft_rev_26 Ah, cool, thanks. (Is there a URL that will always point to the very latest version, by any chance?) is always initialized (by NextJob) with an empty execution context stack. What step in NextJob does this? It seems that step 3 asserts it, but step 1 doesn't seem to affect the stack, and step 2 refers to the suspend prose, which seems mostly non-normative (I can't quite tell it's normative status -- there's no step-by-step algorithms, which seems to be the way the ES spec indications normativity, but there's no RFC2119-style prose either, so I can't tell the descriptive statements in that section from the prescriptive ones). It's because NextJob is only supposed to be used within an Job initiation abstract operation that is passed to EnqueueJob. So, since we start with an empty stack in 8.5 and each job each returns/unwinds to its starting context it flows like this empty stack create dummy root context 8.5 Initialization, does stuff The does stuff in particular includes step 5, Push newContext onto the execution context stack. returns/unwinds to dummy root context Where? NextJob, deletes dummy root context Where? Step 3 of NextJob says Assert: The execution context stack is now empty, but I don't see anything that undoes the effect of 8.5's step 5, which makes it not empty. I admit I haven't made an exhaustive search of all the algorithms directly and indirectly called by 8.5. I started trying to trace all the steps between 8.5:5 and NextJob:3 in this e-mail, but that's a lot of calls so it's probably not worth including here. Do you have a precise pointer to the actual step that unwinds the stack? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Mon, 21 Jul 2014, Allen Wirfs-Brock wrote: Yes, this is pretty much what I had in mind. Cool, thanks. I mentioned in other message, I can refractor things a bit to make it a bit easier to express. Cool, ok. Let me know when I should start speccing things on my end. However, Realms don't provide the isolation that is required for different origin documents. See the discussion at https://github.com/dslomov-chromium/ecmascript-structured-clone/issues/7 I think this is confusing two things: the same-origin policy, and event loops. Multiple documents with different effective script origins can (and frequently do) share one event loop, with script from one origin on the stack below script from another origin. In single-process browsers, there's only one event loop, even though they support cross-origin iframes, tabs, etc. In fact, to make it worse, scripts can on-the-fly change their origin using document.domain. Exactly how this works isn't exactly defined yet, but the work to define this is described here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20701 It's defined at a level slightly above ES itself. It doesn't re-use the realm machinery per se. What prevents two realms from different origins from ever sharing anything isn't anything in ES, it's just that we never actually provide a way for references to make it across (except in edge cases involving document.domain manipulation, though those only allow it for what we call similar origins). Event loops, though, are true isolation. If a browser has two documents in two different event loops, they can never share anything. They have different heaps, stacks, etc. Structured cloning was invented to allow data to be passed between event loops. However, even with one event loop, you still need structured cloning to tranfser data between realms sometimes, because the Web platform logically isolates them, as discussed above. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' [ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
The initialization steps for Web browsers
(I first tried to send this last week, but it seems the es-discuss mailman is filtering some of my mail as spam or something?) Hello, I've been working with jorendorff to try to write a description of the Loader part of the ES6 spec, to make sure I have a good grip of what the spec says before I look at how I need to hook into it to define the Web's dependency mechanism in the context of HTML Imports, etc. As part of this, I'm trying to understand how I should hook the HTML spec into the ES6 spec for the purposes of regular script execution. Is my understanding correct that the HTML spec should invoke this algorithm when the HTML spec creates the Window object?: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-initialization If so, what should the browser do in step 7? I don't fully understand how this is supposed to work. Suppose a page is just: body script alert(document.body.innerHTML); /script script alert(document.body.innerHTML); /script If I read the #sec-initialization algorithm correctly, the scripts will execute back-to-back with no change in the DOM, so they'll output the same text. But the Web requires that these output different text, since the second script element won't be in the DOM when the first executes: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3051 Should I just say to invoke that algorithm but skip steps 6-8? (Also, how could step 6's substeps ever get triggered?) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
as module loading, since they need to share network resources, can have interdependencies, etc. Alternatively, you might define a new kind of ES Task, let's call it a SyncDOMTask. Then at step 7 you might EnqueueTask a DOMSyncTask onto the ScriptTasks queue between the two ScriptEvaluationTasks. Are these tasks related in any way to the HTML spec's task queues and event loop mechanism? Should we integrate these somehow also? I understand that this is all pretty vague and leaves a lot up to you. That's fine. :-) I just want to make sure it's all well-defined, I don't mind doing the heavy lifting. But I need to define ES execution in a host independent manner. I'm trying to provide the building blocks that you and other hosts need to describe how their complex environment-specific semantics integrate with the baseline ES execution semantics. Cool. (Also, how could step 6's substeps ever get triggered?) Working backwards, step 5 does many things, some of which are specified as having error conditions and exceptions, so I have to take into account what happens if any errors occur. Step 6, just says that if they do then the startup of the ES environment has failed. If an implementor can prove that they [can't] trigger any of those error conditions then they don't have to worry about it. But for completeness, I do. Do you have an example of how any of those steps could fail? It seems to me that if step 6 triggers, the whole scripting engine has failed to start up, which seems like it should be something that is non-conforming. :-) It's up to you to define what you initially enqueue in step 7. It could be nothing (step 7 currently says one or more, it probably should say zero or more). Zero or more would, I think, fix my confusion here. Step 8 just says to dispatch the next pending ES Task. You need to do that to actually get things started. NextTask seems like it is somewhat redundant with the HTML event loop mechanism. Ideally I think I'd like to have the hooks set up so that when a task completes on the ES side, it just returns to the HTML event loop, which then does its stuff, and eventually calls back into the ES spec to run the next script. It occurs to be that these implementation-specific extension points may be hard to find as they hare buried as steps in several algorithms. in my next revision I see if I can define an abstraction operation corresponding to each extension points. They we will have a list of operations that a host must define. That would certainly help, yes. Cheers, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The initialization steps for Web browsers
On Tue, 10 Jun 2014, Domenic Denicola wrote: Remember that ES tasks === HTML microtasks (in all implementations today [...] That doesn't sound right. If every script is always running on an ES task, then it sounds like an ES task is neither an HTML task nor an HTML microtask. A single HTML task might involve running multiple scripts (some even nested inside each other, with microtasks firing after each of those). For example, consider a task that changes a flag and then fires an event; the event being fired is then handled by a number of event listeners, each of which then fires an ES task to run the script, and after each one there's the microtask queue is flushed, before finally returning back to the main task, and then continuing the event loop. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
. Steps 4-5 calls out to the host provided task scheduler. Steps 6-10 initiates execution of the task that was selected by the host. Step 9 is an extra hook that allow the host environment to do additional host-spec processing for each task immediately before it is executed. Right, but what I'm saying is that from an editorial perspective it would be simpler for host specs to hook into the ES spec, and would be easier for implementors to understand, if the loop was turned inside-out from what it is now. Instead of the ES spec having an algorithm that works like this: NextTask result: handle problems arising from the last job (result) stop running code get more code to run start running code (eventually calls NextTask) ...it would be easier if it was: RunCode (code): start running code stop running code let result be the result of running the code handle problems arising from the last job (result) return to calling algorithm in host spec ...where RunCode is called by the host spec to run code. On a related note, it would be easier if algorithms that said to Perform any implementation or host environment defined processing named the specific steps. For example, in EnqueueTask step 7, it could say Perform any implementation- or host-environment-defined processing of /pending/ to *queue a new task*, where queue a new task is a magic phrase (hook) that I would then be able to reference in HTML, e.g. by saying When the ES spec says to *queue a new task*, follow these steps Cheers, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The initialization steps for Web browsers
On Wed, 11 Jun 2014, Domenic Denicola wrote: Hmm. How do we reconcile this with the fact that promises use microtasks in all implementations today? Are they nonconformant with the spec? Or is the spec flexible enough that e.g. PromiseTask ES tasks can be put on a HTML microtask queue, while ones involved in the whole script lifecycle business can be put on the HTML task queue? Where in the ES spec are the ES jobs for promises queued up? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The initialization steps for Web browsers
On Wed, 11 Jun 2014, Domenic Denicola wrote: From: Ian Hickson [mailto:i...@hixie.ch] Where in the ES spec are the ES jobs for promises queued up? https://people.mozilla.org/~jorendorff/es6-draft.html#sec-triggerpromisereactions and https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise.prototype.then; search for `EnqueueTask(PromiseTasks`. EnqueueTask() step 7 is where the HTML spec would hook in and treat different jobs as ending up in different task queues. Presumably, if we want all promise resolutions to be treated as microtasks, then that step would be overridden to queue a microtask when queueName = 'PromiseTasks', and queue a regular task otherwise (or whatever the other queues need), where that task/microtask would trigger the NextTask magic to run the actual job. (As far as I can tell, in an HTML implementation the only queue name that is used is PromiseTasks currently, so maybe EnqueueTask() step 7 would just always queue a microtask. The only other queue name used in the ES spec currently is ScriptTasks, but that one is never called in a browser environment, according to the discussion in the other fork of this thread, where I was talking about this with Allen.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Tue, 10 Jun 2014, Allen Wirfs-Brock wrote: Regarding, Domenic's and Boris responses, I don't see why ES6 promise related Jobs need to be translated into HTML Tasks/Microtasks at all. The ES6 spec. takes care of creating and queueing its promise related Jobs. The only thing HTML needs to worry about is specify when the ES PrimiseJobs queue is serviced in relationship to any other ES Job queues it may use. That means the the HTML scheduling algorithm may impose a scheduling priority of promise Jobs relative to various kinds of HTML Tasks/MicroTask. But it doesn't mean that that promise Jobs have any of the other semantic characteristics of those HTML abstractions. Well presumably if promise resolution job enqueings are interleaved with, e.g., table sorting microtasks queueings, they'd need to be executed in that order. So at some point they need to actually interleave with non-ES-driven microtasks. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The initialization steps for Web browsers
On Tue, 10 Jun 2014, Allen Wirfs-Brock wrote: EnqueueTask() step 7 is where the HTML spec would hook in and treat different jobs as ending up in different task queues. Presumably, if we want all promise resolutions to be treated as microtasks, then that step would be overridden to queue a microtask when queueName = 'PromiseTasks', and queue a regular task otherwise (or whatever the other queues need), where that task/microtask would trigger the NextTask magic to run the actual job. No, that's not the intent of the ES design. The EnqueueTask abstract operations takes the name of a specific Job queue as an argument and always places the newly created PendingJob record into the named queue. It's important because the enqueuing order for a specific queue determine the relative ordering of the Jobs in that queue. The whole reason we have a separate queue for promise Jobs is because we need to preserve that execution ordering. Microtasks also preserve execution ordering. My point is just that we need to maintain more than just promise callback ordering -- we need to maintain the relative order of promise callbacks and all the other things that trigger microtasks. (As far as I can tell, in an HTML implementation the only queue name that is used is PromiseTasks currently, so maybe EnqueueTask() step 7 would just always queue a microtask. The only other queue name used in the ES spec currently is ScriptTasks, but that one is never called in a browser environment, according to the discussion in the other fork of this thread, where I was talking about this with Allen.) No, I think you would still use the ScriptJobs queue. It's the only defined way to actually request ES execution of a Script. As far as I can tell, ScriptTasks (or ScriptJobs) isn't actually used anywhere in the spec except in 8.5 Initialization to queue a job. In particular, nothing in NextTask is sensitive to the precise names of the queues, it just grabs tasks from any job queue. In practice, since we have to coordinate all the other tasks going on, and since script execution for legacy scripts is not queued up in a job queue but is instead done synchronously from HTML tasks, it seems like the simplest way to actually manage this from the HTML side is to just spoon feed the ES algorithms a single job at a time, so than NextTask only ever has one job to chose from. This also seems like it would be easiest to implement from browsers, since it means they'd only need one task management system (the HTML event loop), and their requirements with respect to NextTask would boil down to just run this task, with no need to manage any queues at all. The way I think about it is that HTML schedule queue needs to feed down to ES Job queues because it is the ES Jobs that define the actual execution semantics of ES code. Well, we need to feed down to the specific algorithms that set up the execution contxts and realms and so on, sure. But that's separate from the job queues per se, no? HTML could schedule a microtask into the PromiseJobs queue if the microtask needs to be executed after all pending promise Jobs. Or you could define you own ES MicrotaskJobs queue and define the ES scheduling relationship between it and the ES ScriptJobs and PromiseJobs queues. We already have an event loop mechanism, I don't think it makes sense to just recast the whole HTML mechanism into a JS mechanism. (JavaScript is optional in browsers, after all -- we wouldn't want a browser to simply not start up if the user disabled JS!) Finally, note that anything that is internally defined to use promises (for example, module loading phases) will end up getting schedule through the PromiseJobs queue as part of the promise resolution processing. Yeah. I'm still wrapping my head around exactly how to integrate the module loading stuff with all the other loading and dependency management that HTML does. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Thu, 29 May 2014, Kevin Smith wrote: Ok. I'm not really sure how to extend the ES6 module system in a way that won't stomp on this working group. How do I (at the spec level) tell the ES6 module system that it should not evaluate a particular module until some non-script resource, e.g. a style sheet, is available? It seems like it needs a closer integration with load records than the APIs would enable. For example, would we be able to hook the CSS @import loading mechanism into load records? How about marking a load as low-priority, is that something we can do with load records? So, what we currently have is ES6 defining a dependency loading framework and a requirement that the host environment satisfy the contract represented by that framework. An alternative might be to assume that host environment defines a loading framework available through some global, promise-returning primatives, and defining ES module loading in terms of those primatives. I think this would entail moving much of the loader pipeline into HTML, and allowing the ES spec to focus specifically on linkage. My intuition says that this would be a better overall design, since it would bring all resource loading concerns under a common subsystem using a common resource model. Are you thinking along these same general lines? That's an option. I don't have an opinion on whether this is the better way to go or whether ES6 should be extended to provide what is needed to define the plumbing for other features, nor do I mind who writes the spec text. My only opinion here really is that I think we should make sure the Web doesn't end up with multiple redundant dependency systems. On Thu, 29 May 2014, John Barton wrote: My intuition is that any such plan would be vigorously opposed by the JS community. Then it's probably not a good plan. This suggests that the plan should be to instead make sure that whatever ES6 defines can be used by other specs to define the Web's loading model. Is extending the ES6 model (not the API, but the underlying model with load records and so on) something that could be on the table? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Thu, 29 May 2014, Juan Ignacio Dopazo wrote: - some people want to predeclare a bunch of scripts and their dependencies, without actually downloading any of them ahead of time, and then later, when they're needed, have the entire tree downloaded all at once. At the moment we're doing this by running static analysis tools on the ES6 modules and using the information from the dependency tree to know how to download all of them at once. Right, it's relatively common for people to do this. Not just for scripts, indeed, but also for style sheets and other resources. Ideally the browser would take care of this logic for the author. This becomes especially difficult when there's multiple leaves in the dependency tree, with a lot of shared roots, and you just want the files you need (and in particular, you don't want to wait for the files to have been downloaded to discover what the next level of dependencies is, since that would add one round-trip time per dependency level). - sometimes, even a file that is not downloaded immediately upon being referenced by another file might still want to be precached, so that when it _is_ needed, it's already locally available The Loader object is actually a dictionary, so it acts as its own cache. You can call loader.fetch() yourself without the module being executed in order to cache it. The idea here is that the browser would be able to determine when it's best to preload the file; the author would just want to tell the UA that the file is something worth precaching, not actually do it. I'm having difficulty understanding the spec for the instantiate hook. Does it get called before the fetch hook? Is there some way to dynamically add dependencies later? The lifecycle of a module request is normalize - locate - fetch - translate - instantiate. Instantiate doesn't actually execute anything until all of the dependencies have gone through the same 5 steps. Aha, ok. Is there a way to add dependencies before the fetch hook is called? When is the fetch hook called in the current ES6 logic? As soon as locate provides a URL? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Thu, 29 May 2014, John Barton wrote: On Thu, May 29, 2014 at 2:31 PM, Ian Hickson i...@hixie.ch wrote: On Thu, 29 May 2014, Juan Ignacio Dopazo wrote: - some people want to predeclare a bunch of scripts and their dependencies, without actually downloading any of them ahead of time, and then later, when they're needed, have the entire tree downloaded all at once. At the moment we're doing this by running static analysis tools on the ES6 modules and using the information from the dependency tree to know how to download all of them at once. Right, it's relatively common for people to do this. Not just for scripts, indeed, but also for style sheets and other resources. FWIW, we call this bundling. I mentioned it earlier as a problem that ES6 has not addressed. It is specific to browser needs. Ok. Deferring loads and pre-declaring dependencies to enable browsers to bundle requests is part of what I would like to address. Ideally the browser would take care of this logic for the author. This becomes especially difficult when there's multiple leaves in the dependency tree, with a lot of shared roots, and you just want the files you need (and in particular, you don't want to wait for the files to have been downloaded to discover what the next level of dependencies is, since that would add one round-trip time per dependency level). At least for ES this has to be done in the server: the dependencies are declared in the source. Right. CSS has them inline too. For other kinds of resources there's no way to declare them at all right now. Ideally I'd like to add something to browsers (probably something closely related to, augmenting, or subsuming the ES6 module loading infrastructure) that enables authors to declaratively pre-declare the relationships. This would also help with the problem of how to bundle requests for modules and CSS. I'm having difficulty understanding the spec for the instantiate hook. Does it get called before the fetch hook? Is there some way to dynamically add dependencies later? The lifecycle of a module request is normalize - locate - fetch - translate - instantiate. Instantiate doesn't actually execute anything until all of the dependencies have gone through the same 5 steps. Aha, ok. Is there a way to add dependencies before the fetch hook is called? At least the draft of the Loader spec we followed did not allow a loader hook to add dependencies. Honestly the newer draft has so much detail I cannot be sure what the API is, but there were a few calls that amount to parsing the file and extracting the dependencies. If these call were API, then tools could add dependencies at the right time in the pipeline. I've advocated for this simply because it makes the system easier to understand. The current spec seems to require that [[Dependencies]] be empty while [[Status]] is 'loading', so I guess we'd have to change that if we were to extend this. Can anyone explain what the implications of changing this would be? When is the fetch hook called in the current ES6 logic? As soon as locate provides a URL? Yes, unless the request already has full URL and locate() is not called. I guess to make it possible to defer loads, we'd have to add some sort of logic in ProceedToLocate()? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Fri, 23 May 2014, Garrett Smith wrote: And can we change needs= back to depends=? I haven't gotten as far as figuring out what the API should look like, so it's probably too early to bikeshed specific attribute names. :-) The basic theme of script needs= is making it possible for resources (probably more than just scripts) depend on each other and delay loads until they are needed. For example, being able to say this script shouldn't download yet. Shouldn't download or shouldn't be evaluated? Both. When it is needed, though, it should also download and apply this style sheet, Stylesheets, too? :-) Anything, ideally. On Fri, 23 May 2014, Matthew Robb wrote: On Fri, May 23, 2014 at 5:04 PM, Ian Hickson i...@hixie.ch wrote: Could you elaborate on what it would mean for a module to import a template or style sheet? I'm not super-familiar with ES6 modules yet so I'm not sure exactly how this would manifest syntactically. So my (albeit limited) understanding of ES6 Loader is that it is up to the environment to create a relevant implementation. This has been referred to as the System global loader. What I am proposing is that in the browser, dependencies for things like modules, components, templates, stylesheets, are all important for different reasons and in each of those contexts. So the browser's System loader should have a method of loading any of these common browser dependencies. The only thing left to decide is what the exports of non-modules would be. For components it seems obvious by default they would export their components by global name. document.register(x-foo, ...); and import { XFoo } from path/to/component; Ah so the ES6 import statement can import anything, even things that aren't ES6 modules? It would certainly be cool if that was possible. But you could go further and give components the ability to represent modules in script explicitly. You might also want to export all linked components from within a given component by default. link rel=imports href=x-foo-button.html/ module import { XFooButton } from x-foo-button.html; /module In the above case you would either implicitly or explicitly be able to do module export XFooButton as x-foo-button.html; /module I hope any of what I just typed is understandable, if not I will try to put it in better words when I have more time. Well presumably we wouldn't want to require that people write script to add things to the dependency system, right? I mean, we presumably would want the markup to also do the export step implicitly. On Fri, 23 May 2014, Kevin Smith wrote: A script could then tell the system to add this img element / HTMLImageElement object as one of the dependencies for a script it was injecting, so that that script doesn't run until the image is downloaded. (Doing this, assuming the script is then told to run immediately, would be another way of telling the image it was needed. That's one reason to have the dependency system be abstract like this: it lets different parts of the platform participate by just exposing a generic interface, so that Web authors think we designed this all as one coherent whole.) Do you think that, in principle, a resource of a given type should be able to declaratively specify a dependency upon a resource of a different type? I don't think this is a general principle, e.g. I don't think it makes much sense for us to extend the PNG spec to integrate with this. But there are certainly multiple parts of the platform that want to declare dependencies on and from different resource types. So, for example, an ES module might hypothetically declare a dependency upon a CSS stylesheet and vice versa? If that is something that ES wants to be able to declare, I would be happy for us to support it. I think *the* critical attribute that such a dependency system must have is a universal syntax and semantics for identifying resources, across all resource types. In other words, all resources must be identified by URL/URI. I don't think a URL is the right way to identify everything. Many things in the Web platform that you could legitimately want to depend on don't have a URL. For example, a promise, or an inline script block, or an HTML video element (the latter in particular would have several URLs, the whole point would be to depend on the element so that things only happen once that element has figured out which file it wants to play and is ready to do so). On Tue, 27 May 2014, John Barton wrote: On Fri, May 23, 2014 at 5:04 PM, Ian Hickson i...@hixie.ch wrote What/where would be the best place to define such a system, Github. I really meant which specification. As I see it we have four obvious places where we could concretely define the Web's dependency system: - the ES spec - the HTML spec - the Fetch spec - some new spec (HTML Imports
Re: Integrating the Webs' dependency systems
On Tue, 27 May 2014, Matthew Robb wrote: @Ian, It seems like the first real question is, based on what will eventually be in the ES6 Spec for the Loader API, what is the System Loader as it pertains to the web/browser environment and is there potentially a need for a specification of it here (or at least outside of tc39). I'm not sure I understand this question, but I'm happy for us to first answer this question, sure. :-) How do we determine the answer to this question? On Tue, 27 May 2014, John Barton wrote: I think the Loader nicely isolates these particular functions: I don't see any urgency in standardizing them. However the delegation of the specification of System leaves us in the weird place of having everything except the actually external API spec-ed. Web folks could almost just say Browsers shall have a window.System instance of Loader. There is a missing part of the Loader spec essential for Web and not very important for node: bundling for network transmission see https://github.com/systemjs/systemjs. I don't understand this paragraph. What does it mean for us to not standardise Loader's functions? Is System something that we are expecting some non-ES spec, e.g. Fetch or HTML, to define? But to your original question about non-JS loading: you can extend the Loader class to add methods for CSS and HTML. These would be a cache in front of xhr for the most part, hence my suggestion that implementation (GitHub) is a good place to start. The next step, and one quite critical to practice, is integration with bundling. Here practical expertise is essential so again implementation would be a critical guide. There exist solutions in the pre-ES6 space to consult as well. This seems to imply that to do anything with this mechanism, someone (the page author?) has to provide some script code. However, it's very much my goal to be able to address use cases that don't involve any script at all (and that work even when the browser has scripting disabled), for example, I'd like whatever solution we develop here to be able to handle prioritising the loading and applying of different style sheets and images, e.g. so that images that are not currently rendered aren't downloaded yet, even though they are mentioned later in the page. One could imagine having markup like: link href=foo.css rel=stylesheet load-policy=on-demand id=foo-styles ... img src=foo.png alt=... load-policy=on-demand depends-on=foo-styles ...where an img element is defined as being needed when it's rendered, and where the browser would therefore only fetch the image and its stylesheet when the image is scrolled into view. This would need to work without any script involved at all, but should the author later add script with its own dependencies, we would want all the script dependency stuff to use the same underlying system so that if the script needs foo-styles or the foo.png image, it would all work as one coherent whole. On Tue, 27 May 2014, Kris Kowal wrote: Supposing that a page has both a service worker and a custom loader, I would expect all requests for URL’s in the page (href, src, etc) to 1. pass through the page’s loader 2. pass through the browser's fetch mechanism 3. pass through the service worker 4. pass through the browser's fetch mechanism again 5. possibly arrive at the true service [...] This sounds like feedback for the Fetch spec. Anne? On Tue, 27 May 2014, Kevin Smith wrote: I don't think a URL is the right way to identify everything. Many things in the Web platform that you could legitimately want to depend on don't have a URL. For example, a promise, or an inline script block, or an HTML video element (the latter in particular would have several URLs, the whole point would be to depend on the element so that things only happen once that element has figured out which file it wants to play and is ready to do so). How would you identify such dependencies, within this system? (The identification must somehow allow de-duplication.) Well for anything that is handed to the dependency system by calling some API and passing it an object, e.g. a promise or DOM Node, the object's very identity would presumably be sufficient. For declarative mechanisms that refer to elements by ID, the ID would presumably be a way to look up the element and then the element's inherent identity would suffice. In fact in the strawman I had proposed last year, the URL for a script wasn't actually used as the identity, what the proposal did was use the URL to look up the script element and then used the script element as the target of any deduping. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'___ es
Integrating the Webs' dependency systems
Right now there appear to be three separate efforts to develop dependency systems for the Web platform: - ES6 Modules - HTML Imports - script needs= in HTML At the moment they are mostly not overlapping, but it seems likely that all will grow over time and that could get messy. I would therefore like to propose that we integrate these so that we end up with just one system that manages all three. What do people think? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Fri, 23 May 2014, Ryosuke Niwa wrote: On May 23, 2014, at 3:14 PM, Ian Hickson i...@hixie.ch wrote: - script needs= in HTML Could someone give me a pointer about this? This is the first time I've heard of this feature. It's a work in progress, but the last public post from me about it was: http://lists.w3.org/Archives/Public/public-whatwg-archive/2013Aug/0277.html I'm currently going through feedback sent since then to work out how to proceed in its design; that's what led me to looking into the HTML Imports and ES6 Modules features. The basic theme of script needs= is making it possible for resources (probably more than just scripts) depend on each other and delay loads until they are needed. For example, being able to say this script shouldn't download yet. When it is needed, though, it should also download and apply this style sheet, that image, that HTML Import, and that other script, and then once all of those are downloaded and applied, it should itself be applied. There's also related work into how to control the relative priority of downloads (e.g. needed now, needed after things that are needed now, not yet needed, not yet needed but may be precached). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Integrating the Webs' dependency systems
On Fri, 23 May 2014, Matthew Robb wrote: I think this is a great discussion and it would be cool if it could get mirrored to the other working groups (specifically esdiscuss). Assuming you mean this thread, it is. :-) (If you meant the HTML spec discussion regarding needs= and company, that's more about HTML than scripting specifically, which is why it's happening on the WHATWG list.) It would be great if WebComponents used the Loader and thus you could easily import a component into an es6 module and you could build a component that is entirely an es6 module that simply exports it's relevent bits. This would require something like link rel=imports type=module but I almost. I'd love to be able to import css from an es6 module or import a template etc. Could you elaborate on what it would mean for a module to import a template or style sheet? I'm not super-familiar with ES6 modules yet so I'm not sure exactly how this would manifest syntactically. Abstractly, as far as I can tell, we can imagine the superset of the dependency parts of ES6 modules, HTML imports, and HTML in general as described by a model where some central processor has a list of items, along with a mechanism for adding new items to the list, and each item: - has some means of identification so it can be deduped if it is added to the list multiple times - has the ability to fetch its contents if not already available - has the ability to be executed or applied - has a list of other items that it depends on - has a list of promises that it must wait for before being applied - has a current state, probably one of: idle, downloading, waiting for dependencies, ready, applying/executing, loaded, error - has some sort of execution policy, probably one of: block scripts until run, run asap, run when needed (i.e. when its ability to be executed is invoked); maybe some more esoteric policies like running only once anything that depends on it is about to be run itself - has some sort of download policy, e.g.: download asap, download once the asap things are downloaded, download only when needed, download when needed but can be precached if there is free available bandwidth. So for example, a style sheet imported by link today would be identified by its URL, fetching its contents would use the Fetch specification (e.g. fetching over HTTP), applying it would mean adding it to the style sheet set of the current Document, it wouldn't depend on anything initially but if any @imports were found while it was being parsed then those would probably be dependencies, and it would have the policies of run asap and download asap. (Once we have this model in place, it might make sense to add a feature to HTML to control these policies for each resource in the list; e.g., for link rel=stylesheet, an attribute.) Similarly, an ES6 module would presumably map to this as follows: the identifier would be the module name, the ability to fetch the contents would be defined by the Loader (if I understand the spec right), what it depends on would be based on the import statements, and it would presumably have the policies of run asap and download asap. A script src defer element found during parsing could, in this model, be described as an item that is waiting for the promise that describes the Document being parsed, and it would probably have the policies of run asap and download once the 'asap' things are downloaded. One could also imagine having img whenneeded ..., an image that would be represented in this system as an item identified by the HTMLImageElement object, which can be told to download via some method e.g. img.fetch(), and whose policies would be run when needed, download when needed but can be precached. A script could then tell the system to add this img element / HTMLImageElement object as one of the dependencies for a script it was injecting, so that that script doesn't run until the image is downloaded. (Doing this, assuming the script is then told to run immediately, would be another way of telling the image it was needed. That's one reason to have the dependency system be abstract like this: it lets different parts of the platform participate by just exposing a generic interface, so that Web authors think we designed this all as one coherent whole.) Does all that make sense? Did I miss some feature or behaviour that ES6 modules have that can't be described in the above? What/where would be the best place to define such a system, and how would we hook all the specs together to use it? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Language Negotiation API
On Tue, 16 Jul 2013, Andy Earnshaw wrote: navigator.language isn't part of any stable specification It's part of the HTML standard: http://whatwg.org/html/#language-preferences ...which is very stable at this point (there's basically no way that part of the spec can change in an incompatible fashion, since it's widely implemented; the only possible changes are those that approach reality more, and those that add features). and even the current HTML 5.1 draft doesn't specify that tags should be returned in canonical form. Do you think it would be a good idea to raise an issue for this? Fixed. (A change that approaches reality more.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fwd: delay keyword
On Thu, 5 Jul 2012, Boris Zbarsky wrote: On 7/5/12 1:50 PM, Brendan Eich wrote: Seems like a bug in Firefox, a violation of HTML5 even. The slow script dialog should not allow an event loop to nest. Cc'ing Boris for his opinion (this may be a known bug on file, my memory dims with age). [...] Say the user decides to close the tab or window when they get the slow script prompt (something that I think is desirable to allow the user to do, personally). Should this close the tab/window without firing unload events (a spec violation) That's not a script violation, it's just equivalent to turning off scripts briefly and closing the browsing context. or should it fire them while other script from the page is on the stack and at some random point in its execution (hey, another spec violation)? The spec allows user agents to abort scripts (with or without catchable exceptions) upon a timeout or upon user request, so it wouldn't be a spec violation either way. http://www.whatwg.org/specs/web-apps/current-work/#killing-scripts -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fwd: delay keyword
On Thu, 5 Jul 2012, Boris Zbarsky wrote: It's a violation of HTML5, but so, technically, is the entire Firefox event loop. HTML5 specifies a very specific set of event queues, and implementing pretty much anything other than exactly that is likely to lead to page-visible spec bugs. Of course the slow script dialog itself is technically a spec violation. In any case, I believe we are in the process of moving to a more HTML5-like setup here (with multiple per-page event queues, etc), which should more or less fix most of these issues: we'd just disable all of a page's event queues when the slow script dialog comes up. Note that I say most. There are some fundamental problems here. Say the user decides to close the tab or window when they get the slow script prompt (something that I think is desirable to allow the user to do, personally). Should this close the tab/window without firing unload events (a spec violation) or should it fire them while other script from the page is on the stack and at some random point in its execution (hey, another spec violation)? Good points. I have made a note of your e-mail and will in due course ensure that the slow-scripts dialog and harsh termination of a tab are not violations of the HTML spec. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: HTML5 spec. seems to unnecessarily ban strict mode event handlers
On Thu, 3 Feb 2011, Allen Wirfs-Brock wrote: To be sure, I checked the event handler section of the HTML5 spec (http://dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored. This wasn't intentional. I'm happy to change the spec to more correctly interface with the ES spec. Let me know what it should say! -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: HTML5 spec. seems to unnecessarily ban strict mode event handlers
On Thu, 3 Feb 2011, Allen Wirfs-Brock wrote: I included suggested language in bug http://www.w3.org/Bugs/Public/show_bug.cgi?id=11977 Cool, thanks. I'l follow up on the bug once I get to that one (I'm dealing with them first-come-first-served). Let me know if it's more urgent. Cheers, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: WebIDL
On Fri, 25 Sep 2009, Yehuda Katz wrote: At the urging of some folks, I've poked around WebIDL and have a few observations. I'll use the Window object from HTML as a prop here (it is reproduced, in full, below) If there are issues you would like fixed in HTML5 (as opposed to WebIDL), please file them as bugs. The easiest way to do that is to use the little text box at the bottom of the browser window when looking at: http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#the-window-object Cheers, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: WebIDL
On Fri, 25 Sep 2009, Yehuda Katz wrote: On Fri, Sep 25, 2009 at 11:38 PM, Brendan Eich bren...@mozilla.com wrote: I did not single out Replaceable in my efforts to understand. Sure, but it is certainly odd and I wanted to recount some of the history, just so you'd know not to over-attend to it. ;-) Ha. Maybe it would be worth putting a note in HTML5. [Replaceable] is a quirk of history. Do not over-attend to it. If we start calling out all the quirks of history in HTML5, we'd probably end up doubling the size of the spec. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Last weeks meeting notes
On Mon, 3 Aug 2009, Erik Arvidsson wrote: Discussing whether we want to put setTimeout etc into ECMAScript? There is a clearly a gap between ES and HTML5. How can we close the gap? Execution model needs to be standardized. I'd be happy to coordinate on this. As a warning, though, specifying this in a well-defined manner will require some manner of interaction with the event loop mechanism in HTML5 (or rather, in whatever environment the script is running in). I'm not sure exactly how this would work, but it shouldn't be too hard -- we probably just need to define some terms that the host environment's spec can hook into. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Mon, 6 Jul 2009, Brendan Eich wrote: If we must have split windows in all top browser implementations (so the argument goes), then we must have them in a spec. If not ECMA-262, then HTML5. If split windows, then what |this| binds to (outer or inner) needs to be spec'ed. So here we are. Comments? Your e-mail is in line with my understanding. In HTML5, the inner window is the Window object and the outer window is the WindowProxy object. With one minor exception to do with about:blank, there's a 1:1 mapping from Document to Window, and a 1:1 mapping from WindowProxy to browsing context. Each browsing context can have many Window/Document pairs. For what it's worth, right now HTML5 says: If the script's global object is a Window object, then in JavaScript, the |this| keyword in the global scope must return the Window object's WindowProxy object. This is a willful violation of the JavaScript specification current at the time of writing (ECMAScript edition 3). The JavaScript specification requires that the this keyword in the global scope return the global object, but this is not compatible with the security design prevalent in implementations as specified herein. [ECMA262] I'd love to be able to include this requirement without it being a violation of another spec. HTH, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array Like Interface
On Thu, 14 May 2009, Garrett Smith wrote: Implementations could implement this interface for their own interfaces that may be nonstandard, such as window.frames[1] (if that has not made it into Ian Hickson's HTML 5 yet). window.frames === window and is defined here: http://www.whatwg.org/specs/web-apps/current-work/#dom-frames http://www.whatwg.org/specs/web-apps/current-work/#accessing-other-browsing-contexts -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Thu, 19 Feb 2009, David-Sarah Hopwood wrote: MarkM's point is that *given that the object called Window is inaccessible*, there's no way to observe that the object called Window is at the top of the scope chain. Granted, but there _is_ a way to observe that the object at the top of the scope chain isn't the same as the object returned by |this|, which is what I am concerned about. When a browsing context navigates from page A to page B, the object at the top of the scope chain in code from page A and the oject at the top of the scope chain in code from page B are not the same object, It's not possible to observe that, since by hypothesis neither object is accessible to ECMAScript code. The object itself isn't, but properties on the object are. If two scripts check to see what value a variable x on their global object is, and they get different results, in the absence of any code changing anything, one can tell that they are different global objects. I'm confused by the motivation of the change in HTML5. It seems like it is imposing most of the complexity that would be needed to fix some of the security problems associated with the global object, *without* actually fixing those problems. What security problems does in not fix? The motivation is to make HTML5 describe what browsers do. Also, it is a breach of standards development etiquette for the HTML WG to make a a change (even in a draft) that it believes to be incompatible with the ECMAScript spec, without consulting TC39. It should not have been left to you in the role of an implementor to point out the incompatibility. I am the editor of the HTML5 spec. My e-mail was an attempt at the consultation to which you refer. HTH, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Thu, 19 Feb 2009, David-Sarah Hopwood wrote: Ian Hickson wrote: On Tue, 17 Feb 2009, Mark Miller wrote: On Tue, Feb 17, 2009 at 5:03 PM, Ian Hickson i...@hixie.ch wrote: Indeed, I noted this earlier. The behavior HTML5 codifies is the behavior that the majority of browser vendors have asked me to codify. Majority, huh? Which vendors? How does the behavior they ask for correlate with what their browsers do? Opera, Apple, and Mozilla. The HTML5 spec originally specced what IE does, namely throw an exception when running code whose global object doesn't match the current Window object, but Opera, Apple, and Mozilla rejected this on the grounds that it could not be implemented in a high-performance manner. That is clearly false. It would be a single pointer comparison when entering a new context. I make no comment here on whether this behaviour would be a good idea on other criteria, just that rejecting it on performance grounds is absurd. To be honest it doesn't really matter to me what the reason is -- if three browser vendors tell me they're not implementing the spec, I change the spec. My goal is to have a specification that browser vendors implement. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Thu, 19 Feb 2009, David-Sarah Hopwood wrote: I think it should matter. The vendors should be asked to give a reason that makes technical sense. That this option could not be implemented in a high-performance manner does not make sense -- which means that it is quite possible that the vendors were asked the wrong question, or had some misunderstanding about how such a specification could be implemented. I don't believe there was any misunderstanding, but regardless: if you are able to convince the implementors to implement something other than what is currently specced in HTML5, I'm very happy to change the spec to require that instead. I don't really mind how this works, I just want to make sure the spec is clear on what is required and that the spec matches what actually gets implemented, and ideally I would like it to not contradict the ES specs as it unfortunately does now. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The global object in browsers
On Thu, 19 Feb 2009, Allen Wirfs-Brock wrote: Perhaps it would be useful to have a half day (or even full day) session on this general topic at the March F2F. Since Ian is affiliated with an ECMA member he could attend if he chooses and I might get an appropriate IE platform representative to attend. I really don't have an opinion on this topic. I'm happy to spec whatever the browser vendors are willing to implement. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The global object in browsers
On Tue, 17 Feb 2009, Allen Wirfs-Brock wrote: Perhaps this would be a good initial W3C HTML WG/ECMA TC-39 joint work item if we can expeditiously get past the bureaucratic hurdles. The fact that there isn't an existing consensus behavior among the major browsers would seem to present an opportunity to step back a bit and take a new look at the problem. This would be fine by me, though it should be noted that the people who will ultimately decide what the answer is here are those who will be implementing it, and there is nobody who falls into that camp who is on the public-h...@w3.org list and is not on the es-discuss list as far as I am aware. So it's not clear that there would be any benefit to the getting past the bureaucratic hurdles. I'm happy to spec into HTML5 whatever the majority of implementations eventually do (i.e. HTML5 will just track reality, whatever that is), I would hope the same applies to the ES specs. :-) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
The global object in browsers
Right now ES3 assumes that there is a single global object, which is used at the top of the scope chain and that is returned for this in the global scope. It is possible to show that this is now what some browsers do: var x = 1; function f() { return x; } var global = this; function g() { return global.x; } // some other page's script takes references to f and g // browser navigates to a new page var x = 2; Now, if the other page's script calls f() and g(), it will get different results (2 and 1 respectively, if I didn't screw up the example code). For HTML5, this behaviour has been defined in more detail. The global object is a Window object. This object is per-Document. The object returned by the window attribute on that global object is actually a WindowProxy object, which forwards everything to the current Window object. However, doing this has required that I require browsers to violate the requirement that the ES3 spec has, namely that this and the object at the top of the scope chain are both the global object, because in this model an invariant is that script cannot access the actual global object directly, only the proxy. The HTML5 spec says: If the script's global object is a Window object, then in JavaScript, the this keyword in the global scope must, contrary to the ECMAScript specification, return the Window object's WindowProxy object. If it would be possible for the ECMAScript specification to have a hook that allowed me to require this without violating the spec, that would be great. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Tue, 17 Feb 2009, Mark S. Miller wrote: I don't understand. If the object you're calling Window is inaccessible from ES code, and if the object you're calling WindowProxy forwards everything to your Window, why not just relabel Window - InternalWindow, WindowProxy - Window? I don't really mind what the objects are called, the point is just that the object at the top of the scope chain is not the same as the object returned by this (or window on the global object). And in any case, why not just provide your WindowProxy as the global object to ES code? Why does ES need to be aware of your Window at all? When a browsing context navigates from page A to page B, the object at the top of the scope chain in code from page A and the oject at the top of the scope chain in code from page B are not the same object, but the object returned by the global-scope this in scripts from A and B are the same object (===). The deeper problem here is that ES specs to date -- including the draft ES3.1 spec -- have not yet admitted the existence of multiple global objects. We all know we need to, but it is *way* too late to consider such a change for ES3.1. Ok. This unfortunately leaves us in the status quo position where HTML5 has to require something that violates the ES specs. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Tue, 17 Feb 2009, Mark Miller wrote: On Tue, Feb 17, 2009 at 2:02 PM, Ian Hickson i...@hixie.ch wrote: Now, if the other page's script calls f() and g(), it will get different results (2 and 1 respectively, if I didn't screw up the example code). For HTML5, this behaviour has been defined in more detail. The global object is a Window object. This object is per-Document. The object returned by the window attribute on that global object is actually a WindowProxy object, which forwards everything to the current Window object. What do you mean by current? Are you proposing to legitimize the dynamic scoping behavior demonstrated by your example? I'm not really trying to legitimize anything so much as accurately describe the status quo so that new browsers can be written without having to reverse engineer other browsers. If all major browsers agree on this bizarre behavior, we will indeed be stuck. But if some existing browsers use lexical capture (i.e., return 1 in both cases), then ES-Harmony should feel free to specify that. What do each of the major browsers do? My understanding (assuming I got the code right) is that Webkit and Gecko return different values, and Trident returns 2 for the g() and throws an exception for f(). Here are some demos. 001 is a control test. If it says false, you have a violation of ES, and are likely incompatible with legacy content. If it says true, then test 002. If 002 says false, then ES is being violated in some way. If 002 doesn't say anything, then code is being blocked when the global object doesn't match the current document; Mozilla, Apple, and Opera have all told me not to do that for performance reasons. If it says false, then test 005 -- if that says true before and false after, then the browser is probably incompatible with legacy content. http://damowmow.com/playground/demos/global-object/001.html http://damowmow.com/playground/demos/global-object/002.html http://damowmow.com/playground/demos/global-object/005.html -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object in browsers
On Tue, 17 Feb 2009, Mark Miller wrote: On Tue, Feb 17, 2009 at 5:03 PM, Ian Hickson i...@hixie.ch wrote: Indeed, I noted this earlier. The behavior HTML5 codifies is the behavior that the majority of browser vendors have asked me to codify. Majority, huh? Which vendors? How does the behavior they ask for correlate with what their browsers do? Opera, Apple, and Mozilla. The HTML5 spec originally specced what IE does, namely throw an exception when running code whose global object doesn't match the current Window object, but Opera, Apple, and Mozilla rejected this on the grounds that it could not be implemented in a high-performance manner. They requested that the spec be changed to match what Mozilla and Safari do. What Opera does is known to be incompatible with deployed content (they expose Window objects that aren't === to each other). The browsers all do slightly different things. The HTML5 spec right now is a mix of what Gecko and Webkit do. HTH, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss