Modified: trunk/Source/WebCore/dom/Element.cpp (143111 => 143112)
--- trunk/Source/WebCore/dom/Element.cpp 2013-02-16 22:27:12 UTC (rev 143111)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-02-16 22:57:02 UTC (rev 143112)
@@ -94,6 +94,11 @@
using namespace HTMLNames;
using namespace XMLNames;
+
+static inline bool shouldIgnoreAttributeCase(const Element* e)
+{
+ return e && e->document()->isHTMLDocument() && e->isHTMLElement();
+}
class StyleResolverParentPusher {
public:
@@ -331,19 +336,55 @@
return hasAttributeNS(name.namespaceURI(), name.localName());
}
-const AtomicString& Element::getAttribute(const QualifiedName& name) const
+void Element::synchronizeAllAttributes() const
{
if (!elementData())
- return nullAtom;
+ return;
+ if (elementData()->m_styleAttributeIsDirty)
+ updateStyleAttribute();
+#if ENABLE(SVG)
+ if (elementData()->m_animatedSVGAttributesAreDirty)
+ updateAnimatedSVGAttribute(anyQName());
+#endif
+}
- if (UNLIKELY(name == styleAttr && elementData()->m_styleAttributeIsDirty))
+inline void Element::synchronizeAttribute(const QualifiedName& name) const
+{
+ if (!elementData())
+ return;
+ if (UNLIKELY(name == styleAttr && elementData()->m_styleAttributeIsDirty)) {
updateStyleAttribute();
-
+ return;
+ }
#if ENABLE(SVG)
if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty))
updateAnimatedSVGAttribute(name);
#endif
+}
+inline void Element::synchronizeAttribute(const AtomicString& localName) const
+{
+ // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName,
+ // e.g when called from DOM API.
+ if (!elementData())
+ return;
+ if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase(this))) {
+ updateStyleAttribute();
+ return;
+ }
+#if ENABLE(SVG)
+ if (elementData()->m_animatedSVGAttributesAreDirty) {
+ // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
+ updateAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
+ }
+#endif
+}
+
+const AtomicString& Element::getAttribute(const QualifiedName& name) const
+{
+ if (!elementData())
+ return nullAtom;
+ synchronizeAttribute(name);
if (const Attribute* attribute = getAttributeItem(name))
return attribute->value();
return nullAtom;
@@ -698,30 +739,12 @@
return document()->view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
}
-static inline bool shouldIgnoreAttributeCase(const Element* e)
+const AtomicString& Element::getAttribute(const AtomicString& localName) const
{
- return e && e->document()->isHTMLDocument() && e->isHTMLElement();
-}
-
-const AtomicString& Element::getAttribute(const AtomicString& name) const
-{
if (!elementData())
return nullAtom;
-
- bool ignoreCase = shouldIgnoreAttributeCase(this);
-
- // Update the 'style' attribute if it's invalid and being requested:
- if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
- updateStyleAttribute();
-
-#if ENABLE(SVG)
- if (elementData()->m_animatedSVGAttributesAreDirty) {
- // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
- updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
- }
-#endif
-
- if (const Attribute* attribute = elementData()->getAttributeItem(name, ignoreCase))
+ synchronizeAttribute(localName);
+ if (const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase(this)))
return attribute->value();
return nullAtom;
}
@@ -731,28 +754,32 @@
return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
}
-void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
+void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionCode& ec)
{
- if (!Document::isValidName(name)) {
+ if (!Document::isValidName(localName)) {
ec = INVALID_CHARACTER_ERR;
return;
}
- const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
+ synchronizeAttribute(localName);
+ const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase(this) ? localName.lower() : localName;
- size_t index = ensureElementDataWithSynchronizedAttributes()->getAttributeItemIndex(localName, false);
- const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom);
+ size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : notFound;
+ const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
{
- setAttributeInternal(ensureElementDataWithSynchronizedAttributes()->getAttributeItemIndex(name), name, value, NotInSynchronizationOfLazyAttribute);
+ synchronizeAttribute(name);
+ size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : notFound;
+ setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
{
- setAttributeInternal(ensureUniqueElementData()->getAttributeItemIndex(name), name, value, InSynchronizationOfLazyAttribute);
+ size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : notFound;
+ setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
}
inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
@@ -1032,20 +1059,20 @@
bool Element::hasAttributes() const
{
- updateInvalidAttributes();
+ synchronizeAllAttributes();
return elementData() && elementData()->length();
}
bool Element::hasEquivalentAttributes(const Element* other) const
{
- const ElementData* elementData = elementDataWithSynchronizedAttributes();
- const ElementData* otherElementData = other->elementDataWithSynchronizedAttributes();
- if (elementData == otherElementData)
+ synchronizeAllAttributes();
+ other->synchronizeAllAttributes();
+ if (elementData() == other->elementData())
return true;
- if (elementData)
- return elementData->isEquivalent(otherElementData);
- if (otherElementData)
- return otherElementData->isEquivalent(elementData);
+ if (elementData())
+ return elementData()->isEquivalent(other->elementData());
+ if (other->elementData())
+ return other->elementData()->isEquivalent(elementData());
return true;
}
@@ -1685,7 +1712,7 @@
return 0;
}
- updateInvalidAttributes();
+ synchronizeAllAttributes();
UniqueElementData* elementData = ensureUniqueElementData();
size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName());
@@ -1722,10 +1749,9 @@
ASSERT(document() == attr->document());
- const ElementData* elementData = elementDataWithSynchronizedAttributes();
- ASSERT(elementData);
+ synchronizeAttribute(attr->qualifiedName());
- size_t index = elementData->getAttributeItemIndex(attr->qualifiedName());
+ size_t index = elementData()->getAttributeItemIndex(attr->qualifiedName());
if (index == notFound) {
ec = NOT_FOUND_ERR;
return 0;
@@ -1813,12 +1839,12 @@
removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
}
-PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& name)
+PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
{
- const ElementData* elementData = elementDataWithSynchronizedAttributes();
- if (!elementData)
+ if (!elementData())
return 0;
- const Attribute* attribute = elementData->getAttributeItem(name, shouldIgnoreAttributeCase(this));
+ synchronizeAttribute(localName);
+ const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase(this));
if (!attribute)
return 0;
return ensureAttr(attribute->name());
@@ -1826,32 +1852,31 @@
PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
- const ElementData* elementData = elementDataWithSynchronizedAttributes();
- if (!elementData)
+ if (!elementData())
return 0;
- const Attribute* attribute = elementData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
+ QualifiedName qName(nullAtom, localName, namespaceURI);
+ synchronizeAttribute(qName);
+ const Attribute* attribute = elementData()->getAttributeItem(qName);
if (!attribute)
return 0;
return ensureAttr(attribute->name());
}
-bool Element::hasAttribute(const AtomicString& name) const
+bool Element::hasAttribute(const AtomicString& localName) const
{
if (!elementData())
return false;
-
- // This call to String::lower() seems to be required but
- // there may be a way to remove it.
- AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
- return elementDataWithSynchronizedAttributes()->getAttributeItem(localName, false);
+ synchronizeAttribute(localName);
+ return elementData()->getAttributeItem(shouldIgnoreAttributeCase(this) ? localName.lower() : localName, false);
}
bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
- const ElementData* elementData = elementDataWithSynchronizedAttributes();
- if (!elementData)
+ if (!elementData())
return false;
- return elementData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
+ QualifiedName qName(nullAtom, localName, namespaceURI);
+ synchronizeAttribute(qName);
+ return elementData()->getAttributeItem(qName);
}
CSSStyleDeclaration *Element::style()
@@ -2743,7 +2768,7 @@
if (hasSyntheticAttrChildNodes())
detachAllAttrNodesFromElement();
- other.updateInvalidAttributes();
+ other.synchronizeAllAttributes();
if (!other.m_elementData) {
m_elementData.clear();
return;
Modified: trunk/Source/WebCore/dom/Element.h (143111 => 143112)
--- trunk/Source/WebCore/dom/Element.h 2013-02-16 22:27:12 UTC (rev 143111)
+++ trunk/Source/WebCore/dom/Element.h 2013-02-16 22:57:02 UTC (rev 143112)
@@ -369,10 +369,10 @@
void parserSetAttributes(const Vector<Attribute>&, FragmentScriptingPermission);
const ElementData* elementData() const { return m_elementData.get(); }
- const ElementData* elementDataWithSynchronizedAttributes() const;
- const ElementData* ensureElementDataWithSynchronizedAttributes() const;
UniqueElementData* ensureUniqueElementData();
+ void synchronizeAllAttributes() const;
+
// Clones attributes only.
void cloneAttributesFromElement(const Element&);
@@ -647,7 +647,8 @@
void didModifyAttribute(const QualifiedName&, const AtomicString&);
void didRemoveAttribute(const QualifiedName&);
- void updateInvalidAttributes() const;
+ void synchronizeAttribute(const QualifiedName&) const;
+ void synchronizeAttribute(const AtomicString& localName) const;
void scrollByUnits(int units, ScrollGranularity);
@@ -774,20 +775,6 @@
return static_cast<Element*>(n);
}
-inline const ElementData* Element::elementDataWithSynchronizedAttributes() const
-{
- updateInvalidAttributes();
- return elementData();
-}
-
-inline const ElementData* Element::ensureElementDataWithSynchronizedAttributes() const
-{
- updateInvalidAttributes();
- if (elementData())
- return elementData();
- return const_cast<Element*>(this)->ensureUniqueElementData();
-}
-
inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
{
if (!inDocument() || isInShadowTree())
@@ -901,20 +888,6 @@
return elementData()->getAttributeItem(name);
}
-inline void Element::updateInvalidAttributes() const
-{
- if (!elementData())
- return;
-
- if (elementData()->m_styleAttributeIsDirty)
- updateStyleAttribute();
-
-#if ENABLE(SVG)
- if (elementData()->m_animatedSVGAttributesAreDirty)
- updateAnimatedSVGAttribute(anyQName());
-#endif
-}
-
inline bool Element::hasID() const
{
return elementData() && elementData()->hasID();