diff --git a/htmlparser/robot/nsRobotSink.cpp b/htmlparser/robot/nsRobotSink.cpp index 0f36da569bbb..0ebf4280ef19 100644 --- a/htmlparser/robot/nsRobotSink.cpp +++ b/htmlparser/robot/nsRobotSink.cpp @@ -70,6 +70,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode){ return NS_OK; } NS_IMETHOD OpenContainer(const nsIParserNode& aNode); NS_IMETHOD CloseContainer(const nsIParserNode& aNode); NS_IMETHOD NotifyError(const nsParserError* aError); diff --git a/htmlparser/src/CNavDTD.cpp b/htmlparser/src/CNavDTD.cpp index 67b1f3efb67b..cc2abd61e0a9 100644 --- a/htmlparser/src/CNavDTD.cpp +++ b/htmlparser/src/CNavDTD.cpp @@ -686,10 +686,11 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ deque until we can deal with it. --------------------------------------------------------------------------------- */ - if(!execSkipContent) { + if(!execSkipContent && mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { switch(theTag) { case eHTMLTag_html: + case eHTMLTag_noscript: case eHTMLTag_script: case eHTMLTag_markupDecl: break; // simply pass these through to token handler without further ado... @@ -1174,7 +1175,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode STOP_TIMER() MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this)); - if(mParser) { + if(mParser && mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { CObserverService* theService=mParser->GetObserverService(); if(theService) { @@ -1513,11 +1514,6 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { mHasOpenNoXXX++; break; - case eHTMLTag_noscript: - //mHasOpenNoXXX++; // Fix for 33397 - Enable this when we handle NOSCRIPTS. - isTokenHandled=PR_TRUE; // XXX - Throwing NOSCRIPT to the floor...yet another time.. - break; - case eHTMLTag_script: theHeadIsParent=((!mHasOpenBody) || mRequestedHead); mHasOpenScript=PR_TRUE; @@ -3084,7 +3080,76 @@ nsresult CNavDTD::CloseFrameset(const nsIParserNode *aNode){ return result; } +/** + * This method would determine how the noscript content + * should be handled. + * + * harishd 08/24/00 + * @param aNode - The noscript node + * return NS_OK if succeeded else ERROR + */ +nsresult CNavDTD::OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack) { + nsresult result=NS_OK; + if(mSink) { + STOP_TIMER(); + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenNoscript(), this=%p\n", this)); + + result=mSink->OpenNoscript(*aNode); + + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenNoscript(), this=%p\n", this)); + START_TIMER(); + + if(NS_SUCCEEDED(result)) { + if(result==NS_HTMLPARSER_ALTERNATECONTENT) { + // We're here because the sink has identified that + // JS is enabled and therefore noscript content should + // not be treated as a regular content,i.e., make sure + // that head elements are handled correctly and may be + // residual style. + mDTDState=result; + // Though NS_HTMLPARSER_ALTERNATECONTENT is a succeeded message we don't want to propagate it + // because there are lots of places where we don't check for succeeded result instead + // we check for NS_OK. Also, this message is pertinent to the DTD only + result=NS_OK; + } + mHasOpenNoXXX++; + mBodyContext->Push(aNode,aStyleStack); + } + } + + return result; +} + +/** + * Call this method to stop handling noscript content + * + * harishd 08/24/00 + * @param aNode - The noscript node + * return NS_OK if succeeded else ERROR + */ +nsresult CNavDTD::CloseNoscript(const nsIParserNode *aNode) { + nsresult result=NS_OK; + + if(mSink) { + STOP_TIMER(); + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseNoscript(), this=%p\n", this)); + + result=mSink->CloseNoscript(*aNode); + + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::CloseNoscript(), this=%p\n", this)); + START_TIMER(); + + if(NS_SUCCEEDED(result)) { + if(mHasOpenNoXXX > 0) { + mHasOpenNoXXX--; + } + mDTDState=NS_OK; // switch from alternate content state to regular state + } + } + + return result; +} /** * This method does two things: 1st, help construct @@ -3177,6 +3242,10 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB CloseHead(aNode); //do this just in case someone left it open... result=HandleScriptToken(aNode); break; + + case eHTMLTag_noscript: + result=OpenNoscript(aNode,aStyleStack); + break; default: isDefaultNode=PR_TRUE; @@ -3246,6 +3315,10 @@ CNavDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClo case eHTMLTag_frameset: result=CloseFrameset(aNode); break; + + case eHTMLTag_noscript: + result=CloseNoscript(aNode); + break; case eHTMLTag_title: default: @@ -3583,7 +3656,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ nsresult result=NS_OK; - static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_noscript}; + static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes}; eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType(); @@ -3597,42 +3670,50 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ } if(mSink) { - result=OpenHead(aNode); - if(NS_OK==result) { - if(eHTMLTag_title==theTag) { + // Alternate content => Content that shouldn't get processed + // as a regular content. That is, probably the content is + // within NOSCRIPT and since JS is enanbled we should not process + // this content. However, when JS is disabled alternate content + // would become regular content. + if(mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { + result=OpenHead(aNode); + if(NS_OK==result) { + if(eHTMLTag_title==theTag) { - const nsString& theString=aNode->GetSkippedContent(); - PRInt32 theLen=theString.Length(); - CBufDescriptor theBD(theString.GetUnicode(), PR_TRUE, theLen+1, theLen); - nsAutoString theString2(theBD); + const nsString& theString=aNode->GetSkippedContent(); + PRInt32 theLen=theString.Length(); + CBufDescriptor theBD(theString.GetUnicode(), PR_TRUE, theLen+1, theLen); + nsAutoString theString2(theBD); - theString2.CompressWhitespace(); + theString2.CompressWhitespace(); - STOP_TIMER() - MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); - mSink->SetTitle(theString2); - MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); - START_TIMER() + STOP_TIMER() + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); + mSink->SetTitle(theString2); + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); + START_TIMER() - } - else result=AddLeaf(aNode); - // XXX If the return value tells us to block, go - // ahead and close the tag out anyway, since its - // contents will be consumed. - - // Fix for Bug 31392 - // Do not leave a head context open no matter what the result is. - if(mHasOpenHead) { - nsresult rv=CloseHead(aNode); - // XXX Only send along a failure. If the close - // succeeded we still may need to indicate that the - // parser has blocked (i.e. return the result of - // the AddLeaf. - if (rv != NS_OK) { - result = rv; } - } - } + else result=AddLeaf(aNode); + // XXX If the return value tells us to block, go + // ahead and close the tag out anyway, since its + // contents will be consumed. + + // Fix for Bug 31392 + // Do not leave a head context open no matter what the result is. + if(mHasOpenHead) { + nsresult rv=CloseHead(aNode); + // XXX Only send along a failure. If the close + // succeeded we still may need to indicate that the + // parser has blocked (i.e. return the result of + // the AddLeaf. + if (rv != NS_OK) { + result = rv; + } + } + } + } + else result=AddLeaf(aNode); } return result; } diff --git a/htmlparser/src/CNavDTD.h b/htmlparser/src/CNavDTD.h index 10cd47e6a914..d525ca2b3142 100644 --- a/htmlparser/src/CNavDTD.h +++ b/htmlparser/src/CNavDTD.h @@ -429,6 +429,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { nsresult OpenForm(const nsIParserNode *aNode); nsresult OpenMap(const nsIParserNode *aNode); nsresult OpenFrameset(const nsIParserNode *aNode); + nsresult OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack=0); nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0); /** @@ -444,6 +445,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { nsresult CloseForm(const nsIParserNode *aNode); nsresult CloseMap(const nsIParserNode *aNode); nsresult CloseFrameset(const nsIParserNode *aNode); + nsresult CloseNoscript(const nsIParserNode *aNode); /** * The special purpose methods automatically close diff --git a/htmlparser/src/nsElementTable.cpp b/htmlparser/src/nsElementTable.cpp index 30b62653b2cf..cbf2d17e57a9 100644 --- a/htmlparser/src/nsElementTable.cpp +++ b/htmlparser/src/nsElementTable.cpp @@ -81,7 +81,7 @@ TagList gFormKids={1,{eHTMLTag_keygen}}; TagList gFramesetKids={3,{eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes}}; TagList gHtmlKids={9,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_noframes,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; -TagList gHeadKids={9,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript}}; +TagList gHeadKids={8,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed}}; TagList gLabelKids={1,{eHTMLTag_span}}; TagList gLIKids={2,{eHTMLTag_ol,eHTMLTag_ul}}; @@ -435,7 +435,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gRootTags, &gRootTags, /*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0, /*parent,incl,exclgroups*/ kDLChild, kFlowEntity, kNone, - /*special props, prop-range*/ kNoPropagate|kMustCloseSelf,kDefaultPropRange, + /*special props, prop-range*/ kNoPropagate|kMustCloseSelf|kVerifyHierarchy,kDefaultPropRange, /*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown); Initialize( @@ -869,7 +869,7 @@ void InitializeElementTable(void) { /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity|kSelf, kNone, /*special props, prop-range*/ 0, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_noscript); + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_object, diff --git a/htmlparser/src/nsHTMLContentSinkStream.cpp b/htmlparser/src/nsHTMLContentSinkStream.cpp index 9f0b5ece5eb7..6fae533856ae 100644 --- a/htmlparser/src/nsHTMLContentSinkStream.cpp +++ b/htmlparser/src/nsHTMLContentSinkStream.cpp @@ -578,6 +578,8 @@ USE_GENERAL_OPEN_METHOD(OpenMap, eHTMLTag_map) USE_GENERAL_CLOSE_METHOD(CloseMap, eHTMLTag_map) USE_GENERAL_OPEN_METHOD(OpenFrameset, eHTMLTag_frameset) USE_GENERAL_CLOSE_METHOD(CloseFrameset, eHTMLTag_frameset) +USE_GENERAL_OPEN_METHOD(OpenNoscript, eHTMLTag_noscript) +USE_GENERAL_CLOSE_METHOD(CloseNoscript, eHTMLTag_noscript) /** * diff --git a/htmlparser/src/nsHTMLContentSinkStream.h b/htmlparser/src/nsHTMLContentSinkStream.h index 9cca0caa7a37..f39cecc8f5af 100644 --- a/htmlparser/src/nsHTMLContentSinkStream.h +++ b/htmlparser/src/nsHTMLContentSinkStream.h @@ -138,6 +138,8 @@ class nsHTMLContentSinkStream : public nsIHTMLContentSinkStream NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) ; + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode); NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/htmlparser/src/nsHTMLNullSink.cpp b/htmlparser/src/nsHTMLNullSink.cpp index 6b4ad449e556..17c0c3d99845 100644 --- a/htmlparser/src/nsHTMLNullSink.cpp +++ b/htmlparser/src/nsHTMLNullSink.cpp @@ -69,6 +69,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode){ return NS_OK; } NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); diff --git a/htmlparser/src/nsHTMLToTXTSinkStream.cpp b/htmlparser/src/nsHTMLToTXTSinkStream.cpp index 42d4ab664f93..c04596487f9c 100644 --- a/htmlparser/src/nsHTMLToTXTSinkStream.cpp +++ b/htmlparser/src/nsHTMLToTXTSinkStream.cpp @@ -363,6 +363,8 @@ USE_GENERAL_OPEN_METHOD(OpenMap) USE_GENERAL_CLOSE_METHOD(CloseMap) USE_GENERAL_OPEN_METHOD(OpenFrameset) USE_GENERAL_CLOSE_METHOD(CloseFrameset) +USE_GENERAL_OPEN_METHOD(OpenNoscript) +USE_GENERAL_CLOSE_METHOD(CloseNoscript) NS_IMETHODIMP nsHTMLToTXTSinkStream::DoFragment(PRBool aFlag) diff --git a/htmlparser/src/nsHTMLToTXTSinkStream.h b/htmlparser/src/nsHTMLToTXTSinkStream.h index 413934c40c02..d186b4e86402 100644 --- a/htmlparser/src/nsHTMLToTXTSinkStream.h +++ b/htmlparser/src/nsHTMLToTXTSinkStream.h @@ -130,6 +130,8 @@ class nsHTMLToTXTSinkStream : public nsIHTMLToTXTSinkStream NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode); + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode); NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/htmlparser/src/nsIHTMLContentSink.h b/htmlparser/src/nsIHTMLContentSink.h index b569d52846b6..2ffc6ddcfc24 100644 --- a/htmlparser/src/nsIHTMLContentSink.h +++ b/htmlparser/src/nsIHTMLContentSink.h @@ -182,6 +182,22 @@ public: */ NS_IMETHOD CloseFrameset(const nsIParserNode& aNode)=0; + /** + * This method is used in opening a NOSCRIPT container. + * + * @update harishd 08/25/00 + * @param nsIParserNode reference to parser node interface + */ + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode)=0; + + + /** + * This method is used in closing a NOSCRIPT container. + * + * @update harishd 08/25/00 + * @param nsIParserNode reference to parser node interface + */ + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode)=0; /** * This method tells the sink whether or not it is diff --git a/htmlparser/src/nsIParser.h b/htmlparser/src/nsIParser.h index d6a8ebd79ba2..89a1c2d47dec 100644 --- a/htmlparser/src/nsIParser.h +++ b/htmlparser/src/nsIParser.h @@ -292,6 +292,8 @@ class nsIParser : public nsISupports { #define NS_ERROR_HTMLPARSER_STOPPARSING NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1015) #define NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1016) +#define NS_HTMLPARSER_ALTERNATECONTENT NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_HTMLPARSER,1) + #define NS_ERROR_HTMLPARSER_CONTINUE NS_OK diff --git a/htmlparser/src/nsLoggingSink.h b/htmlparser/src/nsLoggingSink.h index 7172812103a4..84bdb74bd568 100644 --- a/htmlparser/src/nsLoggingSink.h +++ b/htmlparser/src/nsLoggingSink.h @@ -62,6 +62,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode) { return NS_OK; } NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/htmlparser/src/nsToken.cpp b/htmlparser/src/nsToken.cpp index 44f3cbeb6532..afa33922a924 100644 --- a/htmlparser/src/nsToken.cpp +++ b/htmlparser/src/nsToken.cpp @@ -139,6 +139,7 @@ CToken::~CToken() { mUseCount=0; } + /** * This method gets called when a token is about to be reused * for some other purpose. The token should initialize itself diff --git a/htmlparser/src/nsWellFormedDTD.cpp b/htmlparser/src/nsWellFormedDTD.cpp index 024cb307a61e..bd0f9e6cbead 100644 --- a/htmlparser/src/nsWellFormedDTD.cpp +++ b/htmlparser/src/nsWellFormedDTD.cpp @@ -636,7 +636,7 @@ nsresult CWellFormedDTD::HandleStartToken(CToken* aToken) { // Pass the ID Attribute atom from the start token to the parser node CStartToken* startToken = NS_STATIC_CAST(CStartToken *, aToken); - nsCOMPtr IDAttr; + nsCOMPtr IDAttr=nsnull; result = startToken->GetIDAttributeAtom(getter_AddRefs(IDAttr)); if (IDAttr && NS_SUCCEEDED(result)) result = theNode.SetIDAttributeAtom(IDAttr); diff --git a/parser/htmlparser/robot/nsRobotSink.cpp b/parser/htmlparser/robot/nsRobotSink.cpp index 0f36da569bbb..0ebf4280ef19 100644 --- a/parser/htmlparser/robot/nsRobotSink.cpp +++ b/parser/htmlparser/robot/nsRobotSink.cpp @@ -70,6 +70,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode){ return NS_OK; } NS_IMETHOD OpenContainer(const nsIParserNode& aNode); NS_IMETHOD CloseContainer(const nsIParserNode& aNode); NS_IMETHOD NotifyError(const nsParserError* aError); diff --git a/parser/htmlparser/src/CNavDTD.cpp b/parser/htmlparser/src/CNavDTD.cpp index 67b1f3efb67b..cc2abd61e0a9 100644 --- a/parser/htmlparser/src/CNavDTD.cpp +++ b/parser/htmlparser/src/CNavDTD.cpp @@ -686,10 +686,11 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){ deque until we can deal with it. --------------------------------------------------------------------------------- */ - if(!execSkipContent) { + if(!execSkipContent && mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { switch(theTag) { case eHTMLTag_html: + case eHTMLTag_noscript: case eHTMLTag_script: case eHTMLTag_markupDecl: break; // simply pass these through to token handler without further ado... @@ -1174,7 +1175,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode STOP_TIMER() MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this)); - if(mParser) { + if(mParser && mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { CObserverService* theService=mParser->GetObserverService(); if(theService) { @@ -1513,11 +1514,6 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { mHasOpenNoXXX++; break; - case eHTMLTag_noscript: - //mHasOpenNoXXX++; // Fix for 33397 - Enable this when we handle NOSCRIPTS. - isTokenHandled=PR_TRUE; // XXX - Throwing NOSCRIPT to the floor...yet another time.. - break; - case eHTMLTag_script: theHeadIsParent=((!mHasOpenBody) || mRequestedHead); mHasOpenScript=PR_TRUE; @@ -3084,7 +3080,76 @@ nsresult CNavDTD::CloseFrameset(const nsIParserNode *aNode){ return result; } +/** + * This method would determine how the noscript content + * should be handled. + * + * harishd 08/24/00 + * @param aNode - The noscript node + * return NS_OK if succeeded else ERROR + */ +nsresult CNavDTD::OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack) { + nsresult result=NS_OK; + if(mSink) { + STOP_TIMER(); + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenNoscript(), this=%p\n", this)); + + result=mSink->OpenNoscript(*aNode); + + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenNoscript(), this=%p\n", this)); + START_TIMER(); + + if(NS_SUCCEEDED(result)) { + if(result==NS_HTMLPARSER_ALTERNATECONTENT) { + // We're here because the sink has identified that + // JS is enabled and therefore noscript content should + // not be treated as a regular content,i.e., make sure + // that head elements are handled correctly and may be + // residual style. + mDTDState=result; + // Though NS_HTMLPARSER_ALTERNATECONTENT is a succeeded message we don't want to propagate it + // because there are lots of places where we don't check for succeeded result instead + // we check for NS_OK. Also, this message is pertinent to the DTD only + result=NS_OK; + } + mHasOpenNoXXX++; + mBodyContext->Push(aNode,aStyleStack); + } + } + + return result; +} + +/** + * Call this method to stop handling noscript content + * + * harishd 08/24/00 + * @param aNode - The noscript node + * return NS_OK if succeeded else ERROR + */ +nsresult CNavDTD::CloseNoscript(const nsIParserNode *aNode) { + nsresult result=NS_OK; + + if(mSink) { + STOP_TIMER(); + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseNoscript(), this=%p\n", this)); + + result=mSink->CloseNoscript(*aNode); + + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::CloseNoscript(), this=%p\n", this)); + START_TIMER(); + + if(NS_SUCCEEDED(result)) { + if(mHasOpenNoXXX > 0) { + mHasOpenNoXXX--; + } + mDTDState=NS_OK; // switch from alternate content state to regular state + } + } + + return result; +} /** * This method does two things: 1st, help construct @@ -3177,6 +3242,10 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB CloseHead(aNode); //do this just in case someone left it open... result=HandleScriptToken(aNode); break; + + case eHTMLTag_noscript: + result=OpenNoscript(aNode,aStyleStack); + break; default: isDefaultNode=PR_TRUE; @@ -3246,6 +3315,10 @@ CNavDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClo case eHTMLTag_frameset: result=CloseFrameset(aNode); break; + + case eHTMLTag_noscript: + result=CloseNoscript(aNode); + break; case eHTMLTag_title: default: @@ -3583,7 +3656,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ nsresult result=NS_OK; - static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_noscript}; + static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes}; eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType(); @@ -3597,42 +3670,50 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ } if(mSink) { - result=OpenHead(aNode); - if(NS_OK==result) { - if(eHTMLTag_title==theTag) { + // Alternate content => Content that shouldn't get processed + // as a regular content. That is, probably the content is + // within NOSCRIPT and since JS is enanbled we should not process + // this content. However, when JS is disabled alternate content + // would become regular content. + if(mDTDState!=NS_HTMLPARSER_ALTERNATECONTENT) { + result=OpenHead(aNode); + if(NS_OK==result) { + if(eHTMLTag_title==theTag) { - const nsString& theString=aNode->GetSkippedContent(); - PRInt32 theLen=theString.Length(); - CBufDescriptor theBD(theString.GetUnicode(), PR_TRUE, theLen+1, theLen); - nsAutoString theString2(theBD); + const nsString& theString=aNode->GetSkippedContent(); + PRInt32 theLen=theString.Length(); + CBufDescriptor theBD(theString.GetUnicode(), PR_TRUE, theLen+1, theLen); + nsAutoString theString2(theBD); - theString2.CompressWhitespace(); + theString2.CompressWhitespace(); - STOP_TIMER() - MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); - mSink->SetTitle(theString2); - MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); - START_TIMER() + STOP_TIMER() + MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); + mSink->SetTitle(theString2); + MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this)); + START_TIMER() - } - else result=AddLeaf(aNode); - // XXX If the return value tells us to block, go - // ahead and close the tag out anyway, since its - // contents will be consumed. - - // Fix for Bug 31392 - // Do not leave a head context open no matter what the result is. - if(mHasOpenHead) { - nsresult rv=CloseHead(aNode); - // XXX Only send along a failure. If the close - // succeeded we still may need to indicate that the - // parser has blocked (i.e. return the result of - // the AddLeaf. - if (rv != NS_OK) { - result = rv; } - } - } + else result=AddLeaf(aNode); + // XXX If the return value tells us to block, go + // ahead and close the tag out anyway, since its + // contents will be consumed. + + // Fix for Bug 31392 + // Do not leave a head context open no matter what the result is. + if(mHasOpenHead) { + nsresult rv=CloseHead(aNode); + // XXX Only send along a failure. If the close + // succeeded we still may need to indicate that the + // parser has blocked (i.e. return the result of + // the AddLeaf. + if (rv != NS_OK) { + result = rv; + } + } + } + } + else result=AddLeaf(aNode); } return result; } diff --git a/parser/htmlparser/src/CNavDTD.h b/parser/htmlparser/src/CNavDTD.h index 10cd47e6a914..d525ca2b3142 100644 --- a/parser/htmlparser/src/CNavDTD.h +++ b/parser/htmlparser/src/CNavDTD.h @@ -429,6 +429,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { nsresult OpenForm(const nsIParserNode *aNode); nsresult OpenMap(const nsIParserNode *aNode); nsresult OpenFrameset(const nsIParserNode *aNode); + nsresult OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack=0); nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0); /** @@ -444,6 +445,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { nsresult CloseForm(const nsIParserNode *aNode); nsresult CloseMap(const nsIParserNode *aNode); nsresult CloseFrameset(const nsIParserNode *aNode); + nsresult CloseNoscript(const nsIParserNode *aNode); /** * The special purpose methods automatically close diff --git a/parser/htmlparser/src/nsElementTable.cpp b/parser/htmlparser/src/nsElementTable.cpp index 30b62653b2cf..cbf2d17e57a9 100644 --- a/parser/htmlparser/src/nsElementTable.cpp +++ b/parser/htmlparser/src/nsElementTable.cpp @@ -81,7 +81,7 @@ TagList gFormKids={1,{eHTMLTag_keygen}}; TagList gFramesetKids={3,{eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes}}; TagList gHtmlKids={9,{eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_noframes,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace}}; -TagList gHeadKids={9,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript}}; +TagList gHeadKids={8,{eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed}}; TagList gLabelKids={1,{eHTMLTag_span}}; TagList gLIKids={2,{eHTMLTag_ol,eHTMLTag_ul}}; @@ -435,7 +435,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gRootTags, &gRootTags, /*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0, /*parent,incl,exclgroups*/ kDLChild, kFlowEntity, kNone, - /*special props, prop-range*/ kNoPropagate|kMustCloseSelf,kDefaultPropRange, + /*special props, prop-range*/ kNoPropagate|kMustCloseSelf|kVerifyHierarchy,kDefaultPropRange, /*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown); Initialize( @@ -869,7 +869,7 @@ void InitializeElementTable(void) { /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity|kSelf, kNone, /*special props, prop-range*/ 0, kNoPropRange, - /*special parents,kids,skip*/ 0,0,eHTMLTag_noscript); + /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( /*tag*/ eHTMLTag_object, diff --git a/parser/htmlparser/src/nsHTMLContentSinkStream.cpp b/parser/htmlparser/src/nsHTMLContentSinkStream.cpp index 9f0b5ece5eb7..6fae533856ae 100644 --- a/parser/htmlparser/src/nsHTMLContentSinkStream.cpp +++ b/parser/htmlparser/src/nsHTMLContentSinkStream.cpp @@ -578,6 +578,8 @@ USE_GENERAL_OPEN_METHOD(OpenMap, eHTMLTag_map) USE_GENERAL_CLOSE_METHOD(CloseMap, eHTMLTag_map) USE_GENERAL_OPEN_METHOD(OpenFrameset, eHTMLTag_frameset) USE_GENERAL_CLOSE_METHOD(CloseFrameset, eHTMLTag_frameset) +USE_GENERAL_OPEN_METHOD(OpenNoscript, eHTMLTag_noscript) +USE_GENERAL_CLOSE_METHOD(CloseNoscript, eHTMLTag_noscript) /** * diff --git a/parser/htmlparser/src/nsHTMLContentSinkStream.h b/parser/htmlparser/src/nsHTMLContentSinkStream.h index 9cca0caa7a37..f39cecc8f5af 100644 --- a/parser/htmlparser/src/nsHTMLContentSinkStream.h +++ b/parser/htmlparser/src/nsHTMLContentSinkStream.h @@ -138,6 +138,8 @@ class nsHTMLContentSinkStream : public nsIHTMLContentSinkStream NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) ; + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode); NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/parser/htmlparser/src/nsHTMLNullSink.cpp b/parser/htmlparser/src/nsHTMLNullSink.cpp index 6b4ad449e556..17c0c3d99845 100644 --- a/parser/htmlparser/src/nsHTMLNullSink.cpp +++ b/parser/htmlparser/src/nsHTMLNullSink.cpp @@ -69,6 +69,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode){ return NS_OK; } NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); diff --git a/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp b/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp index 42d4ab664f93..c04596487f9c 100644 --- a/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp +++ b/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp @@ -363,6 +363,8 @@ USE_GENERAL_OPEN_METHOD(OpenMap) USE_GENERAL_CLOSE_METHOD(CloseMap) USE_GENERAL_OPEN_METHOD(OpenFrameset) USE_GENERAL_CLOSE_METHOD(CloseFrameset) +USE_GENERAL_OPEN_METHOD(OpenNoscript) +USE_GENERAL_CLOSE_METHOD(CloseNoscript) NS_IMETHODIMP nsHTMLToTXTSinkStream::DoFragment(PRBool aFlag) diff --git a/parser/htmlparser/src/nsHTMLToTXTSinkStream.h b/parser/htmlparser/src/nsHTMLToTXTSinkStream.h index 413934c40c02..d186b4e86402 100644 --- a/parser/htmlparser/src/nsHTMLToTXTSinkStream.h +++ b/parser/htmlparser/src/nsHTMLToTXTSinkStream.h @@ -130,6 +130,8 @@ class nsHTMLToTXTSinkStream : public nsIHTMLToTXTSinkStream NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode); + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode); NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/parser/htmlparser/src/nsIHTMLContentSink.h b/parser/htmlparser/src/nsIHTMLContentSink.h index b569d52846b6..2ffc6ddcfc24 100644 --- a/parser/htmlparser/src/nsIHTMLContentSink.h +++ b/parser/htmlparser/src/nsIHTMLContentSink.h @@ -182,6 +182,22 @@ public: */ NS_IMETHOD CloseFrameset(const nsIParserNode& aNode)=0; + /** + * This method is used in opening a NOSCRIPT container. + * + * @update harishd 08/25/00 + * @param nsIParserNode reference to parser node interface + */ + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode)=0; + + + /** + * This method is used in closing a NOSCRIPT container. + * + * @update harishd 08/25/00 + * @param nsIParserNode reference to parser node interface + */ + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode)=0; /** * This method tells the sink whether or not it is diff --git a/parser/htmlparser/src/nsIParser.h b/parser/htmlparser/src/nsIParser.h index d6a8ebd79ba2..89a1c2d47dec 100644 --- a/parser/htmlparser/src/nsIParser.h +++ b/parser/htmlparser/src/nsIParser.h @@ -292,6 +292,8 @@ class nsIParser : public nsISupports { #define NS_ERROR_HTMLPARSER_STOPPARSING NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1015) #define NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1016) +#define NS_HTMLPARSER_ALTERNATECONTENT NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_HTMLPARSER,1) + #define NS_ERROR_HTMLPARSER_CONTINUE NS_OK diff --git a/parser/htmlparser/src/nsLoggingSink.h b/parser/htmlparser/src/nsLoggingSink.h index 7172812103a4..84bdb74bd568 100644 --- a/parser/htmlparser/src/nsLoggingSink.h +++ b/parser/htmlparser/src/nsLoggingSink.h @@ -62,6 +62,8 @@ public: NS_IMETHOD CloseMap(const nsIParserNode& aNode); NS_IMETHOD OpenFrameset(const nsIParserNode& aNode); NS_IMETHOD CloseFrameset(const nsIParserNode& aNode); + NS_IMETHOD OpenNoscript(const nsIParserNode& aNode) { return NS_OK; } + NS_IMETHOD CloseNoscript(const nsIParserNode& aNode) { return NS_OK; } NS_IMETHOD DoFragment(PRBool aFlag); NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); diff --git a/parser/htmlparser/src/nsToken.cpp b/parser/htmlparser/src/nsToken.cpp index 44f3cbeb6532..afa33922a924 100644 --- a/parser/htmlparser/src/nsToken.cpp +++ b/parser/htmlparser/src/nsToken.cpp @@ -139,6 +139,7 @@ CToken::~CToken() { mUseCount=0; } + /** * This method gets called when a token is about to be reused * for some other purpose. The token should initialize itself diff --git a/parser/htmlparser/src/nsWellFormedDTD.cpp b/parser/htmlparser/src/nsWellFormedDTD.cpp index 024cb307a61e..bd0f9e6cbead 100644 --- a/parser/htmlparser/src/nsWellFormedDTD.cpp +++ b/parser/htmlparser/src/nsWellFormedDTD.cpp @@ -636,7 +636,7 @@ nsresult CWellFormedDTD::HandleStartToken(CToken* aToken) { // Pass the ID Attribute atom from the start token to the parser node CStartToken* startToken = NS_STATIC_CAST(CStartToken *, aToken); - nsCOMPtr IDAttr; + nsCOMPtr IDAttr=nsnull; result = startToken->GetIDAttributeAtom(getter_AddRefs(IDAttr)); if (IDAttr && NS_SUCCEEDED(result)) result = theNode.SetIDAttributeAtom(IDAttr);