mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
45975 - Make sure that the head context gets closed before opening up the body.
44285 - Propagate the block message to the parser correctly. 45555 - Pass the node that contains the skipped content to the sink. 46392 - Error message got lost 43481 - P cannot contain P per spec. 44759 - Handling multiple BODYs correctly. 45228, 44758 - Translate entities in TEXTAREA and TITLE before handing the string to the sink r=pollmann
This commit is contained in:
parent
300a4cad60
commit
5f61cc15f5
@ -325,15 +325,16 @@ public:
|
||||
this gets called to close a tag in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsEntryStack *theStack=0;
|
||||
nsIParserNode *theNode=aContext->Pop(theStack);
|
||||
|
||||
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
|
||||
theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
|
||||
aContext->RecycleNode((nsCParserNode*)theNode);
|
||||
|
||||
return NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
@ -1201,11 +1202,35 @@ public:
|
||||
anElement.mIncludeKids=kHeadKids;
|
||||
}
|
||||
|
||||
virtual nsresult OpenContext(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"cannot make a decision without a context");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_FALSE) {
|
||||
result=aSink->OpenHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual nsresult CloseContext(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"cannot make a decision without a context");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_TRUE) {
|
||||
result=aSink->CloseHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_FALSE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CHeadElement(eHTMLTags aTag) : CElement(aTag) {
|
||||
CHeadElement::Initialize(*this,aTag);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1266,8 +1291,8 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_whitespace:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
default:
|
||||
@ -1304,10 +1329,17 @@ public:
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
aSink->OpenHead(*aNode);
|
||||
aSink->SetTitle(mText);
|
||||
aSink->CloseHead(*aNode);
|
||||
mText.Truncate(0);
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->SetTitle(mText);
|
||||
mText.Truncate(0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1318,8 +1350,14 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
if(aNode && aNode->GetTokenType()==eToken_entity) {
|
||||
nsAutoString tmp;
|
||||
aNode->TranslateToUnicodeStr(tmp);
|
||||
mText.Append(tmp);
|
||||
break;
|
||||
}
|
||||
case eHTMLTag_whitespace:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
default:
|
||||
@ -1347,8 +1385,14 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_text:
|
||||
if(aNode && aNode->GetTokenType()==eToken_entity) {
|
||||
nsAutoString tmp;
|
||||
aNode->TranslateToUnicodeStr(tmp);
|
||||
mText.Append(tmp);
|
||||
break;
|
||||
}
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_newline:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
@ -1380,10 +1424,18 @@ public:
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
aSink->OpenHead(*aNode);
|
||||
nsresult result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
aSink->CloseHead(*aNode);
|
||||
mText.Truncate(0);
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
mText.Truncate(0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1436,19 +1488,20 @@ public:
|
||||
|
||||
if(aContext->HasOpenContainer(eHTMLTag_body)) {
|
||||
//add the script to the body
|
||||
CScriptToken theToken(mText);
|
||||
PRInt32 theLineNumber=0;
|
||||
nsCParserNode theNode(&theToken,theLineNumber);
|
||||
theNode.SetSkippedContent(mText);
|
||||
//result=aSink->AddLeaf(theNode);
|
||||
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
else {
|
||||
//add it to the head...
|
||||
aSink->OpenHead(*aNode);
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
aSink->CloseHead(*aNode);
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mText.Truncate(0);
|
||||
return result;
|
||||
@ -1492,7 +1545,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************
|
||||
This is used for both applet and object elements
|
||||
**********************************************************/
|
||||
@ -1752,12 +1804,6 @@ public:
|
||||
result=HandleDoctypeDecl(aNode,aTag,aContext,aSink);
|
||||
break;
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=aSink->OpenBody(*aNode);
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadBody=PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=aSink->OpenFrameset(*aNode);
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
@ -1768,14 +1814,30 @@ public:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_meta:
|
||||
aSink->OpenHead(*aNode);
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
aSink->CloseHead(*aNode);
|
||||
{
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_object:
|
||||
aSink->OpenHead(*aNode);
|
||||
result=OpenContainerInContext(aNode,aTag,aContext,aSink);
|
||||
{
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=OpenContainerInContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
@ -1800,7 +1862,7 @@ public:
|
||||
CToken* theToken=new CStartToken(eHTMLTag_body);
|
||||
nsCParserNode* theNode=new nsCParserNode(theToken,0,0);
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(eHTMLTag_body==aContext->Last()) {
|
||||
@ -1892,12 +1954,35 @@ public:
|
||||
virtual nsresult OpenContainer(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag==aTag) {
|
||||
result=aSink->OpenBody(*aNode);
|
||||
// Close the head before opening a body.
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->OpenBody(*aNode);
|
||||
}
|
||||
}
|
||||
else result=CElement::OpenContainer(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"need a valid context");
|
||||
nsresult result=NS_OK;
|
||||
// Since BODY is optional, we might come across more than one BODY!.
|
||||
// That is, one that's auto opened and one that came from the document itself.
|
||||
// If that's the case then make sure that we don't open up multiple contexts, however,
|
||||
// don't forget to inform the sink because it needs to account for the BODY attributes.
|
||||
if(aContext) {
|
||||
if(!aContext->mHadBody) {
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadBody=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return (NS_SUCCEEDED(result))? OpenContainer(aNode,aTag,aContext,aSink):result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
Body handles the opening of it's own children
|
||||
@ -1979,7 +2064,8 @@ public:
|
||||
mObjectElement(eHTMLTag_object),
|
||||
mFieldsetElement(),
|
||||
mCounterElement(),
|
||||
mFormElement()
|
||||
mFormElement(),
|
||||
mHeadElement(eHTMLTag_head)
|
||||
{
|
||||
memset(mElements,0,sizeof(mElements));
|
||||
InitializeElements();
|
||||
@ -2026,6 +2112,7 @@ public:
|
||||
CFieldsetElement mFieldsetElement;
|
||||
CCounterElement mCounterElement;
|
||||
CFormElement mFormElement;
|
||||
CHeadElement mHeadElement;
|
||||
};
|
||||
|
||||
|
||||
@ -2236,6 +2323,8 @@ void CElementTable::InitializeElements() {
|
||||
mDfltElements[eHTMLTag_option].mContainsGroups.mBits.mLeaf=1;
|
||||
|
||||
CElement::Initialize( mDfltElements[eHTMLTag_p], eHTMLTag_p, CBlockElement::GetGroup(), CInlineElement::GetContainedGroups());
|
||||
mDfltElements[eHTMLTag_p].mContainsGroups.mBits.mSelf=0;
|
||||
|
||||
CElement::InitializeLeaf( mDfltElements[eHTMLTag_param], eHTMLTag_param, CElement::GetEmptyGroup(), CLeafElement::GetContainedGroups());
|
||||
CBlockElement::Initialize( mDfltElements[eHTMLTag_parsererror],eHTMLTag_parsererror);
|
||||
CElement::Initialize( mDfltElements[eHTMLTag_plaintext], eHTMLTag_plaintext);
|
||||
@ -2329,6 +2418,7 @@ void CElementTable::InitializeElements() {
|
||||
mElements[eHTMLTag_fieldset]=&mFieldsetElement;
|
||||
mElements[eHTMLTag_counter]=&mCounterElement;
|
||||
mElements[eHTMLTag_form]=&mFormElement;
|
||||
mElements[eHTMLTag_head]=&mHeadElement;
|
||||
}
|
||||
|
||||
void CElementTable::DebugDumpGroups(CElement* aTag){
|
||||
@ -2737,9 +2827,9 @@ nsresult CElement::HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDConte
|
||||
CElement* theElement=gElementTable->mElements[aTag];
|
||||
if(theElement) {
|
||||
if(theElement->IsSinkContainer()) {
|
||||
CloseContainerInContext(aNode,aTag,aContext,aSink);
|
||||
result=CloseContainerInContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
else CloseContext(aNode,aTag,aContext,aSink);
|
||||
else result=CloseContext(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +376,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
|
||||
mTransitional=PR_FALSE;
|
||||
ResetCounters();
|
||||
mHadDocTypeDecl=PR_FALSE;
|
||||
mHasOpenHead=PR_FALSE;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
memset(mXTags,0,sizeof(mXTags));
|
||||
|
@ -305,6 +305,7 @@ public:
|
||||
PRInt32 mContextTopIndex;
|
||||
PRBool mHadBody;
|
||||
PRBool mHadFrameset;
|
||||
PRBool mHasOpenHead;
|
||||
PRBool mTransitional;
|
||||
PRBool mHadDocTypeDecl;
|
||||
|
||||
|
@ -325,15 +325,16 @@ public:
|
||||
this gets called to close a tag in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsEntryStack *theStack=0;
|
||||
nsIParserNode *theNode=aContext->Pop(theStack);
|
||||
|
||||
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
|
||||
theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
|
||||
aContext->RecycleNode((nsCParserNode*)theNode);
|
||||
|
||||
return NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
@ -1201,11 +1202,35 @@ public:
|
||||
anElement.mIncludeKids=kHeadKids;
|
||||
}
|
||||
|
||||
virtual nsresult OpenContext(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"cannot make a decision without a context");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_FALSE) {
|
||||
result=aSink->OpenHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual nsresult CloseContext(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"cannot make a decision without a context");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_TRUE) {
|
||||
result=aSink->CloseHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_FALSE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CHeadElement(eHTMLTags aTag) : CElement(aTag) {
|
||||
CHeadElement::Initialize(*this,aTag);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1266,8 +1291,8 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_whitespace:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
default:
|
||||
@ -1304,10 +1329,17 @@ public:
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
aSink->OpenHead(*aNode);
|
||||
aSink->SetTitle(mText);
|
||||
aSink->CloseHead(*aNode);
|
||||
mText.Truncate(0);
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->SetTitle(mText);
|
||||
mText.Truncate(0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1318,8 +1350,14 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
if(aNode && aNode->GetTokenType()==eToken_entity) {
|
||||
nsAutoString tmp;
|
||||
aNode->TranslateToUnicodeStr(tmp);
|
||||
mText.Append(tmp);
|
||||
break;
|
||||
}
|
||||
case eHTMLTag_whitespace:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
default:
|
||||
@ -1347,8 +1385,14 @@ public:
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
case eHTMLTag_text:
|
||||
if(aNode && aNode->GetTokenType()==eToken_entity) {
|
||||
nsAutoString tmp;
|
||||
aNode->TranslateToUnicodeStr(tmp);
|
||||
mText.Append(tmp);
|
||||
break;
|
||||
}
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_newline:
|
||||
mText.Append(aNode->GetText());
|
||||
break;
|
||||
@ -1380,10 +1424,18 @@ public:
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
aSink->OpenHead(*aNode);
|
||||
nsresult result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
aSink->CloseHead(*aNode);
|
||||
mText.Truncate(0);
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
mText.Truncate(0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1436,19 +1488,20 @@ public:
|
||||
|
||||
if(aContext->HasOpenContainer(eHTMLTag_body)) {
|
||||
//add the script to the body
|
||||
CScriptToken theToken(mText);
|
||||
PRInt32 theLineNumber=0;
|
||||
nsCParserNode theNode(&theToken,theLineNumber);
|
||||
theNode.SetSkippedContent(mText);
|
||||
//result=aSink->AddLeaf(theNode);
|
||||
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
else {
|
||||
//add it to the head...
|
||||
aSink->OpenHead(*aNode);
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
aSink->CloseHead(*aNode);
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=CTextContainer::NotifyClose(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mText.Truncate(0);
|
||||
return result;
|
||||
@ -1492,7 +1545,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************
|
||||
This is used for both applet and object elements
|
||||
**********************************************************/
|
||||
@ -1752,12 +1804,6 @@ public:
|
||||
result=HandleDoctypeDecl(aNode,aTag,aContext,aSink);
|
||||
break;
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=aSink->OpenBody(*aNode);
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadBody=PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=aSink->OpenFrameset(*aNode);
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
@ -1768,14 +1814,30 @@ public:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_meta:
|
||||
aSink->OpenHead(*aNode);
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
aSink->CloseHead(*aNode);
|
||||
{
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->AddLeaf(*aNode);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_object:
|
||||
aSink->OpenHead(*aNode);
|
||||
result=OpenContainerInContext(aNode,aTag,aContext,aSink);
|
||||
{
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
result=theHead->OpenContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=OpenContainerInContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
@ -1800,7 +1862,7 @@ public:
|
||||
CToken* theToken=new CStartToken(eHTMLTag_body);
|
||||
nsCParserNode* theNode=new nsCParserNode(theToken,0,0);
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(eHTMLTag_body==aContext->Last()) {
|
||||
@ -1892,12 +1954,35 @@ public:
|
||||
virtual nsresult OpenContainer(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag==aTag) {
|
||||
result=aSink->OpenBody(*aNode);
|
||||
// Close the head before opening a body.
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
result=theHead->CloseContext(aNode,aTag,aContext,aSink);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
result=aSink->OpenBody(*aNode);
|
||||
}
|
||||
}
|
||||
else result=CElement::OpenContainer(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"need a valid context");
|
||||
nsresult result=NS_OK;
|
||||
// Since BODY is optional, we might come across more than one BODY!.
|
||||
// That is, one that's auto opened and one that came from the document itself.
|
||||
// If that's the case then make sure that we don't open up multiple contexts, however,
|
||||
// don't forget to inform the sink because it needs to account for the BODY attributes.
|
||||
if(aContext) {
|
||||
if(!aContext->mHadBody) {
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadBody=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return (NS_SUCCEEDED(result))? OpenContainer(aNode,aTag,aContext,aSink):result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
Body handles the opening of it's own children
|
||||
@ -1979,7 +2064,8 @@ public:
|
||||
mObjectElement(eHTMLTag_object),
|
||||
mFieldsetElement(),
|
||||
mCounterElement(),
|
||||
mFormElement()
|
||||
mFormElement(),
|
||||
mHeadElement(eHTMLTag_head)
|
||||
{
|
||||
memset(mElements,0,sizeof(mElements));
|
||||
InitializeElements();
|
||||
@ -2026,6 +2112,7 @@ public:
|
||||
CFieldsetElement mFieldsetElement;
|
||||
CCounterElement mCounterElement;
|
||||
CFormElement mFormElement;
|
||||
CHeadElement mHeadElement;
|
||||
};
|
||||
|
||||
|
||||
@ -2236,6 +2323,8 @@ void CElementTable::InitializeElements() {
|
||||
mDfltElements[eHTMLTag_option].mContainsGroups.mBits.mLeaf=1;
|
||||
|
||||
CElement::Initialize( mDfltElements[eHTMLTag_p], eHTMLTag_p, CBlockElement::GetGroup(), CInlineElement::GetContainedGroups());
|
||||
mDfltElements[eHTMLTag_p].mContainsGroups.mBits.mSelf=0;
|
||||
|
||||
CElement::InitializeLeaf( mDfltElements[eHTMLTag_param], eHTMLTag_param, CElement::GetEmptyGroup(), CLeafElement::GetContainedGroups());
|
||||
CBlockElement::Initialize( mDfltElements[eHTMLTag_parsererror],eHTMLTag_parsererror);
|
||||
CElement::Initialize( mDfltElements[eHTMLTag_plaintext], eHTMLTag_plaintext);
|
||||
@ -2329,6 +2418,7 @@ void CElementTable::InitializeElements() {
|
||||
mElements[eHTMLTag_fieldset]=&mFieldsetElement;
|
||||
mElements[eHTMLTag_counter]=&mCounterElement;
|
||||
mElements[eHTMLTag_form]=&mFormElement;
|
||||
mElements[eHTMLTag_head]=&mHeadElement;
|
||||
}
|
||||
|
||||
void CElementTable::DebugDumpGroups(CElement* aTag){
|
||||
@ -2737,9 +2827,9 @@ nsresult CElement::HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDConte
|
||||
CElement* theElement=gElementTable->mElements[aTag];
|
||||
if(theElement) {
|
||||
if(theElement->IsSinkContainer()) {
|
||||
CloseContainerInContext(aNode,aTag,aContext,aSink);
|
||||
result=CloseContainerInContext(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
else CloseContext(aNode,aTag,aContext,aSink);
|
||||
else result=CloseContext(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +376,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
|
||||
mTransitional=PR_FALSE;
|
||||
ResetCounters();
|
||||
mHadDocTypeDecl=PR_FALSE;
|
||||
mHasOpenHead=PR_FALSE;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
memset(mXTags,0,sizeof(mXTags));
|
||||
|
@ -305,6 +305,7 @@ public:
|
||||
PRInt32 mContextTopIndex;
|
||||
PRBool mHadBody;
|
||||
PRBool mHadFrameset;
|
||||
PRBool mHasOpenHead;
|
||||
PRBool mTransitional;
|
||||
PRBool mHadDocTypeDecl;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user