2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2011 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 #ifndef HTMLElementStack_h
28 #define HTMLElementStack_h
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"
43 // NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using
44 // more standard (grows upwards) stack terminology here.
45 class HTMLElementStack
{
46 WTF_MAKE_NONCOPYABLE(HTMLElementStack
);
47 DISALLOW_ALLOCATION();
52 class ElementRecord final
: public NoBaseWillBeGarbageCollected
<ElementRecord
> {
53 WTF_MAKE_NONCOPYABLE(ElementRecord
); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(ElementRecord
);
56 ~ElementRecord(); // Public for ~PassOwnPtr()
59 Element
* element() const { return m_item
->element(); }
60 ContainerNode
* node() const { return m_item
->node(); }
61 const AtomicString
& namespaceURI() const { return m_item
->namespaceURI(); }
62 PassRefPtrWillBeRawPtr
<HTMLStackItem
> stackItem() const { return m_item
; }
63 void replaceElement(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
65 bool isAbove(ElementRecord
*) const;
67 ElementRecord
* next() const { return m_next
.get(); }
71 friend class HTMLElementStack
;
73 ElementRecord(PassRefPtrWillBeRawPtr
<HTMLStackItem
>, PassOwnPtrWillBeRawPtr
<ElementRecord
>);
75 PassOwnPtrWillBeRawPtr
<ElementRecord
> releaseNext() { return m_next
.release(); }
76 void setNext(PassOwnPtrWillBeRawPtr
<ElementRecord
> next
) { m_next
= next
; }
78 RefPtrWillBeMember
<HTMLStackItem
> m_item
;
79 OwnPtrWillBeMember
<ElementRecord
> m_next
;
82 unsigned stackDepth() const { return m_stackDepth
; }
84 // Inlining this function is a (small) performance win on the parsing
88 ASSERT(m_top
->element());
89 return m_top
->element();
92 ContainerNode
* topNode() const
94 ASSERT(m_top
->node());
98 HTMLStackItem
* topStackItem() const
100 ASSERT(m_top
->stackItem());
101 return m_top
->stackItem().get();
104 HTMLStackItem
* oneBelowTop() const;
105 ElementRecord
* topRecord() const;
106 ElementRecord
* find(Element
*) const;
107 ElementRecord
* furthestBlockForFormattingElement(Element
*) const;
108 ElementRecord
* topmost(const AtomicString
& tagName
) const;
110 void insertAbove(PassRefPtrWillBeRawPtr
<HTMLStackItem
>, ElementRecord
*);
112 void push(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
113 void pushRootNode(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
114 void pushHTMLHtmlElement(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
115 void pushHTMLHeadElement(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
116 void pushHTMLBodyElement(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
119 void popUntil(const AtomicString
& tagName
);
120 void popUntil(Element
*);
121 void popUntilPopped(const AtomicString
& tagName
);
122 void popUntilPopped(const QualifiedName
& tagName
) { popUntilPopped(tagName
.localName()); }
124 void popUntilPopped(Element
*);
125 void popUntilNumberedHeaderElementPopped();
126 void popUntilTableScopeMarker(); // "clear the stack back to a table context" in the spec.
127 void popUntilTableBodyScopeMarker(); // "clear the stack back to a table body context" in the spec.
128 void popUntilTableRowScopeMarker(); // "clear the stack back to a table row context" in the spec.
129 void popUntilForeignContentScopeMarker();
130 void popHTMLHeadElement();
131 void popHTMLBodyElement();
134 static bool isMathMLTextIntegrationPoint(HTMLStackItem
*);
135 static bool isHTMLIntegrationPoint(HTMLStackItem
*);
137 void remove(Element
*);
138 void removeHTMLHeadElement(Element
*);
140 bool contains(Element
*) const;
141 bool contains(const AtomicString
& tagName
) const;
143 bool inScope(Element
*) const;
144 bool inScope(const AtomicString
& tagName
) const;
145 bool inScope(const QualifiedName
&) const;
146 bool inListItemScope(const AtomicString
& tagName
) const;
147 bool inListItemScope(const QualifiedName
&) const;
148 bool inTableScope(const AtomicString
& tagName
) const;
149 bool inTableScope(const QualifiedName
&) const;
150 bool inButtonScope(const AtomicString
& tagName
) const;
151 bool inButtonScope(const QualifiedName
&) const;
152 bool inSelectScope(const AtomicString
& tagName
) const;
153 bool inSelectScope(const QualifiedName
&) const;
155 bool hasNumberedHeaderElementInScope() const;
157 bool hasOnlyOneElement() const;
158 bool secondElementIsHTMLBodyElement() const;
159 bool hasTemplateInHTMLScope() const;
160 Element
* htmlElement() const;
161 Element
* headElement() const;
162 Element
* bodyElement() const;
164 ContainerNode
* rootNode() const;
173 void pushCommon(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
174 void pushRootNodeCommon(PassRefPtrWillBeRawPtr
<HTMLStackItem
>);
176 void removeNonTopCommon(Element
*);
178 OwnPtrWillBeMember
<ElementRecord
> m_top
;
180 // We remember the root node, <head> and <body> as they are pushed. Their
181 // ElementRecords keep them alive. The root node is never popped.
182 // FIXME: We don't currently require type-specific information about
183 // these elements so we haven't yet bothered to plumb the types all the
184 // way down through createElement, etc.
185 RawPtrWillBeMember
<ContainerNode
> m_rootNode
;
186 RawPtrWillBeMember
<Element
> m_headElement
;
187 RawPtrWillBeMember
<Element
> m_bodyElement
;
188 unsigned m_stackDepth
;
191 WILL_NOT_BE_EAGERLY_TRACED_CLASS(HTMLElementStack::ElementRecord
);
195 #endif // HTMLElementStack_h