Diff
Modified: trunk/Source/WebCore/ChangeLog (93379 => 93380)
--- trunk/Source/WebCore/ChangeLog 2011-08-19 01:04:12 UTC (rev 93379)
+++ trunk/Source/WebCore/ChangeLog 2011-08-19 01:09:34 UTC (rev 93380)
@@ -1,3 +1,25 @@
+2011-08-18 Jeffrey Pfau <[email protected]>
+
+ New XML parser: scripting support
+ https://bugs.webkit.org/show_bug.cgi?id=66406
+
+ Reviewed by Adam Barth.
+
+ * xml/parser/NewXMLDocumentParser.cpp:
+ (WebCore::NewXMLDocumentParser::NewXMLDocumentParser):
+ (WebCore::NewXMLDocumentParser::resumeParsing):
+ (WebCore::NewXMLDocumentParser::processScript):
+ (WebCore::NewXMLDocumentParser::append): Add support for pausing the parsing
+ (WebCore::NewXMLDocumentParser::finish): Add support for pausing the parsing
+ (WebCore::NewXMLDocumentParser::notifyFinished):
+ * xml/parser/NewXMLDocumentParser.h:
+ (WebCore::NewXMLDocumentParser::pauseParsing):
+ * xml/parser/XMLTreeBuilder.cpp: Add a shared function between self-closing and end tags
+ (WebCore::XMLTreeBuilder::closeElement): Registers scripts and pops the stack
+ (WebCore::XMLTreeBuilder::processStartTag):
+ (WebCore::XMLTreeBuilder::processEndTag):
+ * xml/parser/XMLTreeBuilder.h:
+
2011-08-18 Mark Hahnenberg <[email protected]>
Move allocation in constructors into separate constructorBody() methods
Modified: trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp (93379 => 93380)
--- trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp 2011-08-19 01:04:12 UTC (rev 93379)
+++ trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp 2011-08-19 01:09:34 UTC (rev 93380)
@@ -27,6 +27,8 @@
#include "NewXMLDocumentParser.h"
#include "DocumentFragment.h"
+#include "ScriptElement.h"
+#include "ScriptSourceCode.h"
#include "SegmentedString.h"
#include "XMLTreeBuilder.h"
@@ -35,7 +37,10 @@
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))
{
}
@@ -43,7 +48,10 @@
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))
{
}
@@ -67,6 +75,30 @@
{
}
+void NewXMLDocumentParser::resumeParsing()
+{
+ m_parserPaused = false;
+ append(m_input);
+}
+
+void NewXMLDocumentParser::processScript(ScriptElement* scriptElement)
+{
+ if (scriptElement->prepareScript(TextPosition1(), ScriptElement::AllowLegacyTypeInTypeAttribute)) {
+ if (scriptElement->readyToBeParserExecuted())
+ scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), TextPosition1()));
+ else if (scriptElement->willBeParserExecuted()) {
+ m_pendingScript = scriptElement->cachedScript();
+ m_scriptElement = scriptElement->element();
+ m_pendingScript->addClient(this);
+
+ // m_pendingScript will be 0 if script was already loaded and addClient() executed it.
+ if (m_pendingScript)
+ pauseParsing();
+ } else
+ m_scriptElement = 0;
+ }
+}
+
TextPosition0 NewXMLDocumentParser::textPosition() const
{
return TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(0),
@@ -85,9 +117,9 @@
void NewXMLDocumentParser::append(const SegmentedString& string)
{
- SegmentedString input = string;
- while (!input.isEmpty()) {
- if (!m_tokenizer->nextToken(input, m_token))
+ m_input = string;
+ while (!m_input.isEmpty() && isParsing() && !m_parserPaused) {
+ if (!m_tokenizer->nextToken(m_input, m_token))
continue;
#ifndef NDEBUG
@@ -97,7 +129,7 @@
AtomicXMLToken token(m_token);
m_treeBuilder->processToken(token);
- if (m_token.type() == XMLTokenTypes::EndOfFile || !isParsing())
+ if (m_token.type() == XMLTokenTypes::EndOfFile)
break;
m_token.clear();
@@ -108,8 +140,11 @@
void NewXMLDocumentParser::finish()
{
ASSERT(!m_finishWasCalled);
+
+ if (m_parserPaused)
+ return;
+
m_finishWasCalled = true;
-
if (isParsing())
prepareToStopParsing();
document()->setReadyState(Document::Interactive);
@@ -140,4 +175,36 @@
{
}
+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);
+
+ // _javascript_ can detach this parser, make sure it's kept alive even if detached.
+ RefPtr<NewXMLDocumentParser> protect(this);
+
+ if (errorOccurred)
+ scriptElement->dispatchErrorEvent();
+ else if (!wasCanceled) {
+ scriptElement->executeScript(sourceCode);
+ scriptElement->dispatchLoadEvent();
+ }
+
+ if (!isDetached() && m_parserPaused)
+ resumeParsing();
}
+
+}
Modified: trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h (93379 => 93380)
--- trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h 2011-08-19 01:04:12 UTC (rev 93379)
+++ trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h 2011-08-19 01:09:34 UTC (rev 93380)
@@ -27,6 +27,8 @@
#define NewXMLDocumentParser_h
#include "CachedResourceClient.h"
+#include "CachedResourceHandle.h"
+#include "CachedScript.h"
#include "ScriptableDocumentParser.h"
#include "XMLToken.h"
#include "XMLTokenizer.h"
@@ -35,11 +37,12 @@
namespace WebCore {
+class ContainerNode;
class Document;
-class ContainerNode;
+class ScriptElement;
class XMLTreeBuilder;
-class NewXMLDocumentParser : public ScriptableDocumentParser {
+class NewXMLDocumentParser : public ScriptableDocumentParser, public CachedResourceClient {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<NewXMLDocumentParser> create(Document* document)
@@ -54,6 +57,10 @@
static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = FragmentScriptingAllowed);
+ void pauseParsing() { m_parserPaused = true; }
+ void resumeParsing();
+ void processScript(ScriptElement*);
+
virtual TextPosition0 textPosition() const;
virtual int lineNumber() const;
@@ -64,6 +71,9 @@
virtual bool isExecutingScript() const;
virtual void executeScriptsWaitingForStylesheets();
+ // CachedResourceClient
+ virtual void notifyFinished(CachedResource*);
+
protected:
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
@@ -74,11 +84,16 @@
NewXMLDocumentParser(DocumentFragment*, Element* parent, FragmentScriptingPermission);
virtual ~NewXMLDocumentParser();
+ SegmentedString m_input;
OwnPtr<XMLTokenizer> m_tokenizer;
XMLToken m_token;
+ bool m_parserPaused;
bool m_finishWasCalled;
+ CachedResourceHandle<CachedScript> m_pendingScript;
+ RefPtr<Element> m_scriptElement;
+
OwnPtr<XMLTreeBuilder> m_treeBuilder;
};
Modified: trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp (93379 => 93380)
--- trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp 2011-08-19 01:04:12 UTC (rev 93379)
+++ trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp 2011-08-19 01:09:34 UTC (rev 93380)
@@ -26,6 +26,7 @@
#include "config.h"
#include "XMLTreeBuilder.h"
+#include "CachedScript.h"
#include "CDATASection.h"
#include "Comment.h"
#include "Document.h"
@@ -35,6 +36,8 @@
#include "HTMLEntitySearch.h"
#include "NewXMLDocumentParser.h"
#include "ProcessingInstruction.h"
+#include "ScriptElement.h"
+#include "ScriptSourceCode.h"
#include "XMLNSNames.h"
#include "XMLNames.h"
@@ -143,6 +146,17 @@
m_currentNodeStack.removeLast();
}
+void XMLTreeBuilder::closeElement(PassRefPtr<Element> element)
+{
+ element->finishParsingChildren();
+
+ ScriptElement* scriptElement = toScriptElement(element.get());
+ if (scriptElement)
+ m_parser->processScript(scriptElement);
+
+ popCurrentNode();
+}
+
void XMLTreeBuilder::processProcessingInstruction(const AtomicXMLToken& token)
{
if (!failOnText())
@@ -230,10 +244,8 @@
if (isFirstElement && m_document->frame())
m_document->frame()->loader()->dispatchDocumentElementAvailable();
- if (token.selfClosing()) {
- popCurrentNode();
- newElement->finishParsingChildren();
- }
+ if (token.selfClosing())
+ closeElement(newElement);
}
void XMLTreeBuilder::processEndTag(const AtomicXMLToken& token)
@@ -245,8 +257,7 @@
if (!node->hasTagName(QualifiedName(token.prefix(), token.name(), m_currentNodeStack.last().namespaceForPrefix(token.prefix(), m_currentNodeStack.last().namespaceURI()))))
m_parser->stopParsing();
- popCurrentNode();
- node->finishParsingChildren();
+ closeElement(toElement(node.get()));
}
void XMLTreeBuilder::processCharacter(const AtomicXMLToken& token)
Modified: trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h (93379 => 93380)
--- trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h 2011-08-19 01:04:12 UTC (rev 93379)
+++ trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h 2011-08-19 01:09:34 UTC (rev 93380)
@@ -81,6 +81,7 @@
void pushCurrentNode(const NodeStackItem&);
void popCurrentNode();
+ void closeElement(PassRefPtr<Element>);
void processProcessingInstruction(const AtomicXMLToken&);
void processXMLDeclaration(const AtomicXMLToken&);