diff --git a/parser/htmlparser/public/nsIDTD.h b/parser/htmlparser/public/nsIDTD.h
index dde056cd3e0..2a9ed212e98 100644
--- a/parser/htmlparser/public/nsIDTD.h
+++ b/parser/htmlparser/public/nsIDTD.h
@@ -102,8 +102,7 @@ public:
* @param anErrorCode - contains error code resulting from parse process
* @return
*/
- NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink,
- nsIParser* aParser) = 0;
+ NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink) = 0;
/**
* Called by the parser after the parsing process has concluded
@@ -111,7 +110,10 @@ public:
* @param anErrorCode - contains error code resulting from parse process
* @return
*/
- NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer) = 0;
+ NS_IMETHOD BuildModel(nsITokenizer* aTokenizer,
+ PRBool aCanInterrupt,
+ PRBool aCountLines,
+ const nsCString* aCharsetPtr) = 0;
/**
* Called during model building phase of parse process. Each token
@@ -123,7 +125,7 @@ public:
* @param aToken -- token object to be put into content model
* @return error code (usually 0)
*/
- NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser) = 0;
+ NS_IMETHOD HandleToken(CToken* aToken) = 0;
/**
* If the parse process gets interrupted midway, this method is
@@ -183,9 +185,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDTD, NS_IDTD_IID)
#define NS_DECL_NSIDTD \
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext, nsITokenizer* aTokenizer, nsIContentSink* aSink);\
- NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink, nsIParser* aParser);\
- NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer);\
- NS_IMETHOD HandleToken(CToken* aToken, nsIParser* aParser);\
+ NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink);\
+ NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, PRBool aCanInterrupt, PRBool aCountLines, const nsCString* aCharsetPtr);\
+ NS_IMETHOD HandleToken(CToken* aToken);\
NS_IMETHOD WillResumeParse();\
NS_IMETHOD WillInterruptParse();\
NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
diff --git a/parser/htmlparser/src/CNavDTD.cpp b/parser/htmlparser/src/CNavDTD.cpp
index 89001e0f60b..a43eccf3f31 100644
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -42,7 +42,6 @@
#include "nsHTMLTokens.h"
#include "nsCRT.h"
#include "nsParser.h"
-#include "nsIParser.h"
#include "nsIHTMLContentSink.h"
#include "nsScanner.h"
#include "prenv.h"
@@ -82,18 +81,8 @@ static const char kInvalidTagStackPos[] = "Error: invalid tag stack position";
#include "nsElementTable.h"
-#ifdef MOZ_PERF_METRICS
-# define START_TIMER() \
- if (mParser) MOZ_TIMER_START(mParser->mParseTime); \
- if (mParser) MOZ_TIMER_START(mParser->mDTDTime);
-
-# define STOP_TIMER() \
- if (mParser) MOZ_TIMER_STOP(mParser->mParseTime); \
- if (mParser) MOZ_TIMER_STOP(mParser->mDTDTime);
-#else
-# define STOP_TIMER()
-# define START_TIMER()
-#endif
+#define START_TIMER()
+#define STOP_TIMER()
// Some flags for use by the DTD.
#define NS_DTD_FLAG_NONE 0x00000000
@@ -127,7 +116,7 @@ CNavDTD::CNavDTD()
mTokenAllocator(0),
mBodyContext(new nsDTDContext()),
mTempContext(0),
- mParser(0),
+ mCountLines(PR_TRUE),
mTokenizer(0),
mDTDMode(eDTDMode_quirks),
mDocType(eHTML_Quirks),
@@ -252,22 +241,24 @@ CNavDTD::WillBuildModel(const CParserContext& aParserContext,
}
nsresult
-CNavDTD::BuildModel(nsIParser* aParser,
- nsITokenizer* aTokenizer)
+CNavDTD::BuildModel(nsITokenizer* aTokenizer,
+ PRBool aCanInterrupt,
+ PRBool aCountLines,
+ const nsCString*)
{
NS_PRECONDITION(mBodyContext != nsnull,
"Create a context before calling build model");
nsresult result = NS_OK;
- if (!aTokenizer || !aParser) {
+ if (!aTokenizer) {
return NS_OK;
}
nsITokenizer* oldTokenizer = mTokenizer;
+ mCountLines = aCountLines;
mTokenizer = aTokenizer;
- mParser = (nsParser*)aParser;
mTokenAllocator = mTokenizer->GetTokenAllocator();
if (!mSink) {
@@ -328,7 +319,7 @@ CNavDTD::BuildModel(nsIParser* aParser,
if (!theToken) {
break;
}
- result = HandleToken(theToken, aParser);
+ result = HandleToken(theToken);
} else {
result = NS_ERROR_HTMLPARSER_STOPPARSING;
break;
@@ -337,17 +328,10 @@ CNavDTD::BuildModel(nsIParser* aParser,
if (NS_ERROR_HTMLPARSER_INTERRUPTED == mSink->DidProcessAToken()) {
// The content sink has requested that DTD interrupt processing tokens
// So we need to make sure the parser is in a state where it can be
- // interrupted.
- // The mParser->CanInterrupt will return TRUE if BuildModel was called
- // from a place in the parser where it prepared to handle a return value of
- // NS_ERROR_HTMLPARSER_INTERRUPTED.
- // If the parser is processing a script's document.write we should not
- // allow it to be interrupted.
+ // interrupted (e.g., not in a document.write).
// We also need to make sure that an interruption does not override
// a request to block the parser.
- if (mParser->CanInterrupt() &&
- !IsParserInDocWrite() &&
- NS_SUCCEEDED(result)) {
+ if (aCanInterrupt && NS_SUCCEEDED(result)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
@@ -360,9 +344,8 @@ CNavDTD::BuildModel(nsIParser* aParser,
nsresult
CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
- eHTMLTokenTypes aType,
- nsIParser* aParser)
-{
+ eHTMLTokenTypes aType)
+{
NS_ASSERTION(mTokenizer, "tokenizer is null! unable to build target.");
NS_ASSERTION(mTokenAllocator, "unable to create tokens without an allocator.");
if (!mTokenizer || !mTokenAllocator) {
@@ -372,20 +355,24 @@ CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
CToken* target = mTokenAllocator->CreateTokenOfType(aType, aTarget);
NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
mTokenizer->PushTokenFront(target);
- return BuildModel(aParser, mTokenizer);
+ // Always safe to disallow interruptions, so it doesn't matter that we've
+ // forgotten the aCanInterrupt parameter to BuildModel. Also, BuildModel
+ // doesn't seem to care about the charset, and at this point we have no idea
+ // what the charset was, so 0 can and must suffice. If either of these
+ // values mattered, we'd want to store them as data members in BuildModel.
+ return BuildModel(mTokenizer, PR_FALSE, mCountLines, 0);
}
nsresult
CNavDTD::DidBuildModel(nsresult anErrorCode,
- PRBool aNotifySink,
- nsIParser* aParser)
+ PRBool aNotifySink)
{
if (!mSink) {
return NS_OK;
}
nsresult result = NS_OK;
- if (aParser && aNotifySink) {
+ if (aNotifySink) {
if (NS_OK == anErrorCode) {
if (!(mFlags & NS_DTD_FLAG_HAS_MAIN_CONTAINER)) {
// This document is not a frameset document, however, it did not contain
@@ -393,7 +380,7 @@ CNavDTD::DidBuildModel(nsresult anErrorCode,
// Also note: We ignore the return value of BuildNeglectedTarget, we
// can't reasonably respond to errors (or requests to block) at this
// point in the parsing process.
- BuildNeglectedTarget(eHTMLTag_body, eToken_start, aParser);
+ BuildNeglectedTarget(eHTMLTag_body, eToken_start);
}
if (mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
// Looks like the misplaced contents are not processed yet.
@@ -590,7 +577,7 @@ HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext)
}
nsresult
-CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
+CNavDTD::HandleToken(CToken* aToken)
{
if (!aToken) {
return NS_OK;
@@ -603,7 +590,7 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
aToken->SetLineNumber(mLineNumber);
- if (!IsParserInDocWrite()) {
+ if (mCountLines) {
mLineNumber += aToken->GetNewlineCount();
}
@@ -740,7 +727,7 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
mTokenAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_body,
NS_LITERAL_STRING("body"));
- result = HandleToken(theBodyToken, aParser);
+ result = HandleToken(theBodyToken);
}
return result;
}
@@ -749,8 +736,6 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
}
if (theToken) {
- mParser = (nsParser*)aParser;
-
switch (theType) {
case eToken_text:
case eToken_start:
@@ -818,7 +803,7 @@ CNavDTD::DidHandleStartTag(nsIParserNode& aNode, eHTMLTags aChildTag)
if (ePlainText != mDocType && theNextToken) {
eHTMLTokenTypes theType = eHTMLTokenTypes(theNextToken->GetTokenType());
if (eToken_newline == theType) {
- if (!IsParserInDocWrite()) {
+ if (mCountLines) {
mLineNumber += theNextToken->GetNewlineCount();
}
theNextToken = mTokenizer->PopToken();
@@ -1651,7 +1636,7 @@ CNavDTD::HandleEndToken(CToken* aToken)
// like 32782.
CToken* theToken = mTokenAllocator->CreateTokenOfType(eToken_start,
theChildTag);
- result = HandleToken(theToken, mParser);
+ result = HandleToken(theToken);
}
}
break;
@@ -1746,11 +1731,11 @@ CNavDTD::HandleEndToken(CToken* aToken)
// Oops, we're in misplaced content. Handle these tokens
// directly instead of trying to push them onto the tokenizer
// stack.
- result = HandleToken(theStartToken, mParser);
+ result = HandleToken(theStartToken);
NS_ENSURE_SUCCESS(result, result);
IF_HOLD(aToken);
- result = HandleToken(aToken, mParser);
+ result = HandleToken(aToken);
}
}
}
@@ -1871,7 +1856,7 @@ CNavDTD::HandleSavedTokens(PRInt32 anIndex)
// difficult to handle misplaced style and link tags, since it's hard
// to propagate the block return all the way up and then re-enter this
// method.
- result = HandleToken(theToken, mParser);
+ result = HandleToken(theToken);
}
}
@@ -1938,7 +1923,7 @@ CNavDTD::HandleEntityToken(CToken* aToken)
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
// theToken should get recycled automagically...
- return HandleToken(theToken, mParser);
+ return HandleToken(theToken);
}
eHTMLTags theParentTag = mBodyContext->Last();
@@ -2050,7 +2035,7 @@ CNavDTD::HandleDocTypeDeclToken(CToken* aToken)
CDoctypeDeclToken* theToken = static_cast(aToken);
nsAutoString docTypeStr(theToken->GetStringValue());
// XXX Doesn't this count the newlines twice?
- if (!IsParserInDocWrite()) {
+ if (mCountLines) {
mLineNumber += docTypeStr.CountChar(kNewLine);
}
@@ -2110,7 +2095,7 @@ CNavDTD::CollectAttributes(nsIParserNode *aNode, eHTMLTags aTag, PRInt32 aCount)
break;
}
- if (!IsParserInDocWrite()) {
+ if (mCountLines) {
mLineNumber += theToken->GetNewlineCount();
}
@@ -3149,7 +3134,7 @@ CNavDTD::CreateContextStackFor(eHTMLTags aParent, eHTMLTags aChild)
// Note: These tokens should all wind up on contextstack, so don't recycle
// them.
CToken *theToken = mTokenAllocator->CreateTokenOfType(eToken_start, theTag);
- HandleToken(theToken, mParser);
+ HandleToken(theToken);
}
}
diff --git a/parser/htmlparser/src/CNavDTD.h b/parser/htmlparser/src/CNavDTD.h
index 0bbd392a395..95049d95151 100644
--- a/parser/htmlparser/src/CNavDTD.h
+++ b/parser/htmlparser/src/CNavDTD.h
@@ -98,7 +98,6 @@
#include "nsIDTD.h"
#include "nsISupports.h"
-#include "nsIParser.h"
#include "nsHTMLTags.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
@@ -295,8 +294,7 @@ private:
nsresult HandleAttributeToken(CToken* aToken);
nsresult HandleProcessingInstructionToken(CToken* aToken);
nsresult HandleDocTypeDeclToken(CToken* aToken);
- nsresult BuildNeglectedTarget(eHTMLTags aTarget, eHTMLTokenTypes aType,
- nsIParser* aParser);
+ nsresult BuildNeglectedTarget(eHTMLTags aTarget, eHTMLTokenTypes aType);
nsresult OpenHTML(const nsCParserNode *aNode);
nsresult OpenBody(const nsCParserNode *aNode);
@@ -376,21 +374,13 @@ protected:
PRBool IsBlockElement(PRInt32 aTagID, PRInt32 aParentID) const;
PRBool IsInlineElement(PRInt32 aTagID, PRInt32 aParentID) const;
- PRBool IsParserInDocWrite() const
- {
- NS_ASSERTION(mParser && mParser->PeekContext(),
- "Parser must be parsing to use this function");
-
- return mParser->PeekContext()->mPrevContext != nsnull;
- }
-
nsDeque mMisplacedContent;
nsCOMPtr mSink;
nsTokenAllocator* mTokenAllocator;
nsDTDContext* mBodyContext;
nsDTDContext* mTempContext;
- nsParser* mParser;
+ PRBool mCountLines;
nsITokenizer* mTokenizer; // weak
nsString mFilename;
diff --git a/parser/htmlparser/src/nsExpatDriver.cpp b/parser/htmlparser/src/nsExpatDriver.cpp
index c081d7cc857..704853aa934 100644
--- a/parser/htmlparser/src/nsExpatDriver.cpp
+++ b/parser/htmlparser/src/nsExpatDriver.cpp
@@ -37,7 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nsExpatDriver.h"
-#include "nsIParser.h"
#include "nsCOMPtr.h"
#include "nsParserCIID.h"
#include "CParserContext.h"
@@ -1302,16 +1301,17 @@ nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
}
NS_IMETHODIMP
-nsExpatDriver::BuildModel(nsIParser* aParser,
- nsITokenizer* aTokenizer)
+nsExpatDriver::BuildModel(nsITokenizer* aTokenizer,
+ PRBool,// aCanInterrupt,
+ PRBool,// aCountLines,
+ const nsCString*)// aCharsetPtr)
{
return mInternalState;
}
NS_IMETHODIMP
nsExpatDriver::DidBuildModel(nsresult anErrorCode,
- PRBool aNotifySink,
- nsIParser* aParser)
+ PRBool aNotifySink)
{
NS_ASSERTION(mSink == nsCOMPtr(do_QueryInterface(mOriginalSink)),
"In nsExpatDriver::DidBuildModel: mOriginalSink not the same object as mSink?");
@@ -1437,7 +1437,7 @@ nsExpatDriver::CopyState(nsITokenizer* aTokenizer)
}
NS_IMETHODIMP
-nsExpatDriver::HandleToken(CToken* aToken,nsIParser* aParser)
+nsExpatDriver::HandleToken(CToken* aToken)
{
return NS_OK;
}
diff --git a/parser/htmlparser/src/nsParser.cpp b/parser/htmlparser/src/nsParser.cpp
index df86a9849b9..eaeee9cc97e 100644
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -1531,7 +1531,7 @@ nsParser::DidBuildModel(nsresult anErrorCode)
PRBool terminated = mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING;
if (mDTD && mSink &&
mSink->ReadyToCallDidBuildModel(terminated)) {
- result = mDTD->DidBuildModel(anErrorCode,PR_TRUE,this);
+ result = mDTD->DidBuildModel(anErrorCode,PR_TRUE);
}
//Ref. to bug 61462.
@@ -2364,7 +2364,13 @@ nsParser::BuildModel()
if (NS_SUCCEEDED(result)) {
if (mDTD) {
MOZ_TIMER_START(mDTDTime);
- result = mDTD->BuildModel(this, theTokenizer);
+ // XXXbenjamn CanInterrupt() and !inDocWrite appear to be redundant.
+ PRBool inDocWrite = !!mParserContext->mPrevContext;
+ result = mDTD->BuildModel(theTokenizer,
+ // ignore interruptions in document.write
+ CanInterrupt() && !inDocWrite,
+ !inDocWrite, // don't count lines in document.write
+ &mCharset);
MOZ_TIMER_STOP(mDTDTime);
}
} else {
diff --git a/parser/htmlparser/src/nsViewSourceHTML.cpp b/parser/htmlparser/src/nsViewSourceHTML.cpp
index db3a38c2bd4..c6e9918d54c 100644
--- a/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -47,26 +47,15 @@
*/
#define NS_VIEWSOURCE_TOKENS_PER_BLOCK 16
-#ifdef RAPTOR_PERF_METRICS
-# define START_TIMER() \
- if(mParser) mParser->mParseTime.Start(PR_FALSE); \
- if(mParser) mParser->mDTDTime.Start(PR_FALSE);
-
-# define STOP_TIMER() \
- if(mParser) mParser->mParseTime.Stop(); \
- if(mParser) mParser->mDTDTime.Stop();
-
-#else
-# define STOP_TIMER()
-# define START_TIMER()
-#endif
+// TODO get rid of these unused macros
+#define STOP_TIMER()
+#define START_TIMER()
#include "nsIAtom.h"
#include "nsViewSourceHTML.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
-#include "nsIParser.h"
#include "nsDTDUtils.h"
#include "nsIContentSink.h"
#include "nsIHTMLContentSink.h"
@@ -223,7 +212,6 @@ CViewSourceHTML::CViewSourceHTML()
mWrapLongLines = NS_SUCCEEDED(rv) ? temp : PR_FALSE;
}
- mParser = 0;
mSink = 0;
mLineNumber = 1;
mTokenizer = 0;
@@ -249,7 +237,7 @@ CViewSourceHTML::CViewSourceHTML()
* @return
*/
CViewSourceHTML::~CViewSourceHTML(){
- mParser=0; //just to prove we destructed...
+ mSink=0; //just to prove we destructed...
}
/**
@@ -338,12 +326,14 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
* @param aFilename is the name of the file being parsed.
* @return error code (almost always 0)
*/
-NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,
- nsITokenizer* aTokenizer)
+NS_IMETHODIMP CViewSourceHTML::BuildModel(nsITokenizer* aTokenizer,
+ PRBool aCanInterrupt,
+ PRBool aCountLines,
+ const nsCString* aCharsetPtr)
{
nsresult result=NS_OK;
- if(aTokenizer && aParser) {
+ if(aTokenizer) {
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
@@ -455,14 +445,20 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,
}
}
+ NS_ASSERTION(aCharsetPtr, "CViewSourceHTML::BuildModel expects a charset!");
+ mCharset = *aCharsetPtr;
+
+ NS_ASSERTION(aCanInterrupt, "CViewSourceHTML can't run scripts, so "
+ "document.write should not forbid interruptions. Why is "
+ "the parser telling us not to interrupt?");
+
while(NS_SUCCEEDED(result)){
CToken* theToken=mTokenizer->PopToken();
if(theToken) {
- result=HandleToken(theToken,aParser);
+ result=HandleToken(theToken);
if(NS_SUCCEEDED(result)) {
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
- if (mParser->CanInterrupt() &&
- mSink->DidProcessAToken() == NS_ERROR_HTMLPARSER_INTERRUPTED) {
+ if (mSink->DidProcessAToken() == NS_ERROR_HTMLPARSER_INTERRUPTED) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
@@ -550,43 +546,36 @@ void CViewSourceHTML::AddAttrToNode(nsCParserStartNode& aNode,
* @return
*/
NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,
- PRBool aNotifySink,
- nsIParser* aParser)
+ PRBool aNotifySink)
{
nsresult result= NS_OK;
//ADD CODE HERE TO CLOSE OPEN CONTAINERS...
- if(aParser){
+ STOP_TIMER();
- mParser=(nsParser*)aParser; //debug XXX
- STOP_TIMER();
-
- mSink=(nsIHTMLContentSink*)aParser->GetContentSink();
- if((aNotifySink) && (mSink)) {
- //now let's close automatically auto-opened containers...
+ if((aNotifySink) && (mSink)) {
+ //now let's close automatically auto-opened containers...
#ifdef DUMP_TO_FILE
- if(gDumpFile) {
- fprintf(gDumpFile, "\n");
- fprintf(gDumpFile, "