Commit 86d6cb5f authored by kling@webkit.org's avatar kling@webkit.org

Decouple Attr logic from ElementAttributeData.

<http://webkit.org/b/101126>

Reviewed by Antti Koivisto.

Move all logic dealing with Attr DOM nodes from ElementAttributeData to Element.
This makes more sense since an Attr is tied to a single Element, but an ElementAttributeData
can be shared by any number of Elements at a given time.

Also updated naming convention from just "Attr" to "Attr node" in the code I was touching.
"Attr" is way too generic, and has been historically confused with WebCore::Attribute a lot.

* dom/Element.h:
* dom/ElementAttributeData.h:
* dom/Element.cpp:
(WebCore::attrNodeListMap):
(WebCore::attrNodeListForElement):
(WebCore::ensureAttrNodeListForElement):
(WebCore::removeAttrNodeListForElement):
(WebCore::findAttrNodeInList):
(WebCore::Element::~Element):
(WebCore::Element::detachAttribute):
(WebCore::Element::setAttributeNode):
(WebCore::Element::removeAttributeInternal):
(WebCore::Element::getAttributeNode):
(WebCore::Element::getAttributeNodeNS):
(WebCore::Element::normalizeAttributes):
(WebCore::Element::attrIfExists):
(WebCore::Element::ensureAttr):
(WebCore::Element::detachAttrNodeFromElementWithValue):
(WebCore::Element::detachAllAttrNodesFromElement):
(WebCore::Element::cloneAttributesFromElement):

    Move everything Attr-related into Element.cpp while simplifying some loops and remove
    conditions that are no longer needed as they used to depend on having an attributeData().

* dom/Node.h:
(WebCore::Node::hasSyntheticAttrChildNodes):
(WebCore::Node::setHasSyntheticAttrChildNodes):

    Renamed the hasAttrList() node flag to hasSyntheticAttrChildNodes().

* dom/Attr.cpp:
(WebCore::Attr::detachFromElementWithValue):

    Remove awkward indirection and let the call site deal with removing the Attr node from
    the Element's list of Attr nodes.

* dom/ElementAttributeData.cpp:
(WebCore::ElementAttributeData::clearAttributes):

    Remove now-unused Element* argument.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@133492 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 062c3fed
