diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index 71d345202df..faf2439c6c6 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -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... diff --git a/mozilla/parser/htmlparser/src/nsElementTable.cpp b/mozilla/parser/htmlparser/src/nsElementTable.cpp index 5ad47f1f910..de62a67bb96 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.cpp +++ b/mozilla/parser/htmlparser/src/nsElementTable.cpp @@ -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
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