зеркало из https://github.com/mozilla/gecko-dev.git
Bug 484121 (6/6) - Don't let DTDs hold parser references. r+sr=mrbkap
This commit is contained in:
Родитель
fbb427a992
Коммит
b5b32ea103
|
@ -102,16 +102,25 @@ public:
|
|||
* @param anErrorCode - contains error code resulting from parse process
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHOD DidBuildModel(nsresult anErrorCode,
|
||||
nsIParser* aParser) = 0;
|
||||
NS_IMETHOD DidBuildModel(nsresult anErrorCode) = 0;
|
||||
|
||||
/**
|
||||
* Called by the parser after the parsing process has concluded
|
||||
* @update gess5/18/98
|
||||
* @param anErrorCode - contains error code resulting from parse process
|
||||
* @return
|
||||
* Called (possibly repeatedly) by the parser to parse tokens and construct
|
||||
* the document model via the sink provided to WillBuildModel.
|
||||
*
|
||||
* @param aTokenizer - tokenizer providing the token stream to be parsed
|
||||
* @param aCanInterrupt - informs the DTD whether the parser can handle
|
||||
* interruptions of the model building process
|
||||
* @param aCountLines - informs the DTD whether to count newlines
|
||||
* (not wanted, e.g., when handling document.write)
|
||||
* @param aCharsetPtr - address of an nsCString containing the charset
|
||||
* that the DTD should use (pointer in case the DTD
|
||||
* opts to ignore this parameter)
|
||||
*/
|
||||
NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer) = 0;
|
||||
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer,
|
||||
PRBool aCanInterrupt,
|
||||
PRBool aCountLines,
|
||||
const nsCString* aCharsetPtr) = 0;
|
||||
|
||||
/**
|
||||
* This method is called to determine whether or not a tag of one
|
||||
|
@ -159,8 +168,8 @@ 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,nsIParser* aParser);\
|
||||
NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer);\
|
||||
NS_IMETHOD DidBuildModel(nsresult anErrorCode);\
|
||||
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, PRBool aCanInterrupt, PRBool aCountLines, const nsCString* aCharsetPtr);\
|
||||
NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
|
||||
NS_IMETHOD_(PRBool) IsContainer(PRInt32 aTag) const;\
|
||||
NS_IMETHOD_(void) Terminate();\
|
||||
|
|
|
@ -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"
|
||||
|
@ -81,18 +80,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
|
||||
|
@ -126,7 +115,7 @@ CNavDTD::CNavDTD()
|
|||
mTokenAllocator(0),
|
||||
mBodyContext(new nsDTDContext()),
|
||||
mTempContext(0),
|
||||
mParser(0),
|
||||
mCountLines(PR_TRUE),
|
||||
mTokenizer(0),
|
||||
mDTDMode(eDTDMode_quirks),
|
||||
mDocType(eHTML_Quirks),
|
||||
|
@ -234,22 +223,24 @@ CNavDTD::WillBuildModel(const CParserContext& aParserContext,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
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;
|
||||
nsITokenizer* const oldTokenizer = mTokenizer;
|
||||
|
||||
mCountLines = aCountLines;
|
||||
mTokenizer = aTokenizer;
|
||||
mParser = (nsParser*)aParser;
|
||||
mTokenAllocator = mTokenizer->GetTokenAllocator();
|
||||
|
||||
if (!mSink) {
|
||||
|
@ -310,7 +301,7 @@ CNavDTD::BuildModel(nsIParser* aParser,
|
|||
if (!theToken) {
|
||||
break;
|
||||
}
|
||||
result = HandleToken(theToken, aParser);
|
||||
result = HandleToken(theToken);
|
||||
} else {
|
||||
result = NS_ERROR_HTMLPARSER_STOPPARSING;
|
||||
break;
|
||||
|
@ -319,17 +310,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;
|
||||
}
|
||||
|
@ -342,8 +326,7 @@ 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.");
|
||||
|
@ -354,19 +337,20 @@ 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);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CNavDTD::DidBuildModel(nsresult anErrorCode,
|
||||
nsIParser* aParser)
|
||||
CNavDTD::DidBuildModel(nsresult anErrorCode)
|
||||
{
|
||||
if (!mSink) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result = NS_OK;
|
||||
if (aParser) {
|
||||
|
||||
if (mSink) {
|
||||
if (NS_OK == anErrorCode) {
|
||||
if (!(mFlags & NS_DTD_FLAG_HAS_MAIN_CONTAINER)) {
|
||||
// This document is not a frameset document, however, it did not contain
|
||||
|
@ -374,7 +358,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.
|
||||
|
@ -566,7 +550,7 @@ HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext)
|
|||
}
|
||||
|
||||
nsresult
|
||||
CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
||||
CNavDTD::HandleToken(CToken* aToken)
|
||||
{
|
||||
if (!aToken) {
|
||||
return NS_OK;
|
||||
|
@ -579,7 +563,7 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
|||
|
||||
aToken->SetLineNumber(mLineNumber);
|
||||
|
||||
if (!IsParserInDocWrite()) {
|
||||
if (mCountLines) {
|
||||
mLineNumber += aToken->GetNewlineCount();
|
||||
}
|
||||
|
||||
|
@ -716,7 +700,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;
|
||||
}
|
||||
|
@ -725,8 +709,6 @@ CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
|
|||
}
|
||||
|
||||
if (theToken) {
|
||||
mParser = (nsParser*)aParser;
|
||||
|
||||
switch (theType) {
|
||||
case eToken_text:
|
||||
case eToken_start:
|
||||
|
@ -794,7 +776,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();
|
||||
|
@ -1611,7 +1593,7 @@ CNavDTD::HandleEndToken(CToken* aToken)
|
|||
|
||||
case eHTMLTag_head:
|
||||
StripWSFollowingTag(theChildTag, mTokenizer, mTokenAllocator,
|
||||
IsParserInDocWrite() ? nsnull : &mLineNumber);
|
||||
!mCountLines ? nsnull : &mLineNumber);
|
||||
if (mBodyContext->LastOf(eHTMLTag_head) != kNotFound) {
|
||||
result = CloseContainersTo(eHTMLTag_head, PR_FALSE);
|
||||
}
|
||||
|
@ -1631,7 +1613,7 @@ CNavDTD::HandleEndToken(CToken* aToken)
|
|||
// like 32782.
|
||||
CToken* theToken = mTokenAllocator->CreateTokenOfType(eToken_start,
|
||||
theChildTag);
|
||||
result = HandleToken(theToken, mParser);
|
||||
result = HandleToken(theToken);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1639,7 +1621,7 @@ CNavDTD::HandleEndToken(CToken* aToken)
|
|||
case eHTMLTag_body:
|
||||
case eHTMLTag_html:
|
||||
StripWSFollowingTag(theChildTag, mTokenizer, mTokenAllocator,
|
||||
IsParserInDocWrite() ? nsnull : &mLineNumber);
|
||||
!mCountLines ? nsnull : &mLineNumber);
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
|
@ -1726,11 +1708,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1851,7 +1833,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1918,7 +1900,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();
|
||||
|
@ -2030,7 +2012,7 @@ CNavDTD::HandleDocTypeDeclToken(CToken* aToken)
|
|||
CDoctypeDeclToken* theToken = static_cast<CDoctypeDeclToken*>(aToken);
|
||||
nsAutoString docTypeStr(theToken->GetStringValue());
|
||||
// XXX Doesn't this count the newlines twice?
|
||||
if (!IsParserInDocWrite()) {
|
||||
if (mCountLines) {
|
||||
mLineNumber += docTypeStr.CountChar(kNewLine);
|
||||
}
|
||||
|
||||
|
@ -2090,7 +2072,7 @@ CNavDTD::CollectAttributes(nsIParserNode *aNode, eHTMLTags aTag, PRInt32 aCount)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!IsParserInDocWrite()) {
|
||||
if (mCountLines) {
|
||||
mLineNumber += theToken->GetNewlineCount();
|
||||
}
|
||||
|
||||
|
@ -3129,6 +3111,6 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ private:
|
|||
*/
|
||||
PRInt32 LastOf(eHTMLTags aTagSet[], PRInt32 aCount) const;
|
||||
|
||||
nsresult HandleToken(CToken* aToken, nsIParser* aParser);
|
||||
nsresult HandleToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when a start token has been
|
||||
|
@ -296,8 +296,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);
|
||||
|
@ -377,21 +376,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<nsIHTMLContentSink> mSink;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
nsDTDContext* mBodyContext;
|
||||
nsDTDContext* mTempContext;
|
||||
nsParser* mParser;
|
||||
PRBool mCountLines;
|
||||
nsITokenizer* mTokenizer; // weak
|
||||
|
||||
nsString mFilename;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsExpatDriver.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "CParserContext.h"
|
||||
|
@ -1302,15 +1301,16 @@ 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,
|
||||
nsIParser* aParser)
|
||||
nsExpatDriver::DidBuildModel(nsresult anErrorCode)
|
||||
{
|
||||
mOriginalSink = nsnull;
|
||||
mSink = nsnull;
|
||||
|
@ -1410,7 +1410,7 @@ nsExpatDriver::CopyState(nsITokenizer* aTokenizer)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsExpatDriver::HandleToken(CToken* aToken,nsIParser* aParser)
|
||||
nsExpatDriver::HandleToken(CToken* aToken)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
const PRUnichar* aNotationName);
|
||||
|
||||
private:
|
||||
nsresult HandleToken(CToken* aToken, nsIParser* aParser);
|
||||
nsresult HandleToken(CToken* aToken);
|
||||
|
||||
// Load up an external stream to get external entity information
|
||||
nsresult OpenInputStreamFromExternalDTD(const PRUnichar* aFPIStr,
|
||||
|
|
|
@ -1605,7 +1605,7 @@ nsParser::DidBuildModel(nsresult anErrorCode)
|
|||
PRBool terminated = mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING;
|
||||
if (mDTD && mSink &&
|
||||
mSink->ReadyToCallDidBuildModel(terminated)) {
|
||||
nsresult dtdResult = mDTD->DidBuildModel(anErrorCode,this),
|
||||
nsresult dtdResult = mDTD->DidBuildModel(anErrorCode),
|
||||
sinkResult = mSink->DidBuildModel();
|
||||
// nsIDTD::DidBuildModel used to be responsible for calling
|
||||
// nsIContentSink::DidBuildModel, but that obligation isn't expressible
|
||||
|
@ -2429,7 +2429,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 covariant.
|
||||
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 {
|
||||
|
|
|
@ -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...
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,12 +315,14 @@ 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;
|
||||
|
@ -444,14 +434,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;
|
||||
}
|
||||
|
@ -538,42 +534,35 @@ void CViewSourceHTML::AddAttrToNode(nsCParserStartNode& aNode,
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,
|
||||
nsIParser* aParser)
|
||||
NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode)
|
||||
{
|
||||
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 (mSink) {
|
||||
//now let's close automatically auto-opened containers...
|
||||
if (mSink) {
|
||||
//now let's close automatically auto-opened containers...
|
||||
|
||||
#ifdef DUMP_TO_FILE
|
||||
if(gDumpFile) {
|
||||
fprintf(gDumpFile, "</pre>\n");
|
||||
fprintf(gDumpFile, "</body>\n");
|
||||
fprintf(gDumpFile, "</html>\n");
|
||||
fclose(gDumpFile);
|
||||
}
|
||||
if(gDumpFile) {
|
||||
fprintf(gDumpFile, "</pre>\n");
|
||||
fprintf(gDumpFile, "</body>\n");
|
||||
fprintf(gDumpFile, "</html>\n");
|
||||
fclose(gDumpFile);
|
||||
}
|
||||
#endif // DUMP_TO_FILE
|
||||
|
||||
if(ePlainText!=mDocType) {
|
||||
mSink->CloseContainer(eHTMLTag_pre);
|
||||
mSink->CloseContainer(eHTMLTag_body);
|
||||
mSink->CloseContainer(eHTMLTag_html);
|
||||
}
|
||||
if(ePlainText!=mDocType) {
|
||||
mSink->CloseContainer(eHTMLTag_pre);
|
||||
mSink->CloseContainer(eHTMLTag_body);
|
||||
mSink->CloseContainer(eHTMLTag_html);
|
||||
}
|
||||
|
||||
START_TIMER();
|
||||
|
||||
}
|
||||
|
||||
START_TIMER();
|
||||
|
||||
#ifdef RAPTOR_PERF_METRICS
|
||||
NS_STOP_STOPWATCH(vsTimer);
|
||||
printf("viewsource timer: ");
|
||||
|
@ -717,6 +706,8 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
|
|||
// On the other hand, the parser messes up newline counting in some token
|
||||
// types (bug 137315). So our line numbers will disagree with the parser's
|
||||
// in some cases...
|
||||
// XXXbenjamn Shouldn't we be paying attention to the aCountLines BuildModel
|
||||
// parameter here?
|
||||
mLineNumber += aText.CountChar(PRUnichar('\n'));
|
||||
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
@ -837,14 +828,13 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
|
|||
* @return 0 if all is well; non-zero is an error
|
||||
*/
|
||||
nsresult
|
||||
CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser)
|
||||
CViewSourceHTML::HandleToken(CToken* aToken)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
CHTMLToken* theToken= (CHTMLToken*)(aToken);
|
||||
eHTMLTokenTypes theType= (eHTMLTokenTypes)theToken->GetTokenType();
|
||||
|
||||
mParser=(nsParser*)aParser;
|
||||
mSink=(nsIHTMLContentSink*)aParser->GetContentSink();
|
||||
NS_ASSERTION(mSink, "No sink in CViewSourceHTML::HandleToken? Was WillBuildModel called?");
|
||||
|
||||
mTokenNode.Init(theToken, mTokenizer->GetTokenAllocator());
|
||||
|
||||
|
@ -855,7 +845,7 @@ CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser)
|
|||
const nsSubstring& startValue = aToken->GetStringValue();
|
||||
result = WriteTag(kStartTag,startValue,aToken->GetAttributeCount(),aToken->IsInError());
|
||||
|
||||
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
|
||||
if((ePlainText!=mDocType) && (NS_OK==result)) {
|
||||
result = mSink->NotifyTagObservers(&mTokenNode);
|
||||
}
|
||||
}
|
||||
|
@ -1050,11 +1040,6 @@ nsresult CViewSourceHTML::CreateViewSourceURL(const nsAString& linkUrl,
|
|||
|
||||
// Default the view source URL to the empty string in case we fail.
|
||||
viewSourceUrl.Truncate();
|
||||
|
||||
// Get the character set.
|
||||
nsCString charset;
|
||||
PRInt32 source;
|
||||
mParser->GetDocumentCharset(charset, source);
|
||||
|
||||
// Get the BaseURI.
|
||||
rv = GetBaseURI(getter_AddRefs(baseURI));
|
||||
|
@ -1064,7 +1049,7 @@ nsresult CViewSourceHTML::CreateViewSourceURL(const nsAString& linkUrl,
|
|||
// the link URL may have untranslated entities in it.
|
||||
nsAutoString expandedLinkUrl;
|
||||
ExpandEntities(linkUrl, expandedLinkUrl);
|
||||
rv = NS_NewURI(getter_AddRefs(hrefURI), expandedLinkUrl, charset.get(), baseURI);
|
||||
rv = NS_NewURI(getter_AddRefs(hrefURI), expandedLinkUrl, mCharset.get(), baseURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the absolute URL from the link URI.
|
||||
|
@ -1202,14 +1187,9 @@ nsresult CViewSourceHTML::GetBaseURI(nsIURI **result) {
|
|||
}
|
||||
|
||||
nsresult CViewSourceHTML::SetBaseURI(const nsAString& baseSpec) {
|
||||
// Get the character set.
|
||||
nsCString charset;
|
||||
PRInt32 source;
|
||||
mParser->GetDocumentCharset(charset, source);
|
||||
|
||||
// Create a new base URI and store it in mBaseURI.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseURI), baseSpec, charset.get());
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseURI), baseSpec, mCharset.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mBaseURI = baseURI;
|
||||
return NS_OK;
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
virtual void SetVerification(PRBool aEnable);
|
||||
|
||||
private:
|
||||
nsresult HandleToken(CToken* aToken, nsIParser* aParser);
|
||||
nsresult HandleToken(CToken* aToken);
|
||||
|
||||
nsresult WriteTag(PRInt32 tagType,
|
||||
const nsSubstring &aText,
|
||||
|
@ -136,7 +136,7 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
nsParser* mParser;
|
||||
nsCString mCharset;
|
||||
nsIHTMLContentSink* mSink;
|
||||
PRInt32 mLineNumber;
|
||||
nsITokenizer* mTokenizer; // weak
|
||||
|
|
Загрузка…
Ссылка в новой задаче