fixed bugs: 22510, 22596, 22670, 22838, 22842, 22898, and removed a warning. r=buster

git-svn-id: svn://10.0.0.236/trunk@56679 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rickg%netscape.com
2000-01-03 23:24:04 +00:00
parent 6418d2a7e5
commit 4446b7a92a
10 changed files with 236 additions and 102 deletions

View File

@@ -1074,25 +1074,40 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
}
if(theChildAgrees) {
//This code is here to allow DT/DD (or similar) to close arbitrary stuff between
//this instance and a prior one on the stack. I had to add this because
//(for now) DT is inline, and fontstyle's can contain them (until Res-style code works)
if(gHTMLElements[aChildTag].HasSpecialProperty(kMustCloseSelf)){
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
}
}
}
if(theChildAgrees && theChildIsContainer) {
if (theParentTag!=aChildTag) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
/*-------------------------------------------------------------------------------------
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>).
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>.
-------------------------------------------------------------------------------------*/
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
if(!theChildAgrees) {
int x=10;
}
} //if
} //if
} //if
} //if parentcontains
if(!(theParentContains && theChildAgrees)) {
if (!CanPropagate(theParentTag,aChildTag,theParentContains)) {
if(theChildIsContainer || (!theParentContains)){
if(!gHTMLElements[aChildTag].CanAutoCloseTag(theParentTag)) {
if(theChildIsContainer || (!theParentContains)){
if((!theChildAgrees) && (!gHTMLElements[aChildTag].CanAutoCloseTag(*mBodyContext,aChildTag))) {
// Closing the tags above might cause non-compatible results.
// Ex. <TABLE><TR><TD><TBODY>Text</TD></TR></TABLE>.
// In the example above <TBODY> is badly misplaced. To be backwards
// compatible we should not attempt to close the tags above it, for
// the contents inside the table might get thrown out of the table.
// In the example above <TBODY> is badly misplaced, but
// we should not attempt to close the tags above it,
// The safest thing to do is to discard this tag.
return result;
}
@@ -1632,8 +1647,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
}
else {
eHTMLTags theParentTag=mBodyContext->Last();
if((kNotFound==GetIndexOfChildOrSynonym(*mBodyContext,theChildTag)) ||
(!gHTMLElements[theChildTag].CanAutoCloseTag(theParentTag))) {
if(kNotFound==GetIndexOfChildOrSynonym(*mBodyContext,theChildTag)) {
PopStyle(theChildTag);
@@ -2116,7 +2130,6 @@ NS_IMETHODIMP CNavDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32*
PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag,PRBool aParentContains) {
PRBool result=PR_FALSE;
PRBool theParentContains=(-1==aParentContains) ? CanContain(aParentTag,aChildTag) : aParentContains;
eHTMLTags theTempTag=eHTMLTag_unknown;
if(aParentTag==aChildTag) {
return result;
@@ -3010,10 +3023,13 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
#ifdef ENABLE_RESIDUALSTYLE
PRBool theTagIsStyle=nsHTMLElement::IsResidualStyleTag(theTag);
PRBool theTargetTagIsStyle=nsHTMLElement::IsResidualStyleTag(aTarget);
PRBool theStyleDoesntLeakOut=gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
PRBool theStyleDoesntLeakOut = gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut);
// (aClosedByStartTag) ? gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut)
// : gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
if(mStyleHandlingEnabled && theTagIsStyle) {
if(theTagIsStyle) {
PRBool theTargetTagIsStyle=nsHTMLElement::IsResidualStyleTag(aTarget);
if(aClosedByStartTag) {
@@ -3095,8 +3111,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
} //if
else {
else {
//the tag is not a style tag...
if(theChildStyleStack) {
if(theStyleDoesntLeakOut) {
RecycleNodes(theChildStyleStack);

View File

@@ -85,6 +85,12 @@ public:
eHTMLTags Last() const;
void Empty(void);
/**
* Find the first instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 FirstOf(eHTMLTags aTag) const {
PRInt32 index=-1;
@@ -98,6 +104,13 @@ public:
return kNotFound;
}
/**
* Find the last instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 LastOf(eHTMLTags aTag) const {
PRInt32 index=mCount;
while(--index>=0) {
@@ -338,10 +351,11 @@ struct TagList {
};
/**
*
* @update gess 01/04/99
* @param
* @return
* Find the last member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 LastOf(nsDTDContext& aContext,TagList& aTagList){
int max = aContext.GetCount();
@@ -356,10 +370,12 @@ inline PRInt32 LastOf(nsDTDContext& aContext,TagList& aTagList){
}
/**
*
* @update gess 01/04/99
* @param
* @return
* Find the first member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aStartOffset
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 FirstOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){
int max = aContext.GetCount();

View File

@@ -104,13 +104,13 @@ TagList gULKids={2,{eHTMLTag_li,eHTMLTag_p}};
//*********************************************************************************************
TagList gRootTags={4,{eHTMLTag_body,eHTMLTag_td,eHTMLTag_table,eHTMLTag_applet}};
TagList gTableRootTags={3,{eHTMLTag_body,eHTMLTag_table,eHTMLTag_applet}};
TagList gTableRootTags={6,{eHTMLTag_applet,eHTMLTag_body,eHTMLTag_dl,eHTMLTag_ol,eHTMLTag_td,eHTMLTag_ul}};
TagList gHTMLRootTags={1,{eHTMLTag_unknown}};
TagList gLIRootTags={7,{eHTMLTag_ul,eHTMLTag_ol,eHTMLTag_dir,eHTMLTag_menu,eHTMLTag_p,eHTMLTag_body,eHTMLTag_td}};
TagList gOLRootTags={3,{eHTMLTag_body,eHTMLTag_li,eHTMLTag_td}};
TagList gTDRootTags={3,{eHTMLTag_tr,eHTMLTag_tbody,eHTMLTag_table}};
TagList gTDRootTags={5,{eHTMLTag_tr,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot,eHTMLTag_table}};
TagList gNoframeRoot={2,{eHTMLTag_body,eHTMLTag_frameset}};
//*********************************************************************************************
@@ -128,6 +128,7 @@ TagList gDivAutoClose={1,{eHTMLTag_p}};
TagList gHeadingTags={6,{eHTMLTag_h1,eHTMLTag_h2,eHTMLTag_h3,eHTMLTag_h4,eHTMLTag_h5,eHTMLTag_h6}};
TagList gTableCloseTags={6,{eHTMLTag_td,eHTMLTag_tr,eHTMLTag_th,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot}};
TagList gTRCloseTags={3,{eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th}};
TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}};
TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
@@ -160,7 +161,7 @@ void Initialize(eHTMLTags aTag,
TagList* aAutocloseStart,
TagList* aAutocloseEnd,
TagList* aSynonymousTags,
TagList* aDontAutocloseEnd,
TagList* aAutoCloseBlockers,
int aParentBits,
int aInclusionBits,
int aExclusionBits,
@@ -179,7 +180,7 @@ void Initialize(eHTMLTags aTag,
gHTMLElements[aTag].mAutocloseStart=aAutocloseStart;
gHTMLElements[aTag].mAutocloseEnd=aAutocloseEnd;
gHTMLElements[aTag].mSynonymousTags=aSynonymousTags;
gHTMLElements[aTag].mDontAutocloseEnd=aDontAutocloseEnd;
gHTMLElements[aTag].mAutoCloseBlockers=aAutoCloseBlockers;
gHTMLElements[aTag].mParentBits=aParentBits;
gHTMLElements[aTag].mInclusionBits=aInclusionBits;
gHTMLElements[aTag].mExclusionBits=aExclusionBits;
@@ -1095,7 +1096,7 @@ void InitializeElementTable(void) {
/*tag*/ eHTMLTag_table,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gTableRootTags,&gTableRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*autoclose starttags and endtags*/ 0,&gTableCloseTags,0,0,
/*parent,incl,exclgroups*/ kBlock, kNone, (kSelf|kInlineEntity),
/*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), 2,
/*special parents,kids,skip*/ 0,&gTableKids,eHTMLTag_unknown);
@@ -1325,7 +1326,7 @@ int nsHTMLElement::GetSynonymousGroups(eHTMLTags aTag) {
}
if(eHTMLTag_font==aTag) //hack for backward compatibility
result+=kFontStyle;
result&=kFontStyle;
return result;
}
@@ -1724,19 +1725,42 @@ PRBool nsHTMLElement::CanContainSelf(void) const {
}
/**
*
* @update harishd 09/20/99
* @param
* @return
* This method is called to determine (once and for all) whether a start tag
* can close another tag on the stack. This method will return
* false if something prevents aParentTag from closing.
*
* @update gess 12/20/99
* @param aContext is the tag stack we're testing against
* @param aChildTag is the child we're trying to close
* @param aCount is the number tags we should test
* @return TRUE if we can autoclose the start tag; FALSE otherwise
*/
PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
PRBool result=PR_TRUE;
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)) {
TagList* theTagList=gHTMLElements[mTagID].mDontAutocloseEnd;
if(theTagList) {
result=!FindTagInSet(aTag,theTagList->mTags,theTagList->mCount);
}
}
PRBool nsHTMLElement::CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aChildTag) const{
PRInt32 thePos=aContext.GetCount();
PRBool result=PR_FALSE;
eHTMLTags thePrevTag=eHTMLTag_unknown;
for(thePos=aContext.GetCount()-1;thePos>0;thePos--) {
thePrevTag=aContext.TagAt(thePos);
switch(thePrevTag) {
case eHTMLTag_applet:
case eHTMLTag_td:
thePos=0;
result=PR_FALSE;
break;
case eHTMLTag_body:
result=aChildTag!=thePrevTag;
thePos=0;
default:
if(aChildTag==thePrevTag) {
result=PR_TRUE;
thePos=0;
}
break;
} //switch
} //for
return result;
}
@@ -1835,11 +1859,21 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
return PR_FALSE;
}
#if 0
//the older version; replaced in december by rickg
if(gHTMLElements[aChild].IsBlockEntity()){
if(nsHTMLElement::IsBlockParent(mTagID)){
return PR_TRUE;
}
}
#else
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
if(nsHTMLElement::IsBlockParent(mTagID)){
return PR_TRUE;
}
}
#endif
if(nsHTMLElement::IsInlineEntity(aChild)){
if(nsHTMLElement::IsInlineParent(mTagID)){

View File

@@ -168,7 +168,7 @@ struct nsHTMLElement {
PRBool CanOmitStartTag(eHTMLTags aChild) const;
PRBool CanOmitEndTag(void) const;
PRBool CanContainSelf(void) const;
PRBool CanAutoCloseTag(eHTMLTags aTag) const;
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
PRBool HasSpecialProperty(PRInt32 aProperty) const;
PRBool IsSpecialParent(eHTMLTags aTag) const;
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
@@ -194,7 +194,7 @@ struct nsHTMLElement {
TagList* mAutocloseStart; //these are the start tags that you can automatically close with this START tag
TagList* mAutocloseEnd; //these are the start tags that you can automatically close with this END tag
TagList* mSynonymousTags; //These are morally equivalent; an end tag for one can close a start tag for another (like <Hn>)
TagList* mDontAutocloseEnd; //...
TagList* mAutoCloseBlockers; //...
int mParentBits; //defines groups that can contain this element
int mInclusionBits; //defines parental and containment rules
int mExclusionBits; //defines things you CANNOT contain

View File

@@ -280,6 +280,7 @@ protected:
nsAutoString mText;
nsAutoString mKey;
nsAutoString mValue;
nsAutoString mPopupTag;
PRBool mIsText;
};

View File

@@ -1074,25 +1074,40 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
}
if(theChildAgrees) {
//This code is here to allow DT/DD (or similar) to close arbitrary stuff between
//this instance and a prior one on the stack. I had to add this because
//(for now) DT is inline, and fontstyle's can contain them (until Res-style code works)
if(gHTMLElements[aChildTag].HasSpecialProperty(kMustCloseSelf)){
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
}
}
}
if(theChildAgrees && theChildIsContainer) {
if (theParentTag!=aChildTag) {
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(*mBodyContext,aChildTag);
if((kNotFound<theChildIndex) && (theChildIndex<theIndex)) {
/*-------------------------------------------------------------------------------------
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>).
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>.
-------------------------------------------------------------------------------------*/
theChildAgrees=CanBeContained(aChildTag,*mBodyContext);
if(!theChildAgrees) {
int x=10;
}
} //if
} //if
} //if
} //if parentcontains
if(!(theParentContains && theChildAgrees)) {
if (!CanPropagate(theParentTag,aChildTag,theParentContains)) {
if(theChildIsContainer || (!theParentContains)){
if(!gHTMLElements[aChildTag].CanAutoCloseTag(theParentTag)) {
if(theChildIsContainer || (!theParentContains)){
if((!theChildAgrees) && (!gHTMLElements[aChildTag].CanAutoCloseTag(*mBodyContext,aChildTag))) {
// Closing the tags above might cause non-compatible results.
// Ex. <TABLE><TR><TD><TBODY>Text</TD></TR></TABLE>.
// In the example above <TBODY> is badly misplaced. To be backwards
// compatible we should not attempt to close the tags above it, for
// the contents inside the table might get thrown out of the table.
// In the example above <TBODY> is badly misplaced, but
// we should not attempt to close the tags above it,
// The safest thing to do is to discard this tag.
return result;
}
@@ -1632,8 +1647,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
}
else {
eHTMLTags theParentTag=mBodyContext->Last();
if((kNotFound==GetIndexOfChildOrSynonym(*mBodyContext,theChildTag)) ||
(!gHTMLElements[theChildTag].CanAutoCloseTag(theParentTag))) {
if(kNotFound==GetIndexOfChildOrSynonym(*mBodyContext,theChildTag)) {
PopStyle(theChildTag);
@@ -2116,7 +2130,6 @@ NS_IMETHODIMP CNavDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32*
PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag,PRBool aParentContains) {
PRBool result=PR_FALSE;
PRBool theParentContains=(-1==aParentContains) ? CanContain(aParentTag,aChildTag) : aParentContains;
eHTMLTags theTempTag=eHTMLTag_unknown;
if(aParentTag==aChildTag) {
return result;
@@ -3010,10 +3023,13 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
#ifdef ENABLE_RESIDUALSTYLE
PRBool theTagIsStyle=nsHTMLElement::IsResidualStyleTag(theTag);
PRBool theTargetTagIsStyle=nsHTMLElement::IsResidualStyleTag(aTarget);
PRBool theStyleDoesntLeakOut=gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
PRBool theStyleDoesntLeakOut = gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut);
// (aClosedByStartTag) ? gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut)
// : gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
if(mStyleHandlingEnabled && theTagIsStyle) {
if(theTagIsStyle) {
PRBool theTargetTagIsStyle=nsHTMLElement::IsResidualStyleTag(aTarget);
if(aClosedByStartTag) {
@@ -3095,8 +3111,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
} //if
else {
else {
//the tag is not a style tag...
if(theChildStyleStack) {
if(theStyleDoesntLeakOut) {
RecycleNodes(theChildStyleStack);

View File

@@ -85,6 +85,12 @@ public:
eHTMLTags Last() const;
void Empty(void);
/**
* Find the first instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 FirstOf(eHTMLTags aTag) const {
PRInt32 index=-1;
@@ -98,6 +104,13 @@ public:
return kNotFound;
}
/**
* Find the last instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 LastOf(eHTMLTags aTag) const {
PRInt32 index=mCount;
while(--index>=0) {
@@ -338,10 +351,11 @@ struct TagList {
};
/**
*
* @update gess 01/04/99
* @param
* @return
* Find the last member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 LastOf(nsDTDContext& aContext,TagList& aTagList){
int max = aContext.GetCount();
@@ -356,10 +370,12 @@ inline PRInt32 LastOf(nsDTDContext& aContext,TagList& aTagList){
}
/**
*
* @update gess 01/04/99
* @param
* @return
* Find the first member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aStartOffset
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline PRInt32 FirstOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){
int max = aContext.GetCount();

View File

@@ -104,13 +104,13 @@ TagList gULKids={2,{eHTMLTag_li,eHTMLTag_p}};
//*********************************************************************************************
TagList gRootTags={4,{eHTMLTag_body,eHTMLTag_td,eHTMLTag_table,eHTMLTag_applet}};
TagList gTableRootTags={3,{eHTMLTag_body,eHTMLTag_table,eHTMLTag_applet}};
TagList gTableRootTags={6,{eHTMLTag_applet,eHTMLTag_body,eHTMLTag_dl,eHTMLTag_ol,eHTMLTag_td,eHTMLTag_ul}};
TagList gHTMLRootTags={1,{eHTMLTag_unknown}};
TagList gLIRootTags={7,{eHTMLTag_ul,eHTMLTag_ol,eHTMLTag_dir,eHTMLTag_menu,eHTMLTag_p,eHTMLTag_body,eHTMLTag_td}};
TagList gOLRootTags={3,{eHTMLTag_body,eHTMLTag_li,eHTMLTag_td}};
TagList gTDRootTags={3,{eHTMLTag_tr,eHTMLTag_tbody,eHTMLTag_table}};
TagList gTDRootTags={5,{eHTMLTag_tr,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot,eHTMLTag_table}};
TagList gNoframeRoot={2,{eHTMLTag_body,eHTMLTag_frameset}};
//*********************************************************************************************
@@ -128,6 +128,7 @@ TagList gDivAutoClose={1,{eHTMLTag_p}};
TagList gHeadingTags={6,{eHTMLTag_h1,eHTMLTag_h2,eHTMLTag_h3,eHTMLTag_h4,eHTMLTag_h5,eHTMLTag_h6}};
TagList gTableCloseTags={6,{eHTMLTag_td,eHTMLTag_tr,eHTMLTag_th,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot}};
TagList gTRCloseTags={3,{eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th}};
TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}};
TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
@@ -160,7 +161,7 @@ void Initialize(eHTMLTags aTag,
TagList* aAutocloseStart,
TagList* aAutocloseEnd,
TagList* aSynonymousTags,
TagList* aDontAutocloseEnd,
TagList* aAutoCloseBlockers,
int aParentBits,
int aInclusionBits,
int aExclusionBits,
@@ -179,7 +180,7 @@ void Initialize(eHTMLTags aTag,
gHTMLElements[aTag].mAutocloseStart=aAutocloseStart;
gHTMLElements[aTag].mAutocloseEnd=aAutocloseEnd;
gHTMLElements[aTag].mSynonymousTags=aSynonymousTags;
gHTMLElements[aTag].mDontAutocloseEnd=aDontAutocloseEnd;
gHTMLElements[aTag].mAutoCloseBlockers=aAutoCloseBlockers;
gHTMLElements[aTag].mParentBits=aParentBits;
gHTMLElements[aTag].mInclusionBits=aInclusionBits;
gHTMLElements[aTag].mExclusionBits=aExclusionBits;
@@ -1095,7 +1096,7 @@ void InitializeElementTable(void) {
/*tag*/ eHTMLTag_table,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gTableRootTags,&gTableRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*autoclose starttags and endtags*/ 0,&gTableCloseTags,0,0,
/*parent,incl,exclgroups*/ kBlock, kNone, (kSelf|kInlineEntity),
/*special props, prop-range*/ (kOmitWS|kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), 2,
/*special parents,kids,skip*/ 0,&gTableKids,eHTMLTag_unknown);
@@ -1325,7 +1326,7 @@ int nsHTMLElement::GetSynonymousGroups(eHTMLTags aTag) {
}
if(eHTMLTag_font==aTag) //hack for backward compatibility
result+=kFontStyle;
result&=kFontStyle;
return result;
}
@@ -1724,19 +1725,42 @@ PRBool nsHTMLElement::CanContainSelf(void) const {
}
/**
*
* @update harishd 09/20/99
* @param
* @return
* This method is called to determine (once and for all) whether a start tag
* can close another tag on the stack. This method will return
* false if something prevents aParentTag from closing.
*
* @update gess 12/20/99
* @param aContext is the tag stack we're testing against
* @param aChildTag is the child we're trying to close
* @param aCount is the number tags we should test
* @return TRUE if we can autoclose the start tag; FALSE otherwise
*/
PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
PRBool result=PR_TRUE;
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)) {
TagList* theTagList=gHTMLElements[mTagID].mDontAutocloseEnd;
if(theTagList) {
result=!FindTagInSet(aTag,theTagList->mTags,theTagList->mCount);
}
}
PRBool nsHTMLElement::CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aChildTag) const{
PRInt32 thePos=aContext.GetCount();
PRBool result=PR_FALSE;
eHTMLTags thePrevTag=eHTMLTag_unknown;
for(thePos=aContext.GetCount()-1;thePos>0;thePos--) {
thePrevTag=aContext.TagAt(thePos);
switch(thePrevTag) {
case eHTMLTag_applet:
case eHTMLTag_td:
thePos=0;
result=PR_FALSE;
break;
case eHTMLTag_body:
result=aChildTag!=thePrevTag;
thePos=0;
default:
if(aChildTag==thePrevTag) {
result=PR_TRUE;
thePos=0;
}
break;
} //switch
} //for
return result;
}
@@ -1835,11 +1859,21 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
return PR_FALSE;
}
#if 0
//the older version; replaced in december by rickg
if(gHTMLElements[aChild].IsBlockEntity()){
if(nsHTMLElement::IsBlockParent(mTagID)){
return PR_TRUE;
}
}
#else
if(gHTMLElements[aChild].IsBlockCloser(aChild)){
if(nsHTMLElement::IsBlockParent(mTagID)){
return PR_TRUE;
}
}
#endif
if(nsHTMLElement::IsInlineEntity(aChild)){
if(nsHTMLElement::IsInlineParent(mTagID)){

View File

@@ -168,7 +168,7 @@ struct nsHTMLElement {
PRBool CanOmitStartTag(eHTMLTags aChild) const;
PRBool CanOmitEndTag(void) const;
PRBool CanContainSelf(void) const;
PRBool CanAutoCloseTag(eHTMLTags aTag) const;
PRBool CanAutoCloseTag(nsDTDContext& aContext,eHTMLTags aTag) const;
PRBool HasSpecialProperty(PRInt32 aProperty) const;
PRBool IsSpecialParent(eHTMLTags aTag) const;
PRBool SectionContains(eHTMLTags aTag,PRBool allowDepthSearch);
@@ -194,7 +194,7 @@ struct nsHTMLElement {
TagList* mAutocloseStart; //these are the start tags that you can automatically close with this START tag
TagList* mAutocloseEnd; //these are the start tags that you can automatically close with this END tag
TagList* mSynonymousTags; //These are morally equivalent; an end tag for one can close a start tag for another (like <Hn>)
TagList* mDontAutocloseEnd; //...
TagList* mAutoCloseBlockers; //...
int mParentBits; //defines groups that can contain this element
int mInclusionBits; //defines parental and containment rules
int mExclusionBits; //defines things you CANNOT contain

View File

@@ -280,6 +280,7 @@ protected:
nsAutoString mText;
nsAutoString mKey;
nsAutoString mValue;
nsAutoString mPopupTag;
PRBool mIsText;
};