Bug 714777 - Refactor fragment parsing out of nsHtml5Parser. r=smaug.

This commit is contained in:
Henri Sivonen 2012-01-20 13:16:27 +02:00
parent 6db281e157
commit 556cef528f
35 changed files with 360 additions and 214 deletions

View File

@ -79,9 +79,14 @@ static fp_except_t oldmask = fpsetmask(~allmask);
#include "nsINode.h"
#include "nsHashtable.h"
#include "nsIDOMNode.h"
#include "nsHtml5Parser.h"
#include "nsHtml5StringParser.h"
#include "nsIParser.h"
#include "nsIDocument.h"
#include "nsIFragmentContentSink.h"
#include "nsContentSink.h"
#include "nsMathUtils.h"
#include "nsThreadUtils.h"
#include "nsIContent.h"
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/AutoRestore.h"
@ -1939,7 +1944,7 @@ private:
static bool sFullScreenKeyInputRestricted;
static PRUint32 sHandlingInputTimeout;
static nsHtml5Parser* sHTMLFragmentParser;
static nsHtml5StringParser* sHTMLFragmentParser;
static nsIParser* sXMLFragmentParser;
static nsIFragmentContentSink* sXMLFragmentSink;

View File

@ -103,7 +103,7 @@ public:
NS_IMETHOD WillParse(void) { return NS_OK; }
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);

View File

@ -1354,7 +1354,7 @@ nsContentSink::WillResumeImpl()
nsresult
nsContentSink::DidProcessATokenImpl()
{
if (!mCanInterruptParser || !mParser || !mParser->CanInterrupt()) {
if (!mCanInterruptParser || !mParser) {
return NS_OK;
}
@ -1483,7 +1483,7 @@ nsContentSink::DropParserAndPerfHint(void)
// actually broken.
// Drop our reference to the parser to get rid of a circular
// reference.
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser.forget());
nsRefPtr<nsParserBase> kungFuDeathGrip(mParser.forget());
if (mDynamicLowerValue) {
// Reset the performance hint which was set to FALSE

View File

@ -307,7 +307,7 @@ private:
protected:
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIParser> mParser;
nsRefPtr<nsParserBase> mParser;
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIDocShell> mDocShell;
nsRefPtr<mozilla::css::Loader> mCSSLoader;

View File

@ -279,7 +279,7 @@ bool nsContentUtils::sFullScreenKeyInputRestricted = true;
PRUint32 nsContentUtils::sHandlingInputTimeout = 1000;
nsHtml5Parser* nsContentUtils::sHTMLFragmentParser = nsnull;
nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nsnull;
nsIParser* nsContentUtils::sXMLFragmentParser = nsnull;
nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nsnull;
bool nsContentUtils::sFragmentParsingActive = false;
@ -3663,8 +3663,7 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer,
mozilla::AutoRestore<bool> guard(nsContentUtils::sFragmentParsingActive);
nsContentUtils::sFragmentParsingActive = true;
if (!sHTMLFragmentParser) {
sHTMLFragmentParser =
static_cast<nsHtml5Parser*>(nsHtml5Module::NewHtml5Parser().get());
NS_ADDREF(sHTMLFragmentParser = new nsHtml5StringParser());
// Now sHTMLFragmentParser owns the object
}
nsresult rv =
@ -3674,7 +3673,6 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer,
aContextNamespace,
aQuirks,
aPreventScriptExecution);
sHTMLFragmentParser->Reset();
return rv;
}

View File

@ -104,7 +104,7 @@ public:
NS_IMETHOD WillParse(void) { return NS_OK; }
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);

View File

