NewXMLDocumentParser.cpp [plain text]
#include "config.h"
#include "NewXMLDocumentParser.h"
#include "DocumentFragment.h"
#include "ScriptElement.h"
#include "ScriptSourceCode.h"
#include "SegmentedString.h"
#include "XMLTreeBuilder.h"
#include "XMLTreeViewer.h"
namespace WebCore {
NewXMLDocumentParser::NewXMLDocumentParser(Document* document)
: ScriptableDocumentParser(document)
, m_tokenizer(XMLTokenizer::create())
, m_parserPaused(false)
, m_finishWasCalled(false)
, m_pendingScript(0)
, m_scriptElement(0)
, m_treeBuilder(XMLTreeBuilder::create(this, document))
{
}
NewXMLDocumentParser::NewXMLDocumentParser(DocumentFragment* fragment, Element* parent, FragmentScriptingPermission)
: ScriptableDocumentParser(fragment->document())
, m_tokenizer(XMLTokenizer::create())
, m_parserPaused(false)
, m_finishWasCalled(false)
, m_pendingScript(0)
, m_scriptElement(0)
, m_treeBuilder(XMLTreeBuilder::create(this, fragment, parent))
{
}
bool NewXMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
{
if (!chunk.length())
return true;
RefPtr<NewXMLDocumentParser> parser = NewXMLDocumentParser::create(fragment, contextElement, scriptingPermission);
parser->append(SegmentedString(chunk));
parser->detach();
return true;
}
NewXMLDocumentParser::~NewXMLDocumentParser()
{
}
void NewXMLDocumentParser::resumeParsing()
{
m_parserPaused = false;
append(m_input);
}
void NewXMLDocumentParser::processScript(ScriptElement* scriptElement)
{
if (scriptElement->prepareScript(TextPosition(), ScriptElement::AllowLegacyTypeInTypeAttribute)) {
if (scriptElement->readyToBeParserExecuted())
scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), TextPosition()));
else if (scriptElement->willBeParserExecuted()) {
m_pendingScript = scriptElement->cachedScript();
m_scriptElement = scriptElement->element();
m_pendingScript->addClient(this);
if (m_pendingScript)
pauseParsing();
} else
m_scriptElement = 0;
}
}
TextPosition NewXMLDocumentParser::textPosition() const
{
return TextPosition::minimumPosition();
}
OrdinalNumber NewXMLDocumentParser::lineNumber() const
{
return OrdinalNumber::first();
}
void NewXMLDocumentParser::insert(const SegmentedString&)
{
ASSERT_NOT_REACHED();
}
void NewXMLDocumentParser::append(const SegmentedString& string)
{
m_input = string;
while (!m_input.isEmpty() && isParsing() && !m_parserPaused) {
if (!m_tokenizer->nextToken(m_input, m_token))
continue;
#ifndef NDEBUG
m_token.print();
#endif
AtomicXMLToken token(m_token);
m_treeBuilder->processToken(token);
if (m_token.type() == XMLTokenTypes::EndOfFile)
break;
m_token.clear();
ASSERT(m_token.isUninitialized());
}
}
void NewXMLDocumentParser::finish()
{
ASSERT(!m_finishWasCalled);
if (m_parserPaused)
return;
m_treeBuilder->finish();
m_finishWasCalled = true;
if (isParsing()) {
#if ENABLE(XSLT)
XMLTreeViewer xmlTreeViewer(document());
if (xmlTreeViewer.hasNoStyleInformation())
xmlTreeViewer.transformDocumentToTreeView();
#endif // ENABLE(XSLT)
prepareToStopParsing();
}
document()->setReadyState(Document::Interactive);
document()->finishedParsing();
}
bool NewXMLDocumentParser::hasInsertionPoint()
{
return false;
}
bool NewXMLDocumentParser::finishWasCalled()
{
return m_finishWasCalled;
}
bool NewXMLDocumentParser::isWaitingForScripts() const
{
return false;
}
bool NewXMLDocumentParser::isExecutingScript() const
{
return false;
}
void NewXMLDocumentParser::executeScriptsWaitingForStylesheets()
{
}
void NewXMLDocumentParser::notifyFinished(CachedResource* unusedResource)
{
ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript);
ASSERT(m_pendingScript->accessCount() > 0);
ScriptSourceCode sourceCode(m_pendingScript.get());
bool errorOccurred = m_pendingScript->errorOccurred();
bool wasCanceled = m_pendingScript->wasCanceled();
m_pendingScript->removeClient(this);
m_pendingScript = 0;
RefPtr<Element> element = m_scriptElement;
ScriptElement* scriptElement = toScriptElement(m_scriptElement.get());
m_scriptElement = 0;
ASSERT(scriptElement);
RefPtr<NewXMLDocumentParser> protect(this);
if (errorOccurred)
scriptElement->dispatchErrorEvent();
else if (!wasCanceled) {
scriptElement->executeScript(sourceCode);
scriptElement->dispatchLoadEvent();
}
if (!isDetached() && m_parserPaused)
resumeParsing();
}
}