diff options
Diffstat (limited to 'Source/WebCore/dom/DatasetDOMStringMap.cpp')
-rw-r--r-- | Source/WebCore/dom/DatasetDOMStringMap.cpp | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/Source/WebCore/dom/DatasetDOMStringMap.cpp b/Source/WebCore/dom/DatasetDOMStringMap.cpp index b4383dc2d..5f01ecf17 100644 --- a/Source/WebCore/dom/DatasetDOMStringMap.cpp +++ b/Source/WebCore/dom/DatasetDOMStringMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,6 +29,7 @@ #include "Element.h" #include "ExceptionCode.h" #include <wtf/ASCIICType.h> +#include <wtf/text/AtomicString.h> #include <wtf/text/StringBuilder.h> namespace WebCore { @@ -105,22 +106,39 @@ static bool isValidPropertyName(const String& name) return true; } -static String convertPropertyNameToAttributeName(const String& name) +template<typename CharacterType> +static inline AtomicString convertPropertyNameToAttributeName(const StringImpl& name) { - StringBuilder builder; - builder.append("data-"); + const CharacterType dataPrefix[] = { 'd', 'a', 't', 'a', '-' }; + + Vector<CharacterType, 32> buffer; unsigned length = name.length(); + buffer.reserveInitialCapacity(WTF_ARRAY_LENGTH(dataPrefix) + length); + + buffer.append(dataPrefix, WTF_ARRAY_LENGTH(dataPrefix)); + + const CharacterType* characters = name.characters<CharacterType>(); for (unsigned i = 0; i < length; ++i) { - UChar character = name[i]; + CharacterType character = characters[i]; if (isASCIIUpper(character)) { - builder.append('-'); - builder.append(toASCIILower(character)); + buffer.append('-'); + buffer.append(toASCIILower(character)); } else - builder.append(character); + buffer.append(character); } + return AtomicString(buffer.data(), buffer.size()); +} - return builder.toString(); +static AtomicString convertPropertyNameToAttributeName(const String& name) +{ + if (name.isNull()) + return nullAtom; + + StringImpl* nameImpl = name.impl(); + if (nameImpl->is8Bit()) + return convertPropertyNameToAttributeName<LChar>(*nameImpl); + return convertPropertyNameToAttributeName<UChar>(*nameImpl); } void DatasetDOMStringMap::ref() @@ -133,61 +151,58 @@ void DatasetDOMStringMap::deref() m_element.deref(); } -void DatasetDOMStringMap::getNames(Vector<String>& names) +Vector<String> DatasetDOMStringMap::supportedPropertyNames() const { - if (!m_element.hasAttributes()) - return; + Vector<String> names; - for (const Attribute& attribute : m_element.attributesIterator()) { - if (isValidAttributeName(attribute.localName())) - names.append(convertAttributeNameToPropertyName(attribute.localName())); + if (m_element.hasAttributes()) { + for (auto& attribute : m_element.attributesIterator()) { + if (isValidAttributeName(attribute.localName())) + names.append(convertAttributeNameToPropertyName(attribute.localName())); + } } + + return names; } -String DatasetDOMStringMap::item(const String& name) +std::optional<const AtomicString&> DatasetDOMStringMap::item(const String& propertyName) const { - if (!m_element.hasAttributes()) - return String(); - - for (const Attribute& attribute : m_element.attributesIterator()) { - if (propertyNameMatchesAttributeName(name, attribute.localName())) - return attribute.value(); + if (m_element.hasAttributes()) { + AttributeIteratorAccessor attributeIteratorAccessor = m_element.attributesIterator(); + + if (attributeIteratorAccessor.attributeCount() == 1) { + // If the node has a single attribute, it is the dataset member accessed in most cases. + // Building a new AtomicString in that case is overkill so we do a direct character comparison. + const Attribute& attribute = *attributeIteratorAccessor.begin(); + if (propertyNameMatchesAttributeName(propertyName, attribute.localName())) + return attribute.value(); + } else { + AtomicString attributeName = convertPropertyNameToAttributeName(propertyName); + for (const Attribute& attribute : attributeIteratorAccessor) { + if (attribute.localName() == attributeName) + return attribute.value(); + } + } } - return String(); + return std::nullopt; } -bool DatasetDOMStringMap::contains(const String& name) +String DatasetDOMStringMap::namedItem(const AtomicString& name) const { - if (!m_element.hasAttributes()) - return false; - - for (const Attribute& attribute : m_element.attributesIterator()) { - if (propertyNameMatchesAttributeName(name, attribute.localName())) - return true; - } - - return false; + return item(name).value_or(String { }); } -void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionCode& ec) +ExceptionOr<void> DatasetDOMStringMap::setItem(const String& name, const String& value) { - if (!isValidPropertyName(name)) { - ec = SYNTAX_ERR; - return; - } - - m_element.setAttribute(convertPropertyNameToAttributeName(name), value, ec); + if (!isValidPropertyName(name)) + return Exception { SYNTAX_ERR }; + return m_element.setAttribute(convertPropertyNameToAttributeName(name), value); } -void DatasetDOMStringMap::deleteItem(const String& name, ExceptionCode& ec) +bool DatasetDOMStringMap::deleteItem(const String& name) { - if (!isValidPropertyName(name)) { - ec = SYNTAX_ERR; - return; - } - - m_element.removeAttribute(convertPropertyNameToAttributeName(name)); + return m_element.removeAttribute(convertPropertyNameToAttributeName(name)); } } // namespace WebCore |