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
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.
27 #include "DatasetDOMStringMap.h"
29 #include "Attribute.h"
31 #include "ExceptionCode.h"
32 #include <wtf/ASCIICType.h>
33 #include <wtf/text/StringBuilder.h>
37 static bool isValidAttributeName(const String& name)
39 if (!name.startsWith("data-"))
42 unsigned length = name.length();
43 for (unsigned i = 5; i < length; ++i) {
44 if (isASCIIUpper(name[i]))
51 static String convertAttributeNameToPropertyName(const String& name)
53 StringBuilder stringBuilder;
55 unsigned length = name.length();
56 for (unsigned i = 5; i < length; ++i) {
57 UChar character = name[i];
59 stringBuilder.append(character);
61 if ((i + 1 < length) && isASCIILower(name[i + 1])) {
62 stringBuilder.append(toASCIIUpper(name[i + 1]));
65 stringBuilder.append(character);
69 return stringBuilder.toString();
72 static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
74 if (!attributeName.startsWith("data-"))
77 unsigned propertyLength = propertyName.length();
78 unsigned attributeLength = attributeName.length();
82 bool wordBoundary = false;
83 while (a < attributeLength && p < propertyLength) {
84 const UChar currentAttributeNameChar = attributeName[a];
85 if (currentAttributeNameChar == '-' && a + 1 < attributeLength && attributeName[a + 1] != '-')
88 if ((wordBoundary ? toASCIIUpper(currentAttributeNameChar) : currentAttributeNameChar) != propertyName[p])
96 return (a == attributeLength && p == propertyLength);
99 static bool isValidPropertyName(const String& name)
101 unsigned length = name.length();
102 for (unsigned i = 0; i < length; ++i) {
103 if (name[i] == '-' && (i + 1 < length) && isASCIILower(name[i + 1]))
109 static String convertPropertyNameToAttributeName(const String& name)
111 StringBuilder builder;
112 builder.append("data-");
114 unsigned length = name.length();
115 for (unsigned i = 0; i < length; ++i) {
116 UChar character = name[i];
117 if (isASCIIUpper(character)) {
119 builder.append(toASCIILower(character));
121 builder.append(character);
124 return builder.toString();
127 void DatasetDOMStringMap::ref()
132 void DatasetDOMStringMap::deref()
137 void DatasetDOMStringMap::getNames(Vector<String>& names)
139 if (!m_element->hasAttributes())
142 unsigned length = m_element->attributeCount();
143 for (unsigned i = 0; i < length; i++) {
144 const Attribute* attribute = m_element->attributeItem(i);
145 if (isValidAttributeName(attribute->localName()))
146 names.append(convertAttributeNameToPropertyName(attribute->localName()));
150 String DatasetDOMStringMap::item(const String& name)
152 if (!m_element->hasAttributes())
155 unsigned length = m_element->attributeCount();
156 for (unsigned i = 0; i < length; i++) {
157 const Attribute* attribute = m_element->attributeItem(i);
158 if (propertyNameMatchesAttributeName(name, attribute->localName()))
159 return attribute->value();
165 bool DatasetDOMStringMap::contains(const String& name)
167 if (!m_element->hasAttributes())
170 unsigned length = m_element->attributeCount();
171 for (unsigned i = 0; i < length; i++) {
172 const Attribute* attribute = m_element->attributeItem(i);
173 if (propertyNameMatchesAttributeName(name, attribute->localName()))
180 void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionCode& ec)
182 if (!isValidPropertyName(name)) {
187 m_element->setAttribute(convertPropertyNameToAttributeName(name), value, ec);
190 void DatasetDOMStringMap::deleteItem(const String& name, ExceptionCode& ec)
192 if (!isValidPropertyName(name)) {
197 m_element->removeAttribute(convertPropertyNameToAttributeName(name));
200 } // namespace WebCore