Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / dom / DatasetDOMStringMap.cpp
blob2e5fea47322ebbd9a8ed3cda75ebcc80e3d52207
1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #include "config.h"
27 #include "core/dom/DatasetDOMStringMap.h"
29 #include "bindings/core/v8/ExceptionState.h"
30 #include "core/dom/Attribute.h"
31 #include "core/dom/Element.h"
32 #include "core/dom/ExceptionCode.h"
33 #include "wtf/ASCIICType.h"
34 #include "wtf/text/StringBuilder.h"
36 namespace blink {
38 static bool isValidAttributeName(const String& name)
40 if (!name.startsWith("data-"))
41 return false;
43 unsigned length = name.length();
44 for (unsigned i = 5; i < length; ++i) {
45 if (isASCIIUpper(name[i]))
46 return false;
49 return true;
52 static String convertAttributeNameToPropertyName(const String& name)
54 StringBuilder stringBuilder;
56 unsigned length = name.length();
57 for (unsigned i = 5; i < length; ++i) {
58 UChar character = name[i];
59 if (character != '-') {
60 stringBuilder.append(character);
61 } else {
62 if ((i + 1 < length) && isASCIILower(name[i + 1])) {
63 stringBuilder.append(toASCIIUpper(name[i + 1]));
64 ++i;
65 } else {
66 stringBuilder.append(character);
71 return stringBuilder.toString();
74 template<typename CharType1, typename CharType2>
75 static bool propertyNameMatchesAttributeName(const CharType1* propertyName, const CharType2* attributeName, unsigned propertyLength, unsigned attributeLength)
77 unsigned a = 5;
78 unsigned p = 0;
79 bool wordBoundary = false;
80 while (a < attributeLength && p < propertyLength) {
81 if (attributeName[a] == '-' && a + 1 < attributeLength && isASCIILower(attributeName[a + 1])) {
82 wordBoundary = true;
83 } else {
84 if ((wordBoundary ? toASCIIUpper(attributeName[a]) : attributeName[a]) != propertyName[p])
85 return false;
86 p++;
87 wordBoundary = false;
89 a++;
92 return (a == attributeLength && p == propertyLength);
95 static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
97 if (!attributeName.startsWith("data-"))
98 return false;
100 unsigned propertyLength = propertyName.length();
101 unsigned attributeLength = attributeName.length();
103 if (propertyName.is8Bit()) {
104 if (attributeName.is8Bit())
105 return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters8(), propertyLength, attributeLength);
106 return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters16(), propertyLength, attributeLength);
109 if (attributeName.is8Bit())
110 return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters8(), propertyLength, attributeLength);
111 return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters16(), propertyLength, attributeLength);
114 static bool isValidPropertyName(const String& name)
116 unsigned length = name.length();
117 for (unsigned i = 0; i < length; ++i) {
118 if (name[i] == '-' && (i + 1 < length) && isASCIILower(name[i + 1]))
119 return false;
121 return true;
124 // This returns an AtomicString because attribute names are always stored
125 // as AtomicString types in Element (see setAttribute()).
126 static AtomicString convertPropertyNameToAttributeName(const String& name)
128 StringBuilder builder;
129 builder.appendLiteral("data-");
131 unsigned length = name.length();
132 for (unsigned i = 0; i < length; ++i) {
133 UChar character = name[i];
134 if (isASCIIUpper(character)) {
135 builder.append('-');
136 builder.append(toASCIILower(character));
137 } else {
138 builder.append(character);
142 return builder.toAtomicString();
145 #if !ENABLE(OILPAN)
146 void DatasetDOMStringMap::ref()
148 m_element->ref();
151 void DatasetDOMStringMap::deref()
153 m_element->deref();
155 #endif
157 void DatasetDOMStringMap::getNames(Vector<String>& names)
159 AttributeCollection attributes = m_element->attributes();
160 for (const Attribute& attr : attributes) {
161 if (isValidAttributeName(attr.localName()))
162 names.append(convertAttributeNameToPropertyName(attr.localName()));
166 String DatasetDOMStringMap::item(const String& name)
168 AttributeCollection attributes = m_element->attributes();
169 for (const Attribute& attr : attributes) {
170 if (propertyNameMatchesAttributeName(name, attr.localName()))
171 return attr.value();
174 return String();
177 bool DatasetDOMStringMap::contains(const String& name)
179 AttributeCollection attributes = m_element->attributes();
180 for (const Attribute& attr : attributes) {
181 if (propertyNameMatchesAttributeName(name, attr.localName()))
182 return true;
184 return false;
187 void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionState& exceptionState)
189 if (!isValidPropertyName(name)) {
190 exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a valid property name.");
191 return;
194 m_element->setAttribute(convertPropertyNameToAttributeName(name), AtomicString(value), exceptionState);
197 bool DatasetDOMStringMap::deleteItem(const String& name)
199 if (isValidPropertyName(name)) {
200 AtomicString attributeName = convertPropertyNameToAttributeName(name);
201 if (m_element->hasAttribute(attributeName)) {
202 m_element->removeAttribute(attributeName);
203 return true;
206 return false;
209 DEFINE_TRACE(DatasetDOMStringMap)
211 visitor->trace(m_element);
212 DOMStringMap::trace(visitor);
215 } // namespace blink