2012-11-05 Andreas Kling <kling@webkit.org>
Decouple Attr logic from ElementAttributeData.
<http://webkit.org/b/101126>
Reviewed by Antti Koivisto.
Move all logic dealing with Attr DOM nodes from ElementAttributeData to Element.
This makes more sense since an Attr is tied to a single Element, but an ElementAttributeData
can be shared by any number of Elements at a given time.
Also updated naming convention from just "Attr" to "Attr node" in the code I was touching.
"Attr" is way too generic, and has been historically confused with WebCore::Attribute a lot.
* dom/Element.h:
* dom/ElementAttributeData.h:
* dom/Element.cpp:
(WebCore::attrNodeListMap):
(WebCore::attrNodeListForElement):
(WebCore::ensureAttrNodeListForElement):
(WebCore::removeAttrNodeListForElement):
(WebCore::findAttrNodeInList):
(WebCore::Element::~Element):
(WebCore::Element::detachAttribute):
(WebCore::Element::setAttributeNode):
(WebCore::Element::removeAttributeInternal):
(WebCore::Element::getAttributeNode):
(WebCore::Element::getAttributeNodeNS):
(WebCore::Element::normalizeAttributes):
(WebCore::Element::attrIfExists):
(WebCore::Element::ensureAttr):
(WebCore::Element::detachAttrNodeFromElementWithValue):
(WebCore::Element::detachAllAttrNodesFromElement):
(WebCore::Element::cloneAttributesFromElement):
Move everything Attr-related into Element.cpp while simplifying some loops and remove
conditions that are no longer needed as they used to depend on having an attributeData().
* dom/Node.h:
(WebCore::Node::hasSyntheticAttrChildNodes):
(WebCore::Node::setHasSyntheticAttrChildNodes):
Renamed the hasAttrList() node flag to hasSyntheticAttrChildNodes().
* dom/Attr.cpp:
(WebCore::Attr::detachFromElementWithValue):
Remove awkward indirection and let the call site deal with removing the Attr node from
the Element's list of Attr nodes.
* dom/ElementAttributeData.cpp:
(WebCore::ElementAttributeData::clearAttributes):
Remove now-unused Element* argument.
2012-11-05 Hans Muller <hmuller@adobe.com> 2012-11-05 Hans Muller <hmuller@adobe.com>
[CSS Exclusions] Polygon edges should span colinear vertices [CSS Exclusions] Polygon edges should span colinear vertices
...@@ -218,7 +218,6 @@ void Attr::detachFromElementWithValue(const AtomicString& value) ...@@ -218,7 +218,6 @@ void Attr::detachFromElementWithValue(const AtomicString& value)
{ {
ASSERT(m_element); ASSERT(m_element);
ASSERT(m_standaloneValue.isNull()); ASSERT(m_standaloneValue.isNull());
m_element->attributeData()->removeAttr(m_element, qualifiedName());
m_standaloneValue = value; m_standaloneValue = value;
m_element = 0; m_element = 0;
} }
......
This diff is collapsed.
...@@ -528,6 +528,9 @@ private: ...@@ -528,6 +528,9 @@ private:
ElementRareData* elementRareData() const; ElementRareData* elementRareData() const;
ElementRareData* ensureElementRareData(); ElementRareData* ensureElementRareData();
void detachAllAttrNodesFromElement();
void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
RefPtr<ElementAttributeData> m_attributeData; RefPtr<ElementAttributeData> m_attributeData;
}; };
......
...@@ -87,101 +87,6 @@ PassRefPtr<ElementAttributeData> ElementAttributeData::makeMutableCopy() const ...@@ -87,101 +87,6 @@ PassRefPtr<ElementAttributeData> ElementAttributeData::makeMutableCopy() const
return adoptRef(new MutableElementAttributeData(static_cast<const ImmutableElementAttributeData&>(*this))); return adoptRef(new MutableElementAttributeData(static_cast<const ImmutableElementAttributeData&>(*this)));
} }
typedef Vector<RefPtr<Attr> > AttrList;
typedef HashMap<Element*, OwnPtr<AttrList> > AttrListMap;
static AttrListMap& attrListMap()
{
DEFINE_STATIC_LOCAL(AttrListMap, map, ());
return map;
}
static AttrList* attrListForElement(Element* element)
{
ASSERT(element);
if (!element->hasAttrList())
return 0;
ASSERT(attrListMap().contains(element));
return attrListMap().get(element);
}
static AttrList* ensureAttrListForElement(Element* element)
{
ASSERT(element);
if (element->hasAttrList()) {
ASSERT(attrListMap().contains(element));
return attrListMap().get(element);
}
ASSERT(!attrListMap().contains(element));
element->setHasAttrList();
AttrListMap::AddResult result = attrListMap().add(element, adoptPtr(new AttrList));
return result.iterator->value.get();
}
static void removeAttrListForElement(Element* element)
{
ASSERT(element);
ASSERT(element->hasAttrList());
ASSERT(attrListMap().contains(element));
attrListMap().remove(element);
element->clearHasAttrList();
}
static Attr* findAttrInList(AttrList* attrList, const QualifiedName& name)
{
for (unsigned i = 0; i < attrList->size(); ++i) {
if (attrList->at(i)->qualifiedName() == name)
return attrList->at(i).get();
}
return 0;
}
PassRefPtr<Attr> ElementAttributeData::attrIfExists(Element* element, const QualifiedName& name) const
{
if (AttrList* attrList = attrListForElement(element))
return findAttrInList(attrList, name);
return 0;
}
PassRefPtr<Attr> ElementAttributeData::ensureAttr(Element* element, const QualifiedName& name) const
{
AttrList* attrList = ensureAttrListForElement(element);
RefPtr<Attr> attr = findAttrInList(attrList, name);
if (!attr) {
attr = Attr::create(element, name);
attrList->append(attr);
}
return attr.release();
}
void ElementAttributeData::setAttr(Element* element, const QualifiedName& name, Attr* attr) const
{
AttrList* attrList = ensureAttrListForElement(element);
if (findAttrInList(attrList, name))
return;
attrList->append(attr);
attr->attachToElement(element);
}
void ElementAttributeData::removeAttr(Element* element, const QualifiedName& name) const
{
AttrList* attrList = attrListForElement(element);
ASSERT(attrList);
for (unsigned i = 0; i < attrList->size(); ++i) {
if (attrList->at(i)->qualifiedName() == name) {
attrList->remove(i);
if (attrList->isEmpty())
removeAttrListForElement(element);
return;
}
}
ASSERT_NOT_REACHED();
}
StylePropertySet* ElementAttributeData::ensureInlineStyle(StyledElement* element) StylePropertySet* ElementAttributeData::ensureInlineStyle(StyledElement* element)
{ {
ASSERT(isMutable()); ASSERT(isMutable());
...@@ -258,20 +163,6 @@ bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const ...@@ -258,20 +163,6 @@ bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const
return true; return true;
} }
void ElementAttributeData::detachAttrObjectsFromElement(Element* element) const
{
ASSERT(element->hasAttrList());
for (unsigned i = 0; i < length(); ++i) {
const Attribute* attribute = attributeItem(i);
if (RefPtr<Attr> attr = attrIfExists(element, attribute->name()))
attr->detachFromElementWithValue(attribute->value());
}
// The loop above should have cleaned out this element's Attr map.
ASSERT(!element->hasAttrList());
}
void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{ {
size_t actualSize = m_isMutable ? sizeof(ElementAttributeData) : sizeForImmutableElementAttributeDataWithAttributeCount(m_arraySize); size_t actualSize = m_isMutable ? sizeof(ElementAttributeData) : sizeForImmutableElementAttributeDataWithAttributeCount(m_arraySize);
...@@ -322,7 +213,7 @@ void ElementAttributeData::cloneDataFrom(const ElementAttributeData& sourceData, ...@@ -322,7 +213,7 @@ void ElementAttributeData::cloneDataFrom(const ElementAttributeData& sourceData,
if (!oldName.isNull() || !newName.isNull()) if (!oldName.isNull() || !newName.isNull())
targetElement.updateName(oldName, newName); targetElement.updateName(oldName, newName);
clearAttributes(&targetElement); clearAttributes();
if (sourceData.isMutable()) if (sourceData.isMutable())
mutableAttributeVector() = sourceData.mutableAttributeVector(); mutableAttributeVector() = sourceData.mutableAttributeVector();
...@@ -347,33 +238,11 @@ void ElementAttributeData::cloneDataFrom(const ElementAttributeData& sourceData, ...@@ -347,33 +238,11 @@ void ElementAttributeData::cloneDataFrom(const ElementAttributeData& sourceData,
} }
} }
void ElementAttributeData::clearAttributes(Element* element) void ElementAttributeData::clearAttributes()
{ {
ASSERT(isMutable()); ASSERT(isMutable());
if (element->hasAttrList())
detachAttrObjectsFromElement(element);
clearClass(); clearClass();
mutableAttributeVector().clear(); mutableAttributeVector().clear();
} }
PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
{
ASSERT(element);
const Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
if (!attribute)
return 0;
return ensureAttr(element, attribute->name());
}
PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
{
ASSERT(element);
const Attribute* attribute = getAttributeItem(name);
if (!attribute)
return 0;
return ensureAttr(element, attribute->name());
}
} }
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
namespace WebCore { namespace WebCore {
class Attr;
class Element; class Element;
class ImmutableElementAttributeData; class ImmutableElementAttributeData;
class MutableElementAttributeData; class MutableElementAttributeData;
...@@ -69,9 +68,6 @@ public: ...@@ -69,9 +68,6 @@ public:
size_t length() const; size_t length() const;
bool isEmpty() const { return !length(); } bool isEmpty() const { return !length(); }
PassRefPtr<Attr> getAttributeNode(const String&, bool shouldIgnoreAttributeCase, Element*) const;
PassRefPtr<Attr> getAttributeNode(const QualifiedName&, Element*) const;
// Internal interface. // Internal interface.
const Attribute* attributeItem(unsigned index) const; const Attribute* attributeItem(unsigned index) const;
const Attribute* getAttributeItem(const QualifiedName&) const; const Attribute* getAttributeItem(const QualifiedName&) const;
...@@ -89,12 +85,6 @@ public: ...@@ -89,12 +85,6 @@ public:
bool isEquivalent(const ElementAttributeData* other) const; bool isEquivalent(const ElementAttributeData* other) const;
void setAttr(Element*, const QualifiedName&, Attr*) const;
void removeAttr(Element*, const QualifiedName&) const;
PassRefPtr<Attr> attrIfExists(Element*, const QualifiedName&) const;
PassRefPtr<Attr> ensureAttr(Element*, const QualifiedName&) const;
void detachAttrObjectsFromElement(Element*) const;
void reportMemoryUsage(MemoryObjectInfo*) const; void reportMemoryUsage(MemoryObjectInfo*) const;
bool isMutable() const { return m_isMutable; } bool isMutable() const { return m_isMutable; }
...@@ -129,7 +119,7 @@ private: ...@@ -129,7 +119,7 @@ private:
const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const; const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const; size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
void cloneDataFrom(const ElementAttributeData& sourceData, const Element& sourceElement, Element& targetElement); void cloneDataFrom(const ElementAttributeData& sourceData, const Element& sourceElement, Element& targetElement);
void clearAttributes(Element*); void clearAttributes();
PassRefPtr<ElementAttributeData> makeMutableCopy() const; PassRefPtr<ElementAttributeData> makeMutableCopy() const;
......
...@@ -237,9 +237,11 @@ public: ...@@ -237,9 +237,11 @@ public:
bool isDocumentNode() const; bool isDocumentNode() const;
bool isShadowRoot() const { return getFlag(IsShadowRootFlag); } bool isShadowRoot() const { return getFlag(IsShadowRootFlag); }
bool inNamedFlow() const { return getFlag(InNamedFlowFlag); } bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
bool hasAttrList() const { return getFlag(HasAttrListFlag); }
bool hasCustomCallbacks() const { return getFlag(HasCustomCallbacksFlag); } bool hasCustomCallbacks() const { return getFlag(HasCustomCallbacksFlag); }
bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
// If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0. // If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0.
Element* shadowHost() const; Element* shadowHost() const;
// If this node is in a shadow tree, returns its shadow host. Otherwise, returns this. // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this.
...@@ -355,9 +357,6 @@ public: ...@@ -355,9 +357,6 @@ public:
void setInNamedFlow() { setFlag(InNamedFlowFlag); } void setInNamedFlow() { setFlag(InNamedFlowFlag); }
void clearInNamedFlow() { clearFlag(InNamedFlowFlag); } void clearInNamedFlow() { clearFlag(InNamedFlowFlag); }
void setHasAttrList() { setFlag(HasAttrListFlag); }
void clearHasAttrList() { clearFlag(HasAttrListFlag); }
bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); } bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); }
void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); } void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); }
...@@ -733,7 +732,7 @@ private: ...@@ -733,7 +732,7 @@ private:
DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag, DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag,
#endif #endif
InNamedFlowFlag = 1 << 26, InNamedFlowFlag = 1 << 26,
HasAttrListFlag = 1 << 27, HasSyntheticAttrChildNodesFlag = 1 << 27,
HasCustomCallbacksFlag = 1 << 28, HasCustomCallbacksFlag = 1 << 28,
HasScopedHTMLStyleChildFlag = 1 << 29, HasScopedHTMLStyleChildFlag = 1 << 29,
HasEventTargetDataFlag = 1 << 30, HasEventTargetDataFlag = 1 << 30,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment