Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/html/parser/HTMLStackItem.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 blink {
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);
48     DISALLOW_ALLOCATION();
49 public:
50     HTMLElementStack();
51     ~HTMLElementStack();
52
53     class ElementRecord FINAL : public NoBaseWillBeGarbageCollected<ElementRecord> {
54         WTF_MAKE_NONCOPYABLE(ElementRecord); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
55     public:
56 #if !ENABLE(OILPAN)
57         ~ElementRecord(); // Public for ~PassOwnPtr()
58 #endif
59
60         Element* element() const { return m_item->element(); }
61         ContainerNode* node() const { return m_item->node(); }
62         const AtomicString& namespaceURI() const { return m_item->namespaceURI(); }
63         PassRefPtrWillBeRawPtr<HTMLStackItem> stackItem() const { return m_item; }
64         void replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
65
66         bool isAbove(ElementRecord*) const;
67
68         ElementRecord* next() const { return m_next.get(); }
69
70         void trace(Visitor*);
71     private:
72         friend class HTMLElementStack;
73
74         ElementRecord(PassRefPtrWillBeRawPtr<HTMLStackItem>, PassOwnPtrWillBeRawPtr<ElementRecord>);
75
76         PassOwnPtrWillBeRawPtr<ElementRecord> releaseNext() { return m_next.release(); }
77         void setNext(PassOwnPtrWillBeRawPtr<ElementRecord> next) { m_next = next; }
78
79         RefPtrWillBeMember<HTMLStackItem> m_item;
80         OwnPtrWillBeMember<ElementRecord> m_next;
81     };
82
83     unsigned stackDepth() const { return m_stackDepth; }
84
85     // Inlining this function is a (small) performance win on the parsing
86     // benchmark.
87     Element* top() const
88     {
89         ASSERT(m_top->element());
90         return m_top->element();
91     }
92
93     ContainerNode* topNode() const
94     {
95         ASSERT(m_top->node());
96         return m_top->node();
97     }
98
99     HTMLStackItem* topStackItem() const
100     {
101         ASSERT(m_top->stackItem());
102         return m_top->stackItem().get();
103     }
104
105     HTMLStackItem* oneBelowTop() const;
106     ElementRecord* topRecord() const;
107     ElementRecord* find(Element*) const;
108     ElementRecord* furthestBlockForFormattingElement(Element*) const;
109     ElementRecord* topmost(const AtomicString& tagName) const;
110
111     void insertAbove(PassRefPtrWillBeRawPtr<HTMLStackItem>, ElementRecord*);
112
113     void push(PassRefPtrWillBeRawPtr<HTMLStackItem>);
114     void pushRootNode(PassRefPtrWillBeRawPtr<HTMLStackItem>);
115     void pushHTMLHtmlElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
116     void pushHTMLHeadElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
117     void pushHTMLBodyElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
118
119     void pop();
120     void popUntil(const AtomicString& tagName);
121     void popUntil(Element*);
122     void popUntilPopped(const AtomicString& tagName);
123     void popUntilPopped(const QualifiedName& tagName) { popUntilPopped(tagName.localName()); }
124
125     void popUntilPopped(Element*);
126     void popUntilNumberedHeaderElementPopped();
127     void popUntilTableScopeMarker(); // "clear the stack back to a table context" in the spec.
128     void popUntilTableBodyScopeMarker(); // "clear the stack back to a table body context" in the spec.
129     void popUntilTableRowScopeMarker(); // "clear the stack back to a table row context" in the spec.
130     void popUntilForeignContentScopeMarker();
131     void popHTMLHeadElement();
132     void popHTMLBodyElement();
133     void popAll();
134
135     static bool isMathMLTextIntegrationPoint(HTMLStackItem*);
136     static bool isHTMLIntegrationPoint(HTMLStackItem*);
137
138     void remove(Element*);
139     void removeHTMLHeadElement(Element*);
140
141     bool contains(Element*) const;
142     bool contains(const AtomicString& tagName) const;
143
144     bool inScope(Element*) const;
145     bool inScope(const AtomicString& tagName) const;
146     bool inScope(const QualifiedName&) const;
147     bool inListItemScope(const AtomicString& tagName) const;
148     bool inListItemScope(const QualifiedName&) const;
149     bool inTableScope(const AtomicString& tagName) const;
150     bool inTableScope(const QualifiedName&) const;
151     bool inButtonScope(const AtomicString& tagName) const;
152     bool inButtonScope(const QualifiedName&) const;
153     bool inSelectScope(const AtomicString& tagName) const;
154     bool inSelectScope(const QualifiedName&) const;
155
156     bool hasNumberedHeaderElementInScope() const;
157
158     bool hasOnlyOneElement() const;
159     bool secondElementIsHTMLBodyElement() const;
160     bool hasTemplateInHTMLScope() const;
161     Element* htmlElement() const;
162     Element* headElement() const;
163     Element* bodyElement() const;
164
165     ContainerNode* rootNode() const;
166
167     void trace(Visitor*);
168
169 #ifndef NDEBUG
170     void show();
171 #endif
172
173 private:
174     void pushCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
175     void pushRootNodeCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
176     void popCommon();
177     void removeNonTopCommon(Element*);
178
179     OwnPtrWillBeMember<ElementRecord> m_top;
180
181     // We remember the root node, <head> and <body> as they are pushed. Their
182     // ElementRecords keep them alive. The root node is never popped.
183     // FIXME: We don't currently require type-specific information about
184     // these elements so we haven't yet bothered to plumb the types all the
185     // way down through createElement, etc.
186     RawPtrWillBeMember<ContainerNode> m_rootNode;
187     RawPtrWillBeMember<Element> m_headElement;
188     RawPtrWillBeMember<Element> m_bodyElement;
189     unsigned m_stackDepth;
190 };
191
192 } // namespace blink
193
194 #endif // HTMLElementStack_h