• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3  * Copyright (C) 2011 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
25  */
26 
27 #ifndef HTMLConstructionSite_h
28 #define HTMLConstructionSite_h
29 
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 
38 namespace WebCore {
39 
40 class AtomicHTMLToken;
41 class Document;
42 class Element;
43 
44 class HTMLConstructionSite {
45     WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
46 public:
47     HTMLConstructionSite(Document*);
48     HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission);
49     ~HTMLConstructionSite();
50 
51     void detach();
52 
53     void insertDoctype(AtomicHTMLToken&);
54     void insertComment(AtomicHTMLToken&);
55     void insertCommentOnDocument(AtomicHTMLToken&);
56     void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&);
57     void insertHTMLElement(AtomicHTMLToken&);
58     void insertSelfClosingHTMLElement(AtomicHTMLToken&);
59     void insertFormattingElement(AtomicHTMLToken&);
60     void insertHTMLHeadElement(AtomicHTMLToken&);
61     void insertHTMLBodyElement(AtomicHTMLToken&);
62     void insertHTMLFormElement(AtomicHTMLToken&, bool isDemoted = false);
63     void insertScriptElement(AtomicHTMLToken&);
64     void insertTextNode(const String&);
65     void insertForeignElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
66 
67     void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
68     void insertHTMLHtmlStartTagInBody(AtomicHTMLToken&);
69     void insertHTMLBodyStartTagInBody(AtomicHTMLToken&);
70 
71     PassRefPtr<Element> createHTMLElement(AtomicHTMLToken&);
72     PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
73 
74     bool shouldFosterParent() const;
75     void fosterParent(Node*);
76 
77     bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
78     void reconstructTheActiveFormattingElements();
79 
80     void generateImpliedEndTags();
81     void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
82 
currentElement()83     Element* currentElement() const { return m_openElements.top(); }
currentNode()84     ContainerNode* currentNode() const { return m_openElements.topNode(); }
oneBelowTop()85     Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
86 
openElements()87     HTMLElementStack* openElements() const { return &m_openElements; }
activeFormattingElements()88     HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
89 
head()90     Element* head() const { return m_head.get(); }
91 
92     void setForm(HTMLFormElement*);
form()93     HTMLFormElement* form() const { return m_form.get(); }
94     PassRefPtr<HTMLFormElement> takeForm();
95 
96     class RedirectToFosterParentGuard {
97         WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
98     public:
RedirectToFosterParentGuard(HTMLConstructionSite & tree)99         RedirectToFosterParentGuard(HTMLConstructionSite& tree)
100             : m_tree(tree)
101             , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
102         {
103             m_tree.m_redirectAttachToFosterParent = true;
104         }
105 
~RedirectToFosterParentGuard()106         ~RedirectToFosterParentGuard()
107         {
108             m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
109         }
110 
111     private:
112         HTMLConstructionSite& m_tree;
113         bool m_wasRedirectingBefore;
114     };
115 
116 private:
117     struct AttachmentSite {
118         ContainerNode* parent;
119         Node* nextChild;
120     };
121 
122     template<typename ChildType>
123     PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
124     PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
125 
126     void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
127     void findFosterSite(AttachmentSite&);
128 
129     PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
130     PassRefPtr<Element> createElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
131 
132     void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*);
133     void dispatchDocumentElementAvailableIfNeeded();
134 
135     Document* m_document;
136 
137     // This is the root ContainerNode to which the parser attaches all newly
138     // constructed nodes. It points to a DocumentFragment when parsing fragments
139     // and a Document in all other cases.
140     ContainerNode* m_attachmentRoot;
141 
142     RefPtr<Element> m_head;
143     RefPtr<HTMLFormElement> m_form;
144     mutable HTMLElementStack m_openElements;
145     mutable HTMLFormattingElementList m_activeFormattingElements;
146 
147     FragmentScriptingPermission m_fragmentScriptingPermission;
148     bool m_isParsingFragment;
149 
150     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
151     // In the "in table" insertion mode, we sometimes get into a state where
152     // "whenever a node would be inserted into the current node, it must instead
153     // be foster parented."  This flag tracks whether we're in that state.
154     bool m_redirectAttachToFosterParent;
155 };
156 
157 }
158 
159 #endif
160