Closed
Bug 276037
Opened 20 years ago
Closed 18 years ago
In application/xhtml+xml during page load getElementsByTagNameNS and getElementsByTagName does not find all currently parsed elements
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: martin.honnen, Unassigned)
References
()
Details
Attachments
(3 files)
2.93 KB,
application/xhtml+xml
|
Details | |
3.26 KB,
application/xhtml+xml
|
Details | |
10.43 KB,
patch
|
Details | Diff | Splinter Review |
HTML and XHTML allow the use of the <script> element to embed script code in the document. The script code inside of a <script> element has traditionally been executed during loading of the document, directly after the <script> element has been parsed. For instance in HTML (text/html) documents people use document.write to insert content into the document during page load. With "real" XHTML, meaning with application/xhtml+xml content, document.write is no longer available but of course scripters would still like to insert content into the document with script while the page loads. My solution for that is to use document.getElementsByTagName('script') respectively document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'script') to grab the last <script> element in the document and call appendChild on its parent node, in the hope that while the script code inside of a <script> element is executed that <script> element is already available in the DOM tree and thus any content is executed directly after the <script> element, the same way document.write would do it. However with Mozilla (tested with the latest nightly Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8a6) Gecko/20041225 as well as with Firefox 1.0 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0) the approach doesn't work when the <script> element sits inside of a table cell inside of a document served as application/xhtml+xml. The test case at: http://home.arcor.de/martin.honnen/mozillaBugs/domInsertionDuringPageLoad/domInsertionDuringPageLoad.xhtml shows that the <script> element inside of the table cell is not yet found by the getElementsByTagName/getElementsByTagNameNS('script') so that the text meant to be inserted into the table cell ends up as a child of the parent node of an earlier <script> element. The same test case served as text/html, available here: http://home.arcor.de/martin.honnen/mozillaBugs/domInsertionDuringPageLoad/domInsertionDuringPageLoad.html however works as intended, the code inside of a <script> element finds that <script> element in the DOM tree and is able to append to its parent node. While I cannot cite a specification saying that script code run during page load needs to have access to the DOM tree including the <script> element the code is contained in that would be highly desirable in my view as it is the only way for script in application/xhtml+xml to insert content at the position of the <script> element. Therefore I file this bug on Mozilla. I add that this is becoming more important as an increasing number of people are using content type negotiation to serve XHTML as text/html to IE but as application/xhtml+xml to Mozilla (or other browsers understanding XML) and therefore use script in application/xhtml+xml and run into the problem to have the script run during page load insert content into the page when and where the script is executed. One newsgroup post about that topic is here: http://groups-beta.google.com/group/netscape.public.mozilla.dom/browse_frm/thread/a9be9f42491271ad/09ad74e3c8fec90c?tvc=1&scrollSave=&&d#09ad74e3c8fec90c
Comment 1•20 years ago
|
||
I think this is because of bug 18333. See also 232004 comment 9.
Depends on: incrementalxml
Comment 2•20 years ago
|
||
Martin, is the table cell relevant? That is, if you replace it with a paragraph, do you still see the problem? What about if the <script> is just a child of <body>? Anne, this is rather unlikely to be a consequence of bug 18333 -- that bug is about _layout_ objects not being constructed, and this bug is about the content model and looks like it should be reproducible even in a display:none iframe (where there are no layout objects in sight).
Updated•20 years ago
|
No longer depends on: incrementalxml
Reporter | ||
Comment 3•20 years ago
|
||
I have done some further tests and Boris rightly suspects that the table is not relevant, changing summary to reflect that. In the following application/xhtml+xml test case: http://home.arcor.de/martin.honnen/mozillaBugs/domInsertionDuringPageLoad/domInsertionDuringPageLoadParagraph.xhtml there are only paragraphs but only the script code in the first <script> element inserts content into its parent node while all following scripts insert content as a child of the first paragraph which is the parent node of the first <script> element. The same test case as text/html works fine: http://home.arcor.de/martin.honnen/mozillaBugs/domInsertionDuringPageLoad/domInsertionDuringPageLoadParagraph.html
Summary: In application/xhtml+xml a script element inside a table cell is not yet available in the DOM when the script executes → In application/xhtml+xml a script element is not yet available in the DOM when the script executes
Reporter | ||
Comment 4•20 years ago
|
||
Further investigation shows that the problem is that during page load in application/xhtml+xml content the methods document.getElementsByTagName and document.getElementsByTagNameNS do not find all parsed elements. The test case during page load counts XHTML span and script elements using the two methods and manually walking the document tree, while the tree walks shows that the last span and script element has been parsed and is in the document tree the two methods do not find those elements, only after onload the methods find the correct number of elements.
Reporter | ||
Comment 5•20 years ago
|
||
Changing summary again to reflect the findings of the last test case <https://bugzilla.mozilla.org/attachment.cgi?id=169634> which shows that the problem is not restricted to <script> elements not being found but other elements like <span> too.
Summary: In application/xhtml+xml a script element is not yet available in the DOM when the script executes → In application/xhtml+xml during page load getElementsByTagNameNS and getElementsByTagName does not find all currently parsed elements
Hmm... It'd be interesting to see exactly what the callstack looks like when we actually do anything in nsHTMLScriptElement::MaybeProcessScript, i.e. when we reach line 649 in that file. I would exect things to work since we in nsGenericElement::AppendChildTo add the new child to mAttrsAndChildren before we call SetDocument on it.
Comment 7•20 years ago
|
||
The problem is that content lists are lazy and rely on the ContentAppended/ContentInserted/ContentRemoved notifications to clear their cached state. But the XML content sink doesn't fire these notifications until the parsing is finished and it fires a single ContentInserted on the root.... Perhaps content lists should be non-lazy for still-loading xml documents (as a short-term hack or something)? What should the behavior of content lists be when they're created by a script element in a document that is then transformed with xslt, btw?
Comment 8•20 years ago
|
||
Shouldn't "we" "just" make the XML content sink fire the notifications like the HTML content sink?
Comment 9•20 years ago
|
||
I'm not sure, in part because I'm not sure how that interacts with XSLT. When we transform, do we change document objects too, or just stick the transformation result into the original document? If the latter, content lists created in the pre-transform document would start seeing post-transform content, which is undesirable. For the rest, I think it should be safe to do content notifications, since we wouldn't call InitialReflow, so frame construction would be suppressed. But we may still up with significant inefficiency from once-per-content notification, whereas a batching system like the HTML sink would take some work (see bug 18333).
Comment 10•20 years ago
|
||
ccing people who may know answers to my questions...
XSLT creates a compleatly new document (so that we can create an html document rather then an xml one). Also, it shouldn't be an issue with stuff created in the original document, since we shouldn't be running any scripts at all in that document once we detect that we're going to XSLT transform it (not sure if we actually do that currently). XSLT currently use DOM methods to create the result tree, so I would think that we send out notifications continously. This might change though if we switch over to the faster nsIContent interfaces.
Reporter | ||
Comment 12•20 years ago
|
||
I attach this as workaround as long as the bug is not fixed as the problem of inserting content during page load into application/xhtml+xml comes up again and again in newsgroups. Instead of using getElementsByTagName(NS) to find the last and current <script> element the workaround looks at the childNodes and that way is able to find the correct <script> element.
Comment 13•19 years ago
|
||
Just as an additional information: I've tripped on this problem in one of my projects too, where a script basically needs to located its own script element in order to be able to "include" more script files automatically. This currently fails, because getElementByTagName() does not return all script DOM nodes. However, when looking at document and its child DOM elements, I can find the "missing" DOM node.
Updated•19 years ago
|
Depends on: incrementalxml
Comment 14•18 years ago
|
||
Fixed by bug 18333. (I was able to reproduce the bug using an opt build from a few days ago, but not using a debug build with the fix for bug 18333.)
Updated•18 years ago
|
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Comment 15•18 years ago
|
||
PLEASE mark the in-testsuite stuff when resolving. Or better yet, add the tests!
Flags: in-testsuite?
Comment 16•18 years ago
|
||
OK. So I wrote a regression test for this based on attachment 169634 [details]. Sometimes the test succeeds. Sometimes it fails.
Reopening.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 17•18 years ago
|
||
could be a regression from 18333
Comment 18•18 years ago
|
||
No, it was broken before 18333.
Comment 19•18 years ago
|
||
The random failures are due to bug 369011 (yay writing regression tests!). Once that lands I'll land these tests.
Comment 20•18 years ago
|
||
Tests committed. Now they pass.
Status: REOPENED → RESOLVED
Closed: 18 years ago → 18 years ago
Flags: in-testsuite? → in-testsuite+
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•