Title: [92709] trunk/Source/WebCore
Revision
92709
Author
jp...@apple.com
Date
2011-08-09 14:32:04 -0700 (Tue, 09 Aug 2011)

Log Message

Initial pass at a new XML tree builder
https://bugs.webkit.org/show_bug.cgi?id=65803

Reviewed by Adam Barth.

* GNUmakefile.list.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* xml/parser/NewXMLDocumentParser.cpp:
(WebCore::NewXMLDocumentParser::NewXMLDocumentParser):
(WebCore::NewXMLDocumentParser::~NewXMLDocumentParser):
(WebCore::NewXMLDocumentParser::append):
(WebCore::NewXMLDocumentParser::finish):
(WebCore::NewXMLDocumentParser::finishWasCalled):
* xml/parser/NewXMLDocumentParser.h:
* xml/parser/XMLTreeBuilder.cpp: Added.
(WebCore::XMLTreeBuilder::XMLTreeBuilder):
(WebCore::XMLTreeBuilder::processToken):
(WebCore::XMLTreeBuilder::pushCurrentNode):
(WebCore::XMLTreeBuilder::popCurrentNode):
(WebCore::XMLTreeBuilder::processProcessingInstruction):
(WebCore::XMLTreeBuilder::processXMLDeclaration):
(WebCore::XMLTreeBuilder::processDOCTYPE):
(WebCore::XMLTreeBuilder::processStartTag):
(WebCore::XMLTreeBuilder::processEndTag):
(WebCore::XMLTreeBuilder::processCharacter):
(WebCore::XMLTreeBuilder::processCDATA):
(WebCore::XMLTreeBuilder::processComment):
(WebCore::XMLTreeBuilder::processEntity):
(WebCore::XMLTreeBuilder::processNamespaces):
(WebCore::XMLTreeBuilder::processAttributes):
(WebCore::XMLTreeBuilder::processXMLEntity):
(WebCore::XMLTreeBuilder::processHTMLEntity):
(WebCore::XMLTreeBuilder::add):
(WebCore::XMLTreeBuilder::appendToText):
(WebCore::XMLTreeBuilder::enterText):
(WebCore::XMLTreeBuilder::exitText):
(WebCore::XMLTreeBuilder::NodeStackItem::NodeStackItem):
(WebCore::XMLTreeBuilder::NodeStackItem::hasNamespaceURI):
(WebCore::XMLTreeBuilder::NodeStackItem::namespaceURI):
(WebCore::XMLTreeBuilder::NodeStackItem::setNamespaceURI):
(WebCore::XMLTreeBuilder::NodeStackItem::namespaceForPrefix):
* xml/parser/XMLTreeBuilder.h: Added.
(WebCore::XMLTreeBuilder::create):
(WebCore::XMLTreeBuilder::NodeStackItem::namespaceURI):
(WebCore::XMLTreeBuilder::NodeStackItem::setNamespaceURI):
(WebCore::XMLTreeBuilder::NodeStackItem::node):
(WebCore::XMLTreeBuilder::NodeStackItem::setNode):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (92708 => 92709)