@ -191,7 +191,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt(void);
NS_IMETHOD WillResume(void);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
virtual void FlushPendingNotifications(mozFlushType aType);
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
virtual nsISupports *GetTarget();
@ -1716,7 +1716,7 @@ HTMLContentSink::DidBuildModel(bool aTerminated)
}
NS_IMETHODIMP
HTMLContentSink::SetParser(nsIParser* aParser)
HTMLContentSink::SetParser(nsParserBase* aParser)
{
NS_PRECONDITION(aParser, "Should have a parser here!");
mParser = aParser;

View File

@ -207,7 +207,7 @@ nsXMLContentSink::WillBuildModel(nsDTDMode aDTDMode)
// Check for correct load-command for maybe prettyprinting
if (mPrettyPrintXML) {
nsCAutoString command;
mParser->GetCommand(command);
GetParser()->GetCommand(command);
if (!command.EqualsLiteral("view")) {
mPrettyPrintXML = false;
}
@ -473,7 +473,7 @@ nsXMLContentSink::WillResume(void)
}
NS_IMETHODIMP
nsXMLContentSink::SetParser(nsIParser* aParser)
nsXMLContentSink::SetParser(nsParserBase* aParser)
{
NS_PRECONDITION(aParser, "Should have a parser here!");
mParser = aParser;
@ -502,7 +502,7 @@ nsXMLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
sele->SetScriptLineNumber(aLineNumber);
sele->SetCreatorParser(mParser);
sele->SetCreatorParser(GetParser());
mConstrainSize = false;
}
@ -604,7 +604,7 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
// I'm not sure if this is actually needed or not.
if (mParser && !mParser->IsParserEnabled()) {
// XXX The HTML sink doesn't call BlockParser here, why do we?
mParser->BlockParser();
GetParser()->BlockParser();
block = true;
}
@ -727,7 +727,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
nsCAutoString cmd;
if (mParser)
mParser->GetCommand(cmd);
GetParser()->GetCommand(cmd);
if (cmd.EqualsASCII(kLoadAsData))
return NS_OK; // Do not load stylesheets when loading as data
@ -1680,7 +1680,7 @@ void
nsXMLContentSink::ContinueInterruptedParsingIfEnabled()
{
if (mParser && mParser->IsParserEnabled()) {
mParser->ContinueInterruptedParsing();
GetParser()->ContinueInterruptedParsing();
}
}
@ -1693,3 +1693,8 @@ nsXMLContentSink::ContinueInterruptedParsingAsync()
NS_DispatchToCurrentThread(ev);
}
nsIParser*
nsXMLContentSink::GetParser()
{
return static_cast<nsIParser*>(mParser.get());
}

View File

@ -97,7 +97,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt(void);
NS_IMETHOD WillResume(void);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
virtual void FlushPendingNotifications(mozFlushType aType);
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
virtual nsISupports *GetTarget();
@ -117,6 +117,8 @@ public:
protected:
nsIParser* GetParser();
void ContinueInterruptedParsingIfEnabled();
// Start layout. If aIgnorePendingSheets is true, this will happen even if

View File

@ -211,7 +211,7 @@ nsXMLFragmentContentSink::WillBuildModel(nsDTDMode aDTDMode)
NS_IMETHODIMP
nsXMLFragmentContentSink::DidBuildModel(bool aTerminated)
{
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser);
nsRefPtr<nsParserBase> kungFuDeathGrip(mParser);
// Drop our reference to the parser to get rid of a circular
// reference.

View File

@ -115,7 +115,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
virtual void FlushPendingNotifications(mozFlushType aType) { }
NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
virtual nsISupports *GetTarget() { return nsnull; }

View File

@ -300,7 +300,7 @@ XULContentSinkImpl::WillResume(void)
}
NS_IMETHODIMP
XULContentSinkImpl::SetParser(nsIParser* aParser)
XULContentSinkImpl::SetParser(nsParserBase* aParser)
{
NS_IF_RELEASE(mParser);
mParser = aParser;

View File

@ -74,7 +74,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt(void);
NS_IMETHOD WillResume(void);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
virtual void FlushPendingNotifications(mozFlushType aType) { }
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
virtual nsISupports *GetTarget();
@ -180,7 +180,7 @@ protected:
nsRefPtr<nsXULPrototypeDocument> mPrototype; // [OWNER]
// We use regular pointer b/c of funky exports on nsIParser:
nsIParser* mParser; // [OWNER]
nsParserBase* mParser; // [OWNER]
nsCOMPtr<nsIScriptSecurityManager> mSecMan;
};

View File

@ -77,6 +77,7 @@ EXPORTS = \
nsHtml5DependentUTF16Buffer.h \
nsHtml5OwningUTF16Buffer.h \
nsHtml5ViewSourceUtils.h \
nsHtml5StringParser.h \
$(NULL)
CPPSRCS = \
@ -110,6 +111,7 @@ CPPSRCS = \
nsHtml5SVGLoadDispatcher.cpp \
nsHtml5Highlighter.cpp \
nsHtml5ViewSourceUtils.cpp \
nsHtml5StringParser.cpp \
$(NULL)
FORCE_STATIC_LIB = 1

