зеркало из https://github.com/mozilla/pjs.git
bug 285250: Give tags the ability to request to be either in the head OR the body. They follow the same rules that userdefined, whitespace, and newline tags used to follow. r=bzbarsky sr=jst
This commit is contained in:
Родитель
084ea02a2f
Коммит
528ae19538
|
@ -476,10 +476,12 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
|||
// NS_ERROR_HTMLPARSER_INTERRUPTED.
|
||||
// If the parser has mPrevContext then it may be processing
|
||||
// Script so we should not allow it to be interrupted.
|
||||
|
||||
// We also need to make sure that an interruption does not override
|
||||
// a request to block the parser.
|
||||
if ((mParser->CanInterrupt()) &&
|
||||
(nsnull == mParser->PeekContext()->mPrevContext) &&
|
||||
(eHTMLTag_unknown==mSkipTarget)) {
|
||||
(eHTMLTag_unknown==mSkipTarget) &&
|
||||
NS_SUCCEEDED(result)) {
|
||||
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
|
||||
break;
|
||||
}
|
||||
|
@ -837,15 +839,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
case eHTMLTag_doctypeDecl:
|
||||
case eHTMLTag_instruction:
|
||||
break;
|
||||
case eHTMLTag_comment:
|
||||
case eHTMLTag_newline:
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_userdefined:
|
||||
if (mMisplacedContent.GetSize() == 0) {
|
||||
// simply pass these through to token handler without further ado...
|
||||
// fix for bugs 17017,18308,23765,24275,69331
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if(!gHTMLElements[eHTMLTag_html].SectionContains(theTag,PR_FALSE)) {
|
||||
if(!(mFlags & (NS_DTD_FLAG_HAD_BODY |
|
||||
|
@ -853,13 +847,25 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
NS_DTD_FLAG_ALTERNATE_CONTENT))) {
|
||||
|
||||
//For bug examples from this code, see bugs: 18928, 20989.
|
||||
|
||||
//At this point we know the body/frameset aren't open.
|
||||
//If the child belongs in the head, then handle it (which may open the head);
|
||||
//otherwise, push it onto the misplaced stack.
|
||||
|
||||
PRBool theExclusive=PR_FALSE;
|
||||
PRBool theChildBelongsInHead=gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag,theExclusive);
|
||||
PRBool isExclusive=PR_FALSE;
|
||||
PRBool theChildBelongsInHead=gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag,isExclusive);
|
||||
if(theChildBelongsInHead && !isExclusive) {
|
||||
if (mMisplacedContent.GetSize() == 0) {
|
||||
// This tag can either be in the body or the head. Since
|
||||
// there is no indication that the body should be open,
|
||||
// put this token in the head.
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, we have received some indication that the body is
|
||||
// "open", so push this token onto the misplaced content stack.
|
||||
theChildBelongsInHead = PR_FALSE;
|
||||
}
|
||||
|
||||
if(!theChildBelongsInHead) {
|
||||
|
||||
//If you're here then we found a child of the body that was out of place.
|
||||
|
@ -1363,18 +1369,21 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode
|
|||
result=gHTMLElements[aTag].HasSpecialProperty(kDiscardTag) ? 1 : NS_OK;
|
||||
}
|
||||
|
||||
//this code is here to make sure the head is closed before we deal
|
||||
//with any tags that don't belong in the head.
|
||||
if (NS_SUCCEEDED(result) && (mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD &&
|
||||
eHTMLTag_newline != aTag &&
|
||||
eHTMLTag_whitespace != aTag &&
|
||||
eHTMLTag_userdefined != aTag)) {
|
||||
PRBool theExclusive = PR_FALSE;
|
||||
if (!gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag, theExclusive)) {
|
||||
result = CloseHead();
|
||||
}
|
||||
// This code is here to make sure the head is closed before we deal
|
||||
// with any tags that don't belong in the head. If the tag is not exclusive
|
||||
// then we do not have enough information, and we have to trust the logic
|
||||
// in HandleToken() to not hand us non-exclusive tokens
|
||||
PRBool isExclusive = PR_FALSE;
|
||||
PRBool isChildOfHead =
|
||||
gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag, isExclusive);
|
||||
|
||||
if (NS_SUCCEEDED(result) && ((mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD) &&
|
||||
isExclusive &&
|
||||
!isChildOfHead)) {
|
||||
result = CloseHead();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1596,8 +1605,8 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
}
|
||||
}
|
||||
|
||||
PRBool theExclusive=PR_FALSE;
|
||||
theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag,theExclusive);
|
||||
PRBool isExclusive=PR_FALSE;
|
||||
theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag,isExclusive);
|
||||
|
||||
switch(theChildTag) {
|
||||
case eHTMLTag_area:
|
||||
|
@ -1625,7 +1634,10 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
theHeadIsParent = !(mFlags & NS_DTD_FLAG_HAS_OPEN_BODY);
|
||||
// Script isn't really exclusively in the head. However, we treat it
|
||||
// as such to make sure that we don't pull scripts outside the head
|
||||
// into the body.
|
||||
isExclusive = !(mFlags & NS_DTD_FLAG_HAD_BODY);
|
||||
mFlags |= NS_DTD_FLAG_HAS_OPEN_SCRIPT;
|
||||
|
||||
default:
|
||||
|
@ -1633,14 +1645,14 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
}//switch
|
||||
|
||||
if(!isTokenHandled) {
|
||||
if(theHeadIsParent || ((mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD) &&
|
||||
(eHTMLTag_newline == theChildTag ||
|
||||
eHTMLTag_whitespace == theChildTag ||
|
||||
eHTMLTag_userdefined == theChildTag))) {
|
||||
result = AddHeadLeaf(theNode);
|
||||
if(theHeadIsParent &&
|
||||
(isExclusive || (mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD))) {
|
||||
// These tokens prefer to be in the head.
|
||||
result = AddHeadLeaf(theNode);
|
||||
}
|
||||
else
|
||||
else {
|
||||
result = HandleDefaultStartToken(aToken,theChildTag,theNode);
|
||||
}
|
||||
}
|
||||
|
||||
//now do any post processing necessary on the tag...
|
||||
|
|
|
@ -113,7 +113,6 @@ DECL_TAG_LIST(gFormKids,{eHTMLTag_keygen})
|
|||
DECL_TAG_LIST(gFramesetKids,{eHTMLTag_frame COMMA eHTMLTag_frameset COMMA eHTMLTag_noframes})
|
||||
|
||||
DECL_TAG_LIST(gHtmlKids,{eHTMLTag_body COMMA eHTMLTag_frameset COMMA eHTMLTag_head COMMA eHTMLTag_map COMMA eHTMLTag_noscript COMMA eHTMLTag_noframes COMMA eHTMLTag_script COMMA eHTMLTag_newline COMMA eHTMLTag_whitespace})
|
||||
DECL_TAG_LIST(gHeadKids,{eHTMLTag_base COMMA eHTMLTag_bgsound COMMA eHTMLTag_link COMMA eHTMLTag_meta COMMA eHTMLTag_script COMMA eHTMLTag_style COMMA eHTMLTag_title COMMA eHTMLTag_noembed})
|
||||
|
||||
DECL_TAG_LIST(gLabelKids,{eHTMLTag_span})
|
||||
DECL_TAG_LIST(gLIKids,{eHTMLTag_ol COMMA eHTMLTag_ul})
|
||||
|
@ -316,7 +315,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInHead, &gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kNone, kNone, kNone,
|
||||
/*parent,incl,exclgroups*/ kHeadContent, kNone, kNone,
|
||||
/*special props, prop-range*/ kNonContainer, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -652,7 +651,7 @@ void InitializeElementTable(void) {
|
|||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHTMLContent, (kHeadContent|kHeadMisc), kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn, kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ &gInHTML,&gHeadKids,eHTMLTag_unknown);
|
||||
/*special parents,kids,skip*/ &gInHTML,0,eHTMLTag_unknown);
|
||||
|
||||
Initialize(
|
||||
/*tag*/ eHTMLTag_hr,
|
||||
|
@ -731,7 +730,7 @@ void InitializeElementTable(void) {
|
|||
/*requiredAncestor*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ (kBlock|kHeadContent), kFlowEntity, kNone,
|
||||
/*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone,
|
||||
/*special props, prop-range*/ kNonContainer,kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ &gInBody,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -787,7 +786,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInHead,&gInHead,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadMisc, kNone, kNone,
|
||||
/*parent,incl,exclgroups*/ kHeadContent, kNone, kNone,
|
||||
/*special props, prop-range*/ kNonContainer,kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -832,7 +831,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInHead, &gInHead,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadMisc, kNone, kNone,
|
||||
/*parent,incl,exclgroups*/ kHeadContent, kNone, kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn|kNonContainer, kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -976,7 +975,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ (kSpecial|kHeadMisc), kCDATA, kNone,
|
||||
/*parent,incl,exclgroups*/ (kSpecial|kHeadContent), kCDATA, kNone, // note: this is kHeadContent since shipping this breaks things.
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn|kLegalOpen, kNoPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gContainsText,eHTMLTag_script);
|
||||
|
||||
|
@ -1013,7 +1012,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ (kFlowEntity|kHeadContent), kNone, kNone, // Added kFlowEntity|kHeadContent & kNonContainer in
|
||||
/*parent,incl,exclgroups*/ (kFlowEntity|kHeadMisc), kNone, kNone, // Added kFlowEntity|kHeadMisc & kNonContainer in
|
||||
/*special props, prop-range*/ kNonContainer,kDefaultPropRange, // Ref. to Bug 25749
|
||||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -1066,7 +1065,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInHead, &gInHead,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadMisc, kCDATA, kNone,
|
||||
/*parent,incl,exclgroups*/ kHeadContent, kCDATA, kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn|kNonContainer, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_style);
|
||||
|
||||
|
@ -1157,7 +1156,7 @@ void InitializeElementTable(void) {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInHead,&gInHead,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadMisc,kPCDATA, kNone,
|
||||
/*parent,incl,exclgroups*/ kHeadContent,kPCDATA, kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,&gContainsText,eHTMLTag_title);
|
||||
|
||||
|
@ -1234,6 +1233,10 @@ void InitializeElementTable(void) {
|
|||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
Initialize(
|
||||
// Whitespace must have a parent model of kHeadMisc to ensure that we
|
||||
// do the right thing for whitespace in the head section of a document.
|
||||
// (i.e., it must be non-exclusively a child of the head).
|
||||
|
||||
/*tag*/ eHTMLTag_whitespace,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInBody,&gInBody,
|
||||
|
@ -1243,6 +1246,10 @@ void InitializeElementTable(void) {
|
|||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
Initialize(
|
||||
// Newlines must have a parent model of kHeadMisc to ensure that we
|
||||
// do the right thing for whitespace in the head section of a document.
|
||||
// (i.e., it must be non-exclusively a child of the head).
|
||||
|
||||
/*tag*/ eHTMLTag_newline,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gInBody,&gInBody,
|
||||
|
@ -1252,11 +1259,15 @@ void InitializeElementTable(void) {
|
|||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
Initialize(
|
||||
// Comments must have a parent model of kHeadMisc to ensure that we
|
||||
// do the right thing for whitespace in the head section of a document
|
||||
// (i.e., it must be non-exclusively a child of the head).
|
||||
|
||||
/*tag*/ eHTMLTag_comment,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kFlowEntity, kNone, kNone,
|
||||
/*parent,incl,exclgroups*/ kFlowEntity|kHeadMisc, kNone, kNone,
|
||||
/*special props, prop-range*/ kOmitEndTag|kLegalOpen,kNoPropRange,
|
||||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
|
@ -1297,11 +1308,15 @@ void InitializeElementTable(void) {
|
|||
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
|
||||
|
||||
Initialize(
|
||||
// Userdefined tags must have a parent model of kHeadMisc to ensure that
|
||||
// we do the right thing for whitespace in the head section of a document.
|
||||
// (i.e., it must be non-exclusively a child of the head).
|
||||
|
||||
/*tag*/ eHTMLTag_userdefined,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_frameset,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ &gBodyAutoClose,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kFlowEntity, (kInlineEntity|kSelf), kNone, // Treat userdefined as inline element - Ref bug 56245,66772
|
||||
/*parent,incl,exclgroups*/ (kFlowEntity|kHeadMisc), (kInlineEntity|kSelf), kNone, // Treat userdefined as inline element - Ref bug 56245,66772
|
||||
/*special props, prop-range*/ kNone, kBodyPropRange,
|
||||
/*special parents,kids,skip*/ &gInNoframes,&gBodyKids,eHTMLTag_unknown);
|
||||
}//if
|
||||
|
@ -1758,45 +1773,31 @@ PRBool nsHTMLElement::CanOmitStartTag(eHTMLTags aChild) const{
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/13/98
|
||||
* @param
|
||||
* @return
|
||||
* Returns whether a given tag can be a direct child of the <head> node of
|
||||
* an HTML document.
|
||||
*
|
||||
* @param aChild The tag in question.
|
||||
* @param aExclusively [out]Whether or not this tag can *only* appear in the
|
||||
* head (as opposed to things like <object> which can be
|
||||
either in the body or the head).
|
||||
* @return Whether this tag can appear in the head.
|
||||
*/
|
||||
PRBool nsHTMLElement::IsChildOfHead(eHTMLTags aChild,PRBool& aExclusively) {
|
||||
#if 0
|
||||
PRBool result=PR_FALSE;
|
||||
aExclusively = PR_TRUE;
|
||||
|
||||
aExclusively=PR_FALSE;
|
||||
|
||||
switch(aChild) {
|
||||
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_title:
|
||||
case eHTMLTag_style:
|
||||
aExclusively=result=PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_bgsound:
|
||||
case eHTMLTag_script:
|
||||
case eHTMLTag_noembed:
|
||||
case eHTMLTag_noscript:
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_newline:
|
||||
case eHTMLTag_comment:
|
||||
result=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
// Is this a head-only tag?
|
||||
if (gHTMLElements[aChild].mParentBits & kHeadContent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
aExclusively=PR_TRUE;
|
||||
return FindTagInSet(aChild,gHeadKids.mTags,gHeadKids.mCount);
|
||||
#endif
|
||||
|
||||
|
||||
// If not, check if it can appear in the head.
|
||||
if (gHTMLElements[aChild].mParentBits & kHeadMisc) {
|
||||
aExclusively = PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@
|
|||
static const int kNone= 0x0;
|
||||
|
||||
static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY)
|
||||
static const int kHeadContent = 0x0002; // TITLE, ISINDEX, BASE
|
||||
static const int kHeadMisc = 0x0004; // SCRIPT, STYLE, META, LINK, OBJECT
|
||||
static const int kHeadContent = 0x0002; // Elements that *must* be in the head.
|
||||
static const int kHeadMisc = 0x0004; // Elements that *can* be in the head.
|
||||
|
||||
static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT,
|
||||
// MAP, Q, SUB, SUP, SPAN, BDO, IFRAME
|
||||
|
|
Загрузка…
Ссылка в новой задаче