Bug 478889: Make script-defer work in xhtml. r/sr=peterv

--HG--
extra : rebase_source : 4e2abc2b35c72f7c5831f58b0f1c6940b1824de7
This commit is contained in:
Jonas Sicking 2009-03-15 17:53:09 -07:00
parent a5e5911cc3
commit b6ff240427
4 changed files with 110 additions and 8 deletions

View File

@ -227,6 +227,7 @@ _TEST_FILES = test_bug5141.html \
test_NodeIterator_mutations_1.xhtml \
test_NodeIterator_mutations_2.html \
test_bug28293.html \
test_bug28293.xhtml \
file_bug28293.sjs \
test_bug445225.html \
file_bug445225_multipart.txt \

View File

@ -0,0 +1,100 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=28293
-->
<head>
<title>Test for Bug 28293</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script>
res = 'A';
SimpleTest.waitForExplicitFinish();
onload = function () {
res+='2';
s = document.createElement('script');
s.textContent="res+='g';";
s.defer = true;
document.body.appendChild(s);
res+='3';
s = document.createElement('script');
s.src="file_bug28293.sjs?res+='h';";
s.defer = true;
document.body.appendChild(s);
s = document.createElement('script');
s.textContent="res+='i';done()";
s.defer = true;
document.body.appendChild(s);
res+='4';
}
function done() {
is(res, "ABCDEFGHIJabcdef1M2g34hi", "scripts executed in the wrong order");
ok(!fHadExecuted, "Dynamic script executed too late");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293">Mozilla Bug 28293</a>
<script defer="defer">
res += 'a';
</script>
<script defer="defer" src="data:text/plain,res+='b'"></script>
<script defer="defer">
res += 'c';
</script>
<script>
res += 'B';
</script>
<script>
res += 'C';
s = document.createElement('script');
s.src="file_bug28293.sjs?res+='d';";
s.defer = true;
document.body.appendChild(s);
s = document.createElement('script');
s.textContent="res+='D';";
document.body.appendChild(s);
res += 'E';
</script>
<script>
res += 'F';
document.addEventListener("DOMContentLoaded", function() {
res += '1'
s = document.createElement('script');
s.src="file_bug28293.sjs?res+='M';";
document.body.appendChild(s);
}, false);
res += 'G';
</script>
<script defer="defer">
res += 'e';
</script>
<script src="file_bug28293.sjs?res+='H';"></script>
<script>
<![CDATA[
res += 'I';
s = document.createElement('script');
s.src="file_bug28293.sjs?fHadExecuted=(res.indexOf('f')>=0);";
document.body.appendChild(s);
res += 'J';
]]>
</script>
<script defer="defer">
res += 'f';
</script>
</body>
</html>

View File

@ -397,6 +397,7 @@ nsExpatDriver::nsExpatDriver()
mInCData(PR_FALSE),
mInInternalSubset(PR_FALSE),
mInExternalDTD(PR_FALSE),
mMadeFinalCallToExpat(PR_FALSE),
mIsFinalChunk(PR_FALSE),
mInternalState(NS_OK),
mExpatBuffered(0),
@ -1071,21 +1072,14 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, PRBool& aFlushTokens)
("Remaining in expat's buffer: %i, remaining in scanner: %i.",
mExpatBuffered, Distance(start, end)));
PRBool flush = mIsFinalChunk;
// We want to call Expat if we have more buffers, or if we know there won't
// be more buffers (and so we want to flush the remaining data), or if we're
// currently blocked and there's data in Expat's buffer.
while (start != end || flush ||
while (start != end || (mIsFinalChunk && !mMadeFinalCallToExpat) ||
(BlockedOrInterrupted() && mExpatBuffered > 0)) {
PRBool noMoreBuffers = start == end && mIsFinalChunk;
PRBool blocked = BlockedOrInterrupted();
// If we're resuming and we know there won't be more data we want to
// flush the remaining data after we resumed the parser (so loop once
// more).
flush = blocked && noMoreBuffers;
const PRUnichar *buffer;
PRUint32 length;
if (blocked || noMoreBuffers) {
@ -1094,6 +1088,7 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, PRBool& aFlushTokens)
buffer = nsnull;
length = 0;
#if defined(PR_LOGGING) || defined (DEBUG)
if (blocked) {
PR_LOG(gExpatDriverLog, PR_LOG_DEBUG,
("Resuming Expat, will parse data remaining in Expat's "
@ -1110,6 +1105,7 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, PRBool& aFlushTokens)
NS_ConvertUTF16toUTF8(currentExpatPosition.get(),
mExpatBuffered).get()));
}
#endif
}
else {
buffer = start.get();
@ -1165,6 +1161,10 @@ nsExpatDriver::ConsumeToken(nsScanner& aScanner, PRBool& aFlushTokens)
return mInternalState;
}
if (noMoreBuffers && mExpatBuffered == 0) {
mMadeFinalCallToExpat = PR_TRUE;
}
if (NS_FAILED(mInternalState)) {
if (XML_GetErrorCode(mExpatParser) != XML_ERROR_NONE) {
NS_ASSERTION(mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING,

View File

@ -145,6 +145,7 @@ private:
PRPackedBool mInCData;
PRPackedBool mInInternalSubset;
PRPackedBool mInExternalDTD;
PRPackedBool mMadeFinalCallToExpat;
// Whether we're sure that we won't be getting more buffers to parse from
// Necko