View File

@ -565,79 +565,6 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsHtml5Parser::ParseHtml5Fragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
PRInt32 aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution)
{
NS_ENSURE_TRUE(aSourceBuffer.Length() <= PR_INT32_MAX,
NS_ERROR_OUT_OF_MEMORY);
nsIDocument* doc = aTargetNode->OwnerDoc();
nsIURI* uri = doc->GetDocumentURI();
NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
mExecutor->EnableFragmentMode(aPreventScriptExecution);
Initialize(doc, uri, nsnull, nsnull);
mExecutor->SetParser(this);
mExecutor->SetNodeInfoManager(doc->NodeInfoManager());
nsIContent* target = aTargetNode;
mTreeBuilder->setFragmentContext(aContextLocalName,
aContextNamespace,
&target,
aQuirks);
#ifdef DEBUG
if (!aPreventScriptExecution) {
NS_ASSERTION(!aTargetNode->IsInDoc(),
"If script execution isn't prevented, "
"the target node must not be in doc.");
nsCOMPtr<nsIDOMDocumentFragment> domFrag = do_QueryInterface(aTargetNode);
NS_ASSERTION(domFrag,
"If script execution isn't prevented, must parse to DOM fragment.");
}
#endif
NS_PRECONDITION(!mExecutor->HasStarted(),
"Tried to start parse without initializing the parser.");
mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
mTokenizer->start();
mExecutor->Start(); // Don't call WillBuildModel in fragment case
if (!aSourceBuffer.IsEmpty()) {
bool lastWasCR = false;
nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
while (buffer.hasMore()) {
buffer.adjust(lastWasCR);
lastWasCR = false;
if (buffer.hasMore()) {
lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
if (mTreeBuilder->HasScript()) {
// Flush on each script, because the execution prevention code
// can handle at most one script per flush.
mTreeBuilder->Flush(); // Move ops to the executor
mExecutor->FlushDocumentWrite(); // run the ops
}
}
}
}
mTokenizer->eof();
mTreeBuilder->StreamEnded();
mTreeBuilder->Flush();
mExecutor->FlushDocumentWrite();
mTokenizer->end();
mExecutor->DropParserAndPerfHint();
mExecutor->DropHeldElements();
mTreeBuilder->DropHandles();
mAtomTable.Clear();
return NS_OK;
}
NS_IMETHODIMP
nsHtml5Parser::BuildModel()
{
@ -655,21 +582,7 @@ nsHtml5Parser::CancelParsingEvents()
void
nsHtml5Parser::Reset()
{
NS_PRECONDITION(mExecutor->IsFragmentMode(),
"Reset called on a non-fragment parser.");
mExecutor->Reset();
mLastWasCR = false;
UnblockParser();
mDocumentClosed = false;
mStreamParser = nsnull;
mRootContextLineNumber = 1;
mParserInsertedScriptsBeingEvaluated = 0;
mAtomTable.Clear(); // should be already cleared in the fragment case anyway
// Portable parser objects
mFirstBuffer->next = nsnull;
mFirstBuffer->setStart(0);
mFirstBuffer->setEnd(0);
mLastBuffer = mFirstBuffer;
NS_NOTREACHED("Don't call this!");
}
bool

View File

@ -213,7 +213,7 @@ class nsHtml5Parser : public nsIParser,
NS_IMETHODIMP CancelParsingEvents();
/**
* Sets the state to initial values
* Don't call. For interface compat only.
*/
virtual void Reset();
@ -253,25 +253,6 @@ class nsHtml5Parser : public nsIParser,
/* End nsIParser */
/**
* Invoke the fragment parsing algorithm (innerHTML).
*
* @param aSourceBuffer the string being set as innerHTML
* @param aTargetNode the target container
* @param aContextLocalName local name of context node
* @param aContextNamespace namespace of context node
* @param aQuirks true to make <table> not close <p>
* @param aPreventScriptExecution true to prevent scripts from executing;
* don't set to false when parsing into a target node that has been bound
* to tree.
*/
nsresult ParseHtml5Fragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
PRInt32 aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution);
// Not from an external interface
// Non-inherited methods

View File