--- trunk/Source/WebCore/ChangeLog	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/ChangeLog	2011-08-09 21:32:04 UTC (rev 92709)
@@ -1,3 +1,56 @@
+2011-08-09  Jeffrey Pfau  <jp...@apple.com>
+
+        Initial pass at a new XML tree builder
+        https://bugs.webkit.org/show_bug.cgi?id=65803
+
+        Reviewed by Adam Barth.
+
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * xml/parser/NewXMLDocumentParser.cpp:
+        (WebCore::NewXMLDocumentParser::NewXMLDocumentParser):
+        (WebCore::NewXMLDocumentParser::~NewXMLDocumentParser):
+        (WebCore::NewXMLDocumentParser::append):
+        (WebCore::NewXMLDocumentParser::finish):
+        (WebCore::NewXMLDocumentParser::finishWasCalled):
+        * xml/parser/NewXMLDocumentParser.h:
+        * xml/parser/XMLTreeBuilder.cpp: Added.
+        (WebCore::XMLTreeBuilder::XMLTreeBuilder):
+        (WebCore::XMLTreeBuilder::processToken):
+        (WebCore::XMLTreeBuilder::pushCurrentNode):
+        (WebCore::XMLTreeBuilder::popCurrentNode):
+        (WebCore::XMLTreeBuilder::processProcessingInstruction):
+        (WebCore::XMLTreeBuilder::processXMLDeclaration):
+        (WebCore::XMLTreeBuilder::processDOCTYPE):
+        (WebCore::XMLTreeBuilder::processStartTag):
+        (WebCore::XMLTreeBuilder::processEndTag):
+        (WebCore::XMLTreeBuilder::processCharacter):
+        (WebCore::XMLTreeBuilder::processCDATA):
+        (WebCore::XMLTreeBuilder::processComment):
+        (WebCore::XMLTreeBuilder::processEntity):
+        (WebCore::XMLTreeBuilder::processNamespaces):
+        (WebCore::XMLTreeBuilder::processAttributes):
+        (WebCore::XMLTreeBuilder::processXMLEntity):
+        (WebCore::XMLTreeBuilder::processHTMLEntity):
+        (WebCore::XMLTreeBuilder::add):
+        (WebCore::XMLTreeBuilder::appendToText):
+        (WebCore::XMLTreeBuilder::enterText):
+        (WebCore::XMLTreeBuilder::exitText):
+        (WebCore::XMLTreeBuilder::NodeStackItem::NodeStackItem):
+        (WebCore::XMLTreeBuilder::NodeStackItem::hasNamespaceURI):
+        (WebCore::XMLTreeBuilder::NodeStackItem::namespaceURI):
+        (WebCore::XMLTreeBuilder::NodeStackItem::setNamespaceURI):
+        (WebCore::XMLTreeBuilder::NodeStackItem::namespaceForPrefix):
+        * xml/parser/XMLTreeBuilder.h: Added.
+        (WebCore::XMLTreeBuilder::create):
+        (WebCore::XMLTreeBuilder::NodeStackItem::namespaceURI):
+        (WebCore::XMLTreeBuilder::NodeStackItem::setNamespaceURI):
+        (WebCore::XMLTreeBuilder::NodeStackItem::node):
+        (WebCore::XMLTreeBuilder::NodeStackItem::setNode):
+
 2011-08-09  Mark Hahnenberg  <mhahnenb...@apple.com>
 
         Add ParentClass typedef in all JSC classes

Modified: trunk/Source/WebCore/GNUmakefile.list.am (92708 => 92709)


--- trunk/Source/WebCore/GNUmakefile.list.am	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2011-08-09 21:32:04 UTC (rev 92709)
@@ -3836,6 +3836,8 @@
 	Source/WebCore/xml/parser/XMLTokenizer.cpp \
 	Source/WebCore/xml/parser/XMLTokenizer.h \
 	Source/WebCore/xml/parser/XMLToken.h \
+	Source/WebCore/xml/parser/XMLTreeBuilder.cpp \
+	Source/WebCore/xml/parser/XMLTreeBuilder.h \
 	Source/WebCore/xml/DOMParser.cpp \
 	Source/WebCore/xml/DOMParser.h \
 	Source/WebCore/xml/NativeXPathNSResolver.cpp \

Modified: trunk/Source/WebCore/WebCore.gypi (92708 => 92709)


--- trunk/Source/WebCore/WebCore.gypi	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/WebCore.gypi	2011-08-09 21:32:04 UTC (rev 92709)
@@ -5135,6 +5135,8 @@
             'xml/parser/XMLTokenizer.cpp',
             'xml/parser/XMLTokenizer.h',
             'xml/parser/XMLToken.h',
+            'xml/parser/XMLTreeBuilder.cpp',
+            'xml/parser/XMLTreeBuilder.h',
             'xml/DOMParser.cpp',
             'xml/DOMParser.h',
             'xml/NativeXPathNSResolver.cpp',

Modified: trunk/Source/WebCore/WebCore.pro (92708 => 92709)


--- trunk/Source/WebCore/WebCore.pro	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/WebCore.pro	2011-08-09 21:32:04 UTC (rev 92709)
@@ -1208,7 +1208,8 @@
     xml/parser/NewXMLDocumentParser.cpp \
     xml/parser/XMLCharacterReferenceParser.cpp \
     xml/parser/XMLDocumentParser.cpp \
-    xml/parser/XMLTokenizer.cpp
+    xml/parser/XMLTokenizer.cpp \
+    xml/parser/XMLTreeBuilder.cpp
 
 HEADERS += \
     accessibility/AccessibilityARIAGridCell.h \
@@ -2520,6 +2521,7 @@
     xml/parser/XMLDocumentParser.h \
     xml/parser/XMLTokenizer.h \
     xml/parser/XMLToken.h \
