зеркало из https://github.com/mozilla/gecko-dev.git
fixed RTM++ compatibility bugs: 53011, 54117, 54651, 54834, 54840, 55095. sr=buster, r=buster, attinasi, harish, sfraser for various portions.
This commit is contained in:
Родитель
2d7911145f
Коммит
8460836715
|
@ -843,7 +843,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
|
|||
case eHTMLTag_counter:
|
||||
{
|
||||
PRInt32 theCount=mBodyContext->GetCount();
|
||||
eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-2);
|
||||
eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-1);
|
||||
|
||||
nsAutoString theNumber;
|
||||
|
||||
|
@ -980,23 +980,47 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) {
|
|||
//Note: This method is going away. First we need to get the elementtable to do closures right, and
|
||||
// therefore we must get residual style handling to work.
|
||||
|
||||
PRBool result=PR_TRUE;
|
||||
if(aContext.GetCount()){
|
||||
//the changes to this method were added to fix bug 54651...
|
||||
|
||||
PRBool result=PR_TRUE;
|
||||
PRInt32 theCount=aContext.GetCount();
|
||||
|
||||
if(0<theCount){
|
||||
TagList* theRootTags=gHTMLElements[aChildTag].GetRootTags();
|
||||
TagList* theSpecialParents=gHTMLElements[aChildTag].GetSpecialParents();
|
||||
if(theRootTags) {
|
||||
PRInt32 theRootIndex=LastOf(aContext,*theRootTags);
|
||||
PRInt32 theSPIndex=(theSpecialParents) ? LastOf(aContext,*theSpecialParents) : kNotFound;
|
||||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aChildTag);
|
||||
PRInt32 theBaseIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex;
|
||||
PRInt32 theTargetIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex;
|
||||
|
||||
if((theBaseIndex==theChildIndex) && (gHTMLElements[aChildTag].CanContainSelf()))
|
||||
if((theTargetIndex==theCount-1) ||
|
||||
((theTargetIndex==theChildIndex) && gHTMLElements[aChildTag].CanContainSelf())) {
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(theBaseIndex>theChildIndex);
|
||||
}
|
||||
else {
|
||||
|
||||
result=PR_FALSE;
|
||||
|
||||
PRInt32 theIndex=theCount-1;
|
||||
while(theChildIndex<theIndex) {
|
||||
eHTMLTags theParentTag=aContext.TagAt(theIndex--);
|
||||
if (gHTMLElements[theParentTag].IsMemberOf(kBlockEntity) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kHeading) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kPreformatted) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kList)) {
|
||||
if(!HasOptionalEndTag(theParentTag)) {
|
||||
result=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
enum eProcessRule {eNormalOp,eLetInlineContainBlock};
|
||||
|
@ -1041,7 +1065,7 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
|||
(nsHTMLElement::IsResidualStyleTag(theParentTag)) &&
|
||||
(IsBlockElement(aChildTag,theParentTag))) {
|
||||
|
||||
if(eHTMLTag_table!=aChildTag) {
|
||||
if((eHTMLTag_table!=aChildTag) && (eHTMLTag_li!=aChildTag)) {
|
||||
nsCParserNode* theParentNode= NS_STATIC_CAST(nsCParserNode*, mBodyContext->PeekNode());
|
||||
if(theParentNode->mToken->IsWellFormed()) {
|
||||
theRule=eLetInlineContainBlock;
|
||||
|
@ -1189,15 +1213,12 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
|||
/**************************************************************************************
|
||||
*
|
||||
* Now a little code to deal with bug #49687 (crash when layout stack gets too deep)
|
||||
* I've also opened this up to any container (not just inlines): re bug 55095
|
||||
*
|
||||
**************************************************************************************/
|
||||
|
||||
if(MAX_REFLOW_DEPTH<mBodyContext->GetCount()) {
|
||||
if(gHTMLElements[aTag].IsMemberOf(kInlineEntity)) {
|
||||
if(!gHTMLElements[aTag].IsMemberOf(kFormControl)) {
|
||||
return kHierarchyTooDeep;
|
||||
}
|
||||
}
|
||||
return kHierarchyTooDeep;
|
||||
}
|
||||
|
||||
STOP_TIMER()
|
||||
|
@ -1640,7 +1661,8 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont
|
|||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aCurrentTag);
|
||||
|
||||
if(kNotFound<theChildIndex) {
|
||||
if(thePrevTag==aContext[theChildIndex]){
|
||||
if((thePrevTag==aContext[theChildIndex]) ||
|
||||
(eHTMLTag_noscript==aCurrentTag)){ //bug 54571
|
||||
return aContext[theChildIndex];
|
||||
}
|
||||
|
||||
|
|
|
@ -1163,7 +1163,7 @@ void InitializeElementTable(void) {
|
|||
|
||||
Initialize(
|
||||
/*tag*/ eHTMLTag_thead,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*req-parent excl-parent*/ eHTMLTag_table,eHTMLTag_unknown, //fix bug 54840...
|
||||
/*rootnodes,endrootnodes*/ &gInTable,&gInTable,
|
||||
/*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kNone, kNone, kSelf,
|
||||
|
@ -1379,8 +1379,20 @@ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) {
|
|||
* @return
|
||||
*/
|
||||
PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{
|
||||
PRBool result=TestBits(aSet,mParentBits);
|
||||
return result;
|
||||
return TestBits(aSet,mParentBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests whether all the bits in the parentbits
|
||||
* are included in the given set. It may be too
|
||||
* broad a question for most cases.
|
||||
*
|
||||
* @update gess12/13/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool nsHTMLElement::ContainsSet(PRInt32 aSet) const{
|
||||
return TestBits(mParentBits,aSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1906,7 +1918,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
|||
}
|
||||
|
||||
//phrasal elements can close other phrasals, along with fontstyle and special tags...
|
||||
if(!gHTMLElements[theTag].IsMemberOf(kSpecial|kFontStyle|kPhrase)) {
|
||||
if(!gHTMLElements[theTag].ContainsSet(kSpecial|kFontStyle|kPhrase)) {
|
||||
break; //it's not something I can close
|
||||
}
|
||||
}
|
||||
|
@ -1949,7 +1961,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
|||
}
|
||||
}
|
||||
|
||||
else if(IsMemberOf(kFormControl|kExtensions|kPreformatted)){
|
||||
else if(ContainsSet(kFormControl|kExtensions|kPreformatted)){ //bug54834...
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
|
|
|
@ -161,6 +161,7 @@ struct nsHTMLElement {
|
|||
TagList* GetSpecialParents(void) const {return mSpecialParents;}
|
||||
|
||||
PRBool IsMemberOf(PRInt32 aType) const;
|
||||
PRBool ContainsSet(PRInt32 aType) const;
|
||||
PRBool CanContainType(PRInt32 aType) const;
|
||||
|
||||
eHTMLTags GetTag(void) const {return mTagID;}
|
||||
|
|
|
@ -343,69 +343,74 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) {
|
|||
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity);
|
||||
PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity);
|
||||
|
||||
if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) {
|
||||
PRBool theTagIsContainer=nsHTMLElement::IsContainer(theTag); //bug54117...
|
||||
|
||||
switch(theType) {
|
||||
if(theTagIsContainer) {
|
||||
PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity);
|
||||
PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity);
|
||||
|
||||
case eToken_start:
|
||||
if(0==theStack.GetSize()) {
|
||||
//track the tag on the top of the stack...
|
||||
theRootToken=theToken;
|
||||
theRootTag=theTag;
|
||||
}
|
||||
theStack.Push(theToken);
|
||||
theStackDepth++;
|
||||
break;
|
||||
if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) {
|
||||
|
||||
case eToken_end:
|
||||
{
|
||||
CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
if(theLastToken) {
|
||||
if(theTag==theLastToken->GetTypeID()) {
|
||||
theStack.Pop(); //yank it for real
|
||||
theStackDepth--;
|
||||
theLastToken->SetContainerInfo(eWellFormed);
|
||||
switch(theType) {
|
||||
|
||||
//in addition, let's look above this container to see if we can find
|
||||
//any tags that are already marked malformed. If so, pop them too!
|
||||
case eToken_start:
|
||||
if(0==theStack.GetSize()) {
|
||||
//track the tag on the top of the stack...
|
||||
theRootToken=theToken;
|
||||
theRootTag=theTag;
|
||||
}
|
||||
theStack.Push(theToken);
|
||||
theStackDepth++;
|
||||
break;
|
||||
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
while(theLastToken) {
|
||||
if(eMalformed==theRootToken->GetContainerInfo()) {
|
||||
theStack.Pop(); //yank the malformed token for real.
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
continue;
|
||||
case eToken_end:
|
||||
{
|
||||
CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
if(theLastToken) {
|
||||
if(theTag==theLastToken->GetTypeID()) {
|
||||
theStack.Pop(); //yank it for real
|
||||
theStackDepth--;
|
||||
theLastToken->SetContainerInfo(eWellFormed);
|
||||
|
||||
//in addition, let's look above this container to see if we can find
|
||||
//any tags that are already marked malformed. If so, pop them too!
|
||||
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
while(theLastToken) {
|
||||
if(eMalformed==theRootToken->GetContainerInfo()) {
|
||||
theStack.Pop(); //yank the malformed token for real.
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//the topmost token isn't what we expected, so that container must
|
||||
//be malformed. If the tag is a block, we don't really care (but we'll
|
||||
//mark it anyway). If it's an inline we DO care, especially if the
|
||||
//inline tried to contain a block (that's when RS handling kicks in).
|
||||
if(theTagIsInline) {
|
||||
PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack);
|
||||
if(kNotFound!=theIndex) {
|
||||
theToken=(CHTMLToken*)theStack.ObjectAt(theIndex);
|
||||
theToken->SetContainerInfo(eMalformed);
|
||||
}
|
||||
//otherwise we ignore an out-of-place end tag.
|
||||
}
|
||||
else {
|
||||
//the topmost token isn't what we expected, so that container must
|
||||
//be malformed. If the tag is a block, we don't really care (but we'll
|
||||
//mark it anyway). If it's an inline we DO care, especially if the
|
||||
//inline tried to contain a block (that's when RS handling kicks in).
|
||||
if(theTagIsInline) {
|
||||
PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack);
|
||||
if(kNotFound!=theIndex) {
|
||||
theToken=(CHTMLToken*)theStack.ObjectAt(theIndex);
|
||||
theToken->SetContainerInfo(eMalformed);
|
||||
}
|
||||
//otherwise we ignore an out-of-place end tag.
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
theToken=(CHTMLToken*)mTokenDeque.ObjectAt(++mTokenScanPos);
|
||||
|
|
|
@ -997,9 +997,13 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
|
|||
nsresult result=PR_TRUE;
|
||||
|
||||
switch(aMode) {
|
||||
|
||||
#if 0 //set to 1 if you want strict comments... bug 53011...
|
||||
case eDTDMode_strict:
|
||||
result=ConsumeStrictComment(aChar,aScanner,mTextValue);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case eDTDMode_transitional:
|
||||
default:
|
||||
result=ConsumeComment(aChar,aScanner,mTextValue);
|
||||
|
|
|
@ -73,7 +73,11 @@
|
|||
{ 0xa6cf9051, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
|
||||
|
||||
#define MAX_REFLOW_DEPTH 200
|
||||
#ifdef XP_MAC
|
||||
#define MAX_REFLOW_DEPTH 75 //setting to 75 to prevent layout from crashing on mac. Bug 55095.
|
||||
#else
|
||||
#define MAX_REFLOW_DEPTH 200 //windows and linux (etc) can do much deeper structures.
|
||||
#endif
|
||||
|
||||
|
||||
class nsIHTMLContentSink : public nsIContentSink {
|
||||
|
|
|
@ -843,7 +843,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
|
|||
case eHTMLTag_counter:
|
||||
{
|
||||
PRInt32 theCount=mBodyContext->GetCount();
|
||||
eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-2);
|
||||
eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-1);
|
||||
|
||||
nsAutoString theNumber;
|
||||
|
||||
|
@ -980,23 +980,47 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) {
|
|||
//Note: This method is going away. First we need to get the elementtable to do closures right, and
|
||||
// therefore we must get residual style handling to work.
|
||||
|
||||
PRBool result=PR_TRUE;
|
||||
if(aContext.GetCount()){
|
||||
//the changes to this method were added to fix bug 54651...
|
||||
|
||||
PRBool result=PR_TRUE;
|
||||
PRInt32 theCount=aContext.GetCount();
|
||||
|
||||
if(0<theCount){
|
||||
TagList* theRootTags=gHTMLElements[aChildTag].GetRootTags();
|
||||
TagList* theSpecialParents=gHTMLElements[aChildTag].GetSpecialParents();
|
||||
if(theRootTags) {
|
||||
PRInt32 theRootIndex=LastOf(aContext,*theRootTags);
|
||||
PRInt32 theSPIndex=(theSpecialParents) ? LastOf(aContext,*theSpecialParents) : kNotFound;
|
||||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aChildTag);
|
||||
PRInt32 theBaseIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex;
|
||||
PRInt32 theTargetIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex;
|
||||
|
||||
if((theBaseIndex==theChildIndex) && (gHTMLElements[aChildTag].CanContainSelf()))
|
||||
if((theTargetIndex==theCount-1) ||
|
||||
((theTargetIndex==theChildIndex) && gHTMLElements[aChildTag].CanContainSelf())) {
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(theBaseIndex>theChildIndex);
|
||||
}
|
||||
else {
|
||||
|
||||
result=PR_FALSE;
|
||||
|
||||
PRInt32 theIndex=theCount-1;
|
||||
while(theChildIndex<theIndex) {
|
||||
eHTMLTags theParentTag=aContext.TagAt(theIndex--);
|
||||
if (gHTMLElements[theParentTag].IsMemberOf(kBlockEntity) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kHeading) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kPreformatted) ||
|
||||
gHTMLElements[theParentTag].IsMemberOf(kList)) {
|
||||
if(!HasOptionalEndTag(theParentTag)) {
|
||||
result=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
enum eProcessRule {eNormalOp,eLetInlineContainBlock};
|
||||
|
@ -1041,7 +1065,7 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
|||
(nsHTMLElement::IsResidualStyleTag(theParentTag)) &&
|
||||
(IsBlockElement(aChildTag,theParentTag))) {
|
||||
|
||||
if(eHTMLTag_table!=aChildTag) {
|
||||
if((eHTMLTag_table!=aChildTag) && (eHTMLTag_li!=aChildTag)) {
|
||||
nsCParserNode* theParentNode= NS_STATIC_CAST(nsCParserNode*, mBodyContext->PeekNode());
|
||||
if(theParentNode->mToken->IsWellFormed()) {
|
||||
theRule=eLetInlineContainBlock;
|
||||
|
@ -1189,15 +1213,12 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
|||
/**************************************************************************************
|
||||
*
|
||||
* Now a little code to deal with bug #49687 (crash when layout stack gets too deep)
|
||||
* I've also opened this up to any container (not just inlines): re bug 55095
|
||||
*
|
||||
**************************************************************************************/
|
||||
|
||||
if(MAX_REFLOW_DEPTH<mBodyContext->GetCount()) {
|
||||
if(gHTMLElements[aTag].IsMemberOf(kInlineEntity)) {
|
||||
if(!gHTMLElements[aTag].IsMemberOf(kFormControl)) {
|
||||
return kHierarchyTooDeep;
|
||||
}
|
||||
}
|
||||
return kHierarchyTooDeep;
|
||||
}
|
||||
|
||||
STOP_TIMER()
|
||||
|
@ -1640,7 +1661,8 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont
|
|||
PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aCurrentTag);
|
||||
|
||||
if(kNotFound<theChildIndex) {
|
||||
if(thePrevTag==aContext[theChildIndex]){
|
||||
if((thePrevTag==aContext[theChildIndex]) ||
|
||||
(eHTMLTag_noscript==aCurrentTag)){ //bug 54571
|
||||
return aContext[theChildIndex];
|
||||
}
|
||||
|
||||
|
|
|
@ -1163,7 +1163,7 @@ void InitializeElementTable(void) {
|
|||
|
||||
Initialize(
|
||||
/*tag*/ eHTMLTag_thead,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*req-parent excl-parent*/ eHTMLTag_table,eHTMLTag_unknown, //fix bug 54840...
|
||||
/*rootnodes,endrootnodes*/ &gInTable,&gInTable,
|
||||
/*autoclose starttags and endtags*/ &gTBodyAutoClose,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kNone, kNone, kSelf,
|
||||
|
@ -1379,8 +1379,20 @@ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) {
|
|||
* @return
|
||||
*/
|
||||
PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{
|
||||
PRBool result=TestBits(aSet,mParentBits);
|
||||
return result;
|
||||
return TestBits(aSet,mParentBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests whether all the bits in the parentbits
|
||||
* are included in the given set. It may be too
|
||||
* broad a question for most cases.
|
||||
*
|
||||
* @update gess12/13/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool nsHTMLElement::ContainsSet(PRInt32 aSet) const{
|
||||
return TestBits(mParentBits,aSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1906,7 +1918,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
|||
}
|
||||
|
||||
//phrasal elements can close other phrasals, along with fontstyle and special tags...
|
||||
if(!gHTMLElements[theTag].IsMemberOf(kSpecial|kFontStyle|kPhrase)) {
|
||||
if(!gHTMLElements[theTag].ContainsSet(kSpecial|kFontStyle|kPhrase)) {
|
||||
break; //it's not something I can close
|
||||
}
|
||||
}
|
||||
|
@ -1949,7 +1961,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
|||
}
|
||||
}
|
||||
|
||||
else if(IsMemberOf(kFormControl|kExtensions|kPreformatted)){
|
||||
else if(ContainsSet(kFormControl|kExtensions|kPreformatted)){ //bug54834...
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
|
|
|
@ -161,6 +161,7 @@ struct nsHTMLElement {
|
|||
TagList* GetSpecialParents(void) const {return mSpecialParents;}
|
||||
|
||||
PRBool IsMemberOf(PRInt32 aType) const;
|
||||
PRBool ContainsSet(PRInt32 aType) const;
|
||||
PRBool CanContainType(PRInt32 aType) const;
|
||||
|
||||
eHTMLTags GetTag(void) const {return mTagID;}
|
||||
|
|
|
@ -343,69 +343,74 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) {
|
|||
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity);
|
||||
PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity);
|
||||
|
||||
if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) {
|
||||
PRBool theTagIsContainer=nsHTMLElement::IsContainer(theTag); //bug54117...
|
||||
|
||||
switch(theType) {
|
||||
if(theTagIsContainer) {
|
||||
PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity);
|
||||
PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity);
|
||||
|
||||
case eToken_start:
|
||||
if(0==theStack.GetSize()) {
|
||||
//track the tag on the top of the stack...
|
||||
theRootToken=theToken;
|
||||
theRootTag=theTag;
|
||||
}
|
||||
theStack.Push(theToken);
|
||||
theStackDepth++;
|
||||
break;
|
||||
if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) {
|
||||
|
||||
case eToken_end:
|
||||
{
|
||||
CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
if(theLastToken) {
|
||||
if(theTag==theLastToken->GetTypeID()) {
|
||||
theStack.Pop(); //yank it for real
|
||||
theStackDepth--;
|
||||
theLastToken->SetContainerInfo(eWellFormed);
|
||||
switch(theType) {
|
||||
|
||||
//in addition, let's look above this container to see if we can find
|
||||
//any tags that are already marked malformed. If so, pop them too!
|
||||
case eToken_start:
|
||||
if(0==theStack.GetSize()) {
|
||||
//track the tag on the top of the stack...
|
||||
theRootToken=theToken;
|
||||
theRootTag=theTag;
|
||||
}
|
||||
theStack.Push(theToken);
|
||||
theStackDepth++;
|
||||
break;
|
||||
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
while(theLastToken) {
|
||||
if(eMalformed==theRootToken->GetContainerInfo()) {
|
||||
theStack.Pop(); //yank the malformed token for real.
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
continue;
|
||||
case eToken_end:
|
||||
{
|
||||
CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
if(theLastToken) {
|
||||
if(theTag==theLastToken->GetTypeID()) {
|
||||
theStack.Pop(); //yank it for real
|
||||
theStackDepth--;
|
||||
theLastToken->SetContainerInfo(eWellFormed);
|
||||
|
||||
//in addition, let's look above this container to see if we can find
|
||||
//any tags that are already marked malformed. If so, pop them too!
|
||||
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
while(theLastToken) {
|
||||
if(eMalformed==theRootToken->GetContainerInfo()) {
|
||||
theStack.Pop(); //yank the malformed token for real.
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//the topmost token isn't what we expected, so that container must
|
||||
//be malformed. If the tag is a block, we don't really care (but we'll
|
||||
//mark it anyway). If it's an inline we DO care, especially if the
|
||||
//inline tried to contain a block (that's when RS handling kicks in).
|
||||
if(theTagIsInline) {
|
||||
PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack);
|
||||
if(kNotFound!=theIndex) {
|
||||
theToken=(CHTMLToken*)theStack.ObjectAt(theIndex);
|
||||
theToken->SetContainerInfo(eMalformed);
|
||||
}
|
||||
//otherwise we ignore an out-of-place end tag.
|
||||
}
|
||||
else {
|
||||
//the topmost token isn't what we expected, so that container must
|
||||
//be malformed. If the tag is a block, we don't really care (but we'll
|
||||
//mark it anyway). If it's an inline we DO care, especially if the
|
||||
//inline tried to contain a block (that's when RS handling kicks in).
|
||||
if(theTagIsInline) {
|
||||
PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack);
|
||||
if(kNotFound!=theIndex) {
|
||||
theToken=(CHTMLToken*)theStack.ObjectAt(theIndex);
|
||||
theToken->SetContainerInfo(eMalformed);
|
||||
}
|
||||
//otherwise we ignore an out-of-place end tag.
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
theToken=(CHTMLToken*)mTokenDeque.ObjectAt(++mTokenScanPos);
|
||||
|
|
|
@ -997,9 +997,13 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
|
|||
nsresult result=PR_TRUE;
|
||||
|
||||
switch(aMode) {
|
||||
|
||||
#if 0 //set to 1 if you want strict comments... bug 53011...
|
||||
case eDTDMode_strict:
|
||||
result=ConsumeStrictComment(aChar,aScanner,mTextValue);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case eDTDMode_transitional:
|
||||
default:
|
||||
result=ConsumeComment(aChar,aScanner,mTextValue);
|
||||
|
|
|
@ -73,7 +73,11 @@
|
|||
{ 0xa6cf9051, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
|
||||
|
||||
#define MAX_REFLOW_DEPTH 200
|
||||
#ifdef XP_MAC
|
||||
#define MAX_REFLOW_DEPTH 75 //setting to 75 to prevent layout from crashing on mac. Bug 55095.
|
||||
#else
|
||||
#define MAX_REFLOW_DEPTH 200 //windows and linux (etc) can do much deeper structures.
|
||||
#endif
|
||||
|
||||
|
||||
class nsIHTMLContentSink : public nsIContentSink {
|
||||
|
|
Загрузка…
Ссылка в новой задаче