1 /* 2 * Copyright (C) 2000 Peter Kelly (pmk (at) post.com) 3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2007 Samuel Weinig (sam (at) webkit.org) 5 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #ifndef XMLDocumentParser_h 26 #define XMLDocumentParser_h 27 28 #include "core/dom/ParserContentPolicy.h" 29 #include "core/dom/ScriptableDocumentParser.h" 30 #include "core/fetch/ResourceClient.h" 31 #include "core/fetch/ResourcePtr.h" 32 #include "core/fetch/ScriptResource.h" 33 #include "core/xml/parser/XMLErrors.h" 34 #include "platform/heap/Handle.h" 35 #include "platform/text/SegmentedString.h" 36 #include "wtf/HashMap.h" 37 #include "wtf/OwnPtr.h" 38 #include "wtf/text/CString.h" 39 #include "wtf/text/StringHash.h" 40 #include <libxml/tree.h> 41 42 namespace blink { 43 44 class ContainerNode; 45 class ResourceFetcher; 46 class DocumentFragment; 47 class Document; 48 class Element; 49 class FrameView; 50 class Text; 51 52 class XMLParserContext : public RefCounted<XMLParserContext> { 53 public: 54 static PassRefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk); 55 static PassRefPtr<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void* userData); 56 ~XMLParserContext(); 57 xmlParserCtxtPtr context() const { return m_context; } 58 59 private: 60 XMLParserContext(xmlParserCtxtPtr context) 61 : m_context(context) 62 { 63 } 64 65 xmlParserCtxtPtr m_context; 66 }; 67 68 class XMLDocumentParser FINAL : public ScriptableDocumentParser, public ScriptResourceClient { 69 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 70 public: 71 static PassRefPtrWillBeRawPtr<XMLDocumentParser> create(Document& document, FrameView* view) 72 { 73 return adoptRefWillBeNoop(new XMLDocumentParser(document, view)); 74 } 75 static PassRefPtrWillBeRawPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, ParserContentPolicy parserContentPolicy) 76 { 77 return adoptRefWillBeNoop(new XMLDocumentParser(fragment, element, parserContentPolicy)); 78 } 79 virtual ~XMLDocumentParser(); 80 virtual void trace(Visitor*) OVERRIDE; 81 82 // Exposed for callbacks: 83 void handleError(XMLErrors::ErrorType, const char* message, TextPosition); 84 85 void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; } 86 bool isXHTMLDocument() const { return m_isXHTMLDocument; } 87 88 bool isCurrentlyParsing8BitChunk() { return m_isCurrentlyParsing8BitChunk; } 89 90 static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, ParserContentPolicy = AllowScriptingContent); 91 92 // Used by the XMLHttpRequest to check if the responseXML was well formed. 93 virtual bool wellFormed() const OVERRIDE { return !m_sawError; } 94 95 virtual TextPosition textPosition() const OVERRIDE; 96 97 static bool supportsXMLVersion(const String&); 98 99 class PendingCallback { 100 public: 101 virtual ~PendingCallback() { } 102 virtual void call(XMLDocumentParser*) = 0; 103 }; 104 105 private: 106 explicit XMLDocumentParser(Document&, FrameView* = 0); 107 XMLDocumentParser(DocumentFragment*, Element*, ParserContentPolicy); 108 109 // From DocumentParser 110 virtual void insert(const SegmentedString&) OVERRIDE; 111 virtual void append(PassRefPtr<StringImpl>) OVERRIDE; 112 virtual void finish() OVERRIDE; 113 virtual bool isWaitingForScripts() const OVERRIDE; 114 virtual void stopParsing() OVERRIDE; 115 virtual void detach() OVERRIDE; 116 virtual OrdinalNumber lineNumber() const OVERRIDE; 117 OrdinalNumber columnNumber() const; 118 119 // from ResourceClient 120 virtual void notifyFinished(Resource*) OVERRIDE; 121 122 void end(); 123 124 void pauseParsing(); 125 void resumeParsing(); 126 127 bool appendFragmentSource(const String&); 128 129 public: 130 // Callbacks from parser SAX 131 void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0); 132 void startElementNs(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri, int namespaceCount, 133 const xmlChar** namespaces, int attributeCount, int defaultedCount, const xmlChar** libxmlAttributes); 134 void endElementNs(); 135 void characters(const xmlChar* chars, int length); 136 void processingInstruction(const String& target, const String& data); 137 void cdataBlock(const String&); 138 void comment(const String&); 139 void startDocument(const String& version, const String& encoding, int standalone); 140 void internalSubset(const String& name, const String& externalID, const String& systemID); 141 void endDocument(); 142 143 private: 144 void initializeParserContext(const CString& chunk = CString()); 145 146 void pushCurrentNode(ContainerNode*); 147 void popCurrentNode(); 148 void clearCurrentNodeStack(); 149 150 void insertErrorMessageBlock(); 151 152 void enterText(); 153 void exitText(); 154 155 void doWrite(const String&); 156 void doEnd(); 157 158 bool m_hasView; 159 160 SegmentedString m_originalSourceForTransform; 161 162 xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; }; 163 RefPtr<XMLParserContext> m_context; 164 Deque<OwnPtr<PendingCallback> > m_pendingCallbacks; 165 Vector<xmlChar> m_bufferedText; 166 167 RawPtrWillBeMember<ContainerNode> m_currentNode; 168 WillBeHeapVector<RawPtrWillBeMember<ContainerNode> > m_currentNodeStack; 169 170 RefPtrWillBeMember<Text> m_leafTextNode; 171 172 bool m_isCurrentlyParsing8BitChunk; 173 bool m_sawError; 174 bool m_sawCSS; 175 bool m_sawXSLTransform; 176 bool m_sawFirstElement; 177 bool m_isXHTMLDocument; 178 bool m_parserPaused; 179 bool m_requestingScript; 180 bool m_finishCalled; 181 182 XMLErrors m_xmlErrors; 183 184 ResourcePtr<ScriptResource> m_pendingScript; 185 RefPtrWillBeMember<Element> m_scriptElement; 186 TextPosition m_scriptStartPosition; 187 188 bool m_parsingFragment; 189 AtomicString m_defaultNamespaceURI; 190 191 typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap; 192 PrefixForNamespaceMap m_prefixToNamespaceMap; 193 SegmentedString m_pendingSrc; 194 }; 195 196 xmlDocPtr xmlDocPtrForString(ResourceFetcher*, const String& source, const String& url); 197 HashMap<String, String> parseAttributes(const String&, bool& attrsOK); 198 199 } // namespace blink 200 201 #endif // XMLDocumentParser_h 202