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