diff --git a/mozilla/content/base/src/nsContentSink.cpp b/mozilla/content/base/src/nsContentSink.cpp index 6c90a020b3f..52e74a41b8e 100644 --- a/mozilla/content/base/src/nsContentSink.cpp +++ b/mozilla/content/base/src/nsContentSink.cpp @@ -246,7 +246,7 @@ nsContentSink::ScriptAvailable(nsresult aResult, // script load, assuming that that error code means that the user // stopped the load through some action (like clicking a link). See // http://bugzilla.mozilla.org/show_bug.cgi?id=243392. - mParser->ContinueParsing(); + mParser->ContinueInterruptedParsing(); } } @@ -277,7 +277,7 @@ nsContentSink::ScriptEvaluated(nsresult aResult, } if (mParser && mParser->IsParserEnabled() && aWasPending) { - mParser->ContinueParsing(); + mParser->ContinueInterruptedParsing(); } return NS_OK; diff --git a/mozilla/parser/htmlparser/public/nsIParser.h b/mozilla/parser/htmlparser/public/nsIParser.h index f889ff88cde..00568956681 100644 --- a/mozilla/parser/htmlparser/public/nsIParser.h +++ b/mozilla/parser/htmlparser/public/nsIParser.h @@ -54,13 +54,15 @@ #include "nsHashtable.h" #include "nsVoidArray.h" +// {22039D29-2798-4412-9EA6-A11B41BA27D0} #define NS_IPARSER_IID \ - {0x355cbba0, 0xbf7d, 0x11d1, \ - {0xaa, 0xd9, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}} +{ 0x22039d29, 0x2798, 0x4412, \ +{ 0x9e, 0xa6, 0xa1, 0x1b, 0x41, 0xba, 0x27, 0xd0 } }; // {41421C60-310A-11d4-816F-000064657374} #define NS_IDEBUG_DUMP_CONTENT_IID \ -{ 0x41421c60, 0x310a, 0x11d4, { 0x81, 0x6f, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; +{ 0x41421c60, 0x310a, 0x11d4, \ +{ 0x81, 0x6f, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; class nsIContentSink; class nsIRequestObserver; @@ -211,11 +213,19 @@ class nsIParser : public nsISupports { /****************************************************************************************** * Parse methods always begin with an input source, and perform conversions * until you wind up being emitted to the given contentsink (which may or may not - * be a proxy for the NGLayout content model). + * be a proxy for the NGLayout content model). ******************************************************************************************/ - // Call this method to resume the parser from the blocked state.. + // Call this method to resume the parser from the blocked state. NS_IMETHOD ContinueParsing() = 0; + + // Call this method to resume the parser from an unblocked state. + // This can happen, for example, if parsing was interrupted and then the + // consumer needed to restart the parser without waiting for more data. + // This also happens after loading scripts, which unblock the parser in + // order to process the output of document.write() and then need to + // continue on with the page load on an enabled parser. + NS_IMETHOD ContinueInterruptedParsing() = 0; // Stops parsing temporarily. NS_IMETHOD_(void) BlockParser() = 0; diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index 42acdb4d033..4f9ef96d0bf 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -480,8 +480,9 @@ nsParser::PostContinueEvent() NS_ERROR("failed to post parser continuation event"); PL_DestroyEvent(ev); } - else + else { mFlags |= NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; + } } return NS_OK; } @@ -1412,14 +1413,28 @@ NS_IMETHODIMP nsParser::Terminate(void) */ NS_IMETHODIMP nsParser::ContinueParsing() { + NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED), + "Trying to continue parsing on a unblocked parser."); + if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) { + return NS_OK; + } + + mFlags |= NS_PARSER_FLAG_PARSER_ENABLED; + + return ContinueInterruptedParsing(); +} + +NS_IMETHODIMP nsParser::ContinueInterruptedParsing() +{ // If the stream has already finished, there's a good chance // that we might start closing things down when the parser // is reenabled. To make sure that we're not deleted across // the reenabling process, hold a reference to ourselves. nsresult result=NS_OK; - nsCOMPtr kungFuDeathGrip(this); + nsCOMPtr kungFuDeathGrip(this); - mFlags |= NS_PARSER_FLAG_PARSER_ENABLED; + NS_ASSERTION(mFlags & NS_PARSER_FLAG_PARSER_ENABLED, + "Don't call ContinueInterruptedParsing on a blocked parser."); PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE; @@ -1456,9 +1471,13 @@ NS_IMETHODIMP_(void) nsParser::BlockParser() */ NS_IMETHODIMP_(void) nsParser::UnblockParser() { - mFlags |= NS_PARSER_FLAG_PARSER_ENABLED; - MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this)); - MOZ_TIMER_START(mParseTime); + NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED), + "Trying to unblock an unblocked parser."); + if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) { + mFlags |= NS_PARSER_FLAG_PARSER_ENABLED; + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this)); + MOZ_TIMER_START(mParseTime); + } } /** @@ -1486,7 +1505,7 @@ NS_IMETHODIMP_(PRBool) nsParser::IsComplete() void nsParser::HandleParserContinueEvent() { mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; - ContinueParsing(); + ContinueInterruptedParsing(); } nsresult nsParser::DataAdded(const nsSubstring& aData, nsIRequest *aRequest) diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h index dfd4f4b8140..bbcc936451c 100644 --- a/mozilla/parser/htmlparser/src/nsParser.h +++ b/mozilla/parser/htmlparser/src/nsParser.h @@ -257,6 +257,7 @@ class nsParser : public nsIParser, * @return current state */ NS_IMETHOD ContinueParsing(); + NS_IMETHOD ContinueInterruptedParsing(); NS_IMETHOD_(void) BlockParser(); NS_IMETHOD_(void) UnblockParser(); NS_IMETHOD Terminate(void);