Re: [whatwg] Link.onload; defer on style, depends
On Thu, 30 Apr 2009, Sean Hogan wrote: Ian Hickson wrote: On Thu, 30 Apr 2009, Sean Hogan wrote: How do I check if the resource is already loaded? In a cross-browser, cross-site manner? Put an onload handler on the element before it loads and make it set a flag you can check later. And what if the link-element is in the HTML text? The only way to guarantee that is to write it as link onload=... / Surely if it is worth adding the onload event it is worth adding readyState or complete property. You can just do onload=this.readyState = 'done' or some such. I don't want to add yet another feature because the more features we add, the harder it will be for browser vendors to implement everything, and from what I understand, this simply isn't a high priority feature. Maybe in the next version it would make more sense; or we might add it in HTML5 if it turns out there is content that requires this feature. But for now I don't think it's worth adding. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
On Tue, 28 Apr 2009, Boris Zbarsky wrote: Ian Hickson wrote: Ah, yes. good point. I can require that relatively simply (just have the tasks that are queued for 'load' events themselves delay the page's load event) That's exactly what Gecko does. should I? I'd prefer that, but I'd be interested in feedback from other implementors. Done. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: On Wed, 25 Mar 2009, Sean Hogan wrote: Ian Hickson wrote: On Sun, 15 Mar 2009, Boris Zbarsky wrote: Sean Hogan wrote: This is a request for the link element to be given an onload attribute. And presumably a readyState property. At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) I haven't added readyState at this time. I am concerned about feature creep here. As for link.onload, link.readyState is implemented in IE since IE6. Same values as document.readyState, etc. Sure, but we only need one way to do this. How do I check if the resource is already loaded? In a cross-browser, cross-site manner?
Re: [whatwg] Link.onload; defer on style, depends
On Thu, 30 Apr 2009, Sean Hogan wrote: At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) I haven't added readyState at this time. I am concerned about feature creep here. As for link.onload, link.readyState is implemented in IE since IE6. Same values as document.readyState, etc. Sure, but we only need one way to do this. How do I check if the resource is already loaded? In a cross-browser, cross-site manner? Put an onload handler on the element before it loads and make it set a flag you can check later. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: On Thu, 30 Apr 2009, Sean Hogan wrote: At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) I haven't added readyState at this time. I am concerned about feature creep here. As for link.onload, link.readyState is implemented in IE since IE6. Same values as document.readyState, etc. Sure, but we only need one way to do this. How do I check if the resource is already loaded? In a cross-browser, cross-site manner? Put an onload handler on the element before it loads and make it set a flag you can check later. And what if the link-element is in the HTML text? The only way to guarantee that is to write it as link onload=... / Surely if it is worth adding the onload event it is worth adding readyState or complete property.
Re: [whatwg] Link.onload; defer on style, depends
On Mon, 27 Apr 2009, Boris Zbarsky wrote: Ian Hickson wrote: The spec requires the page 'load' event to be fired asynchronously. (There's no black-box way to distinguish this from the case of waiting for the other 'load' events to have fired, as far as I can tell.) Phrased that way, yes. But maybe I wasn't clear on the exact behavior Gecko has here. For image load events, not only does the async event prevent the page load from firing until after it has fired, but it also prevents _checking_ whether the page load should fire until after it has fired. So if the image load event has a listener that starts new network requests, the page load would not fire until after those requests complete. In your proposed model above, whether it does or not depends on the precise order in which the image's async load event races with other network access. If it fires before all other network access is complete (and therefore before your proposed async page load event has been posted), the page load event will wait for the load started from the onload handler. If not, then it won't. There are pros and cons to both setups, I guess; the race above is no worse than a network request whose completion would trigger onload racing against a timeout that starts a network request... On Mon, 27 Apr 2009, Boris Zbarsky wrote: Or did I misunderstand and by fired asynchronously you mean asynchronously check again whether all network activity is done? (I expect not, but just checking.) As far as I can tell, as specced, there isn't a race condition (other than the inherent network race condition). http://www.whatwg.org/specs/web-apps/current-work/#delay-the-load-event In this case: body onload=2 img onload=1; image = new Image(); image.src = 'test'; image.onload = 3 The main 'load' event is queued as soon as there is nothing left that depends on it -- which happens as soon as the img load event was queued up, but before it runs. So the handlers run in the order given (1, 2, 3). -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: As far as I can tell, as specced, there isn't a race condition (other than the inherent network race condition). http://www.whatwg.org/specs/web-apps/current-work/#delay-the-load-event In this case: body onload=2 img onload=1; image = new Image(); image.src = 'test'; image.onload = 3 The main 'load' event is queued as soon as there is nothing left that depends on it -- which happens as soon as the img load event was queued up, but before it runs. So the handlers run in the order given (1, 2, 3). The testcase I was thinking of is: body onload=3 img onload=1; image = new Image(); image.src = 'test'; image.onload = 2 src=foo img src=bar In Gecko, on this testcase, the handlers always run in the order 1, 2, 3. In your spec, if I understand it correctly, they can run in the order 1, 2, 3, or they can run in the order 1, 3, 2, depending on the order in which foo and bar load (and even more precisely, the order in which bar loads and the load event for foo runs). While this is pretty similar to the inherent network race condition (you have no way to predict whether the load for foo or bar will complete first), it's not quite the same. In particular, in this case there is a simple manner of eliminating the race without very much sacrifice (e.g. without having to serialize network requests or anything silly like that). Again, I think there are pros and cons to both approaches; it's not clear to me how big a deal the race above is, and it's not clear to me what the benefits of not waiting for the test load before firing onload are. But it's also not clear to me what the benefits of waiting for it would be. Gecko's behavior is largely a result of the load event firing sync and the need to have it fire after image load events. It's just not black-box-equivalent to what you currently have specced; that's all I was saying. -Boris
Re: [whatwg] Link.onload; defer on style, depends
On Tue, 28 Apr 2009, Boris Zbarsky wrote: The testcase I was thinking of is: body onload=3 img onload=1; image = new Image(); image.src = 'test'; image.onload = 2 src=foo img src=bar In Gecko, on this testcase, the handlers always run in the order 1, 2, 3. Ah, yes. good point. I can require that relatively simply (just have the tasks that are queued for 'load' events themselves delay the page's load event), should I? It seems like you can still get into weird conditions, like what if you have this situation: body onload= img src=a onload=setTimeout(f, 100) img src=b If f() creates a new Image object, the order in which the events fire will depend on whether the timeout fires before or after b's onload fires. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: Ah, yes. good point. I can require that relatively simply (just have the tasks that are queued for 'load' events themselves delay the page's load event) That's exactly what Gecko does. should I? I'd prefer that, but I'd be interested in feedback from other implementors. It seems like you can still get into weird conditions, like what if you have this situation: body onload= img src=a onload=setTimeout(f, 100) Yes, I called that out earlier in this thread, no? -Boris
Re: [whatwg] Link.onload; defer on style, depends
On Wed, 25 Mar 2009, Boris Zbarsky wrote: On Sat, 14 Mar 2009, Greg Houston wrote: On a side note, I can actually attach a functioning onload event to a link element in Internet Explorer. Firefox, Safari, and Chrome ignore my attempt, and Opera will fire the onload event but not update the style of the page. Since there are already implementations of this I've gone ahead and defined it. I have a question about this text. It says that the load event is fired asynchronously; that's fine. However, the page load event is fired synchronously on completion of network activity in some cases (at least in Gecko). Which means that if no steps are taken to prevent it, if the last resource loading is a stylesheet the load event for the page will fire before the load event for the stylesheet. It's not clear to me whether this is ok per the spec text. Note that for image load events such steps to prevent are in fact taken (a pending image load event blocks the page onload from firing). The spec requires the page 'load' event to be fired asynchronously. (There's no black-box way to distinguish this from the case of waiting for the other 'load' events to have fired, as far as I can tell.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
On Wed, 25 Mar 2009, Sean Hogan wrote: Ian Hickson wrote: On Sun, 15 Mar 2009, Boris Zbarsky wrote: Sean Hogan wrote: This is a request for the link element to be given an onload attribute. And presumably a readyState property. At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) I haven't added readyState at this time. I am concerned about feature creep here. As for link.onload, link.readyState is implemented in IE since IE6. Same values as document.readyState, etc. Sure, but we only need one way to do this. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: The spec requires the page 'load' event to be fired asynchronously. (There's no black-box way to distinguish this from the case of waiting for the other 'load' events to have fired, as far as I can tell.) Phrased that way, yes. But maybe I wasn't clear on the exact behavior Gecko has here. For image load events, not only does the async event prevent the page load from firing until after it has fired, but it also prevents _checking_ whether the page load should fire until after it has fired. So if the image load event has a listener that starts new network requests, the page load would not fire until after those requests complete. In your proposed model above, whether it does or not depends on the precise order in which the image's async load event races with other network access. If it fires before all other network access is complete (and therefore before your proposed async page load event has been posted), the page load event will wait for the load started from the onload handler. If not, then it won't. There are pros and cons to both setups, I guess; the race above is no worse than a network request whose completion would trigger onload racing against a timeout that starts a network request... -Boris
Re: [whatwg] Link.onload; defer on style, depends
Boris Zbarsky wrote: Ian Hickson wrote: The spec requires the page 'load' event to be fired asynchronously. (There's no black-box way to distinguish this from the case of waiting for the other 'load' events to have fired, as far as I can tell.) Phrased that way, yes. Or did I misunderstand and by fired asynchronously you mean asynchronously check again whether all network activity is done? (I expect not, but just checking.) -Boris
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: On Sun, 15 Mar 2009, Boris Zbarsky wrote: Sean Hogan wrote: This is a request for the link element to be given an onload attribute. And presumably a readyState property. At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) I haven't added readyState at this time. I am concerned about feature creep here. As for link.onload, link.readyState is implemented in IE since IE6. Same values as document.readyState, etc.
Re: [whatwg] Link.onload; defer on style, depends
Ian Hickson wrote: So testing this: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/44 http://software.hixie.ch/utilities/js/live-dom-viewer/saved/45 (44 uses currentStyle, for IE/Opera, 45 uses getComputedStyle, for Opera/ Firefox/Safari) It seems Gecko is the only engine that blocks here. That's quite odd. The behavior this is showing in Safari, in particular, is the one described in http://webkit.org/blog/66/the-fouc-problem/, and last I'd heard that was causing compat issues and was going to be changed. Specifically, see https://bugzilla.mozilla.org/show_bug.cgi?id=84582#c16. Maybe it hasn't been changed after all? It would be interesting to hear from other browser vendors about their opinions on this issue. I would too. No. What's paused is execution of new scripts, not of existing ones. So in this case, b() executes immediately, while a() executes after the stylesheet loads. Woah, so this can affect the order of script execution? Yes, just like document.write(script src=...) would, no? That seems very dangerous. What if b() depends on a()? I would be surprised if this didn't cause compatibility problems. For what it's worth, we shipped this behavior in Firefox 3.0 and I have yet to see a bug report about anything other than rare instances of flashes of unstyled content due to scripts in one frame forcing layout in another while stylesheets are still loading in the latter. On Sat, 14 Mar 2009, Greg Houston wrote: On a side note, I can actually attach a functioning onload event to a link element in Internet Explorer. Firefox, Safari, and Chrome ignore my attempt, and Opera will fire the onload event but not update the style of the page. Since there are already implementations of this I've gone ahead and defined it. I have a question about this text. It says that the load event is fired asynchronously; that's fine. However, the page load event is fired synchronously on completion of network activity in some cases (at least in Gecko). Which means that if no steps are taken to prevent it, if the last resource loading is a stylesheet the load event for the page will fire before the load event for the stylesheet. It's not clear to me whether this is ok per the spec text. Note that for image load events such steps to prevent are in fact taken (a pending image load event blocks the page onload from firing). -Boris
Re: [whatwg] Link.onload; defer on style, depends
Boris Zbarsky wrote: No. What's paused is execution of new scripts, not of existing ones. So in this case, b() executes immediately, while a() executes after the stylesheet loads. Woah, so this can affect the order of script execution? Yes, just like document.write(script src=...) would, no? And just to be clear, since in Gecko 1.8.1 and earlier link rel=stylesheet blocked the parser, it behaved just like script src=... there. So the order of script execution in your testcase was affected in those builds as well. -Boris
Re: [whatwg] Link.onload; defer on style, depends
On Tue, Mar 24, 2009 at 7:24 PM, Ian Hickson i...@hixie.ch wrote: On Sun, 15 Feb 2009, Boris Zbarsky wrote: So in this: !DOCTYPE html ... script document.write('link rel=stylesheet href=style'); document.write('scripta();\/script'); b(); /script ...is the script paused after the second document.write() call, before a() and b() execute? No. What's paused is execution of new scripts, not of existing ones. So in this case, b() executes immediately, while a() executes after the stylesheet loads. Woah, so this can affect the order of script execution? That seems very dangerous. What if b() depends on a()? I would be surprised if this didn't cause compatibility problems. As Boris points out, it doesn't change the order of execution compared to having the link rel=stylesheet block, which is what gecko used to do. Not sure what other browsers do. On Sat, 14 Feb 2009, Garrett Smith wrote: Boris: Garrett: What would make it easier? I'd really like to know how to design my pages so that they are faster and more responsive. Well, one option is to stop worrying about micromanaging the load order and assume that speculative parsing will solve your problems will it? Possibly. If the author could declare what a script depends on and let the implementation determine what to load and when, would that be too complicated? It seems like this is in general an issue that would be best left up to the browsers to optimise for, instead of having authors be able to micromange this (as Boris put it). In general, scripts shouldn't depend on style sheets anyway; if you are writing code where you want things to be fast, just avoid breaking that rule of thumb and then it will never matter. It's unlikely that we'll ever get to a point when scripts won't depend on stylesheets though. Until CSS is perfect we'll always have to have scripts that create more advanced layouts than what CSS can produce, and these scripts are likely going to depend on data not available until all relevant stylesheets have loaded. So basically I put this argument in the same group as content shouldn't depend on undefined behavior ;) In fact, I believe that google was the big problem when we tried not blocking on pending stylesheets. Something about ads hosted on websites where the scripts from google relied on style information. All that said, I would love to not have to block scripts on pending stylesheets. If all other browsers get away with it, I think we should be able to as well. / Jonas
Re: [whatwg] Link.onload; defer on style, depends
On Fri, 13 Feb 2009, Boris Zbarsky wrote: Ian Hickson wrote: By the way, the spec doesn't yet require the blocking behavior. I couldn't work out how to do it. Could you elaborate on when exactly in the process the style sheet is waited on? Does it happen for all scripts? For example, if a script inserts a style sheet and then a script, does that script wait for the style sheet to load? The current Gecko behavior is that any stylesheet load started by parsing a style or link tag will increment a counter on the document (well, on a per-document script loader object, to be more precise). Completion of the load will decrement the counter. While the counter is nonzero, script execution is blocked. When it goes back to 0, the first pending script (if any) is run. If this increments the counter again, no more scripts are run until the count goes to 0 again. So it doesn't matter how the script is created/inserted, but the only stylesheets that block scripts are ones that the parser knows about. So only the ones present in the original source or added via document.write. If you createElement a link and insert it into the DOM, it won't block script execution. Also, link elements pointing to alternate style sheets don't block script execution. So testing this: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/44 http://software.hixie.ch/utilities/js/live-dom-viewer/saved/45 (44 uses currentStyle, for IE/Opera, 45 uses getComputedStyle, for Opera/ Firefox/Safari) It seems Gecko is the only engine that blocks here. It would be interesting to hear from other browser vendors about their opinions on this issue. On Sun, 15 Feb 2009, Boris Zbarsky wrote: So in this: !DOCTYPE html ... script document.write('link rel=stylesheet href=style'); document.write('scripta();\/script'); b(); /script ...is the script paused after the second document.write() call, before a() and b() execute? No. What's paused is execution of new scripts, not of existing ones. So in this case, b() executes immediately, while a() executes after the stylesheet loads. Woah, so this can affect the order of script execution? That seems very dangerous. What if b() depends on a()? I would be surprised if this didn't cause compatibility problems. On Sat, 14 Feb 2009, Garrett Smith wrote: Boris: Garrett: What would make it easier? I'd really like to know how to design my pages so that they are faster and more responsive. Well, one option is to stop worrying about micromanaging the load order and assume that speculative parsing will solve your problems will it? Possibly. If the author could declare what a script depends on and let the implementation determine what to load and when, would that be too complicated? It seems like this is in general an issue that would be best left up to the browsers to optimise for, instead of having authors be able to micromange this (as Boris put it). In general, scripts shouldn't depend on style sheets anyway; if you are writing code where you want things to be fast, just avoid breaking that rule of thumb and then it will never matter. On Sun, 15 Feb 2009, Garrett Smith wrote: Ian wrote: On Mon, 9 Feb 2009, Garrett Smith wrote: There are two/three issues. 1) want to load stylesheets without having scripts block Put the scripts first. Then the scripts block. I explained this and showed this in examples. If the script is deferred, it will wait for the stylesheet. For the case where you just want scripts to load whenever they are ready to load, you can use async=. 2) want to load stylesheets later, (infoPanel example) Put the styles later. The script blocks the stylesheet. The alternative is to just let the browser manage this and load the style sheets whenever they want. 3) (2), but want to make sure the stylesheet is loaded before the script runs. Put the styles first. The stylesheet can be placed right before the script which depends on it, right before closing body tag: http://dhtmlkitchen.com/jstest/block/link-script-bottom.html and the result will work in Firefox. However, that does not works consistently in a wide enough range of current browsers. Particularly, Webkit and Opera will alert('loaded') before getting the stylesheet. Make the script not depend on the style sheet then. In general, I don't think that this feature request is something that really is necessary on the Web. The best way forward is really to just design your scripts such that they don't depend on the style sheets (you have no guarantee that the user will get the CSS anyway), and then to just rely on the browser vendors to make the right decisions about when to fetch each file. On Sat, 14 Mar 2009, Greg Houston wrote: This is a request for the link element to be given an onload attribute. Often when
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 10:21 PM, Garrett Smith dhtmlkitc...@gmail.com wrote: On Sat, Mar 14, 2009 at 6:54 PM, Jonas Sicking jo...@sicking.cc wrote: On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: [...] Garrett: Whatever we decide when it comes to the defer attribute, it is always useful to have scripting APIs as well. There is just no way that you can cover all use cases declaratively, so it's useful to be able to fall back to using scripting for cases not covered. What other cases do you have? A web application, such as GMail, wanting to show a dialog box to the user asking the user to enter some information. In order to do this it needs to first load a stylesheet to properly style the dialog box. The application would do this by inserting a link rel=stylesheet href=dialog.css into the head of the document. It would then want to know when the stylesheet has loaded so that it can display the dialog box. There's a few reasons depends is not a good solution for this scenario. First off, in order to use it the page would have had to not only insert the link element, but also ad a script depends=dialogStylesheetIddisplayDialog()/script. Second, it gets even worse if a specific dialog is to be displayed, since then the script has to not just generate the above script element, but also dynamically generate the javascript code inside it, for example script depends=dialogStylesheetIddisplayDialog(Dialog Title)/script. This is particularly bad if you'd want to pass a reference to an object to the displayDialog function. The only way I can think of for doing that would be using global variables, and serializing the variable name of the global variable into the script. This would be terrible software design. Third, if something like Content Security Policy [1] gets adopted in browsers it would be impossible to use an inline script. You would instead have to host a separate file that contains the call to displayDialog() call. This would get even worse when combined with the ability to show a specific dialog as described above. It seems much simpler to be able to do: link = document.createElement('link'); link.rel = stylesheet; link.href = dialog.css; link.onload = function() { displayDialog(Dialog Title, someObject); } document.getElementsByTagName('head')[0].appendChild(link); / Jonas [1] http://people.mozilla.org/~bsterne/content-security-policy/
Re: [whatwg] Link.onload
Greg Houston wrote: This is a request for the link element to be given an onload attribute. And presumably a readyState property.
Re: [whatwg] Link.onload
Jonas Sicking wrote on 15 mars 2009 02:55: On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: This is a request for the link element to be given an onload attribute. This sounds like a good idea to me. Seems useful for dynamically added stylesheets too, and possibly for stylesheets where the href attribute is dynamically changed. I also think this is a good thing that should make it into the spec independently of the depends ideas. It is already specified that script elements fire (on)load or (on)error events (see end of 4.3.1[0]) to signal whether loading the external file was successful. Wouldn't it be nice and symmetric if analogous behaviour was specified for all loading of external resources? HTML5 already specifies onload/onerror event handlers for all elements so the actual handlers are already in place on link elements (and others). What remains is to define that link should actually fire these events. Best regards Mike Wilson
Re: [whatwg] Link.onload
Sean Hogan wrote: This is a request for the link element to be given an onload attribute. And presumably a readyState property. At least in Gecko, you can already detect whether the sheet is done loading: if you try to get its cssRules and that throws INVALID_ACCESS_ERR, then it's still loading. (If it throws DOM_SECURITY_ERR then you're not allowed to read the style data; that's why you have to check for the exact type of exception thrown. Though really, if you're loading style sheets cross-site you're in for a world of hurt unless you control both sites.) -Boris
Re: [whatwg] Link.onload
Jonas Sicking wrote: This sounds like a good idea to me. Seems useful for dynamically added stylesheets too, and possibly for stylesheets where the href attribute is dynamically changed. Same thing goes for the style element since an inline stylesheet can have @import rules. Indeed, and there are some things that need specifying around this. See https://bugzilla.mozilla.org/show_bug.cgi?id=185236#c12 and https://bugzilla.mozilla.org/show_bug.cgi?id=185236#c15 for example. Note that image onload events do fire asynchronously in Gecko even if the data is synchronously available, so I have no problem with defining that all the load events, including for inline style with no imports, fire async. Note that inline scripts do not fire load events, by the way. Inline sheets with @import really should, though, no matter what happens for inline sheets without @import. -Boris
Re: [whatwg] Link.onload
Here is how to obtain the functionality of a deferred style sheet for a run-time dialogue box: the semantics of the depends attribute must be changed so that it causes all script code *except function definitions* to wait for the style sheet to load (and perhaps cause it to load as well); whereas all functions defined in such a script would be tagged with the dependency of the script element and wait for the dependents when *called*. Thus, the script handling the dialogue box can be static, and the dependents would be loaded only when one of the functions defined there is invoked. style id=dbSheeet /style script depends=dbSheet /* does not wait for dbSheet */ function displayDialogue(title, args) { } /script button onClick=displayDialogue(Peekaboo, this) /* waits for dbSheet and passes a reference to an object */ /button This would work even if dbSheet is dynamic. The downside of this solution is that the instruction window .displayDialogue = function displayDialogue(title, args) {} would not be equivalent to a plain definition of function displayDialogue. This difference, however, would manifest itself only on pages that would be broken anyway. Chris
Re: [whatwg] Link.onload
On Sun, Mar 15, 2009 at 12:07 AM, Jonas Sicking jo...@sicking.cc wrote: On Sat, Mar 14, 2009 at 10:21 PM, Garrett Smith dhtmlkitc...@gmail.com wrote: On Sat, Mar 14, 2009 at 6:54 PM, Jonas Sicking jo...@sicking.cc wrote: On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: [...] What other cases do you have? A web application, such as GMail, wanting to show a dialog box to the user asking the user to enter some information. In order to do this it needs to first load a stylesheet to properly style the dialog box. The application would do this by inserting a link rel=stylesheet href=dialog.css into the head of the document. It would then want to know when the stylesheet has loaded so that it can display the dialog box. (To avoid FOUC on the dialog box). That is a case where it would seem useful to have a scope=[selector] on the link element. (wildly off-topic, I know). There's a few reasons depends is not a good solution for this scenario. First off, in order to use it the page would have had to not only insert the link element, but also ad a script depends=dialogStylesheetIddisplayDialog()/script. Provided that no script was downloaded, then yes, onload would be easier. If the dialog needed a script that did not exist, it might be useful to use depends. [...] Third, if something like Content Security Policy [1] gets adopted in browsers it would be impossible to use an inline script. You would instead have to host a separate file that contains the call to displayDialog() call. This would get even worse when combined with the ability to show a specific dialog as described above. Adding an inline script is painful. It seems much simpler to be able to do: link = document.createElement('link'); link.rel = stylesheet; link.href = dialog.css; link.onload = function() { displayDialog(Dialog Title, someObject); } Why not implement EventTarget on link? For example: link.addEventListener('load', displayDialog, true); What happens if dialog.css has: @import panel.css /* other rules */ ? What do IE and Opera do? document.getElementsByTagName('head')[0].appendChild(link); / Jonas [1] http://people.mozilla.org/~bsterne/content-security-policy/ Will look into that. Garrett
Re: [whatwg] Link.onload
Garrett Smith wrote: On Sun, Mar 15, 2009 at 12:07 AM, Jonas Sicking jo...@sicking.cc wrote: link.onload = function() { displayDialog(Dialog Title, someObject); } Why not implement EventTarget on link? For example: link.addEventListener('load', displayDialog, true); It's the same thing. link already implements EventTarget; the only question is what events are dispatched, not how one listens to them. What happens if dialog.css has: @import panel.css /* other rules */ Then the load event for the link would not fire until the panel.css file has finished loading, I would hope! -Boris
[whatwg] Link.onload
This is a request for the link element to be given an onload attribute. Often when lazy loading a plugin into an web app it is necessary for the plugin's stylesheets to be applied before the plugin's JavaScript is downloaded. Without the link element having an onload event there is not really a straightforward way of doing this. Currently I am using XMLHttpRequests to grab the stylesheets first since XHR has a success callback, and then appending the stylesheets to the document.head relying on the browser using the cached stylesheet. This seems to work for the most part, but really there are no guarantees. There are other odd workarounds but none of them as straightforward, elegant, and easy to use as the link elements simply having an onload attribute. Thank you for your consideration. Greg Houston
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: This is a request for the link element to be given an onload attribute. I see. Often when lazy loading a plugin into an web app it is necessary for the plugin's stylesheets to be applied before the plugin's JavaScript is downloaded. Without the link element having an onload event there is not really a straightforward way of doing this. It sounds like you want to load resource with dependencies. Currently I am using XMLHttpRequests to grab the stylesheets first since XHR has a success callback, and then appending the stylesheets to the document.head relying on the browser using the cached stylesheet. This seems to work for the most part, but really there are no guarantees. When a stylesheet is added to the document, how (or even if) the resource is downloaded and applied is not part of any official standard. There are other odd workarounds but none of them as straightforward, elegant, and easy to use as the link elements simply having an onload attribute. I proposed a solution to a similar problem not too long ago. script depends=[idref] .../script This would allow for scripts to run without having to wait for stylesheets to load. When the browser parses script depends=..., it looks for elements matching ids in the depends attribute and downloads all of them before running the script. This could be used for other resources, too. object depends=[idref] ... /object - where [idref] is the stylesheet to be loaded. Thank you for your consideration. You seem optimistic. Check the thread: [whatwg] defer on style, depends http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-February/018420.html The first sentence:- | This is a request for the link element to be given an onload attribute. Example:- link onload=loadPlayer() ... - would solve your problem, but with less simplicity than the depends=[...] would. Greg Houston Garrett
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 4:46 PM, Garrett Smith dhtmlkitc...@gmail.com wrote: I proposed a solution to a similar problem not too long ago. script depends=[idref] .../script For me to implement my own depends lazy loader without any hacks the only thing missing is that link onload callback. Given the following example, with depends, if a, b, or c are links, how would you set their title, rel, href, media and other attributes? If a, b, or c is a script, how would you set the id or type of that script? script depends=a b c/script Example:- link onload=loadPlayer() ... This is sort of what I am doing, but missing a couple steps: This is basic usage: [The following examples are using Mootools syntax] MyApp.extend({ Calendar: function(args){ // This entire function is replaced when calendear.js is loaded. $require({ dir: MyApp.pluginDirectory + 'Calendar/', cssFirst: true, css: [{url: 'css/calandar.css', media: 'all'}, {url: 'css/calandarPrint.css', media: 'print'}], images: ['images/bg.jpg', 'images/dayHover.png'], javascript: [{url: 'js/calandar.js', id: 'calendarScript'}], onProgress: function(counter, index, assetsToLoad){ console.log(counter + ' of ' + assetsToLoad + ' required files loaded.'); }, onload: function(){ console.log('All required files loaded.'); new MyApp.Calendar(args); }.bind(this) }); }, Chat: function(){ // This entire function is replaced when chat.js is loaded. $require({ // ... onload: function(){ new MyApp.Chat(); } }); } }); There is a Core.js file that sets up the MyApp namespace. There are plugins called MyApp.Calendar, MyApp.Chat, and so forth. If the user does something that fires new MyApp.Calendar(args), all of the Calendar assets are loaded, CSS first. The JavaScript in Calendar.js overwrites the MyApp.Calendar lazy loading function with the Class method for the Calendar. When the $require onload is fired it then runs new MyApp.Calendar(args) again, this time creating a new Calendar instance. calendar.js: MyApp.Calendar = new Class({ Implements: [Events, Options], options: { // }, initialize: function(options){ // } )}; The MyApp.Calendar lazy loader is now completely gone and any future calls to new MyApp.Calendar() immediately creates a new Calendar instance. So instead of link onload=loadPlayer() ... it would be more like: link onload=checkLoadProgress() ... loadPlayer() would not happen until all the required files are loaded. checkLoadProgress() keeps a tally of the progress. The CSS is created something like this: css: function(directory, source, properties){ properties = $merge({ rel: 'stylesheet', media: 'screen', type: 'text/css' }, properties); return new Element('link', { rel: properties.rel, media: properties.media, type: properties.type, href: directory + source, onload: function(){ checkLoadProgress(); } }).inject(document.head); } I think a native lazy loader such as something along the lines of your depends is a great idea. It would obviously have to be much simpler than what I am doing, sort of in the same vein that you can use the HTML 5 meter or create your own and have more control. I think your idea would probably need more fleshing out though and would require a great deal more from the user agents than what I am requesting, which again is just an onload callback from the link element. On a side note, I can actually attach a functioning onload event to a link element in Internet Explorer. Firefox, Safari, and Chrome ignore my attempt, and Opera will fire the onload event but not update the style of the page. Opera gives the most curious result. I didn't actually check the DOM to see if Opera appended the stylesheet or not. It may be that it just short circuits and fires the onload event. return new Element('link', { rel: properties.rel, media: properties.media, type: properties.type, href: directory + source }).addEvent('load', function(){ alert('Hello World'); }).inject(document.head); Cheers, G.
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 5:24 PM, Greg Houston gregory.hous...@gmail.com wrote: On Sat, Mar 14, 2009 at 4:46 PM, Garrett Smith dhtmlkitc...@gmail.com wrote: I proposed a solution to a similar problem not too long ago. script depends=[idref] .../script For me to implement my own depends lazy loader without any hacks the only thing missing is that link onload callback. Given the following example, with depends, if a, b, or c are links, how would you set their title, rel, href, media and other attributes? If a, b, or c is a script, how would you set the id or type of that script? The proposal is to add the id in the markup, using the ID existing attribute:- link rel=stylesheet href=a.css title=a styles media=screen id=a - and - script id=b src=b.js/script script depends=a b c/script Waits for a and b to load and:- script depends=/script waits for nothing. Example:- link onload=loadPlayer() ... This is sort of what I am doing, but missing a couple steps: This is basic usage: [The following examples are using Mootools syntax] I understand you are using Mootools. The syntax is ECMA-compliant (in this case). That, and the example seems to add more complexity than necessary to provide sufficient explanation (IMO, a simpler example is preferable). The method chaining and Mootools' misguided augmentation of Host object (document.head here) makes the code less clear. The reader should not be forced to understand details about Mootools to understand your example. [snip code] I think a native lazy loader such as something along the lines of your depends is a great idea. It would obviously have to be much simpler than what I am doing, sort of in the same vein that you can use the HTML 5 meter or create your own and have more control. I think your idea would probably need more fleshing out though and would require a great deal more from the user agents than what I am requesting, which again is just an onload callback from the link element. It would require more support from implementors than what I have gotten, that is for sure. Link.onload is simpler for implementors. We have at least two browsers (opera, IE) that support that already. OTOH, depends= offers declarative style for automatic resolution of dependencies. Though more complex than link onload, depends= would seem to be cleanly implementable (though slightly more complex) via internal events. If depends= were implemented, what would be the use-case for link onload? On a side note, I can actually attach a functioning onload event to a link element in Internet Explorer. Firefox, Safari, and Chrome ignore my attempt, and Opera will fire the onload event but not update the style of the page. Opera gives the most curious result. I didn't You got a result (in Opera, using Mootools). It should be explainable. Possibly you have invalid css syntax that opera rejects (check your error console). actually check the DOM to see if Opera appended the stylesheet or not. It may be that it just short circuits and fires the onload event. Opera will fire the onload event when the stylesheet load fails. [snip example] Mootools provides a layer of abstration that gets in the way of making your case. It seems more prudent to use the actual syntax you desire, sans the Mootools abstraction layer. !DOCTYPE HTML html lang=en head titlelink onload/title /head body script type=text/javascript function addStyleSheet() { var l = document.createElement(link); l.onload = linkLoaded; l.type = text/css; l.rel = stylesheet; l.href = l.css; document.getElementsByTagName('head')[0].appendChild(l); } function linkLoaded() { document.getElementById('m').firstChild.data = link onload fired.; } /script button onclick=addStyleSheet()addStyleSheet()/button pre id='m'link not added/pre /body /html l.css: body { background: #3f3; } Result: All browsers updated the document. Opera, IE7: link onload fired. Mozilla rv:1.9.1b3pre, Webkit 3.1.2, Chrome: link not added Cheers, G. Garrett
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: This is a request for the link element to be given an onload attribute. Often when lazy loading a plugin into an web app it is necessary for the plugin's stylesheets to be applied before the plugin's JavaScript is downloaded. Without the link element having an onload event there is not really a straightforward way of doing this. This sounds like a good idea to me. Seems useful for dynamically added stylesheets too, and possibly for stylesheets where the href attribute is dynamically changed. Same thing goes for the style element since an inline stylesheet can have @import rules. Garrett: Whatever we decide when it comes to the defer attribute, it is always useful to have scripting APIs as well. There is just no way that you can cover all use cases declaratively, so it's useful to be able to fall back to using scripting for cases not covered. / Jonas
Re: [whatwg] Link.onload
On Sat, Mar 14, 2009 at 6:54 PM, Jonas Sicking jo...@sicking.cc wrote: On Sat, Mar 14, 2009 at 1:48 PM, Greg Houston gregory.hous...@gmail.com wrote: [...] Garrett: Whatever we decide when it comes to the defer attribute, it is always useful to have scripting APIs as well. There is just no way that you can cover all use cases declaratively, so it's useful to be able to fall back to using scripting for cases not covered. What other cases do you have? Garrett