Use the original token to create an element in "reconstruct the active formatting...
[WebKit-https.git] / Source / WebCore / html / parser / HTMLElementStack.h
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 HTMLElementStack_h
28 #define HTMLElementStack_h
29
30 #include "Element.h"
31 #include "HTMLNames.h"
32 #include "HTMLStackItem.h"
33 #include <wtf/Forward.h>
34 #include <wtf/Noncopyable.h>
35 #include <wtf/OwnPtr.h>
36 #include <wtf/PassOwnPtr.h>
37 #include <wtf/RefPtr.h>
38
39 namespace WebCore {
40
41 class ContainerNode;
42 class DocumentFragment;
43 class Element;
44 class QualifiedName;
45
46 // NOTE: The HTML5 spec uses a backwards (grows downward) stack.  We're using
47 // more standard (grows upwards) stack terminology here.
48 class HTMLElementStack {
49     WTF_MAKE_NONCOPYABLE(HTMLElementStack); WTF_MAKE_FAST_ALLOCATED;
50 public:
51     HTMLElementStack();
52     ~HTMLElementStack();
53
54     class ElementRecord {
55         WTF_MAKE_NONCOPYABLE(ElementRecord);
56     public:
57         ~ElementRecord(); // Public for ~PassOwnPtr()
58     
59         Element* element() const { return m_item->element(); }
60         ContainerNode* node() const { return m_item->node(); }
61         PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
62         void replaceElement(PassRefPtr<HTMLStackItem>);
63
64         bool isAbove(ElementRecord*) const;
65
66         ElementRecord* next() const { return m_next.get(); }
67     private:
68         friend class HTMLElementStack;
69
70         ElementRecord(PassRefPtr<HTMLStackItem>, PassOwnPtr<ElementRecord>);
71
72         PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
73         void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
74
75         RefPtr<HTMLStackItem> m_item;
76         OwnPtr<ElementRecord> m_next;
77     };
78
79     unsigned stackDepth() const { return m_stackDepth; }
80
81     // Inlining this function is a (small) performance win on the parsing
82     // benchmark.
83     Element* top() const
84     {
85         ASSERT(m_top->element());
86         return m_top->element();
87     }
88
89     ContainerNode* topNode() const
90     {
91         ASSERT(m_top->node());
92         return m_top->node();
93     }
94
95     Element* oneBelowTop() const;
96     ElementRecord* topRecord() const;
97     Element* bottom() const;
98     ElementRecord* find(Element*) const;
99     ElementRecord* topmost(const AtomicString& tagName) const;
100
101     void insertAbove(PassRefPtr<HTMLStackItem>, ElementRecord*);
102
103     void push(PassRefPtr<HTMLStackItem>);
104     void pushRootNode(PassRefPtr<HTMLStackItem>);
105     void pushHTMLHtmlElement(PassRefPtr<HTMLStackItem>);
106     void pushHTMLHeadElement(PassRefPtr<HTMLStackItem>);
107     void pushHTMLBodyElement(PassRefPtr<HTMLStackItem>);
108
109     void pop();
110     void popUntil(const AtomicString& tagName);
111     void popUntil(Element*);
112     void popUntilPopped(const AtomicString& tagName);
113     void popUntilPopped(Element*);
114     void popUntilNumberedHeaderElementPopped();
115     void popUntilTableScopeMarker(); // "clear the stack back to a table context" in the spec.
116     void popUntilTableBodyScopeMarker(); // "clear the stack back to a table body context" in the spec.
117     void popUntilTableRowScopeMarker(); // "clear the stack back to a table row context" in the spec.
118     void popUntilForeignContentScopeMarker();
119     void popHTMLHeadElement();
120     void popHTMLBodyElement();
121     void popAll();
122
123     static bool isMathMLTextIntegrationPoint(ContainerNode*);
124     static bool isHTMLIntegrationPoint(ContainerNode*);
125
126     void remove(Element*);
127     void removeHTMLHeadElement(Element*);
128
129     bool contains(Element*) const;
130     bool contains(const AtomicString& tagName) const;
131
132     bool inScope(Element*) const;
133     bool inScope(const AtomicString& tagName) const;
134     bool inScope(const QualifiedName&) const;
135     bool inListItemScope(const AtomicString& tagName) const;
136     bool inListItemScope(const QualifiedName&) const;
137     bool inTableScope(const AtomicString& tagName) const;
138     bool inTableScope(const QualifiedName&) const;
139     bool inButtonScope(const AtomicString& tagName) const;
140     bool inButtonScope(const QualifiedName&) const;
141     bool inSelectScope(const AtomicString& tagName) const;
142     bool inSelectScope(const QualifiedName&) const;
143
144     bool hasNumberedHeaderElementInScope() const;
145
146     bool hasOnlyOneElement() const;
147     bool secondElementIsHTMLBodyElement() const;
148
149     Element* htmlElement() const;
150     Element* headElement() const;
151     Element* bodyElement() const;
152     
153     ContainerNode* rootNode() const;
154
155 #ifndef NDEBUG
156     void show();
157 #endif
158
159 private:
160     void pushCommon(PassRefPtr<HTMLStackItem>);
161     void pushRootNodeCommon(PassRefPtr<HTMLStackItem>);
162     void popCommon();
163     void removeNonTopCommon(Element*);
164
165     OwnPtr<ElementRecord> m_top;
166
167     // We remember the root node, <head> and <body> as they are pushed. Their
168     // ElementRecords keep them alive. The root node is never popped.
169     // FIXME: We don't currently require type-specific information about
170     // these elements so we haven't yet bothered to plumb the types all the
171     // way down through createElement, etc.
172     ContainerNode* m_rootNode;
173     Element* m_headElement;
174     Element* m_bodyElement;
175     unsigned m_stackDepth;
176 };
177     
178 inline bool isInHTMLNamespace(Node* node)
179 {
180     // A DocumentFragment takes the place of the document element when parsing
181     // fragments and should be considered in the HTML namespace.
182     return node->namespaceURI() == HTMLNames::xhtmlNamespaceURI
183         || node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE; // FIXME: Does this also apply to ShadowRoot?
184 }
185
186
187 } // namespace WebCore
188
189 #endif // HTMLElementStack_h