From f0e1788e4baa08940bd7c6195ae229f5c40f8175 Mon Sep 17 00:00:00 2001 From: "harishd%netscape.com" Date: Sat, 15 Jan 2000 20:35:57 +0000 Subject: [PATCH] Fix for bugs: 22485, 20799 ( SCRIPT content processing) r=vidur,pollmann Fix for bugs 22260 ( enabling userdifined tags ) - partial fix. 23765 ( handling misplaced newlines/whitespace). r=rickg git-svn-id: svn://10.0.0.236/trunk@57953 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/htmlparser/src/CNavDTD.cpp | 6 +- mozilla/htmlparser/src/nsElementTable.cpp | 8 +- mozilla/htmlparser/src/nsExpatTokenizer.cpp | 2 +- mozilla/htmlparser/src/nsExpatTokenizer.h | 2 +- mozilla/htmlparser/src/nsHTMLTokenizer.cpp | 12 +- mozilla/htmlparser/src/nsHTMLTokenizer.h | 6 +- mozilla/htmlparser/src/nsHTMLTokens.cpp | 10 +- mozilla/htmlparser/src/nsHTMLTokens.h | 3 +- mozilla/htmlparser/src/nsITokenizer.h | 2 +- mozilla/htmlparser/src/nsParser.cpp | 110 ++++++++++++------ mozilla/htmlparser/src/nsScanner.cpp | 16 +++ mozilla/htmlparser/src/nsScanner.h | 9 ++ mozilla/htmlparser/src/nsXMLTokenizer.cpp | 4 +- mozilla/htmlparser/src/nsXMLTokenizer.h | 2 +- mozilla/parser/htmlparser/src/CNavDTD.cpp | 6 +- .../parser/htmlparser/src/nsElementTable.cpp | 8 +- .../htmlparser/src/nsExpatTokenizer.cpp | 2 +- .../parser/htmlparser/src/nsExpatTokenizer.h | 2 +- .../parser/htmlparser/src/nsHTMLTokenizer.cpp | 12 +- .../parser/htmlparser/src/nsHTMLTokenizer.h | 6 +- .../parser/htmlparser/src/nsHTMLTokens.cpp | 10 +- mozilla/parser/htmlparser/src/nsHTMLTokens.h | 3 +- mozilla/parser/htmlparser/src/nsITokenizer.h | 2 +- mozilla/parser/htmlparser/src/nsParser.cpp | 110 ++++++++++++------ mozilla/parser/htmlparser/src/nsScanner.cpp | 16 +++ mozilla/parser/htmlparser/src/nsScanner.h | 9 ++ .../parser/htmlparser/src/nsXMLTokenizer.cpp | 4 +- .../parser/htmlparser/src/nsXMLTokenizer.h | 2 +- 28 files changed, 254 insertions(+), 130 deletions(-) diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index 20fbdbdafce..a096a0e1a69 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -682,7 +682,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse //by forcefully recycling any tokens we might find there. CToken* theToken=0; - while(theToken=(CToken*)mMisplacedContent.Pop()) { + while((theToken=(CToken*)mMisplacedContent.Pop())) { mTokenRecycler->RecycleToken(theToken); } @@ -757,8 +757,6 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ switch(theTag) { case eHTMLTag_html: case eHTMLTag_comment: - case eHTMLTag_newline: - case eHTMLTag_whitespace: case eHTMLTag_script: case eHTMLTag_markupDecl: case eHTMLTag_userdefined: @@ -1446,7 +1444,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { aToken->SetTypeID(theChildTag=eHTMLTag_img); break; - case eHTMLTag_userdefined: + //case eHTMLTag_userdefined: case eHTMLTag_noscript: //HACK XXX! Throw noscript on the floor for now. isTokenHandled=PR_TRUE; break; diff --git a/mozilla/htmlparser/src/nsElementTable.cpp b/mozilla/htmlparser/src/nsElementTable.cpp index a2679f095be..e9ed374c6f2 100644 --- a/mozilla/htmlparser/src/nsElementTable.cpp +++ b/mozilla/htmlparser/src/nsElementTable.cpp @@ -49,7 +49,7 @@ TagList gInTR={1,{eHTMLTag_tr}}; TagList gInDL={2,{eHTMLTag_dl,eHTMLTag_body}}; TagList gInFrameset={1,{eHTMLTag_frameset}}; TagList gInNoframes={1,{eHTMLTag_noframes}}; -TagList gInP={4,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table,eHTMLTag_form}}; +TagList gInP={4,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table,eHTMLTag_form}}; // P containing TABLE - Ref: Bug# 11229 TagList gOptgroupParents={2,{eHTMLTag_select,eHTMLTag_optgroup}}; TagList gBodyParents={2,{eHTMLTag_html,eHTMLTag_noframes}}; TagList gColParents={2,{eHTMLTag_table,eHTMLTag_colgroup}}; @@ -1283,10 +1283,10 @@ void InitializeElementTable(void) { Initialize( /*tag*/ eHTMLTag_userdefined, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_frameset, - /*rootnodes,endrootnodes*/ &gInHTML,&gInHTML, + /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ &gBodyAutoClose,0,0,0, - /*parent,incl,exclgroups*/ kHTMLContent, (kFlowEntity|kSelf), kNone, - /*special props, prop-range*/ kOmitEndTag|kLegalOpen, kBodyPropRange, + /*parent,incl,exclgroups*/ kFlowEntity, (kFlowEntity|kSelf), kNone, + /*special props, prop-range*/ kLegalOpen, kBodyPropRange, /*special parents,kids,skip*/ &gInNoframes,&gBodyKids,eHTMLTag_unknown); }//if }; diff --git a/mozilla/htmlparser/src/nsExpatTokenizer.cpp b/mozilla/htmlparser/src/nsExpatTokenizer.cpp index 5cd3cdd8a6e..e107ec14cba 100644 --- a/mozilla/htmlparser/src/nsExpatTokenizer.cpp +++ b/mozilla/htmlparser/src/nsExpatTokenizer.cpp @@ -338,7 +338,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsExpatTokenizer::ConsumeToken(nsScanner& aScanner) { +nsresult nsExpatTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { // return nsHTMLTokenizer::ConsumeToken(aScanner); diff --git a/mozilla/htmlparser/src/nsExpatTokenizer.h b/mozilla/htmlparser/src/nsExpatTokenizer.h index 78308d700ac..37ff066e716 100644 --- a/mozilla/htmlparser/src/nsExpatTokenizer.h +++ b/mozilla/htmlparser/src/nsExpatTokenizer.h @@ -67,7 +67,7 @@ public: NS_DECL_ISUPPORTS /* nsITokenizer methods */ - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult DidTokenize(PRBool aIsFinalChunk); virtual void FrontloadMisplacedContent(nsDeque& aDeque); diff --git a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp index e3560e4f2a8..54bd12d814c 100644 --- a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp @@ -284,7 +284,7 @@ nsresult nsHTMLTokenizer::DidTokenize(PRBool aIsFinalChunk) * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { PRUnichar theChar; CToken* theToken=0; @@ -304,7 +304,7 @@ nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { if(!mPlainText) { if(kLessThan==theChar) { - return ConsumeTag(theChar,theToken,aScanner); + return ConsumeTag(theChar,theToken,aScanner,aFlushTokens); } else if(kAmpersand==theChar){ return ConsumeEntity(theChar,theToken,aScanner); @@ -340,7 +340,7 @@ nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { * @param aToken is the out arg holding our new token * @return error code. */ -nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens) { nsresult result=aScanner.GetChar(aChar); @@ -376,7 +376,7 @@ nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& default: if(nsString::IsAlpha(aChar)) - result=ConsumeStartTag(aChar,aToken,aScanner); + result=ConsumeStartTag(aChar,aToken,aScanner,aFlushTokens); else if(kEOF!=aChar) { // We are not dealing with a tag. So, put back the char // and leave the decision to ConsumeText(). @@ -482,7 +482,7 @@ nsresult nsHTMLTokenizer::ConsumeScriptContent(nsScanner& aScanner,CToken*& aTok * @param * @return */ -nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens) { PRInt32 theDequeSize=mTokenDeque.GetSize(); //remember this for later in case you have to unwind... nsresult result=NS_OK; @@ -512,7 +512,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan nsAutoString endTag(nsHTMLTags::GetStringValue(theTag)); endTag.Insert("CreateTokenOfType(eToken_text,theTag); - result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text... + result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode,aFlushTokens); //tell new token to finish consuming text... //endTag.Append(">"); CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag); AddToken(textToken,result,&mTokenDeque,theRecycler); diff --git a/mozilla/htmlparser/src/nsHTMLTokenizer.h b/mozilla/htmlparser/src/nsHTMLTokenizer.h index 335a0280c15..527f463dd29 100644 --- a/mozilla/htmlparser/src/nsHTMLTokenizer.h +++ b/mozilla/htmlparser/src/nsHTMLTokenizer.h @@ -60,7 +60,7 @@ public: NS_DECL_ISUPPORTS virtual nsresult WillTokenize(PRBool aIsFinalChunk); - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult DidTokenize(PRBool aIsFinalChunk); virtual nsITokenRecycler* GetTokenRecycler(void); @@ -77,8 +77,8 @@ public: protected: virtual nsresult ConsumeScriptContent(nsScanner& aScanner,CToken*& aToken); - virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); - virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); + virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens); + virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); virtual nsresult ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner); virtual nsresult ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); diff --git a/mozilla/htmlparser/src/nsHTMLTokens.cpp b/mozilla/htmlparser/src/nsHTMLTokens.cpp index 536dd907563..26244279dca 100644 --- a/mozilla/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokens.cpp @@ -505,7 +505,8 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) * @param aScanner -- controller of underlying input source * @return error result */ -nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode){ +nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner, + nsString& aTerminalString,PRInt32 aMode,PRBool& aFlushTokens){ PRBool done=PR_FALSE; nsresult result=NS_OK; PRUnichar theChar; @@ -557,12 +558,15 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann rpos=theRight.RFindChar('<'); //now scan for the '<' if(-1...permit flushing -> Ref: Bug 22485 } } done=PRBool(-1mParserEnabled; + } mParserContext=&aContext; } @@ -968,41 +971,67 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) { if(mParserContext->mDTD) { mParserContext->mDTD->WillResumeParse(); if(NS_OK==result) { + nsresult theTokenizerResult=NS_OK; + + while(result==NS_OK) { - result=Tokenize(aIsFinalChunk); - result=BuildModel(); - - if(result==NS_ERROR_HTMLPARSER_STOPPARSING) mInternalState=result; - - if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) || - ((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){ - - DidBuildModel(mStreamStatus); - - MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this)); - MOZ_TIMER_STOP(mParseTime); - - MOZ_TIMER_LOG(("Parse Time (this=%p): ", this)); - MOZ_TIMER_PRINT(mParseTime); - - MOZ_TIMER_LOG(("DTD Time: ")); - MOZ_TIMER_PRINT(mDTDTime); - - MOZ_TIMER_LOG(("Tokenize Time: ")); - MOZ_TIMER_PRINT(mTokenizeTime); - - return mInternalState; - } - else { - mParserContext->mDTD->WillInterruptParse(); - // If we're told to block the parser, we disable - // all further parsing (and cache any data coming - // in) until the parser is enabled. - //PRUint32 b1=NS_ERROR_HTMLPARSER_BLOCK; - if(NS_ERROR_HTMLPARSER_BLOCK==result) { - result=EnableParser(PR_FALSE); + if(mUnusedInput.Length()>0) { + if(mParserContext->mScanner) { + // -- Ref: Bug# 22485 -- + // Insert the unused input into the source buffer + // as if it was read from the input stream. + // Adding Insert() per vidur!! + mParserContext->mScanner->Insert(mUnusedInput); + mUnusedInput.Truncate(0); + } } - }//if + + result=Tokenize(aIsFinalChunk); + + if(result!=NS_OK) theTokenizerResult=result; + + result=BuildModel(); + + if(result==NS_ERROR_HTMLPARSER_STOPPARSING) mInternalState=result; + + // Make sure not to stop parsing too early. Therefore, before shutting down the + // parser, it's important to check whether the input buffer has been scanned to + // completion ( theTokenizerResult should be kEOF ). kEOF -> End of buffer. + if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) || + ((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result) && (theTokenizerResult==kEOF))){ + + DidBuildModel(mStreamStatus); + + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this)); + MOZ_TIMER_STOP(mParseTime); + + MOZ_TIMER_LOG(("Parse Time (this=%p): ", this)); + MOZ_TIMER_PRINT(mParseTime); + + MOZ_TIMER_LOG(("DTD Time: ")); + MOZ_TIMER_PRINT(mDTDTime); + + MOZ_TIMER_LOG(("Tokenize Time: ")); + MOZ_TIMER_PRINT(mTokenizeTime); + + return mInternalState; + } + // If we're told to block the parser, we disable + // all further parsing (and cache any data coming + // in) until the parser is enabled. + //PRUint32 b1=NS_ERROR_HTMLPARSER_BLOCK; + else if(NS_ERROR_HTMLPARSER_BLOCK==result) { + mParserContext->mDTD->WillInterruptParse(); + result=EnableParser(PR_FALSE); + break; + } + // If we're at the end of the current scanner buffer, + // we interrupt parsing and wait for the next one + else if (theTokenizerResult==kEOF) { + mParserContext->mDTD->WillInterruptParse(); + break; + } + }//while }//if }//if else { @@ -1438,6 +1467,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); if(theTokenizer){ + PRBool flushTokens=PR_FALSE; MOZ_TIMER_START(mTokenizeTime); @@ -1445,22 +1475,26 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ while(NS_SUCCEEDED(result)) { mParserContext->mScanner->Mark(); ++mMinorIteration; - result=theTokenizer->ConsumeToken(*mParserContext->mScanner); - if(!NS_SUCCEEDED(result)) { + result=theTokenizer->ConsumeToken(*mParserContext->mScanner,flushTokens); + if(NS_FAILED(result)) { mParserContext->mScanner->RewindToMark(); if(kEOF==result){ - result=NS_OK; break; } else if(NS_ERROR_HTMLPARSER_STOPPARSING==result) return Terminate(); } + else if(flushTokens) { + // Flush tokens on seeing -- Ref: Bug# 22485 -- + // Also remember to update the marked position. + mParserContext->mScanner->Mark(); + break; + } } DidTokenize(aIsFinalChunk); MOZ_TIMER_STOP(mTokenizeTime); - - } + } else{ result=mInternalState=NS_ERROR_HTMLPARSER_BADTOKENIZER; } diff --git a/mozilla/htmlparser/src/nsScanner.cpp b/mozilla/htmlparser/src/nsScanner.cpp index 9f9b427d4a1..9f85c2d3a17 100644 --- a/mozilla/htmlparser/src/nsScanner.cpp +++ b/mozilla/htmlparser/src/nsScanner.cpp @@ -232,6 +232,22 @@ PRUint32 nsScanner::Mark(PRInt32 anIndex){ } +/** + * Insert data to our underlying input buffer as + * if it were read from an input stream. + * + * @update harishd 01/12/99 + * @return error code + */ +PRBool nsScanner::Insert(const nsString& aBuffer) { + + PRInt32 theLen=aBuffer.Length(); + + mBuffer.Insert(aBuffer,mOffset,theLen); + mTotalRead+=theLen; + return PR_TRUE; +} + /** * Append data to our underlying input buffer as * if it were read from an input stream. diff --git a/mozilla/htmlparser/src/nsScanner.h b/mozilla/htmlparser/src/nsScanner.h index 57a499f9604..dc8120cfdcd 100644 --- a/mozilla/htmlparser/src/nsScanner.h +++ b/mozilla/htmlparser/src/nsScanner.h @@ -241,6 +241,15 @@ class nsScanner { PRUint32 RewindToMark(void); + /** + * + * + * @update harishd 01/12/99 + * @param + * @return + */ + PRBool Insert(const nsString& aBuffer); + /** * * diff --git a/mozilla/htmlparser/src/nsXMLTokenizer.cpp b/mozilla/htmlparser/src/nsXMLTokenizer.cpp index 28ed5c45a09..e09e1cb7c91 100644 --- a/mozilla/htmlparser/src/nsXMLTokenizer.cpp +++ b/mozilla/htmlparser/src/nsXMLTokenizer.cpp @@ -145,8 +145,8 @@ nsXMLTokenizer::~nsXMLTokenizer(){ * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner) { - return nsHTMLTokenizer::ConsumeToken(aScanner); +nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { + return nsHTMLTokenizer::ConsumeToken(aScanner,aFlushTokens); } diff --git a/mozilla/htmlparser/src/nsXMLTokenizer.h b/mozilla/htmlparser/src/nsXMLTokenizer.h index 0ce0486db8a..fa2464bf733 100644 --- a/mozilla/htmlparser/src/nsXMLTokenizer.h +++ b/mozilla/htmlparser/src/nsXMLTokenizer.h @@ -59,7 +59,7 @@ public: NS_DECL_ISUPPORTS - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsITokenRecycler* GetTokenRecycler(void); static void FreeTokenRecycler(void); diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index 20fbdbdafce..a096a0e1a69 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -682,7 +682,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse //by forcefully recycling any tokens we might find there. CToken* theToken=0; - while(theToken=(CToken*)mMisplacedContent.Pop()) { + while((theToken=(CToken*)mMisplacedContent.Pop())) { mTokenRecycler->RecycleToken(theToken); } @@ -757,8 +757,6 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ switch(theTag) { case eHTMLTag_html: case eHTMLTag_comment: - case eHTMLTag_newline: - case eHTMLTag_whitespace: case eHTMLTag_script: case eHTMLTag_markupDecl: case eHTMLTag_userdefined: @@ -1446,7 +1444,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { aToken->SetTypeID(theChildTag=eHTMLTag_img); break; - case eHTMLTag_userdefined: + //case eHTMLTag_userdefined: case eHTMLTag_noscript: //HACK XXX! Throw noscript on the floor for now. isTokenHandled=PR_TRUE; break; diff --git a/mozilla/parser/htmlparser/src/nsElementTable.cpp b/mozilla/parser/htmlparser/src/nsElementTable.cpp index a2679f095be..e9ed374c6f2 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.cpp +++ b/mozilla/parser/htmlparser/src/nsElementTable.cpp @@ -49,7 +49,7 @@ TagList gInTR={1,{eHTMLTag_tr}}; TagList gInDL={2,{eHTMLTag_dl,eHTMLTag_body}}; TagList gInFrameset={1,{eHTMLTag_frameset}}; TagList gInNoframes={1,{eHTMLTag_noframes}}; -TagList gInP={4,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table,eHTMLTag_form}}; +TagList gInP={4,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table,eHTMLTag_form}}; // P containing TABLE - Ref: Bug# 11229 TagList gOptgroupParents={2,{eHTMLTag_select,eHTMLTag_optgroup}}; TagList gBodyParents={2,{eHTMLTag_html,eHTMLTag_noframes}}; TagList gColParents={2,{eHTMLTag_table,eHTMLTag_colgroup}}; @@ -1283,10 +1283,10 @@ void InitializeElementTable(void) { Initialize( /*tag*/ eHTMLTag_userdefined, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_frameset, - /*rootnodes,endrootnodes*/ &gInHTML,&gInHTML, + /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ &gBodyAutoClose,0,0,0, - /*parent,incl,exclgroups*/ kHTMLContent, (kFlowEntity|kSelf), kNone, - /*special props, prop-range*/ kOmitEndTag|kLegalOpen, kBodyPropRange, + /*parent,incl,exclgroups*/ kFlowEntity, (kFlowEntity|kSelf), kNone, + /*special props, prop-range*/ kLegalOpen, kBodyPropRange, /*special parents,kids,skip*/ &gInNoframes,&gBodyKids,eHTMLTag_unknown); }//if }; diff --git a/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp b/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp index 5cd3cdd8a6e..e107ec14cba 100644 --- a/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp +++ b/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp @@ -338,7 +338,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsExpatTokenizer::ConsumeToken(nsScanner& aScanner) { +nsresult nsExpatTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { // return nsHTMLTokenizer::ConsumeToken(aScanner); diff --git a/mozilla/parser/htmlparser/src/nsExpatTokenizer.h b/mozilla/parser/htmlparser/src/nsExpatTokenizer.h index 78308d700ac..37ff066e716 100644 --- a/mozilla/parser/htmlparser/src/nsExpatTokenizer.h +++ b/mozilla/parser/htmlparser/src/nsExpatTokenizer.h @@ -67,7 +67,7 @@ public: NS_DECL_ISUPPORTS /* nsITokenizer methods */ - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult DidTokenize(PRBool aIsFinalChunk); virtual void FrontloadMisplacedContent(nsDeque& aDeque); diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp index e3560e4f2a8..54bd12d814c 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp @@ -284,7 +284,7 @@ nsresult nsHTMLTokenizer::DidTokenize(PRBool aIsFinalChunk) * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { PRUnichar theChar; CToken* theToken=0; @@ -304,7 +304,7 @@ nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { if(!mPlainText) { if(kLessThan==theChar) { - return ConsumeTag(theChar,theToken,aScanner); + return ConsumeTag(theChar,theToken,aScanner,aFlushTokens); } else if(kAmpersand==theChar){ return ConsumeEntity(theChar,theToken,aScanner); @@ -340,7 +340,7 @@ nsresult nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner) { * @param aToken is the out arg holding our new token * @return error code. */ -nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens) { nsresult result=aScanner.GetChar(aChar); @@ -376,7 +376,7 @@ nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& default: if(nsString::IsAlpha(aChar)) - result=ConsumeStartTag(aChar,aToken,aScanner); + result=ConsumeStartTag(aChar,aToken,aScanner,aFlushTokens); else if(kEOF!=aChar) { // We are not dealing with a tag. So, put back the char // and leave the decision to ConsumeText(). @@ -482,7 +482,7 @@ nsresult nsHTMLTokenizer::ConsumeScriptContent(nsScanner& aScanner,CToken*& aTok * @param * @return */ -nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) { +nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens) { PRInt32 theDequeSize=mTokenDeque.GetSize(); //remember this for later in case you have to unwind... nsresult result=NS_OK; @@ -512,7 +512,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan nsAutoString endTag(nsHTMLTags::GetStringValue(theTag)); endTag.Insert("CreateTokenOfType(eToken_text,theTag); - result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text... + result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode,aFlushTokens); //tell new token to finish consuming text... //endTag.Append(">"); CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag); AddToken(textToken,result,&mTokenDeque,theRecycler); diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.h b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.h index 335a0280c15..527f463dd29 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.h +++ b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.h @@ -60,7 +60,7 @@ public: NS_DECL_ISUPPORTS virtual nsresult WillTokenize(PRBool aIsFinalChunk); - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult DidTokenize(PRBool aIsFinalChunk); virtual nsITokenRecycler* GetTokenRecycler(void); @@ -77,8 +77,8 @@ public: protected: virtual nsresult ConsumeScriptContent(nsScanner& aScanner,CToken*& aToken); - virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); - virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); + virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens); + virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens); virtual nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); virtual nsresult ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner); virtual nsresult ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner); diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp index 536dd907563..26244279dca 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp @@ -505,7 +505,8 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) * @param aScanner -- controller of underlying input source * @return error result */ -nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode){ +nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner, + nsString& aTerminalString,PRInt32 aMode,PRBool& aFlushTokens){ PRBool done=PR_FALSE; nsresult result=NS_OK; PRUnichar theChar; @@ -557,12 +558,15 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann rpos=theRight.RFindChar('<'); //now scan for the '<' if(-1...permit flushing -> Ref: Bug 22485 } } done=PRBool(-1mParserEnabled; + } mParserContext=&aContext; } @@ -968,41 +971,67 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) { if(mParserContext->mDTD) { mParserContext->mDTD->WillResumeParse(); if(NS_OK==result) { + nsresult theTokenizerResult=NS_OK; + + while(result==NS_OK) { - result=Tokenize(aIsFinalChunk); - result=BuildModel(); - - if(result==NS_ERROR_HTMLPARSER_STOPPARSING) mInternalState=result; - - if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) || - ((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){ - - DidBuildModel(mStreamStatus); - - MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this)); - MOZ_TIMER_STOP(mParseTime); - - MOZ_TIMER_LOG(("Parse Time (this=%p): ", this)); - MOZ_TIMER_PRINT(mParseTime); - - MOZ_TIMER_LOG(("DTD Time: ")); - MOZ_TIMER_PRINT(mDTDTime); - - MOZ_TIMER_LOG(("Tokenize Time: ")); - MOZ_TIMER_PRINT(mTokenizeTime); - - return mInternalState; - } - else { - mParserContext->mDTD->WillInterruptParse(); - // If we're told to block the parser, we disable - // all further parsing (and cache any data coming - // in) until the parser is enabled. - //PRUint32 b1=NS_ERROR_HTMLPARSER_BLOCK; - if(NS_ERROR_HTMLPARSER_BLOCK==result) { - result=EnableParser(PR_FALSE); + if(mUnusedInput.Length()>0) { + if(mParserContext->mScanner) { + // -- Ref: Bug# 22485 -- + // Insert the unused input into the source buffer + // as if it was read from the input stream. + // Adding Insert() per vidur!! + mParserContext->mScanner->Insert(mUnusedInput); + mUnusedInput.Truncate(0); + } } - }//if + + result=Tokenize(aIsFinalChunk); + + if(result!=NS_OK) theTokenizerResult=result; + + result=BuildModel(); + + if(result==NS_ERROR_HTMLPARSER_STOPPARSING) mInternalState=result; + + // Make sure not to stop parsing too early. Therefore, before shutting down the + // parser, it's important to check whether the input buffer has been scanned to + // completion ( theTokenizerResult should be kEOF ). kEOF -> End of buffer. + if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) || + ((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result) && (theTokenizerResult==kEOF))){ + + DidBuildModel(mStreamStatus); + + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this)); + MOZ_TIMER_STOP(mParseTime); + + MOZ_TIMER_LOG(("Parse Time (this=%p): ", this)); + MOZ_TIMER_PRINT(mParseTime); + + MOZ_TIMER_LOG(("DTD Time: ")); + MOZ_TIMER_PRINT(mDTDTime); + + MOZ_TIMER_LOG(("Tokenize Time: ")); + MOZ_TIMER_PRINT(mTokenizeTime); + + return mInternalState; + } + // If we're told to block the parser, we disable + // all further parsing (and cache any data coming + // in) until the parser is enabled. + //PRUint32 b1=NS_ERROR_HTMLPARSER_BLOCK; + else if(NS_ERROR_HTMLPARSER_BLOCK==result) { + mParserContext->mDTD->WillInterruptParse(); + result=EnableParser(PR_FALSE); + break; + } + // If we're at the end of the current scanner buffer, + // we interrupt parsing and wait for the next one + else if (theTokenizerResult==kEOF) { + mParserContext->mDTD->WillInterruptParse(); + break; + } + }//while }//if }//if else { @@ -1438,6 +1467,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); if(theTokenizer){ + PRBool flushTokens=PR_FALSE; MOZ_TIMER_START(mTokenizeTime); @@ -1445,22 +1475,26 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ while(NS_SUCCEEDED(result)) { mParserContext->mScanner->Mark(); ++mMinorIteration; - result=theTokenizer->ConsumeToken(*mParserContext->mScanner); - if(!NS_SUCCEEDED(result)) { + result=theTokenizer->ConsumeToken(*mParserContext->mScanner,flushTokens); + if(NS_FAILED(result)) { mParserContext->mScanner->RewindToMark(); if(kEOF==result){ - result=NS_OK; break; } else if(NS_ERROR_HTMLPARSER_STOPPARSING==result) return Terminate(); } + else if(flushTokens) { + // Flush tokens on seeing -- Ref: Bug# 22485 -- + // Also remember to update the marked position. + mParserContext->mScanner->Mark(); + break; + } } DidTokenize(aIsFinalChunk); MOZ_TIMER_STOP(mTokenizeTime); - - } + } else{ result=mInternalState=NS_ERROR_HTMLPARSER_BADTOKENIZER; } diff --git a/mozilla/parser/htmlparser/src/nsScanner.cpp b/mozilla/parser/htmlparser/src/nsScanner.cpp index 9f9b427d4a1..9f85c2d3a17 100644 --- a/mozilla/parser/htmlparser/src/nsScanner.cpp +++ b/mozilla/parser/htmlparser/src/nsScanner.cpp @@ -232,6 +232,22 @@ PRUint32 nsScanner::Mark(PRInt32 anIndex){ } +/** + * Insert data to our underlying input buffer as + * if it were read from an input stream. + * + * @update harishd 01/12/99 + * @return error code + */ +PRBool nsScanner::Insert(const nsString& aBuffer) { + + PRInt32 theLen=aBuffer.Length(); + + mBuffer.Insert(aBuffer,mOffset,theLen); + mTotalRead+=theLen; + return PR_TRUE; +} + /** * Append data to our underlying input buffer as * if it were read from an input stream. diff --git a/mozilla/parser/htmlparser/src/nsScanner.h b/mozilla/parser/htmlparser/src/nsScanner.h index 57a499f9604..dc8120cfdcd 100644 --- a/mozilla/parser/htmlparser/src/nsScanner.h +++ b/mozilla/parser/htmlparser/src/nsScanner.h @@ -241,6 +241,15 @@ class nsScanner { PRUint32 RewindToMark(void); + /** + * + * + * @update harishd 01/12/99 + * @param + * @return + */ + PRBool Insert(const nsString& aBuffer); + /** * * diff --git a/mozilla/parser/htmlparser/src/nsXMLTokenizer.cpp b/mozilla/parser/htmlparser/src/nsXMLTokenizer.cpp index 28ed5c45a09..e09e1cb7c91 100644 --- a/mozilla/parser/htmlparser/src/nsXMLTokenizer.cpp +++ b/mozilla/parser/htmlparser/src/nsXMLTokenizer.cpp @@ -145,8 +145,8 @@ nsXMLTokenizer::~nsXMLTokenizer(){ * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner) { - return nsHTMLTokenizer::ConsumeToken(aScanner); +nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens) { + return nsHTMLTokenizer::ConsumeToken(aScanner,aFlushTokens); } diff --git a/mozilla/parser/htmlparser/src/nsXMLTokenizer.h b/mozilla/parser/htmlparser/src/nsXMLTokenizer.h index 0ce0486db8a..fa2464bf733 100644 --- a/mozilla/parser/htmlparser/src/nsXMLTokenizer.h +++ b/mozilla/parser/htmlparser/src/nsXMLTokenizer.h @@ -59,7 +59,7 @@ public: NS_DECL_ISUPPORTS - virtual nsresult ConsumeToken(nsScanner& aScanner); + virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens); virtual nsITokenRecycler* GetTokenRecycler(void); static void FreeTokenRecycler(void);