@ -0,0 +1,137 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsHtml5StringParser.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5Tokenizer.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsHtml5DependentUTF16Buffer.h"
NS_IMPL_ISUPPORTS0(nsHtml5StringParser)
nsHtml5StringParser::nsHtml5StringParser()
: mExecutor(new nsHtml5TreeOpExecutor())
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nsnull))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
{
MOZ_COUNT_CTOR(nsHtml5StringParser);
mAtomTable.Init(); // we aren't checking for OOM anyway...
mTokenizer->setInterner(&mAtomTable);
}
nsHtml5StringParser::~nsHtml5StringParser()
{
MOZ_COUNT_DTOR(nsHtml5StringParser);
}
nsresult
nsHtml5StringParser::ParseHtml5Fragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
PRInt32 aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution)
{
NS_ENSURE_TRUE(aSourceBuffer.Length() <= PR_INT32_MAX,
NS_ERROR_OUT_OF_MEMORY);
nsIDocument* doc = aTargetNode->OwnerDoc();
nsIURI* uri = doc->GetDocumentURI();
NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
mExecutor->EnableFragmentMode(aPreventScriptExecution);
mExecutor->Init(doc, uri, nsnull, nsnull);
mExecutor->SetParser(this);
mExecutor->SetNodeInfoManager(doc->NodeInfoManager());
nsIContent* target = aTargetNode;
mTreeBuilder->setFragmentContext(aContextLocalName,
aContextNamespace,
&target,
aQuirks);
#ifdef DEBUG
if (!aPreventScriptExecution) {
NS_ASSERTION(!aTargetNode->IsInDoc(),
"If script execution isn't prevented, "
"the target node must not be in doc.");
nsCOMPtr<nsIDOMDocumentFragment> domFrag = do_QueryInterface(aTargetNode);
NS_ASSERTION(domFrag,
"If script execution isn't prevented, must parse to DOM fragment.");
}
#endif
NS_PRECONDITION(!mExecutor->HasStarted(),
"Tried to start parse without initializing the parser.");
mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
mTokenizer->start();
mExecutor->Start(); // Don't call WillBuildModel in fragment case
if (!aSourceBuffer.IsEmpty()) {
bool lastWasCR = false;
nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
while (buffer.hasMore()) {
buffer.adjust(lastWasCR);
lastWasCR = false;
if (buffer.hasMore()) {
lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
if (mTreeBuilder->HasScript()) {
// Flush on each script, because the execution prevention code
// can handle at most one script per flush.
mTreeBuilder->Flush(); // Move ops to the executor
mExecutor->FlushDocumentWrite(); // run the ops
}
}
}
}
mTokenizer->eof();
mTreeBuilder->StreamEnded();
mTreeBuilder->Flush();
mExecutor->FlushDocumentWrite();
mTokenizer->end();
mExecutor->DropParserAndPerfHint();
mExecutor->DropHeldElements();
mTreeBuilder->DropHandles();
mAtomTable.Clear();
mExecutor->Reset();
return NS_OK;
}

View File

@ -0,0 +1,101 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsHtml5StringParser_h_
#define nsHtml5StringParser_h_
#include "nsHtml5AtomTable.h"
#include "nsParserBase.h"
class nsHtml5TreeOpExecutor;
class nsHtml5TreeBuilder;
class nsHtml5Tokenizer;
class nsIContent;
class nsHtml5StringParser : public nsParserBase
{
public:
NS_DECL_ISUPPORTS
nsHtml5StringParser();
virtual ~nsHtml5StringParser();
/**
* Invoke the fragment parsing algorithm (innerHTML).
*
* @param aSourceBuffer the string being set as innerHTML
* @param aTargetNode the target container
* @param aContextLocalName local name of context node
* @param aContextNamespace namespace of context node
* @param aQuirks true to make <table> not close <p>
* @param aPreventScriptExecution true to prevent scripts from executing;
* don't set to false when parsing into a target node that has been bound
* to tree.
*/
nsresult ParseHtml5Fragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
PRInt32 aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution);
private:
/**
* The tree operation executor
*/
nsRefPtr<nsHtml5TreeOpExecutor> mExecutor;
/**
* The HTML5 tree builder
*/
const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
/**
* The HTML5 tokenizer
*/
const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
/**
* The scoped atom table
*/
nsHtml5AtomTable mAtomTable;
};
#endif // nsHtml5StringParser_h_

View File

