зеркало из https://github.com/mozilla/gecko-dev.git
Fix for Bugs
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:
Родитель
3dfc17d3d0
Коммит
afe6bb701c
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче