2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2011 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef HTMLConstructionSite_h
28 #define HTMLConstructionSite_h
30 #include "FragmentScriptingPermission.h"
31 #include "HTMLElementStack.h"
32 #include "HTMLFormattingElementList.h"
33 #include "NotImplemented.h"
34 #include <wtf/Noncopyable.h>
35 #include <wtf/PassRefPtr.h>
36 #include <wtf/RefPtr.h>
37 #include <wtf/Vector.h>
41 struct HTMLConstructionSiteTask {
42 HTMLConstructionSiteTask()
47 void take(HTMLConstructionSiteTask& other)
49 parent = other.parent.release();
50 nextChild = other.nextChild.release();
51 child = other.child.release();
52 selfClosing = other.selfClosing;
55 RefPtr<ContainerNode> parent;
56 RefPtr<Node> nextChild;
61 } // namespace WebCore
64 template<> struct VectorTraits<WebCore::HTMLConstructionSiteTask> : SimpleClassVectorTraits { };
75 class AtomicHTMLToken;
78 class HTMLFormElement;
80 class HTMLConstructionSite {
81 WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
83 HTMLConstructionSite(Document*, unsigned maximumDOMTreeDepth);
84 HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission, unsigned maximumDOMTreeDepth);
85 ~HTMLConstructionSite();
88 void executeQueuedTasks();
90 void insertDoctype(AtomicHTMLToken*);
91 void insertComment(AtomicHTMLToken*);
92 void insertCommentOnDocument(AtomicHTMLToken*);
93 void insertCommentOnHTMLHtmlElement(AtomicHTMLToken*);
94 void insertHTMLElement(AtomicHTMLToken*);
95 void insertSelfClosingHTMLElement(AtomicHTMLToken*);
96 void insertFormattingElement(AtomicHTMLToken*);
97 void insertHTMLHeadElement(AtomicHTMLToken*);
98 void insertHTMLBodyElement(AtomicHTMLToken*);
99 void insertHTMLFormElement(AtomicHTMLToken*, bool isDemoted = false);
100 void insertScriptElement(AtomicHTMLToken*);
101 void insertTextNode(const String&, WhitespaceMode = WhitespaceUnknown);
102 void insertForeignElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
104 void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken*);
105 void insertHTMLHtmlStartTagInBody(AtomicHTMLToken*);
106 void insertHTMLBodyStartTagInBody(AtomicHTMLToken*);
108 PassRefPtr<Element> createHTMLElement(AtomicHTMLToken*);
109 PassRefPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
111 bool shouldFosterParent() const;
112 void fosterParent(PassRefPtr<Node>);
114 bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
115 void reconstructTheActiveFormattingElements();
117 void generateImpliedEndTags();
118 void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
120 bool isEmpty() const { return !m_openElements.stackDepth(); }
121 HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
122 Element* currentElement() const { return m_openElements.top(); }
123 ContainerNode* currentNode() const { return m_openElements.topNode(); }
124 Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
126 HTMLElementStack* openElements() const { return &m_openElements; }
127 HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
129 Element* head() const { return m_head.get(); }
131 void setForm(HTMLFormElement*);
132 HTMLFormElement* form() const { return m_form.get(); }
133 PassRefPtr<HTMLFormElement> takeForm();
135 class RedirectToFosterParentGuard {
136 WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
138 RedirectToFosterParentGuard(HTMLConstructionSite& tree)
140 , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
142 m_tree.m_redirectAttachToFosterParent = true;
145 ~RedirectToFosterParentGuard()
147 m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
151 HTMLConstructionSite& m_tree;
152 bool m_wasRedirectingBefore;
156 // In the common case, this queue will have only one task because most
157 // tokens produce only one DOM mutation.
158 typedef Vector<HTMLConstructionSiteTask, 1> AttachmentQueue;
160 void attachLater(ContainerNode* parent, PassRefPtr<Node> child, bool selfClosing = false);
162 void findFosterSite(HTMLConstructionSiteTask&);
164 PassRefPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
166 void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
167 void dispatchDocumentElementAvailableIfNeeded();
169 Document* m_document;
171 // This is the root ContainerNode to which the parser attaches all newly
172 // constructed nodes. It points to a DocumentFragment when parsing fragments
173 // and a Document in all other cases.
174 ContainerNode* m_attachmentRoot;
176 RefPtr<Element> m_head;
177 RefPtr<HTMLFormElement> m_form;
178 mutable HTMLElementStack m_openElements;
179 mutable HTMLFormattingElementList m_activeFormattingElements;
181 AttachmentQueue m_attachmentQueue;
183 FragmentScriptingPermission m_fragmentScriptingPermission;
184 bool m_isParsingFragment;
186 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
187 // In the "in table" insertion mode, we sometimes get into a state where
188 // "whenever a node would be inserted into the current node, it must instead
189 // be foster parented." This flag tracks whether we're in that state.
190 bool m_redirectAttachToFosterParent;
192 unsigned m_maximumDOMTreeDepth;
195 } // namespace WebCore