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