+    xml/parser/XMLTreeBuilder.h \
     xml/DOMParser.h \
     xml/NativeXPathNSResolver.h \
     xml/XMLHttpRequest.h \

Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (92708 => 92709)


--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2011-08-09 21:32:04 UTC (rev 92709)
@@ -42745,6 +42745,14 @@
 					>
 				</File>
 				<File
+					RelativePath="..\xml\parser\NewXMLDocumentParser.h"
+					>
+				</File>
+				<File
+					RelativePath="..\xml\parser\NewXMLDocumentParser.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\xml\parser\XMLDocumentParser.cpp"
 					>
 					<FileConfiguration
@@ -42868,6 +42876,14 @@
 					RelativePath="..\xml\parser\XMLTokenizer.h"
 					>
 				</File>
+				<File
+					RelativePath="..\xml\parser\XMLTreeBuilder.h"
+					>
+				</File>
+				<File
+					RelativePath="..\xml\parser\XMLTreeBuilder.cpp"
+					>
+				</File>
 			</Filter>
 		</Filter>
 		<Filter

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (92708 => 92709)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2011-08-09 21:32:04 UTC (rev 92709)
@@ -51,6 +51,8 @@
 		0002EC5A13C3F67D00040D47 /* XMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0002EC5713C3F67D00040D47 /* XMLTokenizer.h */; };
 		0014628A103CD1DE000B20DB /* OriginAccessEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00146288103CD1DE000B20DB /* OriginAccessEntry.cpp */; };
 		0014628B103CD1DE000B20DB /* OriginAccessEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00146289103CD1DE000B20DB /* OriginAccessEntry.h */; };
+		0035EBBB13F06FF200A56089 /* XMLTreeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0035EBBA13F06FF200A56089 /* XMLTreeBuilder.h */; };
+		0035EBBE13F0713C00A56089 /* XMLTreeBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0035EBBD13F0713C00A56089 /* XMLTreeBuilder.cpp */; };
 		003F1FEA11E6AB43008258D9 /* UserContentTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 003F1FE911E6AB43008258D9 /* UserContentTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		00A629C113D0BEC70050AC52 /* MarkupTokenBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 00A629C013D0BEC70050AC52 /* MarkupTokenBase.h */; };
 		00B9318713BA8DB30035A948 /* XMLDocumentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B9318113BA867F0035A948 /* XMLDocumentParser.cpp */; };
@@ -6488,6 +6490,8 @@
 		0002EC5713C3F67D00040D47 /* XMLTokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLTokenizer.h; sourceTree = "<group>"; };
 		00146288103CD1DE000B20DB /* OriginAccessEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OriginAccessEntry.cpp; sourceTree = "<group>"; };
 		00146289103CD1DE000B20DB /* OriginAccessEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OriginAccessEntry.h; sourceTree = "<group>"; };
+		0035EBBA13F06FF200A56089 /* XMLTreeBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLTreeBuilder.h; sourceTree = "<group>"; };
+		0035EBBD13F0713C00A56089 /* XMLTreeBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLTreeBuilder.cpp; sourceTree = "<group>"; };
 		003F1FE911E6AB43008258D9 /* UserContentTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserContentTypes.h; sourceTree = "<group>"; };
 		00A629C013D0BEC70050AC52 /* MarkupTokenBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkupTokenBase.h; sourceTree = "<group>"; };
 		00B9318113BA867F0035A948 /* XMLDocumentParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLDocumentParser.cpp; sourceTree = "<group>"; };
@@ -12868,6 +12872,8 @@
 				0002EC5513C3F67D00040D47 /* XMLToken.h */,
 				0002EC5613C3F67D00040D47 /* XMLTokenizer.cpp */,
 				0002EC5713C3F67D00040D47 /* XMLTokenizer.h */,
+				0035EBBD13F0713C00A56089 /* XMLTreeBuilder.cpp */,
+				0035EBBA13F06FF200A56089 /* XMLTreeBuilder.h */,
 			);
 			path = parser;
 			sourceTree = "<group>";
@@ -23336,6 +23342,7 @@
 				1ACE53EB0A8D18E70022947D /* XMLSerializer.h in Headers */,
 				0002EC5813C3F67D00040D47 /* XMLToken.h in Headers */,
 				0002EC5A13C3F67D00040D47 /* XMLTokenizer.h in Headers */,
