29048,31392,31940,29379,29735,
25880,26488,27490,31694.

Gist: General bug fixes, Mem. leaks, and
          a little perf. work ( in collectingskipped content ).

r=pollmann
This commit is contained in:
harishd%netscape.com 2000-03-22 22:13:50 +00:00
Родитель 3dfc17d3d0
Коммит afe6bb701c
12 изменённых файлов: 236 добавлений и 134 удалений

Просмотреть файл

@ -209,7 +209,7 @@ nsCParserNode* CNavDTD::CreateNode(void) {
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
if(aNode && (!aNode->mUseCount)) {
if(aNode->mToken) {
if(aNode->mToken) {
if(!aNode->mToken->mUseCount) {
mTokenRecycler->RecycleToken(aNode->mToken);
}
@ -694,8 +694,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
case eHTMLTag_comment:
case eHTMLTag_script:
case eHTMLTag_markupDecl:
case eHTMLTag_userdefined:
break; //simply pass these through to token handler without further ado...
break; // simply pass these through to token handler without further ado...
// Userdefined tags shouldn't just pass through. -- Fix for 31694,31940
case eHTMLTag_newline:
case eHTMLTag_whitespace:
if(mMisplacedContent.GetSize()<=0) // fix for bugs 17017,18308,23765, and 24275
@ -842,7 +842,8 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
mLineNumber++;
mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
if(theNextToken) mTokenRecycler->RecycleToken(theNextToken); // fix for Bug 29379
}//if
}//if
}
@ -1017,31 +1018,33 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
if(theChildAgrees && theChildIsContainer) {
if ((theParentTag!=aChildTag) && (!nsHTMLElement::IsResidualStyleTag(aChildTag))) {
if (!nsHTMLElement::IsResidualStyleTag(aChildTag)) {
if(theParentTag!=aChildTag) {
//trying is blockcloser to widen the set of elements that this effects, re: bug 27865...
//trying is blockcloser to widen the set of elements that this effects, re: bug 27865...
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
/*-------------------------------------------------------------------------------------
1. Here's a tricky case from bug 22596: <h5><li><h5>
/*-------------------------------------------------------------------------------------
1. Here's a tricky case from bug 22596: <h5><li><h5>
How do we know that the 2nd <h5> should close the <LI> rather than nest inside the <LI>?
(Afterall, the <h5> is a legal child of the <LI>).
How do we know that the 2nd <h5> should close the <LI> rather than nest inside the <LI>?
(Afterall, the <h5> is a legal child of the <LI>).
The way you know is that there is no root between the two, so the <h5> binds more
tightly to the 1st <h5> than to the <LI>.
The way you know is that there is no root between the two, so the <h5> binds more
tightly to the 1st <h5> than to the <LI>.
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
From this case we learned not to execute this logic if the parent is a block.
-------------------------------------------------------------------------------------*/
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
From this case we learned not to execute this logic if the parent is a block.
-------------------------------------------------------------------------------------*/
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
} //if
}//if
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
} //if
}//if
}
} //if
} //if
} //if parentcontains
@ -2028,23 +2031,22 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
mScratch.Truncate();
// Dont worry about attributes here because it's already stored in
// the start token as mTrailing content and will get appended in
// start token's GetSource();
if(eToken_attribute!=theTokenType) {
if (eToken_entity==theTokenType) {
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
mScratch.Truncate();
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
// since this is an entity, we know that it's only one character.
// check to see if it's a CR, in which case we'll need to do line
// termination conversion at the end.
aMustConvertLinebreaks |= (mScratch[0] == kCR);
aNode.mSkippedContent->Append(mScratch);
}
}
else theNextToken->GetSource(mScratch);
aNode.mSkippedContent->Append(mScratch);
else theNextToken->GetSource(*aNode.mSkippedContent);
}
mTokenRecycler->RecycleToken(theNextToken);
}
@ -2684,8 +2686,9 @@ nsresult CNavDTD::CloseBody(const nsIParserNode *aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_col,
eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
// Include TD and TH to fix bug 29735.
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,
eHTMLTag_col,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
if(mHasOpenForm)
CloseForm(aNode);
@ -3116,7 +3119,9 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
else if(1==theNode->mUseCount) {
//this fixes bug 30885 and 29626
// This fixes bug 30885 and 29626
// Make sure that the node, which is about to
// get released does not stay on the style stack...
mBodyContext->PopStyle(theTag);
}
mBodyContext->PushStyles(theChildStyleStack);
@ -3348,7 +3353,10 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
if(eHTMLTag_meta==theTag) {
// XXX - SCRIPT inside NOTAGS should not get executed unless the pref.
// says so. Since we don't have this support yet..lets ignore the
// SCRIPT inside NOTAGS. Ref Bug 25880.
if(eHTMLTag_meta==theTag || eHTMLTag_script==theTag) {
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
return result;
}
@ -3374,10 +3382,13 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
}
else result=AddLeaf(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
// Fix for Bug 31392
// Do not leave a head context open no matter what the result is.
if(mHasOpenHead) {
nsresult rv=CloseHead(aNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the

Просмотреть файл

@ -73,23 +73,14 @@ nsEntryStack::~nsEntryStack() {
MOZ_COUNT_DTOR(nsEntryStack);
if(mEntries) {
if(0<mCount) {
PRInt32 anIndex=0;
for(anIndex=0;anIndex<mCount;anIndex++){
if(mEntries[anIndex].mStyles)
delete mEntries[anIndex].mStyles;
//add code here to recycle the node if you have one...
}
}
//add code here to recycle the node if you have one...
delete [] mEntries;
mEntries=0;
}
mCount=mCapacity=0;
}
/**
* Resets state of stack to be empty.
* @update harishd 04/04/99
@ -117,7 +108,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
for(index=0;index<mCount;index++) {
temp[aShiftOffset+index]=mEntries[index];
}
delete [] mEntries;
if(mEntries) delete [] mEntries;
mEntries=temp;
}
else{
@ -562,8 +553,15 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
}
else theStyles->Append(aStyles);
} //if
}//if
} //if(theEntry )
else if(mStack.mCount==0) {
// If you're here it means that we have hit the rock bottom
// ,of the stack, and there's no need to handle anymore styles.
// Fix for bug 29048
delete aStyles;
aStyles=0;
}
}//if(aStyles)
}
@ -592,20 +590,21 @@ nsIParserNode* nsDTDContext::PopStyle(void){
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
PRInt32 theLevel=0;
nsIParserNode* result=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
result=theStack->Pop();
mResidualStyleCount--;
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return 0;
return result;
}
/**
@ -619,20 +618,21 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
PRInt32 theLevel=0;
nsIParserNode* result=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
result=theStack->Pop();
mResidualStyleCount--;
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return 0;
return result;
}
/**************************************************************

Просмотреть файл

@ -136,7 +136,8 @@ TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
TagList gULCloseTags={1,{eHTMLTag_li}};
TagList gExcludableParents={1,{eHTMLTag_pre}}; // Ref Bug 22913,23680
TagList gExcludableParents={1,{eHTMLTag_pre}}; // Ref Bug 22913
TagList gCaptionExcludableParents={1,{eHTMLTag_td}}; //Ref Bug 26488
//*********************************************************************************************
//Lastly, bind tags with their rules, their special parents and special kids.
@ -1389,10 +1390,12 @@ PRBool nsHTMLElement::IsBlockCloser(eHTMLTags aTag){
if(!result) {
// NOBR is a block closure - Ref. Bug# 24462
// DIR is a block closure -- Ref. Bug# 25845
// TD is a block closure - Ref. Bug# 27490
// TR is a block closure - Ref. Bug# 26488
static eHTMLTags gClosers[]={ eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_caption,eHTMLTag_dd,eHTMLTag_dt,
eHTMLTag_td,eHTMLTag_th,
/* eHTMLTag_tfoot, eHTMLTag_thead,eHTMLTag_tr, */
eHTMLTag_td,eHTMLTag_th,eHTMLTag_tr,
/* eHTMLTag_tfoot, eHTMLTag_thead,*/
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
@ -1549,6 +1552,45 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
return result;
}
/**
*
* @update harishd 03/01/00
* @param
* @return
*/
PRBool nsHTMLElement::IsExcludableParent(eHTMLTags aParent) const{
PRBool result=PR_FALSE;
if(!IsTextTag(mTagID)) {
if(mExcludableParents) {
TagList* theParents=mExcludableParents;
if(FindTagInSet(aParent,theParents->mTags,theParents->mCount))
result=PR_TRUE;
}
if(!result) {
// If you're a block parent make sure that you're not the
// parent of a TABLE element. ex. <table><tr><td><div><td></tr></table>
// IE & Nav. render this as table with two cells ( which I think is correct ).
// NOTE: If need arise we could use the root node to solve this problem
if(nsHTMLElement::IsBlockParent(aParent)){
switch(mTagID) {
case eHTMLTag_caption:
case eHTMLTag_thead:
case eHTMLTag_tbody:
case eHTMLTag_tfoot:
case eHTMLTag_td:
case eHTMLTag_th:
case eHTMLTag_tr:
result=PR_TRUE;
default:
break;
}
}
}
}
return result;
}
/**
*
* @update gess 01/04/99
@ -1907,12 +1949,9 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
return PR_FALSE;
}
if(gHTMLElements[aChild].mExcludableParents) {
TagList* theParents=gHTMLElements[aChild].mExcludableParents;
if(FindTagInSet(mTagID,theParents->mTags,theParents->mCount))
return PR_FALSE;
}
if(gHTMLElements[aChild].IsExcludableParent(mTagID))
return PR_FALSE;
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
if(nsHTMLElement::IsBlockParent(mTagID)){

Просмотреть файл

@ -171,6 +171,7 @@ struct nsHTMLElement {
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
PRBool HasSpecialProperty(PRInt32 aProperty) const;
PRBool IsSpecialParent(eHTMLTags aTag) const;
PRBool IsExcludableParent(eHTMLTags aParent) const;
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);

Просмотреть файл

@ -297,7 +297,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CStartToken::GetSource(nsString& anOutputString){
anOutputString="<";
anOutputString+="<";
/*
* mTextValue used to contain the name of the tag.
* But for the sake of performance we now rely on the tagID
@ -429,7 +429,7 @@ void CEndToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CEndToken::GetSource(nsString& anOutputString){
anOutputString="</";
anOutputString+="</";
anOutputString+=mTextValue;
anOutputString+=">";
}
@ -486,8 +486,8 @@ PRInt32 CTextToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static nsString theTerminals("\n\r&<",4);
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {;
static nsString theTerminals("\n\r&<",4);
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -1176,7 +1176,7 @@ void CAttributeToken::DebugDumpToken(nsOutputStream& out) {
* @return nada
*/
void CAttributeToken::GetSource(nsString& anOutputString){
anOutputString=mTextKey;
anOutputString+=mTextKey;
anOutputString+="=";
anOutputString+=mTextValue;
anOutputString+=";";
@ -1670,7 +1670,7 @@ void CEntityToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CEntityToken::GetSource(nsString& anOutputString){
anOutputString="&";
anOutputString+="&";
anOutputString+=mTextValue;
//anOutputString+=";";
}

Просмотреть файл

@ -183,7 +183,7 @@ nsString& CToken::GetStringValueXXX(void) {
* @return reference to string containing string value
*/
void CToken::GetSource(nsString& anOutputString){
anOutputString=mTextValue;
anOutputString+=mTextValue;
}
/**

Просмотреть файл

@ -209,7 +209,7 @@ nsCParserNode* CNavDTD::CreateNode(void) {
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
if(aNode && (!aNode->mUseCount)) {
if(aNode->mToken) {
if(aNode->mToken) {
if(!aNode->mToken->mUseCount) {
mTokenRecycler->RecycleToken(aNode->mToken);
}
@ -694,8 +694,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
case eHTMLTag_comment:
case eHTMLTag_script:
case eHTMLTag_markupDecl:
case eHTMLTag_userdefined:
break; //simply pass these through to token handler without further ado...
break; // simply pass these through to token handler without further ado...
// Userdefined tags shouldn't just pass through. -- Fix for 31694,31940
case eHTMLTag_newline:
case eHTMLTag_whitespace:
if(mMisplacedContent.GetSize()<=0) // fix for bugs 17017,18308,23765, and 24275
@ -842,7 +842,8 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
mLineNumber++;
mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
if(theNextToken) mTokenRecycler->RecycleToken(theNextToken); // fix for Bug 29379
}//if
}//if
}
@ -1017,31 +1018,33 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
if(theChildAgrees && theChildIsContainer) {
if ((theParentTag!=aChildTag) && (!nsHTMLElement::IsResidualStyleTag(aChildTag))) {
if (!nsHTMLElement::IsResidualStyleTag(aChildTag)) {
if(theParentTag!=aChildTag) {
//trying is blockcloser to widen the set of elements that this effects, re: bug 27865...
//trying is blockcloser to widen the set of elements that this effects, re: bug 27865...
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
/*-------------------------------------------------------------------------------------
1. Here's a tricky case from bug 22596: <h5><li><h5>
/*-------------------------------------------------------------------------------------
1. Here's a tricky case from bug 22596: <h5><li><h5>
How do we know that the 2nd <h5> should close the <LI> rather than nest inside the <LI>?
(Afterall, the <h5> is a legal child of the <LI>).
How do we know that the 2nd <h5> should close the <LI> rather than nest inside the <LI>?
(Afterall, the <h5> is a legal child of the <LI>).
The way you know is that there is no root between the two, so the <h5> binds more
tightly to the 1st <h5> than to the <LI>.
The way you know is that there is no root between the two, so the <h5> binds more
tightly to the 1st <h5> than to the <LI>.
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
From this case we learned not to execute this logic if the parent is a block.
-------------------------------------------------------------------------------------*/
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
From this case we learned not to execute this logic if the parent is a block.
-------------------------------------------------------------------------------------*/
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
} //if
}//if
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
} //if
}//if
}
} //if
} //if
} //if parentcontains
@ -2028,23 +2031,22 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
mScratch.Truncate();
// Dont worry about attributes here because it's already stored in
// the start token as mTrailing content and will get appended in
// start token's GetSource();
if(eToken_attribute!=theTokenType) {
if (eToken_entity==theTokenType) {
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
mScratch.Truncate();
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
// since this is an entity, we know that it's only one character.
// check to see if it's a CR, in which case we'll need to do line
// termination conversion at the end.
aMustConvertLinebreaks |= (mScratch[0] == kCR);
aNode.mSkippedContent->Append(mScratch);
}
}
else theNextToken->GetSource(mScratch);
aNode.mSkippedContent->Append(mScratch);
else theNextToken->GetSource(*aNode.mSkippedContent);
}
mTokenRecycler->RecycleToken(theNextToken);
}
@ -2684,8 +2686,9 @@ nsresult CNavDTD::CloseBody(const nsIParserNode *aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_col,
eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
// Include TD and TH to fix bug 29735.
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,
eHTMLTag_col,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
if(mHasOpenForm)
CloseForm(aNode);
@ -3116,7 +3119,9 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
else if(1==theNode->mUseCount) {
//this fixes bug 30885 and 29626
// This fixes bug 30885 and 29626
// Make sure that the node, which is about to
// get released does not stay on the style stack...
mBodyContext->PopStyle(theTag);
}
mBodyContext->PushStyles(theChildStyleStack);
@ -3348,7 +3353,10 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
if(eHTMLTag_meta==theTag) {
// XXX - SCRIPT inside NOTAGS should not get executed unless the pref.
// says so. Since we don't have this support yet..lets ignore the
// SCRIPT inside NOTAGS. Ref Bug 25880.
if(eHTMLTag_meta==theTag || eHTMLTag_script==theTag) {
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
return result;
}
@ -3374,10 +3382,13 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
}
else result=AddLeaf(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
// Fix for Bug 31392
// Do not leave a head context open no matter what the result is.
if(mHasOpenHead) {
nsresult rv=CloseHead(aNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the

Просмотреть файл

@ -73,23 +73,14 @@ nsEntryStack::~nsEntryStack() {
MOZ_COUNT_DTOR(nsEntryStack);
if(mEntries) {
if(0<mCount) {
PRInt32 anIndex=0;
for(anIndex=0;anIndex<mCount;anIndex++){
if(mEntries[anIndex].mStyles)
delete mEntries[anIndex].mStyles;
//add code here to recycle the node if you have one...
}
}
//add code here to recycle the node if you have one...
delete [] mEntries;
mEntries=0;
}
mCount=mCapacity=0;
}
/**
* Resets state of stack to be empty.
* @update harishd 04/04/99
@ -117,7 +108,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
for(index=0;index<mCount;index++) {
temp[aShiftOffset+index]=mEntries[index];
}
delete [] mEntries;
if(mEntries) delete [] mEntries;
mEntries=temp;
}
else{
@ -562,8 +553,15 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
}
else theStyles->Append(aStyles);
} //if
}//if
} //if(theEntry )
else if(mStack.mCount==0) {
// If you're here it means that we have hit the rock bottom
// ,of the stack, and there's no need to handle anymore styles.
// Fix for bug 29048
delete aStyles;
aStyles=0;
}
}//if(aStyles)
}
@ -592,20 +590,21 @@ nsIParserNode* nsDTDContext::PopStyle(void){
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
PRInt32 theLevel=0;
nsIParserNode* result=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
result=theStack->Pop();
mResidualStyleCount--;
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return 0;
return result;
}
/**
@ -619,20 +618,21 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
PRInt32 theLevel=0;
nsIParserNode* result=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
result=theStack->Pop();
mResidualStyleCount--;
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return 0;
return result;
}
/**************************************************************

Просмотреть файл

@ -136,7 +136,8 @@ TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
TagList gULCloseTags={1,{eHTMLTag_li}};
TagList gExcludableParents={1,{eHTMLTag_pre}}; // Ref Bug 22913,23680
TagList gExcludableParents={1,{eHTMLTag_pre}}; // Ref Bug 22913
TagList gCaptionExcludableParents={1,{eHTMLTag_td}}; //Ref Bug 26488
//*********************************************************************************************
//Lastly, bind tags with their rules, their special parents and special kids.
@ -1389,10 +1390,12 @@ PRBool nsHTMLElement::IsBlockCloser(eHTMLTags aTag){
if(!result) {
// NOBR is a block closure - Ref. Bug# 24462
// DIR is a block closure -- Ref. Bug# 25845
// TD is a block closure - Ref. Bug# 27490
// TR is a block closure - Ref. Bug# 26488
static eHTMLTags gClosers[]={ eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_caption,eHTMLTag_dd,eHTMLTag_dt,
eHTMLTag_td,eHTMLTag_th,
/* eHTMLTag_tfoot, eHTMLTag_thead,eHTMLTag_tr, */
eHTMLTag_td,eHTMLTag_th,eHTMLTag_tr,
/* eHTMLTag_tfoot, eHTMLTag_thead,*/
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
@ -1549,6 +1552,45 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
return result;
}
/**
*
* @update harishd 03/01/00
* @param
* @return
*/
PRBool nsHTMLElement::IsExcludableParent(eHTMLTags aParent) const{
PRBool result=PR_FALSE;
if(!IsTextTag(mTagID)) {
if(mExcludableParents) {
TagList* theParents=mExcludableParents;
if(FindTagInSet(aParent,theParents->mTags,theParents->mCount))
result=PR_TRUE;
}
if(!result) {
// If you're a block parent make sure that you're not the
// parent of a TABLE element. ex. <table><tr><td><div><td></tr></table>
// IE & Nav. render this as table with two cells ( which I think is correct ).
// NOTE: If need arise we could use the root node to solve this problem
if(nsHTMLElement::IsBlockParent(aParent)){
switch(mTagID) {
case eHTMLTag_caption:
case eHTMLTag_thead:
case eHTMLTag_tbody:
case eHTMLTag_tfoot:
case eHTMLTag_td:
case eHTMLTag_th:
case eHTMLTag_tr:
result=PR_TRUE;
default:
break;
}
}
}
}
return result;
}
/**
*
* @update gess 01/04/99
@ -1907,12 +1949,9 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
return PR_FALSE;
}
if(gHTMLElements[aChild].mExcludableParents) {
TagList* theParents=gHTMLElements[aChild].mExcludableParents;
if(FindTagInSet(mTagID,theParents->mTags,theParents->mCount))
return PR_FALSE;
}
if(gHTMLElements[aChild].IsExcludableParent(mTagID))
return PR_FALSE;
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
if(nsHTMLElement::IsBlockParent(mTagID)){

Просмотреть файл

@ -171,6 +171,7 @@ struct nsHTMLElement {
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
PRBool HasSpecialProperty(PRInt32 aProperty) const;
PRBool IsSpecialParent(eHTMLTags aTag) const;
PRBool IsExcludableParent(eHTMLTags aParent) const;
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);

Просмотреть файл

@ -297,7 +297,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CStartToken::GetSource(nsString& anOutputString){
anOutputString="<";
anOutputString+="<";
/*
* mTextValue used to contain the name of the tag.
* But for the sake of performance we now rely on the tagID
@ -429,7 +429,7 @@ void CEndToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CEndToken::GetSource(nsString& anOutputString){
anOutputString="</";
anOutputString+="</";
anOutputString+=mTextValue;
anOutputString+=">";
}
@ -486,8 +486,8 @@ PRInt32 CTextToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static nsString theTerminals("\n\r&<",4);
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {;
static nsString theTerminals("\n\r&<",4);
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -1176,7 +1176,7 @@ void CAttributeToken::DebugDumpToken(nsOutputStream& out) {
* @return nada
*/
void CAttributeToken::GetSource(nsString& anOutputString){
anOutputString=mTextKey;
anOutputString+=mTextKey;
anOutputString+="=";
anOutputString+=mTextValue;
anOutputString+=";";
@ -1670,7 +1670,7 @@ void CEntityToken::DebugDumpSource(nsOutputStream& out) {
* @return nada
*/
void CEntityToken::GetSource(nsString& anOutputString){
anOutputString="&";
anOutputString+="&";
anOutputString+=mTextValue;
//anOutputString+=";";
}

Просмотреть файл

@ -183,7 +183,7 @@ nsString& CToken::GetStringValueXXX(void) {
* @return reference to string containing string value
*/
void CToken::GetSource(nsString& anOutputString){
anOutputString=mTextValue;
anOutputString+=mTextValue;
}
/**