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
|
||
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•20 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
|
||
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
•