diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index 23cc5f67edd..28d5c56a586 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -247,6 +247,7 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared mComputedCRC32=0; mExpectedCRC32=0; mDTDState=NS_OK; + mStyleHandlingEnabled=PR_TRUE; if(!gHTMLElements) { InitializeElementTable(); @@ -294,7 +295,7 @@ nsCParserNode* CNavDTD::CreateNode(void) { * This method recycles a given node * @update gess1/8/99 * @param - * @return + * @return */ void CNavDTD::RecycleNode(nsCParserNode* aNode) { if(aNode && (!aNode->mUseCount)) { @@ -464,29 +465,28 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename, mHasOpenScript=PR_FALSE; mParseMode=aParseMode; - - nsString theString; - theString.Append("hello there rick",10); - - if((aNotifySink) && (aSink)) { STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); mTokenRecycler=0; + mStyleHandlingEnabled=PR_TRUE; if(aSink && (!mSink)) { result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink); } - result = aSink->WillBuildModel(); - MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); - START_TIMER(); + if(result==NS_OK) { + result = aSink->WillBuildModel(); - mSkipTarget=eHTMLTag_unknown; - mComputedCRC32=0; - mExpectedCRC32=0; + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); + START_TIMER(); + + mSkipTarget=eHTMLTag_unknown; + mComputedCRC32=0; + mExpectedCRC32=0; + } } return result; } @@ -573,6 +573,10 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse } if(result==NS_OK) { eHTMLTags theTarget; + + //now let's disable style handling to save time when closing remaining stack members... + mStyleHandlingEnabled=PR_FALSE; + while(mBodyContext->GetCount() > 0) { theTarget = mBodyContext->Last(); CloseContainersTo(theTarget,PR_FALSE); @@ -682,8 +686,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ static eHTMLTags passThru[]= { eHTMLTag_html,eHTMLTag_comment,eHTMLTag_newline, - eHTMLTag_whitespace,eHTMLTag_script,eHTMLTag_noscript, - eHTMLTag_nolayer,eHTMLTag_markupDecl,eHTMLTag_userdefined + eHTMLTag_whitespace,eHTMLTag_script, + eHTMLTag_markupDecl,eHTMLTag_userdefined }; if(!FindTagInSet(theTag,passThru,sizeof(passThru)/sizeof(eHTMLTag_unknown))){ @@ -1124,7 +1128,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode return result; } -void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32 aCount) { +void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32& aCount) { if(aCount > 0) { CToken* theAttrToken=nsnull; nsCParserNode* theAttrNode = (nsCParserNode*)&aNode; @@ -1190,15 +1194,13 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount); theToken=mTokenizer->PeekToken(); - PRBool theParentContains=-1; //set to -1 so that CanCmit will recompute. if(theToken) { theToken->mUseCount=0; theTag=(eHTMLTags)theToken->GetTypeID(); if(!nsHTMLElement::IsWhitespaceTag(theTag) && theTag!=eHTMLTag_unknown) { - if((gHTMLElements[theTag].HasSpecialProperty(kBadContentWatch)) || - (!gHTMLElements[mBodyContext->TagAt(theIndex)].CanContain(theTag))|| - (!CanOmit(aParent,theTag,theParentContains))) { + if((gHTMLElements[theTag].HasSpecialProperty(kBadContentWatch)) || + (gHTMLElements[aParent].CanContain(theTag))) { done=PR_TRUE; } } @@ -1953,13 +1955,6 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) { * @return PR_TRUE if parent can contain child */ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const { - if(mHasOpenForm) { - if(aParent==aChild) - return gHTMLElements[aParent].CanContainSelf(); - if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown))) { - return PR_TRUE; - }//if - }//if return gHTMLElements[aParent].CanContain((eHTMLTags)aChild); } @@ -2703,6 +2698,7 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos); nsresult result=NS_OK; + PRBool isDefaultNode=PR_FALSE; #ifdef ENABLE_CRC #define K_OPENOP 100 @@ -2721,11 +2717,17 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB break; case eHTMLTag_body: - mHasOpenBody=PR_TRUE; - if(mHasOpenHead) - mHasOpenHead=1; - CloseHead(aNode); //do this just in case someone left it open... - result=OpenBody(aNode); + { + eHTMLTags theParent=mBodyContext->Last(); + if(!gHTMLElements[aTag].IsSpecialParent(theParent)) { + mHasOpenBody=PR_TRUE; + if(mHasOpenHead) + mHasOpenHead=1; + CloseHead(aNode); //do this just in case someone left it open... + result=OpenBody(aNode); + } + else isDefaultNode=PR_TRUE; + } break; case eHTMLTag_style: @@ -2757,6 +2759,11 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB break; default: + isDefaultNode=PR_TRUE; + break; + } + + if(isDefaultNode) { STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenContainer(), this=%p\n", this)); @@ -2767,10 +2774,8 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB START_TIMER(); mBodyContext->Push(aNode,aResidualStyleLevel); - break; } - return result; } @@ -2869,13 +2874,40 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC #ifdef ENABLE_RESIDUALSTYLE PRBool theTagIsStyle=nsHTMLElement::IsStyleTag(theTag); - if(theTagIsStyle && aClosedByStartTag) { - if(theStyles) { - theStyles->PushFront(theNode); - mBodyContext->PushStyles(theStyles); + + if(mStyleHandlingEnabled) { + if(aClosedByStartTag) { + if(theTagIsStyle) { + if(theStyles) { + theStyles->PushFront(theNode); + mBodyContext->PushStyles(theStyles); + } + else mBodyContext->PushStyle(theNode); + } } - else mBodyContext->PushStyle(theNode); - } + else { + //if you're here, then we're dealing with the closure of tags + //caused by a close tag (as opposed to an open tag). + //At a minimum, we should consider pushing residual styles up + //up the stack... + + if(aTarget!=theTag) { + if(theTagIsStyle) { + if(theStyles) { + theStyles->PushFront(theNode); + mBodyContext->PushStyles(theStyles); + } + else mBodyContext->PushStyle(theNode); + } + else if(theStyles) { + mBodyContext->PushStyles(theStyles); + } + } + } + } + else { + //since stylehandling is disabled, let's recycle the associated nodes here... + } #endif RecycleNode(theNode); } @@ -2995,8 +3027,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ theToken=mTokenizer->PopToken(); theNode.Init(theToken,mLineNumber,0); - result=mSink->AddLeaf(theNode); - STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this)); diff --git a/mozilla/htmlparser/src/CNavDTD.h b/mozilla/htmlparser/src/CNavDTD.h index 2d634e8fc94..0ac0e39d7c9 100644 --- a/mozilla/htmlparser/src/CNavDTD.h +++ b/mozilla/htmlparser/src/CNavDTD.h @@ -540,6 +540,7 @@ protected: PRUint32 mComputedCRC32; PRUint32 mExpectedCRC32; nsAutoString mScratch; //used for various purposes; non-persistent + PRBool mStyleHandlingEnabled; #ifdef NS_DEBUG PRInt32 gNodeCount; diff --git a/mozilla/htmlparser/src/nsElementTable.cpp b/mozilla/htmlparser/src/nsElementTable.cpp index adcd888fb26..c0730053b4d 100644 --- a/mozilla/htmlparser/src/nsElementTable.cpp +++ b/mozilla/htmlparser/src/nsElementTable.cpp @@ -121,7 +121,7 @@ TagList gContainsOpts={3,{eHTMLTag_option,eHTMLTag_optgroup,eHTMLTag_script}}; TagList gContainsParam={1,{eHTMLTag_param}}; TagList gColgroupKids={1,{eHTMLTag_col}}; TagList gAddressKids={1,{eHTMLTag_p}}; -TagList gBodyKids={5,{eHTMLTag_del,eHTMLTag_ins,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_li}}; +TagList gBodyKids={6,{eHTMLTag_del,eHTMLTag_ins,eHTMLTag_noscript,eHTMLTag_nolayer,eHTMLTag_script,eHTMLTag_li}}; TagList gButtonKids={2,{eHTMLTag_caption,eHTMLTag_legend}}; TagList gDLKids={2,{eHTMLTag_dd,eHTMLTag_dt}}; TagList gDTKids={1,{eHTMLTag_dt}}; @@ -130,8 +130,8 @@ TagList gFontKids={2,{eHTMLTag_legend,eHTMLTag_text}}; TagList gFormKids={1,{eHTMLTag_keygen}}; TagList gFramesetKids={3,{eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes}}; -TagList gHtmlKids={8,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; -TagList gHeadKids={9,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript}}; +TagList gHtmlKids={9,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_noframes,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; +TagList gHeadKids={8,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed}}; TagList gLabelKids={1,{eHTMLTag_span}}; TagList gLIKids={2,{eHTMLTag_ol,eHTMLTag_ul}}; @@ -896,26 +896,26 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gNoframeRoot,&gNoframeRoot, /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ &gNoframeRoot,&gNoframesKids,eHTMLTag_noframes); + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ &gNoframeRoot,&gNoframesKids,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_nolayer, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kNone, kNone, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_nolayer); + /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_noscript, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_noscript); + /*parent,incl,exclgroups*/ kBlock, kFlowEntity|kSelf, kNone, + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_object, @@ -1539,6 +1539,21 @@ PRBool nsHTMLElement::IsFlowParent(eHTMLTags aTag){ return result; } +/** + * + * @update harishd 11/19/99 + * @param + * @return + */ +PRBool nsHTMLElement::IsSpecialParent(eHTMLTags aTag) const{ + PRBool result=PR_FALSE; + if(mSpecialParents) { + if(FindTagInSet(aTag,mSpecialParents->mTags,mSpecialParents->mCount)) + result=PR_TRUE; + } + return result; +} + /** * Tells us whether the given tag opens a section * @update gess 01/04/99 diff --git a/mozilla/htmlparser/src/nsElementTable.h b/mozilla/htmlparser/src/nsElementTable.h index a58b1cc6336..095aad35959 100644 --- a/mozilla/htmlparser/src/nsElementTable.h +++ b/mozilla/htmlparser/src/nsElementTable.h @@ -90,6 +90,7 @@ struct nsHTMLElement { PRBool CanContainSelf(void) const; PRBool CanAutoCloseTag(eHTMLTags aTag) const; PRBool HasSpecialProperty(PRInt32 aProperty) const; + PRBool IsSpecialParent(eHTMLTags aTag) const; PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch); static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild); diff --git a/mozilla/htmlparser/src/nsHTMLTokens.cpp b/mozilla/htmlparser/src/nsHTMLTokens.cpp index 889fa89a008..17aabee8a7f 100644 --- a/mozilla/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokens.cpp @@ -542,7 +542,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE); } } - else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) { + else if(('\b'==aChar) || ('\t'==aChar) || (' '==aChar)) { static CWhitespaceToken theWS; result=theWS.Consume(aChar,aScanner,aMode); if(NS_OK==result) { @@ -986,9 +986,22 @@ nsString& CNewlineToken::GetStringValueXXX(void) { * @return error result */ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) { + +#if 0 + mTextValue=kNewLine; //This is what I THINK we should be doing. +#endif mTextValue=aChar; - //we already read the \r or \n, let's see what's next! +/******************************************************************* + + Here's what the HTML spec says about newlines: + + "A line break is defined to be a carriage return ( ), + a line feed ( ), or a carriage return/line feed pair. + All line breaks constitute white space." + + *******************************************************************/ + PRUnichar theChar; nsresult result=aScanner.Peek(theChar); @@ -1000,10 +1013,10 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo mTextValue+=theChar; } break; - case kCR: + case kCR: + //convert CRLF into just CR if(kNewLine==theChar) { result=aScanner.GetChar(theChar); - mTextValue+=theChar; } break; default: diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index 23cc5f67edd..28d5c56a586 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -247,6 +247,7 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared mComputedCRC32=0; mExpectedCRC32=0; mDTDState=NS_OK; + mStyleHandlingEnabled=PR_TRUE; if(!gHTMLElements) { InitializeElementTable(); @@ -294,7 +295,7 @@ nsCParserNode* CNavDTD::CreateNode(void) { * This method recycles a given node * @update gess1/8/99 * @param - * @return + * @return */ void CNavDTD::RecycleNode(nsCParserNode* aNode) { if(aNode && (!aNode->mUseCount)) { @@ -464,29 +465,28 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename, mHasOpenScript=PR_FALSE; mParseMode=aParseMode; - - nsString theString; - theString.Append("hello there rick",10); - - if((aNotifySink) && (aSink)) { STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); mTokenRecycler=0; + mStyleHandlingEnabled=PR_TRUE; if(aSink && (!mSink)) { result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink); } - result = aSink->WillBuildModel(); - MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); - START_TIMER(); + if(result==NS_OK) { + result = aSink->WillBuildModel(); - mSkipTarget=eHTMLTag_unknown; - mComputedCRC32=0; - mExpectedCRC32=0; + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this)); + START_TIMER(); + + mSkipTarget=eHTMLTag_unknown; + mComputedCRC32=0; + mExpectedCRC32=0; + } } return result; } @@ -573,6 +573,10 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse } if(result==NS_OK) { eHTMLTags theTarget; + + //now let's disable style handling to save time when closing remaining stack members... + mStyleHandlingEnabled=PR_FALSE; + while(mBodyContext->GetCount() > 0) { theTarget = mBodyContext->Last(); CloseContainersTo(theTarget,PR_FALSE); @@ -682,8 +686,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ static eHTMLTags passThru[]= { eHTMLTag_html,eHTMLTag_comment,eHTMLTag_newline, - eHTMLTag_whitespace,eHTMLTag_script,eHTMLTag_noscript, - eHTMLTag_nolayer,eHTMLTag_markupDecl,eHTMLTag_userdefined + eHTMLTag_whitespace,eHTMLTag_script, + eHTMLTag_markupDecl,eHTMLTag_userdefined }; if(!FindTagInSet(theTag,passThru,sizeof(passThru)/sizeof(eHTMLTag_unknown))){ @@ -1124,7 +1128,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode return result; } -void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32 aCount) { +void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32& aCount) { if(aCount > 0) { CToken* theAttrToken=nsnull; nsCParserNode* theAttrNode = (nsCParserNode*)&aNode; @@ -1190,15 +1194,13 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount); theToken=mTokenizer->PeekToken(); - PRBool theParentContains=-1; //set to -1 so that CanCmit will recompute. if(theToken) { theToken->mUseCount=0; theTag=(eHTMLTags)theToken->GetTypeID(); if(!nsHTMLElement::IsWhitespaceTag(theTag) && theTag!=eHTMLTag_unknown) { - if((gHTMLElements[theTag].HasSpecialProperty(kBadContentWatch)) || - (!gHTMLElements[mBodyContext->TagAt(theIndex)].CanContain(theTag))|| - (!CanOmit(aParent,theTag,theParentContains))) { + if((gHTMLElements[theTag].HasSpecialProperty(kBadContentWatch)) || + (gHTMLElements[aParent].CanContain(theTag))) { done=PR_TRUE; } } @@ -1953,13 +1955,6 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) { * @return PR_TRUE if parent can contain child */ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const { - if(mHasOpenForm) { - if(aParent==aChild) - return gHTMLElements[aParent].CanContainSelf(); - if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown))) { - return PR_TRUE; - }//if - }//if return gHTMLElements[aParent].CanContain((eHTMLTags)aChild); } @@ -2703,6 +2698,7 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos); nsresult result=NS_OK; + PRBool isDefaultNode=PR_FALSE; #ifdef ENABLE_CRC #define K_OPENOP 100 @@ -2721,11 +2717,17 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB break; case eHTMLTag_body: - mHasOpenBody=PR_TRUE; - if(mHasOpenHead) - mHasOpenHead=1; - CloseHead(aNode); //do this just in case someone left it open... - result=OpenBody(aNode); + { + eHTMLTags theParent=mBodyContext->Last(); + if(!gHTMLElements[aTag].IsSpecialParent(theParent)) { + mHasOpenBody=PR_TRUE; + if(mHasOpenHead) + mHasOpenHead=1; + CloseHead(aNode); //do this just in case someone left it open... + result=OpenBody(aNode); + } + else isDefaultNode=PR_TRUE; + } break; case eHTMLTag_style: @@ -2757,6 +2759,11 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB break; default: + isDefaultNode=PR_TRUE; + break; + } + + if(isDefaultNode) { STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenContainer(), this=%p\n", this)); @@ -2767,10 +2774,8 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB START_TIMER(); mBodyContext->Push(aNode,aResidualStyleLevel); - break; } - return result; } @@ -2869,13 +2874,40 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC #ifdef ENABLE_RESIDUALSTYLE PRBool theTagIsStyle=nsHTMLElement::IsStyleTag(theTag); - if(theTagIsStyle && aClosedByStartTag) { - if(theStyles) { - theStyles->PushFront(theNode); - mBodyContext->PushStyles(theStyles); + + if(mStyleHandlingEnabled) { + if(aClosedByStartTag) { + if(theTagIsStyle) { + if(theStyles) { + theStyles->PushFront(theNode); + mBodyContext->PushStyles(theStyles); + } + else mBodyContext->PushStyle(theNode); + } } - else mBodyContext->PushStyle(theNode); - } + else { + //if you're here, then we're dealing with the closure of tags + //caused by a close tag (as opposed to an open tag). + //At a minimum, we should consider pushing residual styles up + //up the stack... + + if(aTarget!=theTag) { + if(theTagIsStyle) { + if(theStyles) { + theStyles->PushFront(theNode); + mBodyContext->PushStyles(theStyles); + } + else mBodyContext->PushStyle(theNode); + } + else if(theStyles) { + mBodyContext->PushStyles(theStyles); + } + } + } + } + else { + //since stylehandling is disabled, let's recycle the associated nodes here... + } #endif RecycleNode(theNode); } @@ -2995,8 +3027,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ theToken=mTokenizer->PopToken(); theNode.Init(theToken,mLineNumber,0); - result=mSink->AddLeaf(theNode); - STOP_TIMER(); MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this)); diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h index 2d634e8fc94..0ac0e39d7c9 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.h +++ b/mozilla/parser/htmlparser/src/CNavDTD.h @@ -540,6 +540,7 @@ protected: PRUint32 mComputedCRC32; PRUint32 mExpectedCRC32; nsAutoString mScratch; //used for various purposes; non-persistent + PRBool mStyleHandlingEnabled; #ifdef NS_DEBUG PRInt32 gNodeCount; diff --git a/mozilla/parser/htmlparser/src/nsElementTable.cpp b/mozilla/parser/htmlparser/src/nsElementTable.cpp index adcd888fb26..c0730053b4d 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.cpp +++ b/mozilla/parser/htmlparser/src/nsElementTable.cpp @@ -121,7 +121,7 @@ TagList gContainsOpts={3,{eHTMLTag_option,eHTMLTag_optgroup,eHTMLTag_script}}; TagList gContainsParam={1,{eHTMLTag_param}}; TagList gColgroupKids={1,{eHTMLTag_col}}; TagList gAddressKids={1,{eHTMLTag_p}}; -TagList gBodyKids={5,{eHTMLTag_del,eHTMLTag_ins,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_li}}; +TagList gBodyKids={6,{eHTMLTag_del,eHTMLTag_ins,eHTMLTag_noscript,eHTMLTag_nolayer,eHTMLTag_script,eHTMLTag_li}}; TagList gButtonKids={2,{eHTMLTag_caption,eHTMLTag_legend}}; TagList gDLKids={2,{eHTMLTag_dd,eHTMLTag_dt}}; TagList gDTKids={1,{eHTMLTag_dt}}; @@ -130,8 +130,8 @@ TagList gFontKids={2,{eHTMLTag_legend,eHTMLTag_text}}; TagList gFormKids={1,{eHTMLTag_keygen}}; TagList gFramesetKids={3,{eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes}}; -TagList gHtmlKids={8,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; -TagList gHeadKids={9,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript}}; +TagList gHtmlKids={9,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_noframes,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; +TagList gHeadKids={8,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed}}; TagList gLabelKids={1,{eHTMLTag_span}}; TagList gLIKids={2,{eHTMLTag_ol,eHTMLTag_ul}}; @@ -896,26 +896,26 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gNoframeRoot,&gNoframeRoot, /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ &gNoframeRoot,&gNoframesKids,eHTMLTag_noframes); + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ &gNoframeRoot,&gNoframesKids,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_nolayer, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kNone, kNone, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_nolayer); + /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_noscript, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ kDiscardTag, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_noscript); + /*parent,incl,exclgroups*/ kBlock, kFlowEntity|kSelf, kNone, + /*special props, prop-range*/ 0, kNoPropRange, + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_object, @@ -1539,6 +1539,21 @@ PRBool nsHTMLElement::IsFlowParent(eHTMLTags aTag){ return result; } +/** + * + * @update harishd 11/19/99 + * @param + * @return + */ +PRBool nsHTMLElement::IsSpecialParent(eHTMLTags aTag) const{ + PRBool result=PR_FALSE; + if(mSpecialParents) { + if(FindTagInSet(aTag,mSpecialParents->mTags,mSpecialParents->mCount)) + result=PR_TRUE; + } + return result; +} + /** * Tells us whether the given tag opens a section * @update gess 01/04/99 diff --git a/mozilla/parser/htmlparser/src/nsElementTable.h b/mozilla/parser/htmlparser/src/nsElementTable.h index a58b1cc6336..095aad35959 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.h +++ b/mozilla/parser/htmlparser/src/nsElementTable.h @@ -90,6 +90,7 @@ struct nsHTMLElement { PRBool CanContainSelf(void) const; PRBool CanAutoCloseTag(eHTMLTags aTag) const; PRBool HasSpecialProperty(PRInt32 aProperty) const; + PRBool IsSpecialParent(eHTMLTags aTag) const; PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch); static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild); diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp index 889fa89a008..17aabee8a7f 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp @@ -542,7 +542,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE); } } - else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) { + else if(('\b'==aChar) || ('\t'==aChar) || (' '==aChar)) { static CWhitespaceToken theWS; result=theWS.Consume(aChar,aScanner,aMode); if(NS_OK==result) { @@ -986,9 +986,22 @@ nsString& CNewlineToken::GetStringValueXXX(void) { * @return error result */ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) { + +#if 0 + mTextValue=kNewLine; //This is what I THINK we should be doing. +#endif mTextValue=aChar; - //we already read the \r or \n, let's see what's next! +/******************************************************************* + + Here's what the HTML spec says about newlines: + + "A line break is defined to be a carriage return ( ), + a line feed ( ), or a carriage return/line feed pair. + All line breaks constitute white space." + + *******************************************************************/ + PRUnichar theChar; nsresult result=aScanner.Peek(theChar); @@ -1000,10 +1013,10 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo mTextValue+=theChar; } break; - case kCR: + case kCR: + //convert CRLF into just CR if(kNewLine==theChar) { result=aScanner.GetChar(theChar); - mTextValue+=theChar; } break; default: