From 35b0b37df362048ac7883973795b2ce9f0b80ee8 Mon Sep 17 00:00:00 2001 From: "rickg%netscape.com" Date: Tue, 21 Dec 1999 07:53:20 +0000 Subject: [PATCH] landing residual style handling; r=harishd, buster, kmcclusk for various parts; a=jar git-svn-id: svn://10.0.0.236/trunk@56275 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/htmlparser/src/CNavDTD.cpp | 433 +++++++++++------- mozilla/htmlparser/src/CNavDTD.h | 10 +- mozilla/htmlparser/src/COtherDTD.cpp | 2 +- mozilla/htmlparser/src/COtherDTD.h | 2 +- mozilla/htmlparser/src/CRtfDTD.cpp | 14 +- mozilla/htmlparser/src/CRtfDTD.h | 8 +- mozilla/htmlparser/src/nsDTDUtils.cpp | 38 +- mozilla/htmlparser/src/nsDTDUtils.h | 73 ++- mozilla/htmlparser/src/nsElementTable.cpp | 178 +++---- mozilla/htmlparser/src/nsElementTable.h | 132 ++++-- mozilla/htmlparser/src/nsExpatDTD.cpp | 18 +- mozilla/htmlparser/src/nsExpatDTD.h | 2 +- mozilla/htmlparser/src/nsHTMLTokens.cpp | 29 +- mozilla/htmlparser/src/nsHTMLTokens.h | 2 +- mozilla/htmlparser/src/nsIDTD.h | 12 +- mozilla/htmlparser/src/nsParser.cpp | 121 ++--- mozilla/htmlparser/src/nsToken.h | 2 +- mozilla/htmlparser/src/nsValidDTD.cpp | 5 +- mozilla/htmlparser/src/nsValidDTD.h | 6 +- mozilla/htmlparser/src/nsViewSourceHTML.cpp | 19 +- mozilla/htmlparser/src/nsViewSourceHTML.h | 8 +- mozilla/htmlparser/src/nsWellFormedDTD.cpp | 17 +- mozilla/htmlparser/src/nsWellFormedDTD.h | 8 +- mozilla/htmlparser/src/nsXIFDTD.cpp | 25 +- mozilla/htmlparser/src/nsXIFDTD.h | 8 +- mozilla/parser/htmlparser/src/CNavDTD.cpp | 433 +++++++++++------- mozilla/parser/htmlparser/src/CNavDTD.h | 10 +- mozilla/parser/htmlparser/src/COtherDTD.cpp | 2 +- mozilla/parser/htmlparser/src/COtherDTD.h | 2 +- mozilla/parser/htmlparser/src/CRtfDTD.cpp | 14 +- mozilla/parser/htmlparser/src/CRtfDTD.h | 8 +- mozilla/parser/htmlparser/src/nsDTDUtils.cpp | 38 +- mozilla/parser/htmlparser/src/nsDTDUtils.h | 73 ++- .../parser/htmlparser/src/nsElementTable.cpp | 178 +++---- .../parser/htmlparser/src/nsElementTable.h | 132 ++++-- mozilla/parser/htmlparser/src/nsExpatDTD.cpp | 18 +- mozilla/parser/htmlparser/src/nsExpatDTD.h | 2 +- .../parser/htmlparser/src/nsHTMLTokens.cpp | 29 +- mozilla/parser/htmlparser/src/nsHTMLTokens.h | 2 +- mozilla/parser/htmlparser/src/nsIDTD.h | 12 +- mozilla/parser/htmlparser/src/nsParser.cpp | 121 ++--- mozilla/parser/htmlparser/src/nsToken.h | 2 +- mozilla/parser/htmlparser/src/nsValidDTD.cpp | 5 +- mozilla/parser/htmlparser/src/nsValidDTD.h | 6 +- .../htmlparser/src/nsViewSourceHTML.cpp | 19 +- .../parser/htmlparser/src/nsViewSourceHTML.h | 8 +- .../parser/htmlparser/src/nsWellFormedDTD.cpp | 17 +- .../parser/htmlparser/src/nsWellFormedDTD.h | 8 +- mozilla/parser/htmlparser/src/nsXIFDTD.cpp | 25 +- mozilla/parser/htmlparser/src/nsXIFDTD.h | 8 +- 50 files changed, 1328 insertions(+), 1016 deletions(-) diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index fcec3126bc0..84bb7f2ab24 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -19,6 +19,13 @@ * * Contributor(s): */ + +//#define ENABLE_CRC +//#define RICKG_DEBUG +#define ENABLE_RESIDUALSTYLE +#ifdef RICKG_DEBUG +#include +#endif #include "nsDebug.h" #include "nsIDTDDebug.h" @@ -49,13 +56,6 @@ #endif #include "prmem.h" -//#define ENABLE_RESIDUALSTYLE -//#define RICKG_DEBUG -//#define ENABLE_CRC -#ifdef RICKG_DEBUG -#include -#endif - static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -247,10 +247,10 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared InitializeElementTable(); } -// DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules"); #ifdef RICKG_DEBUG - nsHTMLElement::DebugDumpContainment("c:/temp/rules.new","ElementTable Rules"); - nsHTMLElement::DebugDumpMembership("c:/temp/table.out"); + //DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules"); + nsHTMLElement::DebugDumpContainment("c:/temp/contain.new","ElementTable Rules"); + nsHTMLElement::DebugDumpMembership("c:/temp/membership.out"); nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out"); #endif @@ -311,6 +311,40 @@ void CNavDTD::RecycleNode(nsCParserNode* aNode) { } } +/** + * This method recycles the nodes on a nodestack. + * NOTE: Unlike recycleNode(), we force the usecount + * to 0 of all nodes, then force them to recycle. + * @update gess1/8/99 + * @param aNodeStack + * @return nothing + */ +void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) { + if(aNodeStack) { + PRInt32 theCount=aNodeStack->mCount; + PRInt32 theIndex=0; + + for(theIndex=0;theIndexNodeAt(theIndex); + if(theNode) { + + theNode->mUseCount=0; + if(theNode->mToken) { + theNode->mToken->mUseCount=0; + mTokenRecycler->RecycleToken(theNode->mToken); + } + + CToken* theToken=0; + while((theToken=(CToken*)theNode->PopAttributeToken())){ + theNode->mToken->mUseCount=0; + mTokenRecycler->RecycleToken(theToken); + } + + mSharedNodes.Push(theNode); + } //if + } //while + } //if +} /** * @@ -517,6 +551,17 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke } while(NS_SUCCEEDED(result)){ + +#if 0 + int n=aTokenizer->GetCount(); + if(n>50) n=50; + for(int i=0;iGetTokenAt(i); + printf("\nToken[%i],%p",i,theToken); + } + printf("\n"); +#endif + if(mDTDState!=NS_ERROR_HTMLPARSER_STOPPARSING) { CToken* theToken=mTokenizer->PopToken(); if(theToken) { @@ -545,10 +590,13 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke */ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink){ nsresult result=NS_OK; + if(aSink) { if((NS_OK==anErrorCode) && (!mHadBody) && (!mHadFrameset)) { + mSkipTarget=eHTMLTag_unknown; //clear this in case we were searching earlier. + CStartToken *theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_body,"body"); mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack, don't recycle it mTokenizer->PrependTokens(mMisplacedContent); //push misplaced content @@ -625,8 +673,6 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse else result = aSink->DidBuildModel(0); } else result=aSink->DidBuildModel(0); -#else - result=aSink->DidBuildModel(0); #endif MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::DidBuildModel(), this=%p\n", this)); @@ -636,8 +682,12 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse mDTDDebug->DumpVectorRecord(); } } - } - } + } //if aparser + + //No matter what, you need to call did build model. + result=aSink->DidBuildModel(0); + + } //if asink return result; } @@ -877,6 +927,23 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){ return result; } +/** + * Determine whether the given tag is open anywhere + * in our context stack. + * + * @update gess 4/2/98 + * @param eHTMLTags tag to be searched for in stack + * @return topmost index of tag on stack + */ +PRInt32 CNavDTD::LastOf(eHTMLTags aTagSet[],PRInt32 aCount) const { + int theIndex=0; + for(theIndex=mBodyContext->GetCount()-1;theIndex>=0;theIndex--){ + if(FindTagInSet((*mBodyContext)[theIndex],aTagSet,aCount)) { + return theIndex; + } + } + return kNotFound; +} /** * Call this to find the index of a given child, or (if not found) @@ -889,19 +956,21 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){ */ static PRInt32 GetIndexOfChildOrSynonym(nsDTDContext& aContext,eHTMLTags aChildTag) { - PRInt32 theChildIndex=aContext.GetTopmostIndexOf(aChildTag); + PRInt32 theChildIndex=aContext.LastOf(aChildTag); if(kNotFound==theChildIndex) { TagList* theSynTags=gHTMLElements[aChildTag].GetSynonymousTags(); //get the list of tags that THIS tag can close if(theSynTags) { - theChildIndex=GetTopmostIndexOf(aContext,*theSynTags); + theChildIndex=LastOf(aContext,*theSynTags); } else{ - theChildIndex=aContext.GetCount(); PRInt32 theGroup=nsHTMLElement::GetSynonymousGroups(aChildTag); - while(-1<--theChildIndex) { - eHTMLTags theTag=aContext[theChildIndex]; - if(gHTMLElements[theTag].IsMemberOf(theGroup)) { - break; + if(theGroup) { + theChildIndex=aContext.GetCount(); + while(-1<--theChildIndex) { + eHTMLTags theTag=aContext[theChildIndex]; + if(gHTMLElements[theTag].IsMemberOf(theGroup)) { + break; + } } } } @@ -937,8 +1006,8 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) { TagList* theRootTags=gHTMLElements[aChildTag].GetRootTags(); TagList* theSpecialParents=gHTMLElements[aChildTag].GetSpecialParents(); if(theRootTags) { - PRInt32 theRootIndex=GetTopmostIndexOf(aContext,*theRootTags); - PRInt32 theSPIndex=(theSpecialParents) ? GetTopmostIndexOf(aContext,*theSpecialParents) : kNotFound; + PRInt32 theRootIndex=LastOf(aContext,*theRootTags); + PRInt32 theSPIndex=(theSpecialParents) ? LastOf(aContext,*theSpecialParents) : kNotFound; PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aChildTag); PRInt32 theBaseIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex; @@ -1372,16 +1441,16 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { */ static PRBool HasCloseablePeerAboveRoot(TagList& aRootTagList,nsDTDContext& aContext,eHTMLTags aTag,PRBool anEndTag) { - PRInt32 theRootIndex=GetTopmostIndexOf(aContext,aRootTagList); + PRInt32 theRootIndex=LastOf(aContext,aRootTagList); TagList* theCloseTags=(anEndTag) ? gHTMLElements[aTag].GetAutoCloseEndTags() : gHTMLElements[aTag].GetAutoCloseStartTags(); PRInt32 theChildIndex=-1; if(theCloseTags) { - theChildIndex=GetTopmostIndexOf(aContext,*theCloseTags); + theChildIndex=LastOf(aContext,*theCloseTags); } else { if((anEndTag) || (!gHTMLElements[aTag].CanContainSelf())) - theChildIndex=aContext.GetTopmostIndexOf(aTag); + theChildIndex=aContext.LastOf(aTag); } // I changed this to theRootIndex<=theChildIndex so to handle this case: // ... @@ -1560,8 +1629,9 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) { PopStyle(theChildTag); } else { + eHTMLTags theParentTag=mBodyContext->Last(); if((kNotFound==GetIndexOfChildOrSynonym(*mBodyContext,theChildTag)) || - (!gHTMLElements[theChildTag].CanAutoCloseTag(mBodyContext->Last()))) { + (!gHTMLElements[theChildTag].CanAutoCloseTag(theParentTag))) { PopStyle(theChildTag); @@ -1571,7 +1641,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) { // such cases. So, let's simulate that effect for compatibility. // Ex. Hello

