HTMLConstructionSite.h revision 2fc2651226baac27029e38c9d6ef883fa32084db
1/*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef HTMLConstructionSite_h
27#define HTMLConstructionSite_h
28
29#include "FragmentScriptingPermission.h"
30#include "HTMLElementStack.h"
31#include "HTMLFormattingElementList.h"
32#include "NotImplemented.h"
33#include <wtf/Noncopyable.h>
34#include <wtf/PassRefPtr.h>
35#include <wtf/RefPtr.h>
36
37namespace WebCore {
38
39class AtomicHTMLToken;
40class Document;
41class Element;
42
43class HTMLConstructionSite {
44    WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
45public:
46    HTMLConstructionSite(Document*);
47    HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission);
48    ~HTMLConstructionSite();
49
50    void detach();
51
52    void insertDoctype(AtomicHTMLToken&);
53    void insertComment(AtomicHTMLToken&);
54    void insertCommentOnDocument(AtomicHTMLToken&);
55    void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&);
56    void insertHTMLElement(AtomicHTMLToken&);
57    void insertSelfClosingHTMLElement(AtomicHTMLToken&);
58    void insertFormattingElement(AtomicHTMLToken&);
59    void insertHTMLHeadElement(AtomicHTMLToken&);
60    void insertHTMLBodyElement(AtomicHTMLToken&);
61    void insertHTMLFormElement(AtomicHTMLToken&, bool isDemoted = false);
62    void insertScriptElement(AtomicHTMLToken&);
63    void insertTextNode(const String&);
64    void insertForeignElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
65
66    void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
67    void insertHTMLHtmlStartTagInBody(AtomicHTMLToken&);
68    void insertHTMLBodyStartTagInBody(AtomicHTMLToken&);
69
70    PassRefPtr<Element> createHTMLElement(AtomicHTMLToken&);
71    PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
72
73    bool shouldFosterParent() const;
74    void fosterParent(Node*);
75
76    bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
77    void reconstructTheActiveFormattingElements();
78
79    void generateImpliedEndTags();
80    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
81
82    Element* currentElement() const { return m_openElements.top(); }
83    Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
84
85    HTMLElementStack* openElements() const { return &m_openElements; }
86    HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
87
88    Element* head() const { return m_head.get(); }
89
90    void setForm(HTMLFormElement*);
91    HTMLFormElement* form() const { return m_form.get(); }
92    PassRefPtr<HTMLFormElement> takeForm();
93
94    class RedirectToFosterParentGuard {
95        WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
96    public:
97        RedirectToFosterParentGuard(HTMLConstructionSite& tree)
98            : m_tree(tree)
99            , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
100        {
101            m_tree.m_redirectAttachToFosterParent = true;
102        }
103
104        ~RedirectToFosterParentGuard()
105        {
106            m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
107        }
108
109    private:
110        HTMLConstructionSite& m_tree;
111        bool m_wasRedirectingBefore;
112    };
113
114private:
115    struct AttachmentSite {
116        ContainerNode* parent;
117        Node* nextChild;
118    };
119
120    template<typename ChildType>
121    PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
122    PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
123
124    void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
125    void findFosterSite(AttachmentSite&);
126
127    PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
128    PassRefPtr<Element> createElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
129
130    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*);
131    void dispatchDocumentElementAvailableIfNeeded();
132
133    Document* m_document;
134
135    // This is the root ContainerNode to which the parser attaches all newly
136    // constructed nodes. It points to a DocumentFragment when parsing fragments
137    // and a Document in all other cases.
138    ContainerNode* m_attachmentRoot;
139
140    RefPtr<Element> m_head;
141    RefPtr<HTMLFormElement> m_form;
142    mutable HTMLElementStack m_openElements;
143    mutable HTMLFormattingElementList m_activeFormattingElements;
144
145    FragmentScriptingPermission m_fragmentScriptingPermission;
146    bool m_isParsingFragment;
147
148    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
149    // In the "in table" insertion mode, we sometimes get into a state where
150    // "whenever a node would be inserted into the current node, it must instead
151    // be foster parented."  This flag tracks whether we're in that state.
152    bool m_redirectAttachToFosterParent;
153};
154
155}
156
157#endif
158