• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 Company 100, 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 HTMLStackItem_h
27 #define HTMLStackItem_h
28 
29 #include "core/HTMLNames.h"
30 #include "core/MathMLNames.h"
31 #include "core/SVGNames.h"
32 #include "core/dom/Element.h"
33 #include "core/html/parser/AtomicHTMLToken.h"
34 #include "platform/RuntimeEnabledFeatures.h"
35 #include "wtf/RefCounted.h"
36 #include "wtf/RefPtr.h"
37 #include "wtf/text/AtomicString.h"
38 
39 namespace blink {
40 
41 class ContainerNode;
42 
43 class HTMLStackItem : public RefCountedWillBeGarbageCollectedFinalized<HTMLStackItem> {
44 public:
45     enum ItemType {
46         ItemForContextElement,
47         ItemForDocumentFragmentNode
48     };
49 
50     // Used by document fragment node and context element.
create(PassRefPtrWillBeRawPtr<ContainerNode> node,ItemType type)51     static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
52     {
53         return adoptRefWillBeNoop(new HTMLStackItem(node, type));
54     }
55 
56     // Used by HTMLElementStack and HTMLFormattingElementList.
57     static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
58     {
59         return adoptRefWillBeNoop(new HTMLStackItem(node, token, namespaceURI));
60     }
61 
element()62     Element* element() const { return toElement(m_node.get()); }
node()63     ContainerNode* node() const { return m_node.get(); }
64 
isDocumentFragmentNode()65     bool isDocumentFragmentNode() const { return m_isDocumentFragmentNode; }
isElementNode()66     bool isElementNode() const { return !m_isDocumentFragmentNode; }
67 
namespaceURI()68     const AtomicString& namespaceURI() const { return m_namespaceURI; }
localName()69     const AtomicString& localName() const { return m_tokenLocalName; }
70 
attributes()71     const Vector<Attribute>& attributes() const { ASSERT(m_tokenLocalName); return m_tokenAttributes; }
getAttributeItem(const QualifiedName & attributeName)72     Attribute* getAttributeItem(const QualifiedName& attributeName)
73     {
74         ASSERT(m_tokenLocalName);
75         return findAttributeInVector(m_tokenAttributes, attributeName);
76     }
77 
hasLocalName(const AtomicString & name)78     bool hasLocalName(const AtomicString& name) const { return m_tokenLocalName == name; }
hasTagName(const QualifiedName & name)79     bool hasTagName(const QualifiedName& name) const { return m_tokenLocalName == name.localName() && m_namespaceURI == name.namespaceURI(); }
80 
matchesHTMLTag(const AtomicString & name)81     bool matchesHTMLTag(const AtomicString& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
matchesHTMLTag(const QualifiedName & name)82     bool matchesHTMLTag(const QualifiedName& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
83 
causesFosterParenting()84     bool causesFosterParenting()
85     {
86         return hasTagName(HTMLNames::tableTag)
87             || hasTagName(HTMLNames::tbodyTag)
88             || hasTagName(HTMLNames::tfootTag)
89             || hasTagName(HTMLNames::theadTag)
90             || hasTagName(HTMLNames::trTag);
91     }
92 
isInHTMLNamespace()93     bool isInHTMLNamespace() const
94     {
95         // A DocumentFragment takes the place of the document element when parsing
96         // fragments and should be considered in the HTML namespace.
97         return namespaceURI() == HTMLNames::xhtmlNamespaceURI
98             || isDocumentFragmentNode(); // FIXME: Does this also apply to ShadowRoot?
99     }
100 
isNumberedHeaderElement()101     bool isNumberedHeaderElement() const
102     {
103         return hasTagName(HTMLNames::h1Tag)
104             || hasTagName(HTMLNames::h2Tag)
105             || hasTagName(HTMLNames::h3Tag)
106             || hasTagName(HTMLNames::h4Tag)
107             || hasTagName(HTMLNames::h5Tag)
108             || hasTagName(HTMLNames::h6Tag);
109     }
110 
isTableBodyContextElement()111     bool isTableBodyContextElement() const
112     {
113         return hasTagName(HTMLNames::tbodyTag)
114             || hasTagName(HTMLNames::tfootTag)
115             || hasTagName(HTMLNames::theadTag);
116     }
117 
118     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
isSpecialNode()119     bool isSpecialNode() const
120     {
121         if (hasTagName(MathMLNames::miTag)
122             || hasTagName(MathMLNames::moTag)
123             || hasTagName(MathMLNames::mnTag)
124             || hasTagName(MathMLNames::msTag)
125             || hasTagName(MathMLNames::mtextTag)
126             || hasTagName(MathMLNames::annotation_xmlTag)
127             || hasTagName(SVGNames::foreignObjectTag)
128             || hasTagName(SVGNames::descTag)
129             || hasTagName(SVGNames::titleTag))
130             return true;
131         if (isDocumentFragmentNode())
132             return true;
133         if (!isInHTMLNamespace())
134             return false;
135         const AtomicString& tagName = localName();
136         return tagName == HTMLNames::addressTag
137             || tagName == HTMLNames::appletTag
138             || tagName == HTMLNames::areaTag
139             || tagName == HTMLNames::articleTag
140             || tagName == HTMLNames::asideTag
141             || tagName == HTMLNames::baseTag
142             || tagName == HTMLNames::basefontTag
143             || tagName == HTMLNames::bgsoundTag
144             || tagName == HTMLNames::blockquoteTag
145             || tagName == HTMLNames::bodyTag
146             || tagName == HTMLNames::brTag
147             || tagName == HTMLNames::buttonTag
148             || tagName == HTMLNames::captionTag
149             || tagName == HTMLNames::centerTag
150             || tagName == HTMLNames::colTag
151             || tagName == HTMLNames::colgroupTag
152             || tagName == HTMLNames::commandTag
153             || tagName == HTMLNames::ddTag
154             || tagName == HTMLNames::detailsTag
155             || tagName == HTMLNames::dirTag
156             || tagName == HTMLNames::divTag
157             || tagName == HTMLNames::dlTag
158             || tagName == HTMLNames::dtTag
159             || tagName == HTMLNames::embedTag
160             || tagName == HTMLNames::fieldsetTag
161             || tagName == HTMLNames::figcaptionTag
162             || tagName == HTMLNames::figureTag
163             || tagName == HTMLNames::footerTag
164             || tagName == HTMLNames::formTag
165             || tagName == HTMLNames::frameTag
166             || tagName == HTMLNames::framesetTag
167             || isNumberedHeaderElement()
168             || tagName == HTMLNames::headTag
169             || tagName == HTMLNames::headerTag
170             || tagName == HTMLNames::hgroupTag
171             || tagName == HTMLNames::hrTag
172             || tagName == HTMLNames::htmlTag
173             || tagName == HTMLNames::iframeTag
174             || tagName == HTMLNames::imgTag
175             || tagName == HTMLNames::inputTag
176             || tagName == HTMLNames::liTag
177             || tagName == HTMLNames::linkTag
178             || tagName == HTMLNames::listingTag
179             || tagName == HTMLNames::mainTag
180             || tagName == HTMLNames::marqueeTag
181             || tagName == HTMLNames::menuTag
182             || (RuntimeEnabledFeatures::contextMenuEnabled() && tagName == HTMLNames::menuitemTag)
183             || tagName == HTMLNames::metaTag
184             || tagName == HTMLNames::navTag
185             || tagName == HTMLNames::noembedTag
186             || tagName == HTMLNames::noframesTag
187             || tagName == HTMLNames::noscriptTag
188             || tagName == HTMLNames::objectTag
189             || tagName == HTMLNames::olTag
190             || tagName == HTMLNames::pTag
191             || tagName == HTMLNames::paramTag
192             || tagName == HTMLNames::plaintextTag
193             || tagName == HTMLNames::preTag
194             || tagName == HTMLNames::scriptTag
195             || tagName == HTMLNames::sectionTag
196             || tagName == HTMLNames::selectTag
197             || tagName == HTMLNames::styleTag
198             || tagName == HTMLNames::summaryTag
199             || tagName == HTMLNames::tableTag
200             || isTableBodyContextElement()
201             || tagName == HTMLNames::tdTag
202             || tagName == HTMLNames::templateTag
203             || tagName == HTMLNames::textareaTag
204             || tagName == HTMLNames::thTag
205             || tagName == HTMLNames::titleTag
206             || tagName == HTMLNames::trTag
207             || tagName == HTMLNames::ulTag
208             || tagName == HTMLNames::wbrTag
209             || tagName == HTMLNames::xmpTag;
210     }
211 
trace(Visitor * visitor)212     void trace(Visitor* visitor) { visitor->trace(m_node); }
213 
214 private:
HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node,ItemType type)215     HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
216         : m_node(node)
217     {
218         switch (type) {
219         case ItemForDocumentFragmentNode:
220             m_isDocumentFragmentNode = true;
221             break;
222         case ItemForContextElement:
223             m_tokenLocalName = m_node->localName();
224             m_namespaceURI = m_node->namespaceURI();
225             m_isDocumentFragmentNode = false;
226             break;
227         }
228     }
229 
230     HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
m_node(node)231         : m_node(node)
232         , m_tokenLocalName(token->name())
233         , m_tokenAttributes(token->attributes())
234         , m_namespaceURI(namespaceURI)
235         , m_isDocumentFragmentNode(false)
236     {
237     }
238 
239     RefPtrWillBeMember<ContainerNode> m_node;
240 
241     AtomicString m_tokenLocalName;
242     Vector<Attribute> m_tokenAttributes;
243     AtomicString m_namespaceURI;
244     bool m_isDocumentFragmentNode;
245 };
246 
247 } // namespace blink
248 
249 #endif // HTMLStackItem_h
250