Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / parser / AtomicHTMLToken.h
1 /*
2  * Copyright (C) 2013 Google, 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 APPLE 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 APPLE 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 AtomicHTMLToken_h
27 #define AtomicHTMLToken_h
28
29 #include "core/HTMLElementLookupTrie.h"
30 #include "core/dom/Attribute.h"
31 #include "core/html/parser/CompactHTMLToken.h"
32 #include "core/html/parser/HTMLToken.h"
33 #include "wtf/RefCounted.h"
34 #include "wtf/RefPtr.h"
35
36 namespace blink {
37
38 class AtomicHTMLToken {
39     WTF_MAKE_NONCOPYABLE(AtomicHTMLToken);
40 public:
41
42     bool forceQuirks() const
43     {
44         ASSERT(m_type == HTMLToken::DOCTYPE);
45         return m_doctypeData->m_forceQuirks;
46     }
47
48     HTMLToken::Type type() const { return m_type; }
49
50     const AtomicString& name() const
51     {
52         ASSERT(usesName());
53         return m_name;
54     }
55
56     void setName(const AtomicString& name)
57     {
58         ASSERT(usesName());
59         m_name = name;
60     }
61
62     bool selfClosing() const
63     {
64         ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
65         return m_selfClosing;
66     }
67
68     Attribute* getAttributeItem(const QualifiedName& attributeName)
69     {
70         ASSERT(usesAttributes());
71         return findAttributeInVector(m_attributes, attributeName);
72     }
73
74     Vector<Attribute>& attributes()
75     {
76         ASSERT(usesAttributes());
77         return m_attributes;
78     }
79
80     const Vector<Attribute>& attributes() const
81     {
82         ASSERT(usesAttributes());
83         return m_attributes;
84     }
85
86     const String& characters() const
87     {
88         ASSERT(m_type == HTMLToken::Character);
89         return m_data;
90     }
91
92     const String& comment() const
93     {
94         ASSERT(m_type == HTMLToken::Comment);
95         return m_data;
96     }
97
98     // FIXME: Distinguish between a missing public identifer and an empty one.
99     Vector<UChar>& publicIdentifier() const
100     {
101         ASSERT(m_type == HTMLToken::DOCTYPE);
102         return m_doctypeData->m_publicIdentifier;
103     }
104
105     // FIXME: Distinguish between a missing system identifer and an empty one.
106     Vector<UChar>& systemIdentifier() const
107     {
108         ASSERT(m_type == HTMLToken::DOCTYPE);
109         return m_doctypeData->m_systemIdentifier;
110     }
111
112     explicit AtomicHTMLToken(HTMLToken& token)
113         : m_type(token.type())
114     {
115         switch (m_type) {
116         case HTMLToken::Uninitialized:
117             ASSERT_NOT_REACHED();
118             break;
119         case HTMLToken::DOCTYPE:
120             m_name = AtomicString(token.name());
121             m_doctypeData = token.releaseDoctypeData();
122             break;
123         case HTMLToken::EndOfFile:
124             break;
125         case HTMLToken::StartTag:
126         case HTMLToken::EndTag: {
127             m_selfClosing = token.selfClosing();
128             if (StringImpl* tagName = lookupHTMLTag(token.name().data(), token.name().size()))
129                 m_name = AtomicString(tagName);
130             else
131                 m_name = AtomicString(token.name());
132             initializeAttributes(token.attributes());
133             break;
134         }
135         case HTMLToken::Character:
136         case HTMLToken::Comment:
137             if (token.isAll8BitData())
138                 m_data = String::make8BitFrom16BitSource(token.data());
139             else
140                 m_data = String(token.data());
141             break;
142         }
143     }
144
145     explicit AtomicHTMLToken(const CompactHTMLToken& token)
146         : m_type(token.type())
147     {
148         switch (m_type) {
149         case HTMLToken::Uninitialized:
150             ASSERT_NOT_REACHED();
151             break;
152         case HTMLToken::DOCTYPE:
153             m_name = AtomicString(token.data());
154             m_doctypeData = adoptPtr(new DoctypeData());
155             m_doctypeData->m_hasPublicIdentifier = true;
156             append(m_doctypeData->m_publicIdentifier, token.publicIdentifier());
157             m_doctypeData->m_hasSystemIdentifier = true;
158             append(m_doctypeData->m_systemIdentifier, token.systemIdentifier());
159             m_doctypeData->m_forceQuirks = token.doctypeForcesQuirks();
160             break;
161         case HTMLToken::EndOfFile:
162             break;
163         case HTMLToken::StartTag:
164             m_attributes.reserveInitialCapacity(token.attributes().size());
165             for (const CompactHTMLToken::Attribute& attribute : token.attributes()) {
166                 QualifiedName name(nullAtom, AtomicString(attribute.name), nullAtom);
167                 // FIXME: This is N^2 for the number of attributes.
168                 if (!findAttributeInVector(m_attributes, name))
169                     m_attributes.append(Attribute(name, AtomicString(attribute.value)));
170             }
171             // Fall through!
172         case HTMLToken::EndTag:
173             m_selfClosing = token.selfClosing();
174             m_name = AtomicString(token.data());
175             break;
176         case HTMLToken::Character:
177         case HTMLToken::Comment:
178             m_data = token.data();
179             break;
180         }
181     }
182
183     explicit AtomicHTMLToken(HTMLToken::Type type)
184         : m_type(type)
185         , m_selfClosing(false)
186     {
187     }
188
189     AtomicHTMLToken(HTMLToken::Type type, const AtomicString& name, const Vector<Attribute>& attributes = Vector<Attribute>())
190         : m_type(type)
191         , m_name(name)
192         , m_selfClosing(false)
193         , m_attributes(attributes)
194     {
195         ASSERT(usesName());
196     }
197
198 private:
199     HTMLToken::Type m_type;
200
201     void initializeAttributes(const HTMLToken::AttributeList& attributes);
202     QualifiedName nameForAttribute(const HTMLToken::Attribute&) const;
203
204     bool usesName() const;
205
206     bool usesAttributes() const;
207
208     // "name" for DOCTYPE, StartTag, and EndTag
209     AtomicString m_name;
210
211     // "data" for Comment, "characters" for Character
212     String m_data;
213
214     // For DOCTYPE
215     OwnPtr<DoctypeData> m_doctypeData;
216
217     // For StartTag and EndTag
218     bool m_selfClosing;
219
220     Vector<Attribute> m_attributes;
221 };
222
223 inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList& attributes)
224 {
225     size_t size = attributes.size();
226     if (!size)
227         return;
228
229     m_attributes.clear();
230     m_attributes.reserveInitialCapacity(size);
231     for (size_t i = 0; i < size; ++i) {
232         const HTMLToken::Attribute& attribute = attributes[i];
233         if (attribute.name.isEmpty())
234             continue;
235
236         ASSERT(attribute.nameRange.start);
237         ASSERT(attribute.nameRange.end);
238         ASSERT(attribute.valueRange.start);
239         ASSERT(attribute.valueRange.end);
240
241         AtomicString value(attribute.value);
242         const QualifiedName& name = nameForAttribute(attribute);
243         // FIXME: This is N^2 for the number of attributes.
244         if (!findAttributeInVector(m_attributes, name))
245             m_attributes.append(Attribute(name, value));
246     }
247 }
248
249 }
250
251 #endif