- From: liorean <liorean@gmail.com>
- Date: Thu, 31 May 2007 07:37:19 +0200
Mistakenly sent this to the public-html list instead of WhatWG. Sorry for the double for those on both lists. ---------- Forwarded message ---------- From: liorean <liorean@gmail.com> Date: 31-May-2007 07:24 Subject: Re: [whatwg] setting .src of a SCRIPT element To: HTML WG <public-html at w3.org> On 31/05/07, Jonas Sicking <jonas at sicking.cc> wrote: > > I think IE's behaviour is pretty useful and I'd like the spec to make > > this standards-compliant. It is a common technique to create SCRIPT > > elements dynamically to load data (particularly because this gets > > around cross-domain limitations). Firefox's implementation means one > > has to create a new SCRIPT element each time, keep track of them, and > > remove them from the document again, whereas with IE's implementation > > you can have one "data loader" SCRIPT element and set its .src > > repeatedly. > > The reason I designed it this way was that it felt like the least > illogical behavior. In general a document behaves according to its > current DOM. I.e. it doesn't matter what the DOM looked like before, or > how it got to be in the current state, it only matters what's in the DOM > now. > > For <style> elements this work great. Whenever the contents of a <style> > is changed the UA can drop the current style rules associated with the > element, reparse or reload the new stylesheet, and apply the new style > rules to the document. (There was a bug in Firefox up to version 2, > where certain DOM mutations inside the <style> weren't detected, but > that has been fixed in Firefox 3). > > For <script> things are a lot worse. If the contents of a <script> > element is changed it is impossible to 'drop' the script that was there > before. Once the contents of a <script> has executed, it can never be > unexecuted. And since we can't undo what the <script> has already done, > it feels weird to redo the new thing that you're asking it to do. The difference there is that the styles are continually effective, while the script only does it's effect once. The idea of undoing the script doesn't make sense since it's no longer in effect. It may have set up the envirnment or changed things in it, but after that, the script itself is finished. Everything after that are side effects of the script having been there, it's not actually the script being in place. What I'm trying to say here is that undoing the script after it has executed amounts to exactly no change because the script is no longer in effect which means there is no effect to remove. In my opinion changing the source should just replace the no-longer-in-effect script with a new one, and send that one to the ECMAScript engine for parsing. > Another thing that would be weird would be inline scripts. How would the > following behave: > s = document.createElement('script'); > document.head.appendChild(s); > for (i = 0; i < 10; i++) { > s.textContent += "a" + i + " += 5;"; > } > Would you reexecute the entire script every time data was appended to > the script? Would you try to just execute the new parts? Would you do > nothing? IE gets around this problem by not supporting dynamically > created inline scripts at all, which I think is a really bad solution. I agree this is a problem. I see several non-solutions that simply would close the issue without dealing with valid concerns. The only solution I see that actually handles most concerns is to not execute inline scripts at all without some API call on the script element to tell that it's been set up fully. What if you were building a script body in many text nodes and CDATA nodes and entity reference nodes where you only have a final, executable form once you have set it all up? It makes sense to me to have an API function for triggering evaluation of the script inline contents. So, what are these issues I talk about? Well, mostly it's questions about what is appropriate to do in cases like: 1. We have a script element, without inline content, in the document hierarchy. A src attribute is added. 2. We have a script element, with either a src attribute or inline content, in the document hierarchy. A type attribute is added, removed or modified. 3. We have a script element, with inline contents, in the document hierarchy. A src attribute is added. 4. We have a script element, with no inline content but with a src attribute, in the document hierarchy. Inline content is added. 5. We have a script element, with inline content and a src attribute, in the document hierarchy. The src attribute is removed. 6. We have a script element, in the document hierarchy. It is removed from and reinserted into the document hierarchy. 7. We have a script element, with inline content, in the document hierarchy. The inline content is changed. 8. We have a script element, without inline content, not in the document hierarchy. A src attribute is added. 9. We have a script element, with a src attribute, in the document hierarchy. The src attribute is changed. (An similar example cases, on and on...) I think it would be logical to handle DOM manipulation like so: - Any script element: If a src, type, defer, async, language, charset, for or event attribute is added, removed or changed, the script is flagged as unexecuted. - Any script element: If a src attribute is added or changed, load that resource. - A script element, without src attribute: If inline content is changed, removed or added, the script is flagged as unexecuted. I think it would be logical to handle execution of script like so: - A script element, with an unexecuted flag: If inserted into the document hierarchy, the script is sent to the scripting engine queue and flagged as executed. - A script element, with an unexecuted flag, in the document hierarchy: If an evaluation method on the script element is called or the loading of a resource completes, the script is sent to the scripting engine queue and flagged as executed. - A script element, with an executed flag: If an evaluation method on the script is called with a first argument of true, the script is sent to the scripting engine queue again. Or at least something like that. It would have to be expanded, since I haven't even taken the for, event, defer and async attributes into account here nor the initial document parsing. Why an executed flag? Because I doubt authors would like their scripts reexecuted just because they move an ancestor element in the document or something similar. > So I opted for 'killing' script elements once they have executed, they > become in effect dead elements. This felt simple and consistent. ECMAScript doesn't have a continuous effect, nor does it have incremental parsing/execution. All of the script is executed in one go unless it calls a halting function like alert, but then the script execution is just delayed and not cancelled. After executing the script is no longer in effect, though it might have had persistent side effects. In the face of that it doesn't seem like killing the script element is much good the script itself dies of itself after execution. This behaviour of Gecko only prevents element reuse if you ask me, and that's not particularly desired. -- David "liorean" Andersson
Received on Wednesday, 30 May 2007 22:37:19 UTC