@ -196,7 +196,7 @@ nsHtml5TreeOpExecutor::WillResume()
}
NS_IMETHODIMP
nsHtml5TreeOpExecutor::SetParser(nsIParser* aParser)
nsHtml5TreeOpExecutor::SetParser(nsParserBase* aParser)
{
mParser = aParser;
return NS_OK;
@ -426,7 +426,7 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
nsHtml5FlushLoopGuard guard(this); // this is also the self-kungfu!
nsCOMPtr<nsIParser> parserKungFuDeathGrip(mParser);
nsCOMPtr<nsISupports> parserKungFuDeathGrip(mParser);
// Remember the entry time
(void) nsContentSink::WillParseImpl();
@ -593,7 +593,7 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
// avoid crashing near EOF
nsRefPtr<nsHtml5TreeOpExecutor> kungFuDeathGrip(this);
nsCOMPtr<nsIParser> parserKungFuDeathGrip(mParser);
nsRefPtr<nsParserBase> parserKungFuDeathGrip(mParser);
NS_ASSERTION(!mReadingFromStage,
"Got doc write flush when reading from stage");
@ -746,7 +746,7 @@ nsHtml5TreeOpExecutor::RunScript(nsIContent* aScriptElement)
mReadingFromStage = false;
sele->SetCreatorParser(mParser);
sele->SetCreatorParser(GetParser());
// Copied from nsXMLContentSink
// Now tell the script that it's ready to go. This may execute the script
@ -757,7 +757,7 @@ nsHtml5TreeOpExecutor::RunScript(nsIContent* aScriptElement)
// Else, block the parser till the script has loaded.
if (block) {
if (mParser) {
mParser->BlockParser();
GetParser()->BlockParser();
}
} else {
// mParser may have been nulled out by now, but the flusher deals
@ -833,12 +833,12 @@ void
nsHtml5TreeOpExecutor::Reset()
{
DropHeldElements();
mReadingFromStage = false;
mOpQueue.Clear();
mStarted = false;
mFlushState = eNotFlushing;
mRunFlushLoopOnStack = false;
NS_ASSERTION(!mBroken, "Fragment parser got broken.");
NS_ASSERTION(!mReadingFromStage, "String parser reading from stage?");
NS_ASSERTION(!mBroken, "String parser got broken.");
}
void

View File

@ -179,7 +179,7 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
/**
* Sets the parser.
*/
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
/**
* No-op for backwards compat.

View File

@ -67,6 +67,7 @@ EXPORTS = \
nsParserCIID.h \
nsToken.h \
nsParserConstants.h \
nsParserBase.h \
$(NULL)
ifdef MOZ_DEBUG

View File

@ -54,7 +54,7 @@
#include "mozFlushType.h"
#include "nsIDTD.h"
class nsIParser;
class nsParserBase;
#define NS_ICONTENT_SINK_IID \
{ 0xcf9a7cbb, 0xfcbc, 0x4e13, \
@ -122,7 +122,7 @@ public:
* is that the content sink will drop the reference when it
* gets the DidBuildModel notification i.e. when parsing is done.
*/
NS_IMETHOD SetParser(nsIParser* aParser)=0;
NS_IMETHOD SetParser(nsParserBase* aParser)=0;
/**
* Flush content so that the content model is in sync with the state

View File

@ -59,9 +59,8 @@
#include "nsITokenizer.h"
#define NS_IDTD_IID \
{ 0xcc374204, 0xcea2, 0x41a2, \
{ 0xb2, 0x7f, 0x83, 0x75, 0xe2, 0xcf, 0x97, 0xcf } }
{ 0x3de05873, 0xefa7, 0x410d, \
{ 0xa4, 0x61, 0x80, 0x33, 0xaf, 0xd9, 0xe3, 0x26 } }
enum eAutoDetectResult {
eUnknownDetect,
@ -109,8 +108,6 @@ public:
* 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
@ -118,7 +115,6 @@ public:
* opts to ignore this parameter)
*/
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer,
bool aCanInterrupt,
bool aCountLines,
const nsCString* aCharsetPtr) = 0;
@ -169,7 +165,7 @@ 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);\
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, bool aCanInterrupt, bool aCountLines, const nsCString* aCharsetPtr);\
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, bool aCountLines, const nsCString* aCharsetPtr);\
NS_IMETHOD_(bool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
NS_IMETHOD_(bool) IsContainer(PRInt32 aTag) const;\
NS_IMETHOD_(void) Terminate();\

View File

@ -53,10 +53,11 @@
#include "nsStringGlue.h"
#include "nsTArray.h"
#include "nsIAtom.h"
#include "nsParserBase.h"
#define NS_IPARSER_IID \
{ 0x11a4f41f, 0x7044, 0x4c57, \
{ 0xb3, 0xa4, 0xed, 0x79, 0xc7, 0xc4, 0x61, 0x99 } }
{ 0xd064f0d6, 0x44e3, 0x4366, \
{ 0xa7, 0x05, 0xcf, 0x7a, 0x91, 0x26, 0x14, 0xb6 } }
// {41421C60-310A-11d4-816F-000064657374}
#define NS_IDEBUG_DUMP_CONTENT_IID \
@ -129,7 +130,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDebugDumpContent, NS_IDEBUG_DUMP_CONTENT_IID)
* This class defines the iparser interface. This XPCOM
* inteface is all that parser clients ever need to see.
*/
class nsIParser : public nsISupports {
class nsIParser : public nsParserBase {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSER_IID)
@ -273,12 +274,6 @@ class nsIParser : public nsISupports {
virtual void Reset() = 0;
/**
* True if the parser can currently be interrupted. Returns false when
* parsing for example document.write or innerHTML.
*/
virtual bool CanInterrupt() = 0;
/**
* True if the insertion point (per HTML5) is defined.
*/

View File

@ -0,0 +1,53 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is parser base code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsParserBase_h_
#define nsParserBase_h_
#include "nsIChannel.h"
class nsParserBase : public nsISupports
{
public:
virtual bool IsParserEnabled() { return true; }
NS_IMETHOD GetChannel(nsIChannel** aChannel) {
*aChannel = nsnull;
return NS_OK;
};
};
#endif // nsParserBase_h_

View File

@ -225,7 +225,6 @@ CNavDTD::WillBuildModel(const CParserContext& aParserContext,
NS_IMETHODIMP
CNavDTD::BuildModel(nsITokenizer* aTokenizer,
bool aCanInterrupt,
bool aCountLines,
const nsCString*)
{
@ -310,11 +309,9 @@ CNavDTD::BuildModel(nsITokenizer* aTokenizer,
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 (e.g., not in a document.write).
// We also need to make sure that an interruption does not override
// We need to make sure that an interruption does not override
// a request to block the parser.
if (aCanInterrupt && NS_SUCCEEDED(result)) {
if (NS_SUCCEEDED(result)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
@ -338,12 +335,10 @@ CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
CToken* target = mTokenAllocator->CreateTokenOfType(aType, aTarget);
NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
mTokenizer->PushTokenFront(target);
// Always safe to disallow interruptions, so it doesn't matter that we've
// forgotten the aCanInterrupt parameter to BuildModel. Also, 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, false, mCountLines, 0);
// what the charset was, so 0 can and must suffice.
return BuildModel(mTokenizer, mCountLines, 0);
}
NS_IMETHODIMP

View File

@ -1302,7 +1302,6 @@ nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
NS_IMETHODIMP
nsExpatDriver::BuildModel(nsITokenizer* aTokenizer,
bool,// aCanInterrupt,
bool,// aCountLines,
const nsCString*)// aCharsetPtr)
{

View File

@ -66,7 +66,6 @@ nsLoggingSink::nsLoggingSink() {
mOutput = 0;
mLevel=-1;
mSink=0;
mParser=0;
}
nsLoggingSink::~nsLoggingSink() {
@ -152,7 +151,7 @@ nsLoggingSink::WillResume() {
}
NS_IMETHODIMP
nsLoggingSink::SetParser(nsIParser* aParser) {
nsLoggingSink::SetParser(nsParserBase* aParser) {
nsresult theResult=NS_OK;
//proxy the call to the real sink if you have one.
@ -160,12 +159,6 @@ nsLoggingSink::SetParser(nsIParser* aParser) {
theResult=mSink->SetParser(aParser);
}
NS_IF_RELEASE(mParser);
mParser = aParser;
NS_IF_ADDREF(mParser);
return theResult;
}

View File

@ -65,7 +65,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt();
NS_IMETHOD WillResume();
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
@ -106,7 +106,6 @@ protected:
int mLevel;
nsIHTMLContentSink *mSink;
bool mAutoDeleteOutput;
nsIParser* mParser;
};
#endif

View File

@ -80,7 +80,6 @@ using namespace mozilla;
#define NS_PARSER_FLAG_PARSER_ENABLED 0x00000002
#define NS_PARSER_FLAG_OBSERVERS_ENABLED 0x00000004
#define NS_PARSER_FLAG_PENDING_CONTINUE_EVENT 0x00000008
#define NS_PARSER_FLAG_CAN_INTERRUPT 0x00000010
#define NS_PARSER_FLAG_FLUSH_TOKENS 0x00000020
#define NS_PARSER_FLAG_CAN_TOKENIZE 0x00000040
@ -1231,12 +1230,6 @@ void nsParser::HandleParserContinueEvent(nsParserContinueEvent *ev)
ContinueInterruptedParsing();
}
bool
nsParser::CanInterrupt()
{
return (mFlags & NS_PARSER_FLAG_CAN_INTERRUPT) != 0;
}
bool
nsParser::IsInsertionPointDefined()
{
@ -1264,16 +1257,6 @@ nsParser::IsScriptCreated()
return false;
}
void
nsParser::SetCanInterrupt(bool aCanInterrupt)
{
if (aCanInterrupt) {
mFlags |= NS_PARSER_FLAG_CAN_INTERRUPT;
} else {
mFlags &= ~NS_PARSER_FLAG_CAN_INTERRUPT;
}
}
/**
* This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner,
@ -1601,7 +1584,6 @@ nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk,
// Only allow parsing to be interrupted in the subsequent call to
// build model.
SetCanInterrupt(aCanInterrupt);
nsresult theTokenizerResult = (mFlags & NS_PARSER_FLAG_CAN_TOKENIZE)
? Tokenize(aIsFinalChunk)
: NS_OK;
@ -1610,7 +1592,6 @@ nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk,
if (result == NS_ERROR_HTMLPARSER_INTERRUPTED && aIsFinalChunk) {
PostContinueEvent();
}
SetCanInterrupt(false);
theIterationIsOk = theTokenizerResult != kEOF &&
result != NS_ERROR_HTMLPARSER_INTERRUPTED;
@ -1700,11 +1681,9 @@ nsParser::BuildModel()
if (NS_SUCCEEDED(result)) {
if (mDTD) {
// XXXbenjamn CanInterrupt() and !inDocWrite appear to be covariant.
bool inDocWrite = !!mParserContext->mPrevContext;
result = mDTD->BuildModel(theTokenizer,
// ignore interruptions in document.write
CanInterrupt() && !inDocWrite,
!inDocWrite, // don't count lines in document.write
&mCharset);
}

View File

@ -309,14 +309,6 @@ class nsParser : public nsIParser,
NS_IMETHODIMP CancelParsingEvents();
/**
* Indicates whether the parser is in a state where it
* can be interrupted.
* @return true if parser can be interrupted, false if it can not be interrupted.
* @update kmcclusk 5/18/98
*/
virtual bool CanInterrupt();
/**
* Return true.
*/

View File

@ -107,7 +107,7 @@ nsSAXXMLReader::DidBuildModel(bool aTerminated)
}
NS_IMETHODIMP
nsSAXXMLReader::SetParser(nsIParser *aParser)
nsSAXXMLReader::SetParser(nsParserBase *aParser)
{
return NS_OK;
}

View File

@ -79,7 +79,7 @@ public:
NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode);
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
NS_IMETHOD WillInterrupt()
{

View File

@ -169,7 +169,7 @@ public:
NS_IMETHOD DidBuildModel(bool aTerminated);
NS_IMETHOD WillInterrupt(void);
NS_IMETHOD WillResume(void);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD SetParser(nsParserBase* aParser);
virtual void FlushPendingNotifications(mozFlushType aType) { }
NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
virtual nsISupports *GetTarget() { return nsnull; }
@ -643,7 +643,7 @@ RDFContentSinkImpl::WillResume(void)
}
NS_IMETHODIMP
RDFContentSinkImpl::SetParser(nsIParser* aParser)
RDFContentSinkImpl::SetParser(nsParserBase* aParser)
{
return NS_OK;
}

View File

@ -355,7 +355,7 @@ public:
NS_IMETHOD WillParse() { return NS_OK; }
NS_IMETHOD WillInterrupt() { return NS_OK; }
NS_IMETHOD WillResume() { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
virtual void FlushPendingNotifications(mozFlushType aType) { }
NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
virtual nsISupports *GetTarget() { return nsnull; }