+				0035EBBB13F06FF200A56089 /* XMLTreeBuilder.h in Headers */,
 				5905ADC01302F3CE00F116DF /* XMLTreeViewer.h in Headers */,
 				1AB7FC690A8B92EC00D9D37B /* XPathEvaluator.h in Headers */,
 				BC60DA5B0D2A31F700B9918F /* XPathException.h in Headers */,
@@ -26148,6 +26155,7 @@
 				E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */,
 				1ACE53EA0A8D18E70022947D /* XMLSerializer.cpp in Sources */,
 				0002EC5913C3F67D00040D47 /* XMLTokenizer.cpp in Sources */,
+				0035EBBE13F0713C00A56089 /* XMLTreeBuilder.cpp in Sources */,
 				5905ADBF1302F3CE00F116DF /* XMLTreeViewer.cpp in Sources */,
 				1AB7FC680A8B92EC00D9D37B /* XPathEvaluator.cpp in Sources */,
 				1AB7FC6B0A8B92EC00D9D37B /* XPathExpression.cpp in Sources */,

Modified: trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp (92708 => 92709)


--- trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.cpp	2011-08-09 21:32:04 UTC (rev 92709)
@@ -27,15 +27,22 @@
 #include "NewXMLDocumentParser.h"
 
 #include "SegmentedString.h"
