зеркало из 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) {
|
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
||||||
if(aNode && (!aNode->mUseCount)) {
|
if(aNode && (!aNode->mUseCount)) {
|
||||||
|
|
||||||
if(aNode->mToken) {
|
if(aNode->mToken) {
|
||||||
if(!aNode->mToken->mUseCount) {
|
if(!aNode->mToken->mUseCount) {
|
||||||
mTokenRecycler->RecycleToken(aNode->mToken);
|
mTokenRecycler->RecycleToken(aNode->mToken);
|
||||||
}
|
}
|
||||||
|
@ -694,8 +694,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||||
case eHTMLTag_comment:
|
case eHTMLTag_comment:
|
||||||
case eHTMLTag_script:
|
case eHTMLTag_script:
|
||||||
case eHTMLTag_markupDecl:
|
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_newline:
|
||||||
case eHTMLTag_whitespace:
|
case eHTMLTag_whitespace:
|
||||||
if(mMisplacedContent.GetSize()<=0) // fix for bugs 17017,18308,23765, and 24275
|
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());
|
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
|
||||||
if(eToken_newline==theType){
|
if(eToken_newline==theType){
|
||||||
mLineNumber++;
|
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
|
||||||
}//if
|
}//if
|
||||||
}
|
}
|
||||||
|
@ -1017,31 +1018,33 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
||||||
}
|
}
|
||||||
|
|
||||||
if(theChildAgrees && theChildIsContainer) {
|
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)) {
|
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
|
||||||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
|
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>?
|
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>).
|
(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
|
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>.
|
tightly to the 1st <h5> than to the <LI>.
|
||||||
|
|
||||||
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
|
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.
|
From this case we learned not to execute this logic if the parent is a block.
|
||||||
-------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
|
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
|
||||||
} //if
|
} //if
|
||||||
}//if
|
}//if
|
||||||
|
}
|
||||||
} //if
|
} //if
|
||||||
} //if
|
} //if
|
||||||
} //if parentcontains
|
} //if parentcontains
|
||||||
|
@ -2028,23 +2031,22 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||||
|
|
||||||
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
||||||
|
|
||||||
mScratch.Truncate();
|
|
||||||
// Dont worry about attributes here because it's already stored in
|
// Dont worry about attributes here because it's already stored in
|
||||||
// the start token as mTrailing content and will get appended in
|
// the start token as mTrailing content and will get appended in
|
||||||
// start token's GetSource();
|
// start token's GetSource();
|
||||||
if(eToken_attribute!=theTokenType) {
|
if(eToken_attribute!=theTokenType) {
|
||||||
if (eToken_entity==theTokenType) {
|
if (eToken_entity==theTokenType) {
|
||||||
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
|
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
|
||||||
|
mScratch.Truncate();
|
||||||
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
|
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
|
||||||
// since this is an entity, we know that it's only one character.
|
// 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
|
// check to see if it's a CR, in which case we'll need to do line
|
||||||
// termination conversion at the end.
|
// termination conversion at the end.
|
||||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||||
|
aNode.mSkippedContent->Append(mScratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else theNextToken->GetSource(mScratch);
|
else theNextToken->GetSource(*aNode.mSkippedContent);
|
||||||
|
|
||||||
aNode.mSkippedContent->Append(mScratch);
|
|
||||||
}
|
}
|
||||||
mTokenRecycler->RecycleToken(theNextToken);
|
mTokenRecycler->RecycleToken(theNextToken);
|
||||||
}
|
}
|
||||||
|
@ -2684,8 +2686,9 @@ nsresult CNavDTD::CloseBody(const nsIParserNode *aNode){
|
||||||
* @return TRUE if ok, FALSE if error
|
* @return TRUE if ok, FALSE if error
|
||||||
*/
|
*/
|
||||||
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
|
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
|
||||||
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_col,
|
// Include TD and TH to fix bug 29735.
|
||||||
eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
|
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,
|
||||||
|
eHTMLTag_col,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
|
||||||
if(mHasOpenForm)
|
if(mHasOpenForm)
|
||||||
CloseForm(aNode);
|
CloseForm(aNode);
|
||||||
|
|
||||||
|
@ -3116,7 +3119,9 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(1==theNode->mUseCount) {
|
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->PopStyle(theTag);
|
||||||
}
|
}
|
||||||
mBodyContext->PushStyles(theChildStyleStack);
|
mBodyContext->PushStyles(theChildStyleStack);
|
||||||
|
@ -3348,7 +3353,10 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
||||||
|
|
||||||
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
|
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))) {
|
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3374,10 +3382,13 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
||||||
|
|
||||||
}
|
}
|
||||||
else result=AddLeaf(aNode);
|
else result=AddLeaf(aNode);
|
||||||
// XXX If the return value tells us to block, go
|
// XXX If the return value tells us to block, go
|
||||||
// ahead and close the tag out anyway, since its
|
// ahead and close the tag out anyway, since its
|
||||||
// contents will be consumed.
|
// contents will be consumed.
|
||||||
if (NS_SUCCEEDED(result)) {
|
|
||||||
|
// Fix for Bug 31392
|
||||||
|
// Do not leave a head context open no matter what the result is.
|
||||||
|
if(mHasOpenHead) {
|
||||||
nsresult rv=CloseHead(aNode);
|
nsresult rv=CloseHead(aNode);
|
||||||
// XXX Only send along a failure. If the close
|
// XXX Only send along a failure. If the close
|
||||||
// succeeded we still may need to indicate that the
|
// succeeded we still may need to indicate that the
|
||||||
|
|
|
@ -73,23 +73,14 @@ nsEntryStack::~nsEntryStack() {
|
||||||
MOZ_COUNT_DTOR(nsEntryStack);
|
MOZ_COUNT_DTOR(nsEntryStack);
|
||||||
|
|
||||||
if(mEntries) {
|
if(mEntries) {
|
||||||
if(0<mCount) {
|
//add code here to recycle the node if you have one...
|
||||||
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...
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete [] mEntries;
|
delete [] mEntries;
|
||||||
mEntries=0;
|
mEntries=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCount=mCapacity=0;
|
mCount=mCapacity=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets state of stack to be empty.
|
* Resets state of stack to be empty.
|
||||||
* @update harishd 04/04/99
|
* @update harishd 04/04/99
|
||||||
|
@ -117,7 +108,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
|
||||||
for(index=0;index<mCount;index++) {
|
for(index=0;index<mCount;index++) {
|
||||||
temp[aShiftOffset+index]=mEntries[index];
|
temp[aShiftOffset+index]=mEntries[index];
|
||||||
}
|
}
|
||||||
delete [] mEntries;
|
if(mEntries) delete [] mEntries;
|
||||||
mEntries=temp;
|
mEntries=temp;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -562,8 +553,15 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||||
|
|
||||||
}
|
}
|
||||||
else theStyles->Append(aStyles);
|
else theStyles->Append(aStyles);
|
||||||
} //if
|
} //if(theEntry )
|
||||||
}//if
|
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){
|
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||||
|
|
||||||
PRInt32 theLevel=0;
|
PRInt32 theLevel=0;
|
||||||
|
nsIParserNode* result=0;
|
||||||
|
|
||||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||||
if(theStack) {
|
if(theStack) {
|
||||||
if(aTag==theStack->Last()) {
|
if(aTag==theStack->Last()) {
|
||||||
|
result=theStack->Pop();
|
||||||
mResidualStyleCount--;
|
mResidualStyleCount--;
|
||||||
return theStack->Pop();
|
|
||||||
} else {
|
} else {
|
||||||
// NS_ERROR("bad residual style entry");
|
// NS_ERROR("bad residual style entry");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -619,20 +618,21 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||||
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||||
|
|
||||||
PRInt32 theLevel=0;
|
PRInt32 theLevel=0;
|
||||||
|
nsIParserNode* result=0;
|
||||||
|
|
||||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||||
if(theStack) {
|
if(theStack) {
|
||||||
if(aTag==theStack->Last()) {
|
if(aTag==theStack->Last()) {
|
||||||
|
result=theStack->Pop();
|
||||||
mResidualStyleCount--;
|
mResidualStyleCount--;
|
||||||
return theStack->Pop();
|
|
||||||
} else {
|
} else {
|
||||||
// NS_ERROR("bad residual style entry");
|
// 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 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.
|
//Lastly, bind tags with their rules, their special parents and special kids.
|
||||||
|
@ -1389,10 +1390,12 @@ PRBool nsHTMLElement::IsBlockCloser(eHTMLTags aTag){
|
||||||
if(!result) {
|
if(!result) {
|
||||||
// NOBR is a block closure - Ref. Bug# 24462
|
// NOBR is a block closure - Ref. Bug# 24462
|
||||||
// DIR is a block closure -- Ref. Bug# 25845
|
// 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,
|
static eHTMLTags gClosers[]={ eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_caption,eHTMLTag_dd,eHTMLTag_dt,
|
||||||
eHTMLTag_td,eHTMLTag_th,
|
eHTMLTag_td,eHTMLTag_th,eHTMLTag_tr,
|
||||||
/* eHTMLTag_tfoot, eHTMLTag_thead,eHTMLTag_tr, */
|
/* eHTMLTag_tfoot, eHTMLTag_thead,*/
|
||||||
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
|
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
|
||||||
|
|
||||||
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
|
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
|
||||||
|
@ -1549,6 +1552,45 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
|
||||||
return result;
|
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
|
* @update gess 01/04/99
|
||||||
|
@ -1907,12 +1949,9 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
|
||||||
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
|
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gHTMLElements[aChild].mExcludableParents) {
|
if(gHTMLElements[aChild].IsExcludableParent(mTagID))
|
||||||
TagList* theParents=gHTMLElements[aChild].mExcludableParents;
|
return PR_FALSE;
|
||||||
if(FindTagInSet(mTagID,theParents->mTags,theParents->mCount))
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
|
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
|
||||||
if(nsHTMLElement::IsBlockParent(mTagID)){
|
if(nsHTMLElement::IsBlockParent(mTagID)){
|
||||||
|
|
|
@ -171,6 +171,7 @@ struct nsHTMLElement {
|
||||||
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
|
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
|
||||||
PRBool HasSpecialProperty(PRInt32 aProperty) const;
|
PRBool HasSpecialProperty(PRInt32 aProperty) const;
|
||||||
PRBool IsSpecialParent(eHTMLTags aTag) const;
|
PRBool IsSpecialParent(eHTMLTags aTag) const;
|
||||||
|
PRBool IsExcludableParent(eHTMLTags aParent) const;
|
||||||
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
|
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
|
||||||
|
|
||||||
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);
|
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);
|
||||||
|
|
|
@ -297,7 +297,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CStartToken::GetSource(nsString& anOutputString){
|
void CStartToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="<";
|
anOutputString+="<";
|
||||||
/*
|
/*
|
||||||
* mTextValue used to contain the name of the tag.
|
* mTextValue used to contain the name of the tag.
|
||||||
* But for the sake of performance we now rely on the tagID
|
* But for the sake of performance we now rely on the tagID
|
||||||
|
@ -429,7 +429,7 @@ void CEndToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CEndToken::GetSource(nsString& anOutputString){
|
void CEndToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="</";
|
anOutputString+="</";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
anOutputString+=">";
|
anOutputString+=">";
|
||||||
}
|
}
|
||||||
|
@ -486,8 +486,8 @@ PRInt32 CTextToken::GetTokenType(void) {
|
||||||
* @param aScanner -- controller of underlying input source
|
* @param aScanner -- controller of underlying input source
|
||||||
* @return error result
|
* @return error result
|
||||||
*/
|
*/
|
||||||
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
|
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {;
|
||||||
static nsString theTerminals("\n\r&<",4);
|
static nsString theTerminals("\n\r&<",4);
|
||||||
nsresult result=NS_OK;
|
nsresult result=NS_OK;
|
||||||
PRBool done=PR_FALSE;
|
PRBool done=PR_FALSE;
|
||||||
|
|
||||||
|
@ -1176,7 +1176,7 @@ void CAttributeToken::DebugDumpToken(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CAttributeToken::GetSource(nsString& anOutputString){
|
void CAttributeToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString=mTextKey;
|
anOutputString+=mTextKey;
|
||||||
anOutputString+="=";
|
anOutputString+="=";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
anOutputString+=";";
|
anOutputString+=";";
|
||||||
|
@ -1670,7 +1670,7 @@ void CEntityToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CEntityToken::GetSource(nsString& anOutputString){
|
void CEntityToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="&";
|
anOutputString+="&";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
//anOutputString+=";";
|
//anOutputString+=";";
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ nsString& CToken::GetStringValueXXX(void) {
|
||||||
* @return reference to string containing string value
|
* @return reference to string containing string value
|
||||||
*/
|
*/
|
||||||
void CToken::GetSource(nsString& anOutputString){
|
void CToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -209,7 +209,7 @@ nsCParserNode* CNavDTD::CreateNode(void) {
|
||||||
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
||||||
if(aNode && (!aNode->mUseCount)) {
|
if(aNode && (!aNode->mUseCount)) {
|
||||||
|
|
||||||
if(aNode->mToken) {
|
if(aNode->mToken) {
|
||||||
if(!aNode->mToken->mUseCount) {
|
if(!aNode->mToken->mUseCount) {
|
||||||
mTokenRecycler->RecycleToken(aNode->mToken);
|
mTokenRecycler->RecycleToken(aNode->mToken);
|
||||||
}
|
}
|
||||||
|
@ -694,8 +694,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||||
case eHTMLTag_comment:
|
case eHTMLTag_comment:
|
||||||
case eHTMLTag_script:
|
case eHTMLTag_script:
|
||||||
case eHTMLTag_markupDecl:
|
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_newline:
|
||||||
case eHTMLTag_whitespace:
|
case eHTMLTag_whitespace:
|
||||||
if(mMisplacedContent.GetSize()<=0) // fix for bugs 17017,18308,23765, and 24275
|
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());
|
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
|
||||||
if(eToken_newline==theType){
|
if(eToken_newline==theType){
|
||||||
mLineNumber++;
|
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
|
||||||
}//if
|
}//if
|
||||||
}
|
}
|
||||||
|
@ -1017,31 +1018,33 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
||||||
}
|
}
|
||||||
|
|
||||||
if(theChildAgrees && theChildIsContainer) {
|
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)) {
|
if(nsHTMLElement::IsBlockCloser(theParentTag)) {
|
||||||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
|
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>?
|
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>).
|
(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
|
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>.
|
tightly to the 1st <h5> than to the <LI>.
|
||||||
|
|
||||||
2. Also, bug 6148 shows this case: <SPAN><DIV><SPAN>
|
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.
|
From this case we learned not to execute this logic if the parent is a block.
|
||||||
-------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
|
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
|
||||||
} //if
|
} //if
|
||||||
}//if
|
}//if
|
||||||
|
}
|
||||||
} //if
|
} //if
|
||||||
} //if
|
} //if
|
||||||
} //if parentcontains
|
} //if parentcontains
|
||||||
|
@ -2028,23 +2031,22 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||||
|
|
||||||
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
||||||
|
|
||||||
mScratch.Truncate();
|
|
||||||
// Dont worry about attributes here because it's already stored in
|
// Dont worry about attributes here because it's already stored in
|
||||||
// the start token as mTrailing content and will get appended in
|
// the start token as mTrailing content and will get appended in
|
||||||
// start token's GetSource();
|
// start token's GetSource();
|
||||||
if(eToken_attribute!=theTokenType) {
|
if(eToken_attribute!=theTokenType) {
|
||||||
if (eToken_entity==theTokenType) {
|
if (eToken_entity==theTokenType) {
|
||||||
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
|
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
|
||||||
|
mScratch.Truncate();
|
||||||
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
|
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
|
||||||
// since this is an entity, we know that it's only one character.
|
// 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
|
// check to see if it's a CR, in which case we'll need to do line
|
||||||
// termination conversion at the end.
|
// termination conversion at the end.
|
||||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||||
|
aNode.mSkippedContent->Append(mScratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else theNextToken->GetSource(mScratch);
|
else theNextToken->GetSource(*aNode.mSkippedContent);
|
||||||
|
|
||||||
aNode.mSkippedContent->Append(mScratch);
|
|
||||||
}
|
}
|
||||||
mTokenRecycler->RecycleToken(theNextToken);
|
mTokenRecycler->RecycleToken(theNextToken);
|
||||||
}
|
}
|
||||||
|
@ -2684,8 +2686,9 @@ nsresult CNavDTD::CloseBody(const nsIParserNode *aNode){
|
||||||
* @return TRUE if ok, FALSE if error
|
* @return TRUE if ok, FALSE if error
|
||||||
*/
|
*/
|
||||||
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
|
nsresult CNavDTD::OpenForm(const nsIParserNode *aNode){
|
||||||
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_col,
|
// Include TD and TH to fix bug 29735.
|
||||||
eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
|
static eHTMLTags gTableElements[]={eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,
|
||||||
|
eHTMLTag_col,eHTMLTag_tfoot,eHTMLTag_thead,eHTMLTag_colgroup};
|
||||||
if(mHasOpenForm)
|
if(mHasOpenForm)
|
||||||
CloseForm(aNode);
|
CloseForm(aNode);
|
||||||
|
|
||||||
|
@ -3116,7 +3119,9 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(1==theNode->mUseCount) {
|
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->PopStyle(theTag);
|
||||||
}
|
}
|
||||||
mBodyContext->PushStyles(theChildStyleStack);
|
mBodyContext->PushStyles(theChildStyleStack);
|
||||||
|
@ -3348,7 +3353,10 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
||||||
|
|
||||||
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
|
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))) {
|
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3374,10 +3382,13 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
||||||
|
|
||||||
}
|
}
|
||||||
else result=AddLeaf(aNode);
|
else result=AddLeaf(aNode);
|
||||||
// XXX If the return value tells us to block, go
|
// XXX If the return value tells us to block, go
|
||||||
// ahead and close the tag out anyway, since its
|
// ahead and close the tag out anyway, since its
|
||||||
// contents will be consumed.
|
// contents will be consumed.
|
||||||
if (NS_SUCCEEDED(result)) {
|
|
||||||
|
// Fix for Bug 31392
|
||||||
|
// Do not leave a head context open no matter what the result is.
|
||||||
|
if(mHasOpenHead) {
|
||||||
nsresult rv=CloseHead(aNode);
|
nsresult rv=CloseHead(aNode);
|
||||||
// XXX Only send along a failure. If the close
|
// XXX Only send along a failure. If the close
|
||||||
// succeeded we still may need to indicate that the
|
// succeeded we still may need to indicate that the
|
||||||
|
|
|
@ -73,23 +73,14 @@ nsEntryStack::~nsEntryStack() {
|
||||||
MOZ_COUNT_DTOR(nsEntryStack);
|
MOZ_COUNT_DTOR(nsEntryStack);
|
||||||
|
|
||||||
if(mEntries) {
|
if(mEntries) {
|
||||||
if(0<mCount) {
|
//add code here to recycle the node if you have one...
|
||||||
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...
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete [] mEntries;
|
delete [] mEntries;
|
||||||
mEntries=0;
|
mEntries=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCount=mCapacity=0;
|
mCount=mCapacity=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets state of stack to be empty.
|
* Resets state of stack to be empty.
|
||||||
* @update harishd 04/04/99
|
* @update harishd 04/04/99
|
||||||
|
@ -117,7 +108,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
|
||||||
for(index=0;index<mCount;index++) {
|
for(index=0;index<mCount;index++) {
|
||||||
temp[aShiftOffset+index]=mEntries[index];
|
temp[aShiftOffset+index]=mEntries[index];
|
||||||
}
|
}
|
||||||
delete [] mEntries;
|
if(mEntries) delete [] mEntries;
|
||||||
mEntries=temp;
|
mEntries=temp;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -562,8 +553,15 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||||
|
|
||||||
}
|
}
|
||||||
else theStyles->Append(aStyles);
|
else theStyles->Append(aStyles);
|
||||||
} //if
|
} //if(theEntry )
|
||||||
}//if
|
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){
|
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||||
|
|
||||||
PRInt32 theLevel=0;
|
PRInt32 theLevel=0;
|
||||||
|
nsIParserNode* result=0;
|
||||||
|
|
||||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||||
if(theStack) {
|
if(theStack) {
|
||||||
if(aTag==theStack->Last()) {
|
if(aTag==theStack->Last()) {
|
||||||
|
result=theStack->Pop();
|
||||||
mResidualStyleCount--;
|
mResidualStyleCount--;
|
||||||
return theStack->Pop();
|
|
||||||
} else {
|
} else {
|
||||||
// NS_ERROR("bad residual style entry");
|
// NS_ERROR("bad residual style entry");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -619,20 +618,21 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||||
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||||
|
|
||||||
PRInt32 theLevel=0;
|
PRInt32 theLevel=0;
|
||||||
|
nsIParserNode* result=0;
|
||||||
|
|
||||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||||
if(theStack) {
|
if(theStack) {
|
||||||
if(aTag==theStack->Last()) {
|
if(aTag==theStack->Last()) {
|
||||||
|
result=theStack->Pop();
|
||||||
mResidualStyleCount--;
|
mResidualStyleCount--;
|
||||||
return theStack->Pop();
|
|
||||||
} else {
|
} else {
|
||||||
// NS_ERROR("bad residual style entry");
|
// 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 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.
|
//Lastly, bind tags with their rules, their special parents and special kids.
|
||||||
|
@ -1389,10 +1390,12 @@ PRBool nsHTMLElement::IsBlockCloser(eHTMLTags aTag){
|
||||||
if(!result) {
|
if(!result) {
|
||||||
// NOBR is a block closure - Ref. Bug# 24462
|
// NOBR is a block closure - Ref. Bug# 24462
|
||||||
// DIR is a block closure -- Ref. Bug# 25845
|
// 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,
|
static eHTMLTags gClosers[]={ eHTMLTag_table,eHTMLTag_tbody,eHTMLTag_caption,eHTMLTag_dd,eHTMLTag_dt,
|
||||||
eHTMLTag_td,eHTMLTag_th,
|
eHTMLTag_td,eHTMLTag_th,eHTMLTag_tr,
|
||||||
/* eHTMLTag_tfoot, eHTMLTag_thead,eHTMLTag_tr, */
|
/* eHTMLTag_tfoot, eHTMLTag_thead,*/
|
||||||
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
|
eHTMLTag_nobr,eHTMLTag_optgroup,eHTMLTag_ol,eHTMLTag_ul,eHTMLTag_dir};
|
||||||
|
|
||||||
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
|
result=FindTagInSet(aTag,gClosers,sizeof(gClosers)/sizeof(eHTMLTag_body));
|
||||||
|
@ -1549,6 +1552,45 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
|
||||||
return result;
|
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
|
* @update gess 01/04/99
|
||||||
|
@ -1907,12 +1949,9 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
|
||||||
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
|
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gHTMLElements[aChild].mExcludableParents) {
|
if(gHTMLElements[aChild].IsExcludableParent(mTagID))
|
||||||
TagList* theParents=gHTMLElements[aChild].mExcludableParents;
|
return PR_FALSE;
|
||||||
if(FindTagInSet(mTagID,theParents->mTags,theParents->mCount))
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
|
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
|
||||||
if(nsHTMLElement::IsBlockParent(mTagID)){
|
if(nsHTMLElement::IsBlockParent(mTagID)){
|
||||||
|
|
|
@ -171,6 +171,7 @@ struct nsHTMLElement {
|
||||||
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
|
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
|
||||||
PRBool HasSpecialProperty(PRInt32 aProperty) const;
|
PRBool HasSpecialProperty(PRInt32 aProperty) const;
|
||||||
PRBool IsSpecialParent(eHTMLTags aTag) const;
|
PRBool IsSpecialParent(eHTMLTags aTag) const;
|
||||||
|
PRBool IsExcludableParent(eHTMLTags aParent) const;
|
||||||
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
|
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
|
||||||
|
|
||||||
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);
|
static PRBool CanContain(eHTMLTags aParent,eHTMLTags aChild);
|
||||||
|
|
|
@ -297,7 +297,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CStartToken::GetSource(nsString& anOutputString){
|
void CStartToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="<";
|
anOutputString+="<";
|
||||||
/*
|
/*
|
||||||
* mTextValue used to contain the name of the tag.
|
* mTextValue used to contain the name of the tag.
|
||||||
* But for the sake of performance we now rely on the tagID
|
* But for the sake of performance we now rely on the tagID
|
||||||
|
@ -429,7 +429,7 @@ void CEndToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CEndToken::GetSource(nsString& anOutputString){
|
void CEndToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="</";
|
anOutputString+="</";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
anOutputString+=">";
|
anOutputString+=">";
|
||||||
}
|
}
|
||||||
|
@ -486,8 +486,8 @@ PRInt32 CTextToken::GetTokenType(void) {
|
||||||
* @param aScanner -- controller of underlying input source
|
* @param aScanner -- controller of underlying input source
|
||||||
* @return error result
|
* @return error result
|
||||||
*/
|
*/
|
||||||
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
|
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {;
|
||||||
static nsString theTerminals("\n\r&<",4);
|
static nsString theTerminals("\n\r&<",4);
|
||||||
nsresult result=NS_OK;
|
nsresult result=NS_OK;
|
||||||
PRBool done=PR_FALSE;
|
PRBool done=PR_FALSE;
|
||||||
|
|
||||||
|
@ -1176,7 +1176,7 @@ void CAttributeToken::DebugDumpToken(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CAttributeToken::GetSource(nsString& anOutputString){
|
void CAttributeToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString=mTextKey;
|
anOutputString+=mTextKey;
|
||||||
anOutputString+="=";
|
anOutputString+="=";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
anOutputString+=";";
|
anOutputString+=";";
|
||||||
|
@ -1670,7 +1670,7 @@ void CEntityToken::DebugDumpSource(nsOutputStream& out) {
|
||||||
* @return nada
|
* @return nada
|
||||||
*/
|
*/
|
||||||
void CEntityToken::GetSource(nsString& anOutputString){
|
void CEntityToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString="&";
|
anOutputString+="&";
|
||||||
anOutputString+=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
//anOutputString+=";";
|
//anOutputString+=";";
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ nsString& CToken::GetStringValueXXX(void) {
|
||||||
* @return reference to string containing string value
|
* @return reference to string containing string value
|
||||||
*/
|
*/
|
||||||
void CToken::GetSource(nsString& anOutputString){
|
void CToken::GetSource(nsString& anOutputString){
|
||||||
anOutputString=mTextValue;
|
anOutputString+=mTextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче