HTMLConstructionSite.h revision cad810f21b803229eb11403f9209855525a25d57
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 : public Noncopyable {
44public:
45    HTMLConstructionSite(Document*, FragmentScriptingPermission, bool isParsingFragment);
46    ~HTMLConstructionSite();
47
48    void detach();
49
50    void insertDoctype(AtomicHTMLToken&);
51    void insertComment(AtomicHTMLToken&);
52    void insertCommentOnDocument(AtomicHTMLToken&);
53    void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&);
54    void insertHTMLElement(AtomicHTMLToken&);
55    void insertSelfClosingHTMLElement(AtomicHTMLToken&);
56    void insertFormattingElement(AtomicHTMLToken&);
57    void insertHTMLHeadElement(AtomicHTMLToken&);
58    void insertHTMLBodyElement(AtomicHTMLToken&);
59    void insertHTMLFormElement(AtomicHTMLToken&, bool isDemoted = false);
60    void insertScriptElement(AtomicHTMLToken&);
61    void insertTextNode(const String&);
62    void insertForeignElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
63
64    void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
65    void insertHTMLHtmlStartTagInBody(AtomicHTMLToken&);
66    void insertHTMLBodyStartTagInBody(AtomicHTMLToken&);
67
68    PassRefPtr<Element> createHTMLElement(AtomicHTMLToken&);
69    PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
70
71    bool shouldFosterParent() const;
72    void fosterParent(Node*);
73
74    bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
75    void reconstructTheActiveFormattingElements();
76
77    void generateImpliedEndTags();
78    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
79
80    Element* currentElement() const { return m_openElements.top(); }
81    Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
82
83    HTMLElementStack* openElements() const { return &m_openElements; }
84    HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
85
86    Element* head() const { return m_head.get(); }
87
88    void setForm(HTMLFormElement*);
89    HTMLFormElement* form() const { return m_form.get(); }
90    PassRefPtr<HTMLFormElement> takeForm();
91
92    class RedirectToFosterParentGuard : public Noncopyable {
93    public:
94        RedirectToFosterParentGuard(HTMLConstructionSite& tree)
95            : m_tree(tree)
96            , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
97        {
98            m_tree.m_redirectAttachToFosterParent = true;
99        }
100
101        ~RedirectToFosterParentGuard()
102        {
103            m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
104        }
105
106    private:
107        HTMLConstructionSite& m_tree;
108        bool m_wasRedirectingBefore;
109    };
110
111private:
112    struct AttachmentSite {
113        ContainerNode* parent;
114        Node* nextChild;
115    };
116
117    template<typename ChildType>
118    PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
119    PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
120
121    void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
122    void findFosterSite(AttachmentSite&);
123
124    PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
125    PassRefPtr<Element> createElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
126
127    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*);
128    void dispatchDocumentElementAvailableIfNeeded();
129
130    Document* m_document;
131    RefPtr<Element> m_head;
132    RefPtr<HTMLFormElement> m_form;
133    mutable HTMLElementStack m_openElements;
134    mutable HTMLFormattingElementList m_activeFormattingElements;
135
136    FragmentScriptingPermission m_fragmentScriptingPermission;
137    bool m_isParsingFragment;
138
139    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
140    // In the "in table" insertion mode, we sometimes get into a state where
141    // "whenever a node would be inserted into the current node, it must instead
142    // be foster parented."  This flag tracks whether we're in that state.
143    bool m_redirectAttachToFosterParent;
144};
145
146}
147
148#endif
149