+#include "XMLTreeBuilder.h"
 
 namespace WebCore {
 
 NewXMLDocumentParser::NewXMLDocumentParser(Document* document)
     : ScriptableDocumentParser(document)
     , m_tokenizer(XMLTokenizer::create())
+    , m_finishWasCalled(false)
+    , m_treeBuilder(XMLTreeBuilder::create(this, document))
 {
 }
 
+NewXMLDocumentParser::~NewXMLDocumentParser()
+{
+}
+
 TextPosition0 NewXMLDocumentParser::textPosition() const
 {
     return TextPosition0(WTF::ZeroBasedNumber::fromZeroBasedInt(0),
@@ -63,7 +70,10 @@
         m_token.print();
 #endif
 
-        if (m_token.type() == XMLTokenTypes::EndOfFile)
+        AtomicXMLToken token(m_token);
+        m_treeBuilder->processToken(token);
+
+        if (m_token.type() == XMLTokenTypes::EndOfFile || !isParsing())
             break;
 
         m_token.clear();
@@ -73,11 +83,13 @@
 
 void NewXMLDocumentParser::finish()
 {
-}
+    ASSERT(!m_finishWasCalled);
+    m_finishWasCalled = true;
 
-void NewXMLDocumentParser::detach()
-{
-    ScriptableDocumentParser::detach();
+    if (isParsing())
+        prepareToStopParsing();
+    document()->setReadyState(Document::Interactive);
+    document()->finishedParsing();
 }
 
 bool NewXMLDocumentParser::hasInsertionPoint()
@@ -87,22 +99,9 @@
 
 bool NewXMLDocumentParser::finishWasCalled()
 {
-    return false;
+    return m_finishWasCalled;
 }
 
-bool NewXMLDocumentParser::processingData() const
-{
-    return false;
-}
-
-void NewXMLDocumentParser::prepareToStopParsing()
-{
-}
-
-void NewXMLDocumentParser::stopParsing()
-{
-}
-
 bool NewXMLDocumentParser::isWaitingForScripts() const
 {
     return false;

Modified: trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h (92708 => 92709)


--- trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h	2011-08-09 21:21:20 UTC (rev 92708)
+++ trunk/Source/WebCore/xml/parser/NewXMLDocumentParser.h	2011-08-09 21:32:04 UTC (rev 92709)
@@ -36,6 +36,8 @@
 namespace WebCore {
 
 class Document;
+class ContainerNode;
+class XMLTreeBuilder;
 
 class NewXMLDocumentParser : public ScriptableDocumentParser {
     WTF_MAKE_FAST_ALLOCATED;
@@ -44,32 +46,32 @@
     {
         return adoptRef(new NewXMLDocumentParser(document));
     }
-    
+
     virtual TextPosition0 textPosition() const;
     virtual int lineNumber() const;
 
+    // DocumentParser
+    virtual bool hasInsertionPoint();
+    virtual bool finishWasCalled();
+    virtual bool isWaitingForScripts() const;
+    virtual bool isExecutingScript() const;
+    virtual void executeScriptsWaitingForStylesheets();
+
 protected:
     virtual void insert(const SegmentedString&);
     virtual void append(const SegmentedString&);
     virtual void finish();
 
-
 private:
     NewXMLDocumentParser(Document*);
+    virtual ~NewXMLDocumentParser();
 
-    // DocumentParser
-    virtual void detach();
-    virtual bool hasInsertionPoint();
-    virtual bool finishWasCalled();
-    virtual bool processingData() const;
-    virtual void prepareToStopParsing();
-    virtual void stopParsing();
-    virtual bool isWaitingForScripts() const;
-    virtual bool isExecutingScript() const;
-    virtual void executeScriptsWaitingForStylesheets();
-
     OwnPtr<XMLTokenizer> m_tokenizer;
     XMLToken m_token;
+
+    bool m_finishWasCalled;
+
+    OwnPtr<XMLTreeBuilder> m_treeBuilder;
 };
 
 }

Added: trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp (0 => 92709)


--- trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp	                        (rev 0)
+++ trunk/Source/WebCore/xml/parser/XMLTreeBuilder.cpp	2011-08-09 21:32:04 UTC (rev 92709)
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XMLTreeBuilder.h"
+
+#include "CDATASection.h"
+#include "Comment.h"
+#include "Document.h"
+#include "DocumentType.h"
+#include "Frame.h"
+#include "HTMLEntitySearch.h"
+#include "NewXMLDocumentParser.h"
+#include "ProcessingInstruction.h"
+#include "XMLNSNames.h"
+
+namespace WebCore {
+
+XMLTreeBuilder::XMLTreeBuilder(NewXMLDocumentParser* parser, Document* document)
+    : m_document(document)
+    , m_parser(parser)
+    , m_isXHTML(false)
+{
+    m_currentNodeStack.append(NodeStackItem(document));
+}
+
+void XMLTreeBuilder::processToken(const AtomicXMLToken& token)
+{
+    switch (token.type()) {
+    case XMLTokenTypes::Uninitialized:
+        ASSERT_NOT_REACHED();
+        break;
+    case XMLTokenTypes::ProcessingInstruction:
+        processProcessingInstruction(token);
+        break;
+    case XMLTokenTypes::XMLDeclaration:
+        processXMLDeclaration(token);
+        break;
+    case XMLTokenTypes::DOCTYPE:
+        processDOCTYPE(token);
+        break;
+    case XMLTokenTypes::StartTag:
+        processStartTag(token);
+        break;
+    case XMLTokenTypes::EndTag:
+        processEndTag(token);
+        break;
+    case XMLTokenTypes::CDATA:
+        processCDATA(token);
+        break;
+    case XMLTokenTypes::Character:
+        processCharacter(token);
+        break;
+    case XMLTokenTypes::Comment:
+        processComment(token);
+        break;
+    case XMLTokenTypes::Entity:
+        processEntity(token);
+        break;
+    case XMLTokenTypes::EndOfFile:
+        return;
+    }
+}
+
+void XMLTreeBuilder::pushCurrentNode(const NodeStackItem& stackItem)
+{
+    m_currentNodeStack.append(stackItem);
+    // FIXME: is there a maximum DOM depth?
+}
+
+void XMLTreeBuilder::popCurrentNode()
+{
+    ASSERT(m_currentNodeStack.size());
+
+    m_currentNodeStack.removeLast();
+}
+
+void XMLTreeBuilder::processProcessingInstruction(const AtomicXMLToken& token)
+{
+    ASSERT(!m_leafText);
+    // FIXME: fall back if we can't handle the PI ourself.
+
+    add(ProcessingInstruction::create(m_document, token.target(), token.data()));
+}
+
+void XMLTreeBuilder::processXMLDeclaration(const AtomicXMLToken& token)
+{
+    ASSERT(!m_leafText);
+
+    ExceptionCode ec = 0;
+
+    m_document->setXMLVersion(String(token.xmlVersion()), ec);
+    if (ec)
+        m_parser->stopParsing();
+
+    m_document->setXMLStandalone(token.xmlStandalone(), ec);
+    if (ec)
+        m_parser->stopParsing();
+    // FIXME: how should this behave if standalone is not specified?
+    // FIXME: set encoding.
+}
+
+void XMLTreeBuilder::processDOCTYPE(const AtomicXMLToken& token)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlTransitional, ("-//W3C//DTD XHTML 1.0 Transitional//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtml11, ("-//W3C//DTD XHTML 1.1//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlStrict, ("-//W3C//DTD XHTML 1.0 Strict//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlFrameset, ("-//W3C//DTD XHTML 1.0 Frameset//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlBasic, ("-//W3C//DTD XHTML Basic 1.0//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlMathML, ("-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlMathMLSVG, ("-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"));
+    DEFINE_STATIC_LOCAL(AtomicString, xhtmlMobile, ("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"));
+
+    ASSERT(!m_leafText);
+
+    AtomicString publicIdentifier(token.publicIdentifier().data(), token.publicIdentifier().size());
+    AtomicString systemIdentifier(token.systemIdentifier().data(), token.systemIdentifier().size());
+    RefPtr<DocumentType> doctype = DocumentType::create(m_document, token.name(), publicIdentifier, systemIdentifier);
+    m_document->setDocType(doctype);
+
+    if ((publicIdentifier == xhtmlTransitional)
+        || (publicIdentifier == xhtml11)
+        || (publicIdentifier == xhtmlStrict)
+        || (publicIdentifier == xhtmlFrameset)
+        || (publicIdentifier == xhtmlBasic)
+        || (publicIdentifier == xhtmlMathML)
+        || (publicIdentifier == xhtmlMathMLSVG)
+        || (publicIdentifier == xhtmlMobile))
+        m_isXHTML = true;
+}
+
+void XMLTreeBuilder::processStartTag(const AtomicXMLToken& token)
+{
+    exitText();
+
+    bool isFirstElement = !m_sawFirstElement;
+    m_sawFirstElement = true;
+
+    NodeStackItem top = m_currentNodeStack.last();
+
+    processNamespaces(token, top);
+
+    QualifiedName qName(token.prefix(), token.name(), top.namespaceForPrefix(token.prefix(), top.namespaceURI()));
+    RefPtr<Element> newElement = m_document->createElement(qName, true);
+
+    processAttributes(token, top, newElement);
+
+    newElement->beginParsingChildren();
+    m_currentNodeStack.last().node()->parserAddChild(newElement.get());
+
+    top.setNode(newElement);
+    pushCurrentNode(top);
+
+    if (!newElement->attached())
+        newElement->attach();
+
+    if (isFirstElement && m_document->frame())
+        m_document->frame()->loader()->dispatchDocumentElementAvailable();
+
+    if (token.selfClosing()) {
+        popCurrentNode();
+        newElement->finishParsingChildren();
+    }
+}
+
+void XMLTreeBuilder::processEndTag(const AtomicXMLToken& token)
+{
+    exitText();
+
+    RefPtr<ContainerNode> node = m_currentNodeStack.last().node();
+
+    if (!node->hasTagName(QualifiedName(token.prefix(), token.name(), m_currentNodeStack.last().namespaceForPrefix(token.prefix(), m_currentNodeStack.last().namespaceURI()))))
+        m_parser->stopParsing();
+
+    popCurrentNode();
+    node->finishParsingChildren();
+}
+
+void XMLTreeBuilder::processCharacter(const AtomicXMLToken& token)
+{
+    appendToText(token.characters().data(), token.characters().size());
+}
+
+void XMLTreeBuilder::processCDATA(const AtomicXMLToken& token)
+{
+    exitText();
+    add(CDATASection::create(m_document, token.data()));
+}
+
+void XMLTreeBuilder::processComment(const AtomicXMLToken& token)
+{
+    exitText();
+    add(Comment::create(m_document, token.comment()));
+}
+
+void XMLTreeBuilder::processEntity(const AtomicXMLToken& token)
+{
+    // FIXME: we should support internal subset.
+    if (m_isXHTML)
+        processHTMLEntity(token);
+    else
+        processXMLEntity(token);
+}
+
+void XMLTreeBuilder::processNamespaces(const AtomicXMLToken& token, NodeStackItem& stackItem)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, xmlnsPrefix, ("xmlns"));
+    if (!token.attributes())
+        return;
+
+    for (size_t i = 0; i < token.attributes()->length(); ++i) {
+        Attribute* attribute = token.attributes()->attributeItem(i);
+        if (attribute->name().prefix() == xmlnsPrefix)
+            stackItem.setNamespaceURI(attribute->name().localName(), attribute->value());
+        else if (attribute->name() == xmlnsPrefix)
+            stackItem.setNamespaceURI(attribute->value());
+    }
+}
+
+void XMLTreeBuilder::processAttributes(const AtomicXMLToken& token, NodeStackItem& stackItem, PassRefPtr<Element> newElement)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, xmlnsPrefix, ("xmlns"));
+    if (!token.attributes())
+        return;
+
+    for (size_t i = 0; i < token.attributes()->length(); ++i) {
+        Attribute* attribute = token.attributes()->attributeItem(i);
+        ExceptionCode ec = 0;
+        if (attribute->name().prefix() == xmlnsPrefix)
+            newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, "xmlns:" + attribute->name().localName(), attribute->value(), ec);
+        else if (attribute->name() == xmlnsPrefix)
+            newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, xmlnsAtom, attribute->value(), ec);
+        else {
+            QualifiedName qName(attribute->prefix(), attribute->localName(), stackItem.namespaceForPrefix(attribute->prefix(), nullAtom));
+            newElement->setAttribute(qName, attribute->value(), ec);
+        }
+        if (ec) {
+            m_parser->stopParsing();
+            return;
+        }
+    }
+}
+
+void XMLTreeBuilder::processXMLEntity(const AtomicXMLToken& token)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, amp, ("amp"));
+    DEFINE_STATIC_LOCAL(AtomicString, apos, ("apos"));
+    DEFINE_STATIC_LOCAL(AtomicString, gt, ("gt"));
+    DEFINE_STATIC_LOCAL(AtomicString, lt, ("lt"));
+    DEFINE_STATIC_LOCAL(AtomicString, quot, ("quot"));
+    DEFINE_STATIC_LOCAL(String, ampS, ("&"));
+    DEFINE_STATIC_LOCAL(String, aposS, ("'"));
+    DEFINE_STATIC_LOCAL(String, gtS, (">"));
+    DEFINE_STATIC_LOCAL(String, ltS, ("<"));
+    DEFINE_STATIC_LOCAL(String, quotS, ("\""));
+
+    if (token.name() == amp)
+        appendToText(ampS.characters(), 1);
+    else if (token.name() == apos)
+        appendToText(aposS.characters(), 1);
+    else if (token.name() == gt)
+        appendToText(gtS.characters(), 1);
+    else if (token.name() == lt)
+        appendToText(ltS.characters(), 1);
+    else if (token.name() == quot)
+        appendToText(quotS.characters(), 1);
+    else
+        m_parser->stopParsing();
+}
+
+void XMLTreeBuilder::processHTMLEntity(const AtomicXMLToken& token)
+{
+    HTMLEntitySearch search;
+    const AtomicString& name = token.name();
+    for (size_t i = 0; i < name.length(); ++i) {
+        search.advance(name[i]);
+        if (!search.isEntityPrefix()) {
+            m_parser->stopParsing();
+            return;
+        }
+    }
+    search.advance(';');
+    UChar32 entityValue = search.currentValue();
+    if (entityValue <= 0xFFFF)
+       appendToText(reinterpret_cast<UChar*>(&entityValue), 1);
+    else {
+        UChar utf16Pair[2] = { U16_LEAD(entityValue), U16_TRAIL(entityValue) };
+        appendToText(utf16Pair, 2);
+    }
+}
+
+inline void XMLTreeBuilder::add(PassRefPtr<Node> node)
+{
+    m_currentNodeStack.last().node()->parserAddChild(node.get());
+    if (!node->attached())
+        node->attach();
+}
+
+void XMLTreeBuilder::appendToText(const UChar* text, size_t length)
+{
+    enterText();
+
+    if (!m_leafText)
+        return;
+
+    m_leafText->append(text, length);
+}
+
+void XMLTreeBuilder::enterText()
+{
+    if (!m_sawFirstElement) {
+        // FIXME: ensure it's just whitespace
+        return;
+    }
+
+    m_leafText = adoptPtr(new StringBuilder());
+}
+
+void XMLTreeBuilder::exitText()
+{
+    if (!m_leafText.get())
+        return;
+
+    add(Text::create(m_document, m_leafText->toString()));
+
+    m_leafText.clear();
+}
+
+XMLTreeBuilder::NodeStackItem::NodeStackItem(PassRefPtr<ContainerNode> n, NodeStackItem* parent)
+    : m_node(n)
+{
+    if (!parent)
+        return;
+
+        m_namespace = parent->m_namespace;
+        m_scopedNamespaces = parent->m_scopedNamespaces;
+}
+
+bool XMLTreeBuilder::NodeStackItem::hasNamespaceURI(AtomicString prefix)
+{
+    ASSERT(!prefix.isNull());
+    return m_scopedNamespaces.contains(prefix);
+}
+
+AtomicString XMLTreeBuilder::NodeStackItem::namespaceURI(AtomicString prefix)
+{
+    ASSERT(!prefix.isNull());
+    if (m_scopedNamespaces.contains(prefix))
+        return m_scopedNamespaces.get(prefix);
+    return nullAtom;
+}
+
+void XMLTreeBuilder::NodeStackItem::setNamespaceURI(AtomicString prefix, AtomicString uri)
+{
+    m_scopedNamespaces.set(prefix, uri);
+}
+
+AtomicString XMLTreeBuilder::NodeStackItem::namespaceForPrefix(AtomicString prefix, AtomicString fallback)
+{
+    AtomicString uri = fallback;
+    if (!prefix.isNull() && hasNamespaceURI(prefix))
+        uri = namespaceURI(prefix);
+
+    return uri;
+}
+
+}

