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