diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp
index d7764e52e58..5dc39b27e34 100644
--- a/mozilla/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/htmlparser/src/CNavDTD.cpp
@@ -730,7 +730,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
eHTMLTags theParentTag=mBodyContext->Last();
theTag=(eHTMLTags)theToken->GetTypeID();
if((FindTagInSet(theTag,gLegalElements,sizeof(gLegalElements)/sizeof(theTag))) ||
- (gHTMLElements[theParentTag].CanContain(theTag))) {
+ (gHTMLElements[theParentTag].CanContain(theTag)) && (theTag!=eHTMLTag_comment)) { // Added comment -> bug 40855
mDTDState=NS_OK; // reset the state since all the misplaced tokens are about to get handled.
result=HandleSavedTokens(mBodyContext->mContextTopIndex);
@@ -1928,6 +1928,12 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
if(result==NS_OK) {
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,*mBodyContext);
if(eHTMLTag_unknown!=theTarget) {
+ if (nsHTMLElement::IsResidualStyleTag(theChildTag)) {
+ result=OpenTransientStyles(theChildTag);
+ if(NS_FAILED(result)) {
+ return result;
+ }
+ }
result=CloseContainersTo(theTarget,PR_FALSE);
}
}
@@ -3739,69 +3745,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
result=mSink->AddLeaf(*aNode);
-
- if(NS_SUCCEEDED(result)) {
- PRBool done=PR_FALSE;
- eHTMLTags thePrevTag=theTag;
- //nsCParserNode theNode;
-
- while(!done && NS_SUCCEEDED(result)) {
- CToken* theToken=mTokenizer->PeekToken();
- if(theToken) {
- nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
- if(theNode) {
- theTag=(eHTMLTags)theToken->GetTypeID();
- switch(theTag) {
- case eHTMLTag_newline:
- mLineNumber++;
- case eHTMLTag_whitespace:
- {
- theToken=mTokenizer->PopToken();
-
- STOP_TIMER();
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
-
- result=mSink->AddLeaf(*theNode);
-
- if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
- IF_FREE(theToken);
- }
-
- MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- START_TIMER();
- thePrevTag=theTag;
- }
- break;
- case eHTMLTag_text:
- if((mHasOpenBody) && (!mHasOpenHead) &&
- !(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
- theToken=mTokenizer->PopToken();
-
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- STOP_TIMER();
-
- mLineNumber += theToken->mNewlineCount;
- result=mSink->AddLeaf(*theNode);
-
- if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
- IF_FREE(theToken);
- }
-
- MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- START_TIMER();
- }
- else done=PR_TRUE;
- break;
-
- default:
- done=PR_TRUE;
- } //switch
- NS_IF_RELEASE(theNode);
- } //if
- }//if
- else done=PR_TRUE;
- } //while
- } //if
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
START_TIMER();
diff --git a/mozilla/htmlparser/src/CParserContext.cpp b/mozilla/htmlparser/src/CParserContext.cpp
index f2760f3149c..c3bbaaacf78 100644
--- a/mozilla/htmlparser/src/CParserContext.cpp
+++ b/mozilla/htmlparser/src/CParserContext.cpp
@@ -56,7 +56,6 @@ CParserContext::CParserContext(nsScanner* aScanner,
mDTD=aDTD;
NS_IF_ADDREF(mDTD);
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=PR_TRUE;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
mContextType=eCTNone;
@@ -90,7 +89,6 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
NS_IF_ADDREF(mDTD);
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=aContext.mParserEnabled;
mStreamListenerState=aContext.mStreamListenerState;
mMultipart=aContext.mMultipart;
mContextType=aContext.mContextType;
diff --git a/mozilla/htmlparser/src/CParserContext.h b/mozilla/htmlparser/src/CParserContext.h
index 7b458f1041e..9e282589875 100644
--- a/mozilla/htmlparser/src/CParserContext.h
+++ b/mozilla/htmlparser/src/CParserContext.h
@@ -83,7 +83,6 @@ public:
void* mKey;
PRUint32 mTransferBufferSize;
- PRBool mParserEnabled;
PRBool mCopyUnused;
};
diff --git a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp
index e56490dafaf..3e8a207f89e 100644
--- a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp
+++ b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp
@@ -606,11 +606,6 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
done=PR_TRUE;
}
else if(aChar==kLessThan) {
- eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
- if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
- CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
- AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
- }
done=PR_TRUE;
}
}//if
diff --git a/mozilla/htmlparser/src/nsIParser.h b/mozilla/htmlparser/src/nsIParser.h
index dc6cc4ad23a..8f1a91df521 100644
--- a/mozilla/htmlparser/src/nsIParser.h
+++ b/mozilla/htmlparser/src/nsIParser.h
@@ -219,8 +219,20 @@ class nsIParser : public nsISupports {
* until you wind up being emitted to the given contentsink (which may or may not
* be a proxy for the NGLayout content model).
******************************************************************************************/
- virtual nsresult EnableParser(PRBool aState) = 0;
- virtual PRBool IsParserEnabled() = 0;
+
+ // This method enables the parser ( by calling UnblockParser() ) and resumes parsing.
+ virtual nsresult ResumeParsing() =0;
+
+ // Stops parsing temporarily.
+ virtual void BlockParser() =0;
+
+ // Open up the parser for tokenization, building up content
+ // model..etc. However, this method does not resume parsing
+ // automatically. It's the callers' responsibility to restart
+ // the parsing engine.
+ virtual void UnblockParser() =0;
+
+ virtual PRBool IsParserEnabled() =0;
virtual nsresult Parse(nsIURI* aURL,nsIStreamObserver* aListener = nsnull,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
virtual nsresult Parse(nsIInputStream& aStream, const nsString& aMimeType,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
diff --git a/mozilla/htmlparser/src/nsParser.cpp b/mozilla/htmlparser/src/nsParser.cpp
index 8730b8837f2..2b36aafe988 100644
--- a/mozilla/htmlparser/src/nsParser.cpp
+++ b/mozilla/htmlparser/src/nsParser.cpp
@@ -237,6 +237,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) {
mInternalState=NS_OK;
mObserversEnabled=PR_TRUE;
mCommand=eViewNormal;
+ mParserEnabled=PR_TRUE;
mBundle=nsnull;
MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this));
@@ -1413,10 +1414,12 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
//One last thing...close any open containers.
nsresult result=anErrorCode;
- if((mParserContext) && mParserContext->mParserEnabled) {
- if((!mParserContext->mPrevContext) && (mParserContext->mDTD)) {
+ if(mParserEnabled && mParserContext && !mParserContext->mPrevContext) {
+ if(mParserContext->mDTD) {
result=mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
}
+ //Ref. to bug 61462.
+ NS_IF_RELEASE(mBundle);
}//if
return result;
@@ -1432,9 +1435,6 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
*/
void nsParser::PushContext(CParserContext& aContext) {
aContext.mPrevContext=mParserContext;
- if (mParserContext) {
- aContext.mParserEnabled = mParserContext->mParserEnabled;
- }
mParserContext=&aContext;
}
@@ -1453,7 +1453,6 @@ CParserContext* nsParser::PopContext() {
// back to the new one. Also, propagate the stream listener state
// but don't override onStop state to guarantee the call to DidBuildModel().
if (mParserContext) {
- mParserContext->mParserEnabled = oldContext->mParserEnabled;
if(mParserContext->mStreamListenerState!=eOnStop) {
mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
}
@@ -1499,49 +1498,64 @@ nsresult nsParser::Terminate(void){
return mInternalState;
}
+
/**
- * Call this when you want control whether or not the parser will parse
- * and tokenize input (TRUE), or whether it just caches input to be
- * parsed later (FALSE).
+ * Call this when you want to toggle from the blocked state and resume parsing
*
* @update gess 1/29/99
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
-nsresult nsParser::EnableParser(PRBool aState){
-
+nsresult nsParser::ResumeParsing(){
+
// 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;
- nsIParser* me = this;
- NS_ADDREF(me);
+ nsCOMPtr kungFuDeathGrip(this);
- // If we're reenabling the parser
- if(mParserContext) {
- mParserContext->mParserEnabled=aState;
- if(aState) {
+ // Enable the parser
+ UnblockParser();
- //printf(" Re-enable parser\n");
- PRBool isFinalChunk=(mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
-
- result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
-
- if(result!=NS_OK)
- result=mInternalState;
- }
- else {
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::EnableParser(), this=%p\n", this));
- MOZ_TIMER_STOP(mParseTime);
- }
- }
+ PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
+
+ result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
+
+ if(result!=NS_OK)
+ result=mInternalState;
- // Release reference if we added one at the top of this routine
- NS_IF_RELEASE(me);
return result;
}
+/**
+ * Stops parsing temporarily. That's it will prevent the
+ * parser from building up content model.
+ *
+ * @update
+ * @return
+ */
+void nsParser::BlockParser() {
+ mParserEnabled=PR_FALSE;
+ MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::BlockParser(), this=%p\n", this));
+ MOZ_TIMER_STOP(mParseTime);
+}
+
+/**
+ * Open up the parser for tokenization, building up content
+ * model..etc. However, this method does not resume parsing
+ * automatically. It's the callers' responsibility to restart
+ * the parsing engine.
+ *
+ * @update
+ * @return
+ */
+void nsParser::UnblockParser() {
+ mParserEnabled=PR_TRUE;
+ MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
+ MOZ_TIMER_START(mParseTime);
+}
+
/**
* Call this to query whether the parser is enabled or not.
*
@@ -1549,7 +1563,7 @@ nsresult nsParser::EnableParser(PRBool aState){
* @return current state
*/
PRBool nsParser::IsParserEnabled() {
- return mParserContext->mParserEnabled;
+ return mParserEnabled;
}
@@ -1863,7 +1877,7 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
nsresult result=NS_OK;
- if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
+ if(mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
@@ -1904,8 +1918,8 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
if(NS_ERROR_HTMLPARSER_BLOCK==result) {
//BLOCK == 2152596464
mParserContext->mDTD->WillInterruptParse();
- result=EnableParser(PR_FALSE);
- return result;
+ BlockParser();
+ return NS_OK;
}
else if (NS_ERROR_HTMLPARSER_STOPPARSING==result) {
@@ -2392,7 +2406,7 @@ nsresult nsParser::OnStopRequest(nsIChannel* channel, nsISupports* aContext,
gOutFile=0;
}
#endif
- NS_IF_RELEASE(mBundle);
+
return result;
}
diff --git a/mozilla/htmlparser/src/nsParser.h b/mozilla/htmlparser/src/nsParser.h
index ae72d064538..2a89af5b537 100644
--- a/mozilla/htmlparser/src/nsParser.h
+++ b/mozilla/htmlparser/src/nsParser.h
@@ -213,7 +213,9 @@ class nsParser : public nsIParser,
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
- virtual nsresult EnableParser(PRBool aState);
+ virtual nsresult ResumeParsing();
+ virtual void BlockParser();
+ virtual void UnblockParser();
virtual nsresult Terminate(void);
/**
@@ -407,7 +409,7 @@ protected:
CObserverService mObserverService;
PRBool mObserversEnabled;
nsString mCommandStr;
-
+ PRBool mParserEnabled;
nsParserBundle* mBundle;
nsTokenAllocator mTokenAllocator;
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index d7764e52e58..5dc39b27e34 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -730,7 +730,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
eHTMLTags theParentTag=mBodyContext->Last();
theTag=(eHTMLTags)theToken->GetTypeID();
if((FindTagInSet(theTag,gLegalElements,sizeof(gLegalElements)/sizeof(theTag))) ||
- (gHTMLElements[theParentTag].CanContain(theTag))) {
+ (gHTMLElements[theParentTag].CanContain(theTag)) && (theTag!=eHTMLTag_comment)) { // Added comment -> bug 40855
mDTDState=NS_OK; // reset the state since all the misplaced tokens are about to get handled.
result=HandleSavedTokens(mBodyContext->mContextTopIndex);
@@ -1928,6 +1928,12 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
if(result==NS_OK) {
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,*mBodyContext);
if(eHTMLTag_unknown!=theTarget) {
+ if (nsHTMLElement::IsResidualStyleTag(theChildTag)) {
+ result=OpenTransientStyles(theChildTag);
+ if(NS_FAILED(result)) {
+ return result;
+ }
+ }
result=CloseContainersTo(theTarget,PR_FALSE);
}
}
@@ -3739,69 +3745,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
result=mSink->AddLeaf(*aNode);
-
- if(NS_SUCCEEDED(result)) {
- PRBool done=PR_FALSE;
- eHTMLTags thePrevTag=theTag;
- //nsCParserNode theNode;
-
- while(!done && NS_SUCCEEDED(result)) {
- CToken* theToken=mTokenizer->PeekToken();
- if(theToken) {
- nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
- if(theNode) {
- theTag=(eHTMLTags)theToken->GetTypeID();
- switch(theTag) {
- case eHTMLTag_newline:
- mLineNumber++;
- case eHTMLTag_whitespace:
- {
- theToken=mTokenizer->PopToken();
-
- STOP_TIMER();
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
-
- result=mSink->AddLeaf(*theNode);
-
- if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
- IF_FREE(theToken);
- }
-
- MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- START_TIMER();
- thePrevTag=theTag;
- }
- break;
- case eHTMLTag_text:
- if((mHasOpenBody) && (!mHasOpenHead) &&
- !(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
- theToken=mTokenizer->PopToken();
-
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- STOP_TIMER();
-
- mLineNumber += theToken->mNewlineCount;
- result=mSink->AddLeaf(*theNode);
-
- if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
- IF_FREE(theToken);
- }
-
- MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
- START_TIMER();
- }
- else done=PR_TRUE;
- break;
-
- default:
- done=PR_TRUE;
- } //switch
- NS_IF_RELEASE(theNode);
- } //if
- }//if
- else done=PR_TRUE;
- } //while
- } //if
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
START_TIMER();
diff --git a/mozilla/parser/htmlparser/src/CParserContext.cpp b/mozilla/parser/htmlparser/src/CParserContext.cpp
index f2760f3149c..c3bbaaacf78 100644
--- a/mozilla/parser/htmlparser/src/CParserContext.cpp
+++ b/mozilla/parser/htmlparser/src/CParserContext.cpp
@@ -56,7 +56,6 @@ CParserContext::CParserContext(nsScanner* aScanner,
mDTD=aDTD;
NS_IF_ADDREF(mDTD);
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=PR_TRUE;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
mContextType=eCTNone;
@@ -90,7 +89,6 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
NS_IF_ADDREF(mDTD);
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=aContext.mParserEnabled;
mStreamListenerState=aContext.mStreamListenerState;
mMultipart=aContext.mMultipart;
mContextType=aContext.mContextType;
diff --git a/mozilla/parser/htmlparser/src/CParserContext.h b/mozilla/parser/htmlparser/src/CParserContext.h
index 7b458f1041e..9e282589875 100644
--- a/mozilla/parser/htmlparser/src/CParserContext.h
+++ b/mozilla/parser/htmlparser/src/CParserContext.h
@@ -83,7 +83,6 @@ public:
void* mKey;
PRUint32 mTransferBufferSize;
- PRBool mParserEnabled;
PRBool mCopyUnused;
};
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp
index e56490dafaf..3e8a207f89e 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp
+++ b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp
@@ -606,11 +606,6 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
done=PR_TRUE;
}
else if(aChar==kLessThan) {
- eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
- if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
- CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
- AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
- }
done=PR_TRUE;
}
}//if
diff --git a/mozilla/parser/htmlparser/src/nsIParser.h b/mozilla/parser/htmlparser/src/nsIParser.h
index dc6cc4ad23a..8f1a91df521 100644
--- a/mozilla/parser/htmlparser/src/nsIParser.h
+++ b/mozilla/parser/htmlparser/src/nsIParser.h
@@ -219,8 +219,20 @@ class nsIParser : public nsISupports {
* until you wind up being emitted to the given contentsink (which may or may not
* be a proxy for the NGLayout content model).
******************************************************************************************/
- virtual nsresult EnableParser(PRBool aState) = 0;
- virtual PRBool IsParserEnabled() = 0;
+
+ // This method enables the parser ( by calling UnblockParser() ) and resumes parsing.
+ virtual nsresult ResumeParsing() =0;
+
+ // Stops parsing temporarily.
+ virtual void BlockParser() =0;
+
+ // Open up the parser for tokenization, building up content
+ // model..etc. However, this method does not resume parsing
+ // automatically. It's the callers' responsibility to restart
+ // the parsing engine.
+ virtual void UnblockParser() =0;
+
+ virtual PRBool IsParserEnabled() =0;
virtual nsresult Parse(nsIURI* aURL,nsIStreamObserver* aListener = nsnull,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
virtual nsresult Parse(nsIInputStream& aStream, const nsString& aMimeType,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp
index 8730b8837f2..2b36aafe988 100644
--- a/mozilla/parser/htmlparser/src/nsParser.cpp
+++ b/mozilla/parser/htmlparser/src/nsParser.cpp
@@ -237,6 +237,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) {
mInternalState=NS_OK;
mObserversEnabled=PR_TRUE;
mCommand=eViewNormal;
+ mParserEnabled=PR_TRUE;
mBundle=nsnull;
MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this));
@@ -1413,10 +1414,12 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
//One last thing...close any open containers.
nsresult result=anErrorCode;
- if((mParserContext) && mParserContext->mParserEnabled) {
- if((!mParserContext->mPrevContext) && (mParserContext->mDTD)) {
+ if(mParserEnabled && mParserContext && !mParserContext->mPrevContext) {
+ if(mParserContext->mDTD) {
result=mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
}
+ //Ref. to bug 61462.
+ NS_IF_RELEASE(mBundle);
}//if
return result;
@@ -1432,9 +1435,6 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
*/
void nsParser::PushContext(CParserContext& aContext) {
aContext.mPrevContext=mParserContext;
- if (mParserContext) {
- aContext.mParserEnabled = mParserContext->mParserEnabled;
- }
mParserContext=&aContext;
}
@@ -1453,7 +1453,6 @@ CParserContext* nsParser::PopContext() {
// back to the new one. Also, propagate the stream listener state
// but don't override onStop state to guarantee the call to DidBuildModel().
if (mParserContext) {
- mParserContext->mParserEnabled = oldContext->mParserEnabled;
if(mParserContext->mStreamListenerState!=eOnStop) {
mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
}
@@ -1499,49 +1498,64 @@ nsresult nsParser::Terminate(void){
return mInternalState;
}
+
/**
- * Call this when you want control whether or not the parser will parse
- * and tokenize input (TRUE), or whether it just caches input to be
- * parsed later (FALSE).
+ * Call this when you want to toggle from the blocked state and resume parsing
*
* @update gess 1/29/99
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
-nsresult nsParser::EnableParser(PRBool aState){
-
+nsresult nsParser::ResumeParsing(){
+
// 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;
- nsIParser* me = this;
- NS_ADDREF(me);
+ nsCOMPtr kungFuDeathGrip(this);
- // If we're reenabling the parser
- if(mParserContext) {
- mParserContext->mParserEnabled=aState;
- if(aState) {
+ // Enable the parser
+ UnblockParser();
- //printf(" Re-enable parser\n");
- PRBool isFinalChunk=(mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
-
- result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
-
- if(result!=NS_OK)
- result=mInternalState;
- }
- else {
- MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::EnableParser(), this=%p\n", this));
- MOZ_TIMER_STOP(mParseTime);
- }
- }
+ PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
+
+ result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
+
+ if(result!=NS_OK)
+ result=mInternalState;
- // Release reference if we added one at the top of this routine
- NS_IF_RELEASE(me);
return result;
}
+/**
+ * Stops parsing temporarily. That's it will prevent the
+ * parser from building up content model.
+ *
+ * @update
+ * @return
+ */
+void nsParser::BlockParser() {
+ mParserEnabled=PR_FALSE;
+ MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::BlockParser(), this=%p\n", this));
+ MOZ_TIMER_STOP(mParseTime);
+}
+
+/**
+ * Open up the parser for tokenization, building up content
+ * model..etc. However, this method does not resume parsing
+ * automatically. It's the callers' responsibility to restart
+ * the parsing engine.
+ *
+ * @update
+ * @return
+ */
+void nsParser::UnblockParser() {
+ mParserEnabled=PR_TRUE;
+ MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
+ MOZ_TIMER_START(mParseTime);
+}
+
/**
* Call this to query whether the parser is enabled or not.
*
@@ -1549,7 +1563,7 @@ nsresult nsParser::EnableParser(PRBool aState){
* @return current state
*/
PRBool nsParser::IsParserEnabled() {
- return mParserContext->mParserEnabled;
+ return mParserEnabled;
}
@@ -1863,7 +1877,7 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
nsresult result=NS_OK;
- if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
+ if(mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
@@ -1904,8 +1918,8 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
if(NS_ERROR_HTMLPARSER_BLOCK==result) {
//BLOCK == 2152596464
mParserContext->mDTD->WillInterruptParse();
- result=EnableParser(PR_FALSE);
- return result;
+ BlockParser();
+ return NS_OK;
}
else if (NS_ERROR_HTMLPARSER_STOPPARSING==result) {
@@ -2392,7 +2406,7 @@ nsresult nsParser::OnStopRequest(nsIChannel* channel, nsISupports* aContext,
gOutFile=0;
}
#endif
- NS_IF_RELEASE(mBundle);
+
return result;
}
diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h
index ae72d064538..2a89af5b537 100644
--- a/mozilla/parser/htmlparser/src/nsParser.h
+++ b/mozilla/parser/htmlparser/src/nsParser.h
@@ -213,7 +213,9 @@ class nsParser : public nsIParser,
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
- virtual nsresult EnableParser(PRBool aState);
+ virtual nsresult ResumeParsing();
+ virtual void BlockParser();
+ virtual void UnblockParser();
virtual nsresult Terminate(void);
/**
@@ -407,7 +409,7 @@ protected:
CObserverService mObserverService;
PRBool mObserversEnabled;
nsString mCommandStr;
-
+ PRBool mParserEnabled;
nsParserBundle* mBundle;
nsTokenAllocator mTokenAllocator;