Added: trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h (0 => 92709)


--- trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h	                        (rev 0)
+++ trunk/Source/WebCore/xml/parser/XMLTreeBuilder.h	2011-08-09 21:32:04 UTC (rev 92709)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef XMLTreeBuilder_h
+#define XMLTreeBuilder_h
+
+#include "Text.h"
+#include "XMLToken.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+class ContainerNode;
+class Document;
+class NewXMLDocumentParser;
+
+class XMLTreeBuilder {
+    WTF_MAKE_NONCOPYABLE(XMLTreeBuilder);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static PassOwnPtr<XMLTreeBuilder> create(NewXMLDocumentParser* parser, Document* document)
+    {
+        return adoptPtr(new XMLTreeBuilder(parser, document));
+    }
+
+    void processToken(const AtomicXMLToken&);
+
+private:
+    XMLTreeBuilder(NewXMLDocumentParser*, Document*);
+
+    class NodeStackItem {
+    public:
+        NodeStackItem(PassRefPtr<ContainerNode> item, NodeStackItem* parent = 0);
+
+        bool hasNamespaceURI(AtomicString prefix);
+        AtomicString namespaceURI(AtomicString prefix);
+        AtomicString namespaceURI() { return m_namespace; }
+        void setNamespaceURI(AtomicString prefix, AtomicString uri);
+        void setNamespaceURI(AtomicString uri) { m_namespace = uri; }
+        AtomicString namespaceForPrefix(AtomicString prefix, AtomicString fallback);
+
+        PassRefPtr<ContainerNode> node() { return m_node; }
+        void setNode(PassRefPtr<ContainerNode> node) { m_node = node; }
+
+    private:
+        HashMap<AtomicString, AtomicString> m_scopedNamespaces;
+        RefPtr<ContainerNode> m_node;
+        AtomicString m_namespace;
+    };
+
+    void pushCurrentNode(const NodeStackItem&);
+    void popCurrentNode();
+
+    void processProcessingInstruction(const AtomicXMLToken&);
+    void processXMLDeclaration(const AtomicXMLToken&);
+    void processDOCTYPE(const AtomicXMLToken&);
+    void processStartTag(const AtomicXMLToken&);
+    void processEndTag(const AtomicXMLToken&);
+    void processCDATA(const AtomicXMLToken&);
+    void processCharacter(const AtomicXMLToken&);
+    void processComment(const AtomicXMLToken&);
+    void processEntity(const AtomicXMLToken&);
+
+    void processNamespaces(const AtomicXMLToken&, NodeStackItem&);
+    void processAttributes(const AtomicXMLToken&, NodeStackItem&, PassRefPtr<Element> newElement);
+    void processXMLEntity(const AtomicXMLToken&);
+    void processHTMLEntity(const AtomicXMLToken&);
+
+    inline void add(PassRefPtr<Node>);
+
+    void appendToText(const UChar* characters, size_t length);
+    void enterText();
+    void exitText();
+
+    AtomicString namespaceForPrefix(AtomicString prefix, AtomicString fallback);
+
+    Document* m_document;
+    NewXMLDocumentParser* m_parser;
+
+    bool m_isXHTML;
+
+    bool m_sawFirstElement;
+    Vector<NodeStackItem> m_currentNodeStack;
+
+    OwnPtr<StringBuilder> m_leafText;
+};
+
+}
+
+#endif // XMLTreeBuilder_h
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to