There PRBool theParentContains=-1; //set to -1 to force canomit to recompute. - if(!CanOmit(mBodyContext->Last(),theChildTag,theParentContains)) { + if(!CanOmit(theParentTag,theChildTag,theParentContains)) { mTokenizer->PushTokenFront(aToken); //put this end token back... CHTMLToken* theToken = (CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theChildTag); mTokenizer->PushTokenFront(theToken); //put this new token onto stack... @@ -1994,7 +2064,7 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) { mLineNumber += aNode.mSkippedContent.CountChar(kNewLine); return NS_OK; } - + /*********************************************************************************** The preceeding tables determine the set of elements each tag can contain... ***********************************************************************************/ @@ -2032,49 +2102,52 @@ NS_IMETHODIMP CNavDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32* } /** - * This method is called to determine whether or not + * This method is called to determine whether or not * the necessary intermediate tags should be propagated * between the given parent and given child. - * + * * @update gess 4/8/98 * @param aParent -- tag enum of parent container * @param aChild -- tag enum of child container * @return PR_TRUE if propagation should occur */ -PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag,PRBool aParentContains) const { - PRBool result=PR_FALSE; - PRBool theParentContains=(-1==aParentContains) ? CanContain(aParentTag,aChildTag) : aParentContains; +PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag,PRBool aParentContains) { + PRBool result=PR_FALSE; + PRBool theParentContains=(-1==aParentContains) ? CanContain(aParentTag,aChildTag) : aParentContains; eHTMLTags theTempTag=eHTMLTag_unknown; if(aParentTag==aChildTag) { return result; } - int thePropLevel=0; if(nsHTMLElement::IsContainer(aChildTag)){ + mScratch.Truncate(); if(!gHTMLElements[aChildTag].HasSpecialProperty(kNoPropagate)){ if(nsHTMLElement::IsBlockParent(aParentTag) || (gHTMLElements[aParentTag].GetSpecialChildren())) { - theTempTag=aChildTag; - while(eHTMLTag_unknown!=aChildTag) { - if(theParentContains){ - if(!CanOmit(aParentTag,aChildTag,theParentContains)) - result=PR_TRUE; - break; - }//if - TagList* theTagList=gHTMLElements[aChildTag].GetRootTags(); - aChildTag=GetTagAt(0,*theTagList); - if(aChildTag==theTempTag) break; - theParentContains=CanContain(aParentTag,aChildTag); - ++thePropLevel; - }//while + + result=ForwardPropagate(mScratch,aParentTag,aChildTag); + + if(PR_FALSE==result){ + + if(eHTMLTag_unknown!=aParentTag) { + if(aParentTag!=aChildTag) //dont even bother if we're already inside a similar element... + result=BackwardPropagate(mScratch,aParentTag,aChildTag); + } //if + else result=BackwardPropagate(mScratch,eHTMLTag_html,aChildTag); + + } //elseif + }//if }//if - if(thePropLevel>gHTMLElements[aParentTag].mPropagateRange) + if(mScratch.Length()-1>gHTMLElements[aParentTag].mPropagateRange) result=PR_FALSE; }//if else result=theParentContains; + + return result; -} +} + /** * This method gets called to determine whether a given @@ -2086,7 +2159,7 @@ PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag,PRBool aPa * @param aParentContains * @return PR_TRUE if given tag can contain other tags */ -PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const { +PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) { eHTMLTags theAncestor=gHTMLElements[aChild].mExcludingAncestor; if(eHTMLTag_unknown!=theAncestor){ @@ -2123,7 +2196,7 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContai return PR_FALSE; } - if(nsHTMLElement::IsBlockEntity(aParent)) { + if(gHTMLElements[aParent].IsBlockEntity()) { if(nsHTMLElement::IsInlineEntity(aChild)) { //feel free to drop inlines that a block doesn't contain. return PR_TRUE; } @@ -2225,7 +2298,7 @@ PRBool CNavDTD::BackwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTML do { TagList* theRootTags=gHTMLElements[aChildTag].GetRootTags(); if(theRootTags) { - theParentTag=GetTagAt(0,*theRootTags); + theParentTag=theRootTags->mTags[0]; if(CanContain(theParentTag,aChildTag)) { //we've found a complete sequence, so push the parent... aChildTag=theParentTag; @@ -2294,25 +2367,6 @@ eHTMLTags CNavDTD::GetTopNode() const { return mBodyContext->Last(); } - -/** - * Determine whether the given tag is open anywhere - * in our context stack. - * - * @update gess 4/2/98 - * @param eHTMLTags tag to be searched for in stack - * @return topmost index of tag on stack - */ -PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTagSet[],PRInt32 aCount) const { - int theIndex=0; - for(theIndex=mBodyContext->GetCount()-1;theIndex>=0;theIndex--){ - if(FindTagInSet((*mBodyContext)[theIndex],aTagSet,aCount)) { - return theIndex; - } - } - return kNotFound; -} - /********************************************* Here comes code that handles the interface to our content sink. @@ -2335,39 +2389,47 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){ //later, change this so that transients only open in containers that get leaked in to. - if(mStyleHandlingEnabled) { + if(mStyleHandlingEnabled && (eHTMLTag_newline!=aChildTag)) { #ifdef ENABLE_RESIDUALSTYLE - eHTMLTags theParentTag=mBodyContext->Last(); - if(CanContain(eHTMLTag_font,aChildTag)) { - if(!gHTMLElements[theParentTag].HasSpecialProperty(kNoStyleLeaksIn)) { - //the following code builds the set of style tags to be opened... - PRUint32 theCount=mBodyContext->GetCount(); - PRUint32 theLevel=0; - for(theLevel=0;theLevelGetStylesAt(theLevel); - if(theStack){ - PRUint32 scount=theStack->mCount; - PRUint32 sindex=0; + PRUint32 theCount=mBodyContext->GetCount(); + PRUint32 theLevel=theCount; + + //this first loop is used to determine how far up the containment + //hierarchy we go looking for residual styles. + while ( 1TagAt(--theLevel); + if(gHTMLElements[theParentTag].HasSpecialProperty(kNoStyleLeaksIn)) { + break; + } + } + + mStyleHandlingEnabled=PR_FALSE; + for(;theLevelGetStylesAt(theLevel); + if(theStack){ + + PRUint32 scount=theStack->mCount; + PRUint32 sindex=0; + + nsTagEntry *theEntry=theStack->mEntries; + for(sindex=0;sindexmNode; + if(1==theNode->mUseCount) { + theEntry->mParent=theStack; //we do this too, because this entry differs from the new one we're pushing... + result=OpenContainer(theNode,(eHTMLTags)theNode->GetNodeType(),PR_FALSE,theStack); + } + theEntry++; + } //for + } //if + } //for + mStyleHandlingEnabled=PR_TRUE; + + } //if - nsTagEntry *theEntry=theStack->mEntries; - for(sindex=0;sindexmParent) { - theEntry->mParent=theStack; //we do this too, because this entry differs from the new one we're pushing... - nsIParserNode* theNode=theEntry->mNode; - if(theNode) { - result=OpenContainer(theNode,(eHTMLTags)theNode->GetNodeType(),PR_FALSE,theStack); - } - } - theEntry++; - } //for - } //if - } //for - } //if - } #endif }//if return result; @@ -2422,7 +2484,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){ if(mStyleHandlingEnabled) { #ifdef ENABLE_RESIDUALSTYLE - if(nsHTMLElement::IsStyleTag(aTag)) { + if(nsHTMLElement::IsResidualStyleTag(aTag)) { nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag); if(theNode) { RecycleNode(theNode); @@ -2551,7 +2613,7 @@ nsresult CNavDTD::OpenBody(const nsIParserNode *aNode){ PRBool theBodyIsOpen=HasOpenContainer(eHTMLTag_body); if(!theBodyIsOpen){ //body is not already open, but head may be so close it - PRInt32 theHTMLPos=mBodyContext->GetTopmostIndexOf(eHTMLTag_html); + PRInt32 theHTMLPos=mBodyContext->LastOf(eHTMLTag_html); result=CloseContainersTo(theHTMLPos+1,eHTMLTag_body,PR_TRUE); //close current stack containers. } @@ -2766,6 +2828,10 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB nsresult result=NS_OK; PRBool isDefaultNode=PR_FALSE; + + if (nsHTMLElement::IsResidualStyleTag(aTag)) + OpenTransientStyles(aTag); + #ifdef ENABLE_CRC #define K_OPENOP 100 CRCStruct theStruct(aTag,K_OPENOP); @@ -2925,93 +2991,126 @@ CNavDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClo nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aClosedByStartTag){ NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos); nsresult result=NS_OK; - eHTMLTags theTag=eHTMLTag_unknown; + if((anIndexGetCount()) && (anIndex>=0)) { + while(mBodyContext->GetCount()>anIndex) { - theTag=mBodyContext->Last(); - - nsEntryStack *theChildStyleStack=0; - - nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyleStack); - result=CloseContainer(theNode,aTarget,aClosedByStartTag); + nsEntryStack *theChildStyleStack=0; + eHTMLTags theTag=mBodyContext->Last(); + nsCParserNode *theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyleStack); + eHTMLTags theParent=mBodyContext->Last(); if(theNode) { + result=CloseContainer(theNode,aTarget,aClosedByStartTag); #ifdef ENABLE_RESIDUALSTYLE - PRBool theTagIsStyle=nsHTMLElement::IsStyleTag(theTag); - if(mStyleHandlingEnabled) { - if(aClosedByStartTag && (0==theNode->mUseCount)) { + PRBool theTagIsStyle=nsHTMLElement::IsResidualStyleTag(theTag); + PRBool theTargetTagIsStyle=nsHTMLElement::IsResidualStyleTag(aTarget); + PRBool theStyleDoesntLeakOut=gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut); + if(mStyleHandlingEnabled && theTagIsStyle) { + + if(aClosedByStartTag) { + + /*********************************************************** + Handle closure due to new start tag. - /*************************************************************************** The cases we're handing here: 1.
// gets pushed onto .mStyles. + 2. text //in this case, the target matches, so don't push style ***************************************************************************/ - if(theTagIsStyle) { - if(theChildStyleStack) { - theChildStyleStack->PushFront(theNode); - mBodyContext->PushStyles(theChildStyleStack); + if(0==theNode->mUseCount){ + if(theTag!=aTarget) { + //don't push if thechild==theTarget + if(theChildStyleStack) { + theChildStyleStack->PushFront(theNode); + } + else mBodyContext->PushStyle(theNode); } - else mBodyContext->PushStyle(theNode); } + if(theChildStyleStack) { + mBodyContext->PushStyles(theChildStyleStack); + } } - 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 or popping and recycling displaced nodes. + else { //Handle closure due to another close tag. - /*************************************************************************** - There are 2 cases: + /*********************************************************** + 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 or popping and recycling displaced nodes. + + Known cases: 1.
text
Here the will leak into
(see case given above), and when
closes the is dropped since it's already residual. + 2.
text
Here the will leak out of the
and get pushed onto the RS stack for the , since it originated in the
. + + 3. text + In this case, the the get's pushed onto the style stack. + Later we deal with RS styles stored on the + + 4. text + Here we the is closed by a (synonymous) style tag. + In this case, the is simply closed. ***************************************************************************/ - if(theTagIsStyle) { - if(theChildStyleStack) { - theChildStyleStack->PushFront(theNode); + if(theChildStyleStack) { + if(!theStyleDoesntLeakOut) { + if(theTag!=aTarget) { + if (0==theNode->mUseCount) { + theChildStyleStack->PushFront(theNode); + } + } mBodyContext->PushStyles(theChildStyleStack); } - else if (0==theNode->mUseCount) { - if(theTag!=aTarget) { - mBodyContext->PushStyle(theNode); - } //otherwise just let the node recycle, because it was explicty closed - //and does not live on a style stack. - } - else { - //Ah, at last, the final case. If you're here, then we just popped a - //style tag that got onto that tag stack from a stylestack somewhere. - //The the target==theTag, then pop it from the stylestack. - if(theTag==aTarget) { - theNode=(nsCParserNode*)mBodyContext->PopStyle(theTag); - } + else{ + //add code here to recycle styles... + RecycleNodes(theChildStyleStack); } + } + else if (0==theNode->mUseCount) { + + if(!theTargetTagIsStyle) { + mBodyContext->PushStyle(theNode); + } //otherwise just let the node recycle, because it was explicty closed + //and does not live on a style stack. } - else if(theChildStyleStack) { - mBodyContext->PushStyles(theChildStyleStack); + else { + //Ah, at last, the final case. If you're here, then we just popped a + //style tag that got onto that tag stack from a stylestack somewhere. + //Pop it from the stylestack if the target is also a style tag. + if(theTargetTagIsStyle) { + theNode=(nsCParserNode*)mBodyContext->PopStyle(theTag); + } } } } //if else { - //since stylehandling is disabled, let's recycle the associated nodes here... + + if(theChildStyleStack) { + if(theStyleDoesntLeakOut) { + RecycleNodes(theChildStyleStack); + } + else mBodyContext->PushStyles(theChildStyleStack); + } } #endif - }//if + }//if anode RecycleNode(theNode); } if(eParseMode_quirks==mParseMode) { -#ifdef ENABLE_RESIDUALSTYLE +#if 0 //This code takes any nodes in style stack for at this level and reopens //then where they were originally. @@ -3052,7 +3151,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC nsresult CNavDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aClosedByStartTag){ NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos); - PRInt32 pos=mBodyContext->GetTopmostIndexOf(aTarget); + PRInt32 pos=mBodyContext->LastOf(aTarget); if(kNotFound!=pos) { //the tag is indeed open, so close it. @@ -3061,7 +3160,7 @@ nsresult CNavDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aClosedByStartTag){ eHTMLTags theTopTag=mBodyContext->Last(); - PRBool theTagIsSynonymous=((nsHTMLElement::IsStyleTag(aTarget)) && (nsHTMLElement::IsStyleTag(theTopTag))); + PRBool theTagIsSynonymous=((nsHTMLElement::IsResidualStyleTag(aTarget)) && (nsHTMLElement::IsResidualStyleTag(theTopTag))); if(!theTagIsSynonymous){ theTagIsSynonymous=((nsHTMLElement::IsHeadingTag(aTarget)) && (nsHTMLElement::IsHeadingTag(theTopTag))); } @@ -3071,7 +3170,7 @@ nsresult CNavDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aClosedByStartTag){ //but a different (synonymous) one is actually open. Because this is NAV4x //compatibililty mode, we must close the one that's really open. aTarget=theTopTag; - pos=mBodyContext->GetTopmostIndexOf(aTarget); + pos=mBodyContext->LastOf(aTarget); if(kNotFound!=pos) { //the tag is indeed open, so close it. return CloseContainersTo(pos,aTarget,aClosedByStartTag); @@ -3080,8 +3179,8 @@ nsresult CNavDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aClosedByStartTag){ nsresult result=NS_OK; TagList* theRootTags=gHTMLElements[aTarget].GetRootTags(); - eHTMLTags theParentTag=GetTagAt(0,*theRootTags); - pos=mBodyContext->GetTopmostIndexOf(theParentTag); + eHTMLTags theParentTag=(theRootTags) ? theRootTags->mTags[0] : eHTMLTag_unknown; + pos=mBodyContext->LastOf(theParentTag); if(kNotFound!=pos) { //the parent container is open, so close it instead result=CloseContainersTo(pos+1,aTarget,aClosedByStartTag); @@ -3293,6 +3392,21 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){ return result; } +/** + * Retrieve the preferred tokenizer for use by this DTD. + * @update gess12/28/98 + * @param none + * @return ptr to tokenizer + */ +nsresult CNavDTD::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; + if(!mTokenizer) { + result=NS_NewHTMLTokenizer(&mTokenizer); + } + aTokenizer=mTokenizer; + return result; +} + /** * @@ -3302,25 +3416,14 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){ */ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){ if(!mTokenRecycler) { - mTokenizer=GetTokenizer(); - mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler(); + nsresult result=GetTokenizer(mTokenizer); + if (NS_SUCCEEDED(result)) { + mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler(); + } } return mTokenRecycler; } -/** - * Retrieve the preferred tokenizer for use by this DTD. - * @update gess12/28/98 - * @param none - * @return ptr to tokenizer - */ -nsITokenizer* CNavDTD::GetTokenizer(void) { - if(!mTokenizer) { - nsresult result=NS_NewHTMLTokenizer(&mTokenizer); - } - return mTokenizer; -} - /** * * @update gess5/18/98 diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h index ef1050fd413..838467dda60 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.h +++ b/mozilla/parser/htmlparser/src/CNavDTD.h @@ -244,8 +244,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param * @return */ - nsITokenizer* GetTokenizer(void); - + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * @@ -291,7 +290,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param aChild -- int tag of child container * @return PR_TRUE if parent can contain child */ - virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild,PRBool aParentContains) const; + virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild,PRBool aParentContains) ; /** * This method gets called to determine whether a given @@ -303,7 +302,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param aParentContains -- can be 0,1,-1 (false,true, unknown) * @return PR_TRUE if given tag can be omitted */ - virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const; + virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) ; /** * This method gets called to determine whether a given @@ -386,7 +385,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param tag to be found * @return index of topmost tag occurance -- may be -1 (kNotFound). */ - virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTagSet[],PRInt32 aCount) const; + virtual PRInt32 LastOf(eHTMLTags aTagSet[],PRInt32 aCount) const; /** * Use this id you want to stop the building content model @@ -508,6 +507,7 @@ protected: nsresult HandleSavedTokens(PRInt32 anIndex); nsCParserNode* CreateNode(void); void RecycleNode(nsCParserNode* aNode); + void RecycleNodes(nsEntryStack *aNodeStack); nsIHTMLContentSink* mSink; diff --git a/mozilla/parser/htmlparser/src/COtherDTD.cpp b/mozilla/parser/htmlparser/src/COtherDTD.cpp index 224f7d8471f..8909587144d 100644 --- a/mozilla/parser/htmlparser/src/COtherDTD.cpp +++ b/mozilla/parser/htmlparser/src/COtherDTD.cpp @@ -337,7 +337,7 @@ NS_IMETHODIMP COtherDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32 * @param aTag -- tag to test for containership * @return PR_TRUE if given tag can contain other tags */ -PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const { +PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) { return CNavDTD::CanOmit(aParent,aChild,aParentContains); } diff --git a/mozilla/parser/htmlparser/src/COtherDTD.h b/mozilla/parser/htmlparser/src/COtherDTD.h index 558db944872..e87e849c9a9 100644 --- a/mozilla/parser/htmlparser/src/COtherDTD.h +++ b/mozilla/parser/htmlparser/src/COtherDTD.h @@ -123,7 +123,7 @@ class COtherDTD : public CNavDTD { * @param aTag -- tag to test for containership * @return PR_TRUE if given tag can contain other tags */ - virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const; + virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) ; /** * Give rest of world access to our tag enums, so that CanContain(), etc, diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.cpp b/mozilla/parser/htmlparser/src/CRtfDTD.cpp index 4703059d837..2e5a4d2ce73 100644 --- a/mozilla/parser/htmlparser/src/CRtfDTD.cpp +++ b/mozilla/parser/htmlparser/src/CRtfDTD.cpp @@ -294,13 +294,15 @@ NS_IMETHODIMP CRtfDTD::DidBuildModel(nsresult anErrorCode,PRInt32 aLevel,nsIPars } /** - * - * @update gess12/28/98 - * @param - * @return + * Retrieve the preferred tokenizer for use by this DTD. + * @update gess12/28/98 + * @param none + * @return ptr to tokenizer */ -nsITokenizer* CRtfDTD::GetTokenizer(void){ - return 0; +nsresult CRtfDTD::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; + aTokenizer=0; + return result; } /** diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.h b/mozilla/parser/htmlparser/src/CRtfDTD.h index 6e66fc0d2ee..085362b3ad9 100644 --- a/mozilla/parser/htmlparser/src/CRtfDTD.h +++ b/mozilla/parser/htmlparser/src/CRtfDTD.h @@ -278,11 +278,11 @@ class CRtfDTD : public nsIDTD { /** * - * @update gess12/28/98 - * @param - * @return + * @update gess 12/20/99 + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp index b4791586976..50fe546237c 100644 --- a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp +++ b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp @@ -47,6 +47,7 @@ MOZ_DECL_CTOR_COUNTER(CObserverService); **************************************************************************************/ + /** * Default constructor * @update harishd 04/04/99 @@ -218,7 +219,7 @@ nsIParserNode* nsEntryStack::Pop(void) { PRUint32 sindex=0; nsTagEntry *theStyleEntry=theStyleStack->mEntries; - for(sindex=scount-1;sindex>=0;sindex--){ + for(sindex=scount-1;sindex>0;sindex--){ if(theStyleEntry->mTag==mEntries[mCount].mTag) { theStyleEntry->mParent=0; //this tells us that the style is not open at any level break; @@ -317,7 +318,7 @@ eHTMLTags nsEntryStack::Last() const { */ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const { int theIndex=0; - for(theIndex=mCount-1;theIndex>=0;theIndex--){ + for(theIndex=mCount-1;theIndex>0;theIndex--){ if(aTag==TagAt(theIndex)) return theIndex; } @@ -339,6 +340,7 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const { nsDTDContext::nsDTDContext() : mStack() { MOZ_COUNT_CTOR(nsDTDContext); + mResidualStyleCount=0; #ifdef NS_DEBUG memset(mXTags,0,sizeof(mXTags)); @@ -354,33 +356,15 @@ nsDTDContext::~nsDTDContext() { MOZ_COUNT_DTOR(nsDTDContext); } -/** - * - * @update gess7/9/98, harishd 04/04/99 - */ -PRInt32 nsDTDContext::GetCount(void) { - return mStack.mCount; -} - - /** * * @update gess7/9/98 */ PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const { - PRInt32 theIndex=mStack.FindLast(aTag); + PRInt32 theIndex=mStack.LastOf(aTag); return PRBool(-1Push(aNode); + mResidualStyleCount++; } } //if } @@ -512,6 +505,7 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){ for(sindex=0;sindexmParent=0; //this tells us that the style is not open at any level theEntry++; + mResidualStyleCount++; } //for } @@ -533,6 +527,7 @@ nsIParserNode* nsDTDContext::PopStyle(void){ nsEntryStack* theStyleStack=theEntry->mParent; if(theStyleStack){ result=theStyleStack->Pop(); + mResidualStyleCount--; } } //if return result; @@ -551,6 +546,7 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){ if(theStack) { if(aTag==theStack->Last()) { return theStack->Pop(); + mResidualStyleCount--; } else { // NS_ERROR("bad residual style entry"); } diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.h b/mozilla/parser/htmlparser/src/nsDTDUtils.h index e8b1700f2c7..ec77215794a 100644 --- a/mozilla/parser/htmlparser/src/nsDTDUtils.h +++ b/mozilla/parser/htmlparser/src/nsDTDUtils.h @@ -44,18 +44,6 @@ class nsIParserNode; -/*************************************************************** - Before digging into the NavDTD, we'll define a helper - class called CTagStack. - - Simply put, we've built ourselves a little data structure that - serves as a stack for htmltags (and associated bits). - What's special is that if you #define rickgdebug 1, the stack - size can grow dynamically (like you'ld want in a release build.) - If you don't #define rickgdebug 1, then the stack is a fixed size, - equal to the eStackSize enum. This makes debugging easier, because - you can see the htmltags on the stack if its not dynamic. - ***************************************************************/ void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle); void DebugDumpContainmentRules2(nsIDTD& theDTD,const char* aFilename,const char* aTitle); @@ -97,7 +85,7 @@ public: eHTMLTags Last() const; void Empty(void); - inline PRInt32 FindFirst(eHTMLTags aTag) const { + inline PRInt32 FirstOf(eHTMLTags aTag) const { PRInt32 index=-1; if(0=0) { if(aTag==mEntries[index].mTag) { @@ -126,6 +114,9 @@ public: }; +//********************************************************************************************* +//********************************************************************************************* + class nsDTDContext { public: nsDTDContext(); @@ -135,13 +126,16 @@ public: nsIParserNode* Pop(nsEntryStack*& aChildStack); eHTMLTags First(void) const; eHTMLTags Last(void) const; + nsTagEntry* LastEntry(void) const; eHTMLTags TagAt(PRInt32 anIndex) const; eHTMLTags operator[](PRInt32 anIndex) const {return TagAt(anIndex);} PRBool HasOpenContainer(eHTMLTags aTag) const; - PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const; + PRInt32 FirstOf(eHTMLTags aTag) const {return mStack.FirstOf(aTag);} + PRInt32 LastOf(eHTMLTags aTag) const {return mStack.LastOf(aTag);} void Empty(void); - PRInt32 GetCount(void); + PRInt32 GetCount(void) {return mStack.mCount;} + PRInt32 GetResidualStyleCount(void) {return mResidualStyleCount;} nsEntryStack* GetStylesAt(PRInt32 anIndex) const; void PushStyle(const nsIParserNode* aNode); void PushStyles(nsEntryStack *theStyles); @@ -149,6 +143,7 @@ public: nsIParserNode* PopStyle(eHTMLTags aTag); nsEntryStack mStack; //this will hold a list of tagentries... + PRInt32 mResidualStyleCount; #ifdef NS_DEBUG enum { eMaxTags = 100 }; @@ -332,6 +327,52 @@ public: const PRUnichar* mTagName; }; + +//********************************************************************************************* +//********************************************************************************************* + + +struct TagList { + PRUint32 mCount; + eHTMLTags mTags[10]; +}; + +/** + * + * @update gess 01/04/99 + * @param + * @return + */ +inline PRInt32 LastOf(nsDTDContext& aContext,TagList& aTagList){ + int max = aContext.GetCount(); + int index; + for(index=max-1;index>=0;index--){ + PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount); + if(result) { + return index; + } + } + return kNotFound; +} + +/** + * + * @update gess 01/04/99 + * @param + * @return + */ +inline PRInt32 FirstOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){ + int max = aContext.GetCount(); + int index; + for(index=aStartOffset;index=0;index--){ - PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount); - if(result) { - return index; - } - } - return kNotFound; -} - -/** - * - * @update gess 01/04/99 - * @param - * @return - */ -PRInt32 GetBottommostIndexOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){ - int max = aContext.GetCount(); - int index; - for(index=aStartOffset;index /***************************************************************************** @@ -108,7 +58,7 @@ TagList gLegendParents={1,{eHTMLTag_fieldset}}; TagList gAreaParent={1,{eHTMLTag_map}}; TagList gParamParents={2,{eHTMLTag_applet,eHTMLTag_object}}; TagList gTRParents={4,{eHTMLTag_tbody,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_table}}; -TagList gTREndParents={6,{eHTMLTag_tbody,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_table,eHTMLTag_td,eHTMLTag_th}}; +TagList gTREndParents={4,{eHTMLTag_tbody,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_table}}; //********************************************************************************************* @@ -121,7 +71,8 @@ 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={6,{eHTMLTag_del,eHTMLTag_ins,eHTMLTag_noscript,eHTMLTag_nolayer,eHTMLTag_script,eHTMLTag_li}}; +TagList gBodyKids={8, {eHTMLTag_dd,eHTMLTag_del,eHTMLTag_dt,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}}; @@ -182,11 +133,6 @@ TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}}; TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}}; TagList gULCloseTags={1,{eHTMLTag_li}}; -//********************************************************************************************* -// The following tag lists are used to define the non-autoclose properties of the html elements... -//********************************************************************************************* - -TagList gDontAutoClose={1,{eHTMLTag_td}}; //********************************************************************************************* //Lastly, bind tags with their rules, their special parents and special kids. @@ -431,7 +377,7 @@ void InitializeElementTable(void) { /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kBlock, (kInlineEntity|kSelf|kFlowEntity), kNone, + /*parent,incl,exclgroups*/ kBlock, (kSelf|kFlowEntity), kNone, /*special props, prop-range*/ 0,kDefaultPropRange, /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); @@ -476,7 +422,7 @@ void InitializeElementTable(void) { /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags, &gRootTags, /*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0, - /*parent,incl,exclgroups*/ kInlineEntity, kFlowEntity, kNone, + /*parent,incl,exclgroups*/ kDLChild, kFlowEntity-kHeading, kNone, /*special props, prop-range*/ kNoPropagate|kMustCloseSelf,kDefaultPropRange, /*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown); @@ -520,7 +466,7 @@ void InitializeElementTable(void) { /*tag*/ eHTMLTag_dl, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, - /*autoclose starttags and endtags*/ 0,0,0,0, + /*autoclose starttags and endtags*/ &gDLKids,0,0,0, /*parent,incl,exclgroups*/ kBlock, kSelf|kFlowEntity, kNone, /*special props, prop-range*/ kOmitWS, kNoPropRange, /*special parents,kids,skip*/ 0,&gDLKids,eHTMLTag_unknown); @@ -530,7 +476,7 @@ void InitializeElementTable(void) { /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags, &gRootTags, /*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0, - /*parent,incl,exclgroups*/ kInlineEntity, kFlowEntity, kNone, + /*parent,incl,exclgroups*/ kDLChild, kFlowEntity-kHeading, kNone, /*special props, prop-range*/ (kNoPropagate|kMustCloseSelf),kDefaultPropRange, /*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown); @@ -575,7 +521,7 @@ void InitializeElementTable(void) { /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, - /*parent,incl,exclgroups*/ kSpecial|kFontStyle, (kSelf|kInlineEntity), kNone, + /*parent,incl,exclgroups*/ kFontStyle, (kSelf|kInlineEntity), kNone, /*special props, prop-range*/ 0,kDefaultPropRange, /*special parents,kids,skip*/ 0,&gFontKids,eHTMLTag_unknown); @@ -810,7 +756,7 @@ void InitializeElementTable(void) { /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gLIRootTags,&gLIRootTags, /*autoclose starttags and endtags*/ &gLIAutoClose,0,0,0, - /*parent,incl,exclgroups*/ kBlockEntity, kFlowEntity, kSelf, + /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kSelf, //changed this from blockentity to block during RS cleanup /*special props, prop-range*/ kNoPropagate, kDefaultPropRange, /*special parents,kids,skip*/ 0,&gLIKids,eHTMLTag_unknown); @@ -953,7 +899,7 @@ void InitializeElementTable(void) { /*tag*/ eHTMLTag_p, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, - /*autoclose starttags and endtags*/ 0,0,0,&gDontAutoClose, + /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kInlineEntity, kNone, //this used to contain FLOW. But it's really an inline container. /*special props, prop-range*/ 0,kDefaultPropRange, //otherwise it tries to contain things like H1..H6 /*special parents,kids,skip*/ 0,&gInP,eHTMLTag_unknown); @@ -1151,16 +1097,16 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gRootTags,&gInBody, /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kNone, (kSelf|kInlineEntity), - /*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn), 2, + /*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), 2, /*special parents,kids,skip*/ 0,&gTableKids,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_tbody, /*requiredAncestor*/ eHTMLTag_table, eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gInTable, &gInTable, - /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,&gDontAutoClose, + /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,0, /*parent,incl,exclgroups*/ kNone, kNone, (kSelf|kInlineEntity), - /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn), kDefaultPropRange, + /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), kDefaultPropRange, /*special parents,kids,skip*/ &gInTable,&gTBodyKids,eHTMLTag_unknown); Initialize( @@ -1169,7 +1115,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gTDRootTags,&gTDRootTags, /*autoclose starttags and endtags*/ &gTDCloseTags,&gTDCloseTags,0,0, /*parent,incl,exclgroups*/ kNone, kFlowEntity, kSelf, - /*special props, prop-range*/ kNoStyleLeaksIn, kDefaultPropRange, + /*special props, prop-range*/ kNoStyleLeaksIn|kNoStyleLeaksOut, kDefaultPropRange, /*special parents,kids,skip*/ &gTDRootTags,&gBodyKids,eHTMLTag_unknown); Initialize( @@ -1185,9 +1131,9 @@ void InitializeElementTable(void) { /*tag*/ eHTMLTag_tfoot, /*requiredAncestor*/ eHTMLTag_table, eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gInTable, &gInTable, - /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,&gDontAutoClose, + /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,0, /*parent,incl,exclgroups*/ kNone, kNone, kSelf, - /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn), kNoPropRange, + /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), kNoPropRange, /*special parents,kids,skip*/ &gInTable,&gTableElemKids,eHTMLTag_unknown); Initialize( @@ -1196,16 +1142,16 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gTDRootTags,&gTDRootTags, /*autoclose starttags and endtags*/ &gTDCloseTags,&gTDCloseTags,0,0, /*parent,incl,exclgroups*/ kNone, kFlowEntity, kSelf, - /*special props, prop-range*/ kNoStyleLeaksIn, kDefaultPropRange, + /*special props, prop-range*/ (kNoStyleLeaksIn|kNoStyleLeaksOut), kDefaultPropRange, /*special parents,kids,skip*/ &gTDRootTags,&gBodyKids,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_thead, /*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown, /*rootnodes,endrootnodes*/ &gInTable,&gInTable, - /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,&gDontAutoClose, + /*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,0, /*parent,incl,exclgroups*/ kNone, kNone, kSelf, - /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn), kNoPropRange, + /*special props, prop-range*/ (kNoPropagate|kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), kNoPropRange, /*special parents,kids,skip*/ &gInTable,&gTableElemKids,eHTMLTag_unknown); Initialize( @@ -1223,7 +1169,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gTRParents,&gTREndParents, /*autoclose starttags and endtags*/ &gTRCloseTags,0,0,0, /*parent,incl,exclgroups*/ kNone, kNone, kInlineEntity, - /*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn), kNoPropRange, + /*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), kNoPropRange, /*special parents,kids,skip*/ &gTRParents,&gTRKids,eHTMLTag_unknown); Initialize( @@ -1384,18 +1330,6 @@ int nsHTMLElement::GetSynonymousGroups(eHTMLTags aTag) { return result; } -/** - * - * @update gess 01/04/99 - * @param - * @return - */ -inline PRBool TestBits(int aBitset,int aTest) { - PRInt32 result=aBitset & aTest; - return (aTest) ? PRBool(result==aTest) : PR_FALSE; //was aTest -} - - /** * * @update gess1/21/99 @@ -1412,7 +1346,7 @@ PRBool nsHTMLElement::HasSpecialProperty(PRInt32 aProperty) const{ * @update gess12/13/98 * @param * @return - */ + */ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) { PRBool result=(eHTMLTag_unknown==aChild); @@ -1423,23 +1357,23 @@ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) { } /** - * - * @update gess 01/04/99 + * This tests whether all the bits in the parentbits + * are included in the given set. It may be too + * broad a question for most cases. + * + * @update gess12/13/98 * @param * @return */ -PRBool nsHTMLElement::IsBlockEntity(eHTMLTags aTag){ - PRBool result=PR_FALSE; - - if((aTag>=eHTMLTag_unknown) & (aTag<=eHTMLTag_userdefined)){ - result=TestBits(gHTMLElements[aTag].mParentBits,kBlockEntity); - } +PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{ + PRBool result=TestBits(aSet,mParentBits); return result; } -/** +/** + * This method determines whether the given tag closes other blocks. * - * @update gess 01/04/99 + * @update gess 12/20/99 -- added H1..H6 to this list. * @param * @return */ @@ -1448,8 +1382,9 @@ PRBool nsHTMLElement::IsBlockCloser(eHTMLTags aTag){ if((aTag>=eHTMLTag_unknown) & (aTag<=eHTMLTag_userdefined)){ -// result=IsFlowElement(aTag); - result=gHTMLElements[aTag].IsMemberOf(kBlockEntity); //was kFlowEntity... + result=(gHTMLElements[aTag].IsBlock() || + gHTMLElements[aTag].IsBlockEntity() || + (kHeading==gHTMLElements[aTag].mParentBits)); if(!result) { static eHTMLTags gClosers[]={ eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_caption,eHTMLTag_dd,eHTMLTag_dt, @@ -1658,7 +1593,7 @@ PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch) if(theRootTags){ if(!FindTagInSet(mTagID,theRootTags->mTags,theRootTags->mCount)){ - eHTMLTags theRootBase=GetTagAt(0,*theRootTags); + eHTMLTags theRootBase=theRootTags->mTags[0]; if((eHTMLTag_unknown!=theRootBase) && (allowDepthSearch)) result=SectionContains(theRootBase,allowDepthSearch); } @@ -1673,7 +1608,7 @@ PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch) * @param * @return */ -PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) { +PRBool nsHTMLElement::IsResidualStyleTag(eHTMLTags aChild) { PRBool result=PR_FALSE; switch(aChild) { case eHTMLTag_a: @@ -1697,7 +1632,7 @@ PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) { case eHTMLTag_s: // case eHTMLTag_samp: case eHTMLTag_small: - case eHTMLTag_span: +// case eHTMLTag_span: case eHTMLTag_strike: // case eHTMLTag_strong: case eHTMLTag_sub: @@ -1735,17 +1670,6 @@ PRBool nsHTMLElement::CanContainType(PRInt32 aType) const{ return result; } -/** - * - * @update gess12/13/98 - * @param - * @return - */ -PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{ - PRBool result=(aSet && TestBits(aSet,mParentBits)); - return result; -} - /** * * @update gess12/13/98 @@ -1807,7 +1731,7 @@ PRBool nsHTMLElement::CanContainSelf(void) const { */ PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{ PRBool result=PR_TRUE; - if((mTagID>=eHTMLTag_unknown) && (mTagID<=eHTMLTag_userdefined)) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)) { TagList* theTagList=gHTMLElements[mTagID].mDontAutocloseEnd; if(theTagList) { result=!FindTagInSet(aTag,theTagList->mTags,theTagList->mCount); @@ -1847,8 +1771,10 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 eHTMLTags theTag=aContext.TagAt(theIndex); if(theTag!=mTagID) { //phrasal elements can close other phrasals, along with fontstyle and special tags... - if(gHTMLElements[theTag].IsMemberOf(kSpecial) || - gHTMLElements[theTag].IsMemberOf(kFontStyle)){ + + if(gHTMLElements[theTag].IsSpecialEntity() || gHTMLElements[theTag].IsFontStyleEntity()) { +// if(TestBits(gHTMLElements[theTag].mParentBits,kSpecial) || +// TestBits(gHTMLElements[theTag].mParentBits,kFontStyle)) { } else { break; //it's not something I can close @@ -1870,13 +1796,13 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 } else { result=theTag; //stop because you just found yourself on the stack - break; + break; } } } - else if(IsStyleTag(mTagID)){ + else if(IsResidualStyleTag(mTagID)){ eHTMLTags theTag=aContext.Last(); - if(IsStyleTag(theTag)) { + if(IsResidualStyleTag(theTag)) { result=theTag; } } @@ -1909,7 +1835,7 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{ return PR_FALSE; } - if(nsHTMLElement::IsBlockEntity(aChild)){ + if(gHTMLElements[aChild].IsBlockEntity()){ if(nsHTMLElement::IsBlockParent(mTagID)){ return PR_TRUE; } @@ -1948,6 +1874,10 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{ return PR_FALSE; } +//#define RICKG_DEBUG +#ifdef RICKG_DEBUG +#include +#endif void nsHTMLElement::DebugDumpContainment(const char* aFilename,const char* aTitle){ #ifdef RICKG_DEBUG @@ -2000,11 +1930,12 @@ void nsHTMLElement::DebugDumpContainment(const char* aFilename,const char* aTitl linenum++; } } //for -#endif +#endif } + void nsHTMLElement::DebugDumpMembership(const char* aFilename){ -#ifdef RICKG_DEBUG +#ifdef RICKG_DEBUG const char* prefix=" "; const char* suffix=" "; @@ -2062,6 +1993,7 @@ void nsHTMLElement::DebugDumpMembership(const char* aFilename){ } void nsHTMLElement::DebugDumpContainType(const char* aFilename){ +#define RICKG_DEBUG #ifdef RICKG_DEBUG const char* prefix=" "; diff --git a/mozilla/parser/htmlparser/src/nsElementTable.h b/mozilla/parser/htmlparser/src/nsElementTable.h index 934bcd71a55..a469882c8d2 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.h +++ b/mozilla/parser/htmlparser/src/nsElementTable.h @@ -35,13 +35,41 @@ #include "nsHTMLTokens.h" #include "nsDTDUtils.h" -struct TagList { - PRUint32 mCount; - eHTMLTags mTags[10]; -}; -extern PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList); -extern eHTMLTags GetTagAt(PRUint32 anIndex,TagList& aTagList); +//********************************************************************************************* +// The following ints define the standard groups of HTML elements... +//********************************************************************************************* + +static const int kNone= 0x0; + +static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY) +static const int kHeadContent = 0x0002; // TITLE, ISINDEX, BASE +static const int kHeadMisc = 0x0004; // SCRIPT, STYLE, META, LINK, OBJECT + +static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT, + // MAP, Q, SUB, SUP, SPAN, BDO, IFRAME + +static const int kFormControl = 0x0010; // INPUT SELECT TEXTAREA LABEL BUTTON +static const int kPreformatted = 0x0020; // PRE +static const int kPreExclusion = 0x0040; // IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT +static const int kFontStyle = 0x0080; // TT, I, B, U, S, STRIKE, BIG, SMALL, BLINK +static const int kPhrase = 0x0100; // EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM +static const int kHeading = 0x0200; // H1..H6 +static const int kBlockMisc = 0x0400; // OBJECT, SCRIPT +static const int kBlock = 0x0800; // ADDRESS, BLOCKQUOTE, CENTER, DIV, DL, FIELDSET, FORM, + // ISINDEX, HR, NOSCRIPT, NOFRAMES, P, TABLE +static const int kList = 0x1000; // UL, OL, DIR, MENU +static const int kPCDATA = 0x2000; // just plain text... +static const int kSelf = 0x4000; // whatever THIS tag is... +static const int kExtensions = 0x8000; // BGSOUND, WBR, NOBR +static const int kTable = 0x10000;// TR,TD,THEAD,TBODY,TFOOT,CAPTION,TH +static const int kDLChild = 0x20000;// DL, DT + +static const int kInlineEntity = (kPCDATA|kFontStyle|kPhrase|kSpecial|kFormControl|kExtensions); // #PCDATA, %fontstyle, %phrase, %special, %formctrl +static const int kBlockEntity = (kHeading|kList|kPreformatted|kBlock); // %heading, %list, %preformatted, %block +static const int kFlowEntity = (kBlockEntity|kInlineEntity); // %blockentity, %inlineentity +static const int kAllTags = 0xffffff; + //********************************************************************************************* // The following ints define the standard groups of HTML elements... @@ -50,6 +78,23 @@ extern eHTMLTags GetTagAt(PRUint32 anIndex,TagList& aTagList); extern void InitializeElementTable(void); + +/** + * We're asking the question: is aTest a member of bitset. + * + * @update gess 01/04/99 + * @param + * @return TRUE or FALSE + */ +inline PRBool TestBits(int aBitset,int aTest) { + if(aTest) { + PRInt32 result=(aBitset & aTest); + return PRBool(result==aTest); + } + return PR_FALSE; +} + + /** * * @update gess 01/04/99 @@ -62,12 +107,48 @@ struct nsHTMLElement { static void DebugDumpContainment(const char* aFilename,const char* aTitle); static void DebugDumpContainType(const char* aFilename); - static PRBool IsBlockEntity(eHTMLTags aTag); static PRBool IsInlineEntity(eHTMLTags aTag); static PRBool IsFlowEntity(eHTMLTags aTag); static PRBool IsBlockCloser(eHTMLTags aTag); + + inline PRBool IsBlock(void) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)){ + return TestBits(mParentBits,kBlock); + } + return PR_FALSE; + } + + inline PRBool IsBlockEntity(void) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)){ + return TestBits(mParentBits,kBlockEntity); + } + return PR_FALSE; + } + + inline PRBool IsSpecialEntity(void) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)){ + return TestBits(mParentBits,kSpecial); + } + return PR_FALSE; + } + + inline PRBool IsPhraseEntity(void) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)){ + return TestBits(mParentBits,kPhrase); + } + return PR_FALSE; + } + + inline PRBool IsFontStyleEntity(void) { + if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)){ + return TestBits(mParentBits,kFontStyle); + } + return PR_FALSE; + } + static int GetSynonymousGroups(eHTMLTags aTag); + TagList* GetSynonymousTags(void) const {return mSynonymousTags;} TagList* GetRootTags(void) const {return mRootNodes;} TagList* GetEndRootTags(void) const {return mEndRootNodes;} @@ -94,7 +175,7 @@ struct nsHTMLElement { static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild); static PRBool IsContainer(eHTMLTags aTag) ; - static PRBool IsStyleTag(eHTMLTags aTag) ; + static PRBool IsResidualStyleTag(eHTMLTags aTag) ; static PRBool IsHeadingTag(eHTMLTags aTag) ; static PRBool IsTextTag(eHTMLTags aTag); static PRBool IsWhitespaceTag(eHTMLTags aTag); @@ -133,44 +214,13 @@ static const int kLegalOpen = 0x0004; //Lets BODY, TITLE, SCRIPT to reope static const int kOmitWS = 0x0008; //If set, the tag can omit all ws and newlines static const int kNoPropagate = 0x0010; //If set, this tag won't propagate as a child static const int kBadContentWatch = 0x0020; + static const int kNoStyleLeaksIn = 0x0040; static const int kNoStyleLeaksOut = 0x0080; + static const int kMustCloseSelf = 0x0100; static const int kSaveMisplaced = 0x0200; //If set, then children this tag can't contain are pushed onto the misplaced stack static const int kNonContainer = 0x0400; //If set, then this tag is not a container. -//********************************************************************************************* -// The following ints define the standard groups of HTML elements... -//********************************************************************************************* - -static const int kNone= 0x0; - -static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY) -static const int kHeadContent = 0x0002; // TITLE, ISINDEX, BASE -static const int kHeadMisc = 0x0004; // SCRIPT, STYLE, META, LINK, OBJECT - -static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT, - // MAP, Q, SUB, SUP, SPAN, BDO, IFRAME - -static const int kFormControl = 0x0010; // INPUT SELECT TEXTAREA LABEL BUTTON -static const int kPreformatted = 0x0020; // PRE -static const int kPreExclusion = 0x0040; // IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT -static const int kFontStyle = 0x0080; // TT, I, B, U, S, STRIKE, BIG, SMALL, BLINK -static const int kPhrase = 0x0100; // EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM -static const int kHeading = 0x0200; // H1..H6 -static const int kBlockMisc = 0x0400; // OBJECT, SCRIPT -static const int kBlock = 0x0800; // ADDRESS, BLOCKQUOTE, CENTER, DIV, DL, FIELDSET, FORM, - // ISINDEX, HR, NOSCRIPT, NOFRAMES, P, TABLE -static const int kList = 0x1000; // UL, OL, DIR, MENU -static const int kPCDATA = 0x2000; // just plain text... -static const int kSelf = 0x4000; // whatever THIS tag is... -static const int kExtensions = 0x8000; // BGSOUND, WBR, NOBR -static const int kTable = 0x10000;// TR,TD,THEAD,TBODY,TFOOT,CAPTION,TH - -static const int kInlineEntity = (kPCDATA|kFontStyle|kPhrase|kSpecial|kFormControl|kExtensions); // #PCDATA, %fontstyle, %phrase, %special, %formctrl -static const int kBlockEntity = (kHeading|kList|kPreformatted|kBlock); // %heading, %list, %preformatted, %blockmisc -static const int kFlowEntity = (kBlockEntity|kInlineEntity); // %block, %inline -static const int kAllTags = 0xffffff; - #endif diff --git a/mozilla/parser/htmlparser/src/nsExpatDTD.cpp b/mozilla/parser/htmlparser/src/nsExpatDTD.cpp index 1789039c794..c0888ab1bb9 100644 --- a/mozilla/parser/htmlparser/src/nsExpatDTD.cpp +++ b/mozilla/parser/htmlparser/src/nsExpatDTD.cpp @@ -279,9 +279,12 @@ NS_IMETHODIMP nsExpatDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink, * @return */ nsITokenRecycler* nsExpatDTD::GetTokenRecycler(void){ - nsITokenizer* theTokenizer=GetTokenizer(); - if(theTokenizer) + nsITokenizer* theTokenizer=0; + nsresult result=GetTokenizer(theTokenizer); + + if (NS_SUCCEEDED(result)) { return theTokenizer->GetTokenRecycler(); + } return 0; } @@ -319,21 +322,24 @@ void nsExpatDTD::SetupExpatCallbacks(void) { } } + /** * Retrieve the preferred tokenizer for use by this DTD. - * @update gess12/28/98 + * @update gess12/28/98 * @param none * @return ptr to tokenizer */ -nsITokenizer* nsExpatDTD::GetTokenizer(void) { +nsresult nsExpatDTD::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; if(!mTokenizer) { - nsresult result=NS_New_Expat_Tokenizer(&mTokenizer); + result=NS_New_Expat_Tokenizer(&mTokenizer); mExpatParser = XML_ParserCreate(NULL); if (mExpatParser) { SetupExpatCallbacks(); } } - return mTokenizer; + aTokenizer=mTokenizer; + return result; } diff --git a/mozilla/parser/htmlparser/src/nsExpatDTD.h b/mozilla/parser/htmlparser/src/nsExpatDTD.h index 479888945bb..b8ee69f6939 100644 --- a/mozilla/parser/htmlparser/src/nsExpatDTD.h +++ b/mozilla/parser/htmlparser/src/nsExpatDTD.h @@ -165,7 +165,7 @@ class nsExpatDTD : public nsIDTD { * @param * @return */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp index 53f21540120..536dd907563 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp @@ -626,13 +626,13 @@ PRInt32 CCDATASectionToken::GetTokenType(void) { /* * Consume as much marked test from scanner as possible. * - * @update vidur 11/12/98 + * @update rgess 12/15/99: had to handle case: "", in addition to "". * @param aChar -- last char consumed from stream * @param aScanner -- controller of underlying input source * @return error result */ nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) { - static const char* theTerminals="\r]"; + static const char* theTerminals="\r]"; nsresult result=NS_OK; PRBool done=PR_FALSE; @@ -659,26 +659,18 @@ nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt3 } //switch } //if } - else if (kRightSquareBracket==aChar) { + else if (']'==aChar) { result=aScanner.GetChar(aChar); //strip off the ] + mTextValue.Append(aChar); result=aScanner.Peek(aChar); //then see what's next. if((NS_OK==result) && (kRightSquareBracket==aChar)) { result=aScanner.GetChar(aChar); //strip off the second ] + mTextValue.Append(aChar); result=aScanner.Peek(aChar); //then see what's next. - if(NS_OK==result) { - if (kGreaterThan==aChar) { - result=aScanner.GetChar(aChar); //strip off the > - done=PR_TRUE; - } - else { - // This isn't the end of the CDATA section so go on - mTextValue.Append("]"); - } - }//if } - else { - // This isn't the end of the CDATA section so go on - mTextValue.Append("]"); + if((NS_OK==result) && (kGreaterThan==aChar)) { + result=aScanner.GetChar(aChar); //strip off the > + done=PR_TRUE; } } else done=PR_TRUE; @@ -991,10 +983,11 @@ nsString& CNewlineToken::GetStringValueXXX(void) { */ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) { -#if 0 +#if 1 mTextValue=kNewLine; //This is what I THINK we should be doing. -#endif +#else mTextValue=aChar; +#endif /******************************************************************* diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.h b/mozilla/parser/htmlparser/src/nsHTMLTokens.h index 8476f05f615..549d183d712 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.h +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.h @@ -129,7 +129,7 @@ class CStartToken: public CHTMLToken { virtual void Reinitialize(PRInt32 aTag, const nsString& aString); - nsAutoString mTrailingContent; + nsString mTrailingContent; PRInt32 mOrigin; protected: PRBool mAttributed; diff --git a/mozilla/parser/htmlparser/src/nsIDTD.h b/mozilla/parser/htmlparser/src/nsIDTD.h index 066b86145c9..07e76e95f27 100644 --- a/mozilla/parser/htmlparser/src/nsIDTD.h +++ b/mozilla/parser/htmlparser/src/nsIDTD.h @@ -141,14 +141,12 @@ class nsIDTD : public nsISupports { NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser)=0; /** - * Cause the tokenizer to consume and create the next token, and - * return an error result. - * - * @update gess 3/25/98 - * @param aToken -- will contain newly created and consumed token - * @return error code (usually 0) + * + * @update gess 12/20/99 + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - virtual nsITokenizer* GetTokenizer(void)=0; + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer)=0; virtual nsITokenRecycler* GetTokenRecycler(void)=0; diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index 7a6da94be75..4152745a38f 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -1026,10 +1026,12 @@ nsresult nsParser::BuildModel() { //Get the root DTD for use in model building... - nsresult result=NS_OK; CParserContext* theRootContext=mParserContext; - nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer(); + nsITokenizer* theTokenizer=0; + + nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); if(theTokenizer){ + while(theRootContext->mPrevContext) { theRootContext=theRootContext->mPrevContext; } @@ -1057,7 +1059,7 @@ nsresult nsParser::BuildModel() { nsITokenizer* nsParser::GetTokenizer(void) { nsITokenizer* theTokenizer=0; if(mParserContext && mParserContext->mDTD) { - theTokenizer=mParserContext->mDTD->GetTokenizer(); + mParserContext->mDTD->GetTokenizer(theTokenizer); } return theTokenizer; } @@ -1274,56 +1276,62 @@ nsresult nsParser::OnDataAvailable(nsIChannel* channel, nsISupports* aContext, mParserContext->mTransferBuffer=new char[newLength+20]; } - PRUint32 theTotalRead=0; - PRUint32 theNumRead=1; //init to a non-zero value - int theStartPos=0; nsresult result=NS_OK; - PRBool needCheckFirst4Bytes = - ((0 == sourceOffset) && (mCharsetSource0) && (aLength>theTotalRead) && (NS_OK==result)) { - result = pIStream->Read(mParserContext->mTransferBuffer, aLength, &theNumRead); - if(NS_SUCCEEDED(result) && (theNumRead>0)) { - if(needCheckFirst4Bytes && (theNumRead >= 4)) { - nsCharsetSource guessSource; - nsAutoString guess(""); + if(mParserContext->mTransferBuffer) { + + //We need to add code to defensively deal with the case where the transfer buffer is null. + + PRUint32 theTotalRead=0; + PRUint32 theNumRead=1; //init to a non-zero value + int theStartPos=0; + + PRBool needCheckFirst4Bytes = + ((0 == sourceOffset) && (mCharsetSource0) && (aLength>theTotalRead) && (NS_OK==result)) { + result = pIStream->Read(mParserContext->mTransferBuffer, aLength, &theNumRead); + if(NS_SUCCEEDED(result) && (theNumRead>0)) { + if(needCheckFirst4Bytes && (theNumRead >= 4)) { + nsCharsetSource guessSource; + nsAutoString guess(""); - needCheckFirst4Bytes = PR_FALSE; - if(detectByteOrderMark((const unsigned char*)mParserContext->mTransferBuffer, - theNumRead, guess, guessSource)) - { -#ifdef DEBUG_XMLENCODING - printf("xmlencoding detect- %s\n", guess.ToNewCString()); -#endif - this->SetDocumentCharset(guess, guessSource); - mParserContext->mScanner->SetDocumentCharset(guess, guessSource); - } - } - theTotalRead+=theNumRead; - if(mParserFilter) - mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &theNumRead); - -#ifdef NS_DEBUG - unsigned int index=0; - for(index=0;indexmTransferBuffer[index]){ - printf("\nNull found at buffer[%i] provided by netlib...\n",index); - break; + needCheckFirst4Bytes = PR_FALSE; + if(detectByteOrderMark((const unsigned char*)mParserContext->mTransferBuffer, + theNumRead, guess, guessSource)) + { + #ifdef DEBUG_XMLENCODING + printf("xmlencoding detect- %s\n", guess.ToNewCString()); + #endif + this->SetDocumentCharset(guess, guessSource); + mParserContext->mScanner->SetDocumentCharset(guess, guessSource); + } } - } -#endif + theTotalRead+=theNumRead; + if(mParserFilter) + mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &theNumRead); - mParserContext->mScanner->Append(mParserContext->mTransferBuffer,theNumRead); + #ifdef NS_DEBUG + unsigned int index=0; + for(index=0;indexmTransferBuffer[index]){ + printf("\nNull found at buffer[%i] provided by netlib...\n",index); + break; + } + } + #endif -#ifdef rickgdebug - (*gDumpFile) << mParserContext->mTransferBuffer; -#endif + mParserContext->mScanner->Append(mParserContext->mTransferBuffer,theNumRead); - } //if - theStartPos+=theNumRead; - }//while + #ifdef rickgdebug + (*gDumpFile) << mParserContext->mTransferBuffer; + #endif - result=ResumeParse(); + } //if + theStartPos+=theNumRead; + }//while + + result=ResumeParse(); + } return result; } @@ -1395,12 +1403,12 @@ nsresult nsParser::OnStopRequest(nsIChannel* channel, nsISupports* aContext, * @return TRUE if it's ok to proceed */ PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){ - nsresult rv = NS_OK; - nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer(); + nsITokenizer* theTokenizer=0; + nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); if (theTokenizer) { - rv = theTokenizer->WillTokenize(aIsFinalChunk); + result = theTokenizer->WillTokenize(aIsFinalChunk); } - return rv; + return result; } @@ -1414,11 +1422,11 @@ PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){ */ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ - nsresult result=NS_OK; - ++mMajorIteration; - nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer(); + nsITokenizer* theTokenizer=0; + nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); + if(theTokenizer){ MOZ_TIMER_START(mTokenizeTime); @@ -1461,7 +1469,9 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){ PRBool nsParser::DidTokenize(PRBool aIsFinalChunk){ PRBool result=PR_TRUE; - nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer(); + nsITokenizer* theTokenizer=0; + nsresult rv=mParserContext->mDTD->GetTokenizer(theTokenizer); + if (theTokenizer) { result = theTokenizer->DidTokenize(aIsFinalChunk); if(mTokenObserver) { @@ -1479,7 +1489,10 @@ PRBool nsParser::DidTokenize(PRBool aIsFinalChunk){ void nsParser::DebugDumpSource(nsOutputStream& aStream) { PRInt32 theIndex=-1; - nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer(); + + nsITokenizer* theTokenizer=0; + nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer); + if(theTokenizer){ CToken* theToken; while(nsnull != (theToken=theTokenizer->GetTokenAt(++theIndex))) { diff --git a/mozilla/parser/htmlparser/src/nsToken.h b/mozilla/parser/htmlparser/src/nsToken.h index 8730b4cc092..c99038cd024 100644 --- a/mozilla/parser/htmlparser/src/nsToken.h +++ b/mozilla/parser/htmlparser/src/nsToken.h @@ -210,7 +210,7 @@ class CToken { protected: PRInt32 mTypeID; PRInt16 mAttrCount; - nsAutoString mTextValue; + nsString mTextValue; }; diff --git a/mozilla/parser/htmlparser/src/nsValidDTD.cpp b/mozilla/parser/htmlparser/src/nsValidDTD.cpp index 5d7a5cd7c81..01eb7d7af00 100644 --- a/mozilla/parser/htmlparser/src/nsValidDTD.cpp +++ b/mozilla/parser/htmlparser/src/nsValidDTD.cpp @@ -240,8 +240,9 @@ NS_IMETHODIMP CValidDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,n * @param * @return */ -nsITokenizer* CValidDTD::GetTokenizer(void){ - return 0; +nsresult CValidDTD::GetTokenizer(nsITokenizer*& aTokenizer){ + aTokenizer=0; + return NS_OK; } /** diff --git a/mozilla/parser/htmlparser/src/nsValidDTD.h b/mozilla/parser/htmlparser/src/nsValidDTD.h index 91106f8e6a7..b0484a4ad6f 100644 --- a/mozilla/parser/htmlparser/src/nsValidDTD.h +++ b/mozilla/parser/htmlparser/src/nsValidDTD.h @@ -171,10 +171,10 @@ class CValidDTD : public nsIDTD { /** * * @update gess12/28/98 - * @param - * @return + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * diff --git a/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp b/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp index b38d05b0ac1..c8a88217b7f 100644 --- a/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp +++ b/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp @@ -435,9 +435,12 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify * @return */ nsITokenRecycler* CViewSourceHTML::GetTokenRecycler(void){ - nsITokenizer* theTokenizer=GetTokenizer(); - if(theTokenizer) + nsITokenizer* theTokenizer=0; + nsresult result=GetTokenizer(theTokenizer); + + if (NS_SUCCEEDED(result)) { return theTokenizer->GetTokenRecycler(); + } return 0; } @@ -455,19 +458,23 @@ nsresult CViewSourceHTML::Terminate(void) { return NS_ERROR_HTMLPARSER_STOPPARSING; } + /** * Retrieve the preferred tokenizer for use by this DTD. - * @update gess12/28/98 + * @update gess12/28/98 * @param none * @return ptr to tokenizer */ -nsITokenizer* CViewSourceHTML::GetTokenizer(void) { +nsresult CViewSourceHTML::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; if(!mTokenizer) { - nsresult result=NS_NewHTMLTokenizer(&mTokenizer); + result=NS_NewHTMLTokenizer(&mTokenizer); } - return mTokenizer; + aTokenizer=mTokenizer; + return result; } + /** * * @update gess5/18/98 diff --git a/mozilla/parser/htmlparser/src/nsViewSourceHTML.h b/mozilla/parser/htmlparser/src/nsViewSourceHTML.h index 1bd26fd9939..2eec94f2fe9 100644 --- a/mozilla/parser/htmlparser/src/nsViewSourceHTML.h +++ b/mozilla/parser/htmlparser/src/nsViewSourceHTML.h @@ -144,11 +144,11 @@ class CViewSourceHTML: public nsIDTD { /** * - * @update gess12/28/98 - * @param - * @return + * @update gess 12/20/99 + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** diff --git a/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp b/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp index bdb3c98c3ad..bda0f40750f 100644 --- a/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp +++ b/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp @@ -320,9 +320,13 @@ NS_IMETHODIMP CWellFormedDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifyS * @return */ nsITokenRecycler* CWellFormedDTD::GetTokenRecycler(void){ - nsITokenizer* theTokenizer=GetTokenizer(); - if(theTokenizer) + nsITokenizer* theTokenizer=0; + + nsresult result=GetTokenizer(theTokenizer); + + if (NS_SUCCEEDED(result)) { return theTokenizer->GetTokenRecycler(); + } return 0; } @@ -341,18 +345,21 @@ nsresult CWellFormedDTD::Terminate(void) return mDTDState=NS_ERROR_HTMLPARSER_STOPPARSING; } + /** * Retrieve the preferred tokenizer for use by this DTD. - * @update gess12/28/98 + * @update gess12/28/98 * @param none * @return ptr to tokenizer */ -nsITokenizer* CWellFormedDTD::GetTokenizer(void) { +nsresult CWellFormedDTD::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; if(!mTokenizer) { mTokenizer=(nsHTMLTokenizer*)new nsExpatTokenizer(&mFilename); NS_IF_ADDREF(mTokenizer); } - return mTokenizer; + aTokenizer=mTokenizer; + return result; } /** diff --git a/mozilla/parser/htmlparser/src/nsWellFormedDTD.h b/mozilla/parser/htmlparser/src/nsWellFormedDTD.h index 1642fd48d61..a4c1f804bdd 100644 --- a/mozilla/parser/htmlparser/src/nsWellFormedDTD.h +++ b/mozilla/parser/htmlparser/src/nsWellFormedDTD.h @@ -156,11 +156,11 @@ class CWellFormedDTD : public nsIDTD { /** * - * @update gess12/28/98 - * @param - * @return + * @update gess 12/20/99 + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp index 4e1c759dca1..ad6e100c6aa 100644 --- a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp +++ b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp @@ -1217,17 +1217,20 @@ nsresult nsXIFDTD::AddLeaf(const nsIParserNode& aNode) return result; } + /** - * - * @update gess12/28/98 - * @param - * @return + * Retrieve the preferred tokenizer for use by this DTD. + * @update gess12/28/98 + * @param none + * @return ptr to tokenizer */ -nsITokenizer* nsXIFDTD::GetTokenizer(void){ +nsresult nsXIFDTD::GetTokenizer(nsITokenizer*& aTokenizer) { + nsresult result=NS_OK; if(!mTokenizer) { - nsresult result=NS_NewXMLTokenizer(&mTokenizer); + result=NS_NewXMLTokenizer(&mTokenizer); } - return mTokenizer; + aTokenizer=mTokenizer; + return result; } @@ -1238,9 +1241,13 @@ nsITokenizer* nsXIFDTD::GetTokenizer(void){ * @return */ nsITokenRecycler* nsXIFDTD::GetTokenRecycler(void){ - nsITokenizer* theTokenizer=GetTokenizer(); - if(theTokenizer) + nsITokenizer* theTokenizer=0; + + nsresult result=GetTokenizer(theTokenizer); + + if (NS_SUCCEEDED(result)) { return theTokenizer->GetTokenRecycler(); + } return 0; } diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.h b/mozilla/parser/htmlparser/src/nsXIFDTD.h index 62a65b98e8d..481cd8b5c95 100644 --- a/mozilla/parser/htmlparser/src/nsXIFDTD.h +++ b/mozilla/parser/htmlparser/src/nsXIFDTD.h @@ -418,11 +418,11 @@ private: /** * - * @update gess12/28/98 - * @param - * @return + * @update gess 12/20/99 + * @param ptr-ref to (out) tokenizer + * @return nsresult */ - nsITokenizer* GetTokenizer(void); + NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer); /** * Retrieve a ptr to the global token recycler...