Title: [164856] trunk/Source/WebCore
Revision
164856
Author
[email protected]
Date
2014-02-27 23:50:20 -0800 (Thu, 27 Feb 2014)

Log Message

Element::attributeChanged shouldn't do any work when attribute value didn't change
https://bugs.webkit.org/show_bug.cgi?id=129467

Reviewed by Geoffrey Garen.

Exit early in childrenChanged when the attribute value didn't change.

* dom/Attr.cpp:
(WebCore::Attr::setValue):
(WebCore::Attr::childrenChanged):
* dom/Element.cpp:
(WebCore::Element::setAttributeInternal):
(WebCore::Element::attributeChanged):
(WebCore::Element::parserSetAttributes):
(WebCore::Element::removeAttributeInternal):
(WebCore::Element::didAddAttribute):
(WebCore::Element::didModifyAttribute):
(WebCore::Element::didRemoveAttribute):
(WebCore::Element::cloneAttributesFromElement):
* dom/Element.h:
* dom/StyledElement.cpp:
(WebCore::StyledElement::attributeChanged):
* dom/StyledElement.h:
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::updateType):
* mathml/MathMLElement.cpp:
(WebCore::MathMLElement::attributeChanged):
* mathml/MathMLElement.h:
* mathml/MathMLSelectElement.cpp:
(WebCore::MathMLSelectElement::attributeChanged):
* mathml/MathMLSelectElement.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::attributeChanged):
* svg/SVGElement.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (164855 => 164856)


--- trunk/Source/WebCore/ChangeLog	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/ChangeLog	2014-02-28 07:50:20 UTC (rev 164856)
@@ -1,3 +1,40 @@
+2014-02-27  Ryosuke Niwa  <[email protected]>
+
+        Element::attributeChanged shouldn't do any work when attribute value didn't change
+        https://bugs.webkit.org/show_bug.cgi?id=129467
+
+        Reviewed by Geoffrey Garen.
+
+        Exit early in childrenChanged when the attribute value didn't change.
+
+        * dom/Attr.cpp:
+        (WebCore::Attr::setValue):
+        (WebCore::Attr::childrenChanged):
+        * dom/Element.cpp:
+        (WebCore::Element::setAttributeInternal):
+        (WebCore::Element::attributeChanged):
+        (WebCore::Element::parserSetAttributes):
+        (WebCore::Element::removeAttributeInternal):
+        (WebCore::Element::didAddAttribute):
+        (WebCore::Element::didModifyAttribute):
+        (WebCore::Element::didRemoveAttribute):
+        (WebCore::Element::cloneAttributesFromElement):
+        * dom/Element.h:
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::attributeChanged):
+        * dom/StyledElement.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::updateType):
+        * mathml/MathMLElement.cpp:
+        (WebCore::MathMLElement::attributeChanged):
+        * mathml/MathMLElement.h:
+        * mathml/MathMLSelectElement.cpp:
+        (WebCore::MathMLSelectElement::attributeChanged):
+        * mathml/MathMLSelectElement.h:
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::attributeChanged):
+        * svg/SVGElement.h:
+
 2014-02-27  Jinwoo Song  <[email protected]>
 
         [EFL] Remove duplicated keyboard string key from keyMap

Modified: trunk/Source/WebCore/dom/Attr.cpp (164855 => 164856)


--- trunk/Source/WebCore/dom/Attr.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/dom/Attr.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -122,13 +122,14 @@
 
 void Attr::setValue(const AtomicString& value, ExceptionCode&)
 {
+    AtomicString oldValue = this->value();
     if (m_element)
-        m_element->willModifyAttribute(qualifiedName(), this->value(), value);
+        m_element->willModifyAttribute(qualifiedName(), oldValue, value);
 
     setValue(value);
 
     if (m_element)
-        m_element->didModifyAttribute(qualifiedName(), value);
+        m_element->didModifyAttribute(qualifiedName(), oldValue, value);
 }
 
 void Attr::setNodeValue(const String& v, ExceptionCode& ec)
@@ -165,9 +166,10 @@
     StringBuilder valueBuilder;
     TextNodeTraversal::appendContents(this, valueBuilder);
 
+    AtomicString oldValue = value();
     AtomicString newValue = valueBuilder.toAtomicString();
     if (m_element)
-        m_element->willModifyAttribute(qualifiedName(), value(), newValue);
+        m_element->willModifyAttribute(qualifiedName(), oldValue, newValue);
 
     if (m_element)
         elementAttribute().setValue(newValue);
@@ -175,7 +177,7 @@
         m_standaloneValue = newValue;
 
     if (m_element)
-        m_element->attributeChanged(qualifiedName(), newValue);
+        m_element->attributeChanged(qualifiedName(), oldValue, newValue);
 }
 
 bool Attr::isId() const

Modified: trunk/Source/WebCore/dom/Element.cpp (164855 => 164856)


--- trunk/Source/WebCore/dom/Element.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/dom/Element.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -1025,11 +1025,13 @@
         return;
     }
 
-    bool valueChanged = newValue != attributeAt(index).value();
-    QualifiedName attributeName = (!inSynchronizationOfLazyAttribute || valueChanged) ? attributeAt(index).name() : name;
+    const Attribute& attribute = attributeAt(index);
+    AtomicString oldValue = attribute.value();
+    bool valueChanged = newValue != oldValue;
+    const QualifiedName& attributeName = (!inSynchronizationOfLazyAttribute || valueChanged) ? attribute.name() : name;
 
     if (!inSynchronizationOfLazyAttribute)
-        willModifyAttribute(attributeName, attributeAt(index).value(), newValue);
+        willModifyAttribute(attributeName, oldValue, newValue);
 
     if (valueChanged) {
         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
@@ -1042,7 +1044,7 @@
     }
 
     if (!inSynchronizationOfLazyAttribute)
-        didModifyAttribute(attributeName, newValue);
+        didModifyAttribute(attributeName, oldValue, newValue);
 }
 
 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
@@ -1062,12 +1064,15 @@
     return false;
 }
 
-void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason)
+void Element::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason)
 {
     parseAttribute(name, newValue);
 
     document().incDOMTreeVersion();
 
+    if (oldValue == newValue)
+        return;
+
     StyleResolver* styleResolver = document().styleResolverIfExists();
     bool testShouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
     bool shouldInvalidateStyle = false;
@@ -1244,7 +1249,7 @@
 
     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
     for (unsigned i = 0; i < attributeVector.size(); ++i)
-        attributeChanged(attributeVector[i].name(), attributeVector[i].value(), ModifiedDirectly);
+        attributeChanged(attributeVector[i].name(), nullAtom, attributeVector[i].value(), ModifiedDirectly);
 }
 
 bool Element::hasAttributes() const
@@ -1803,7 +1808,7 @@
     elementData.removeAttribute(index);
 
     if (!inSynchronizationOfLazyAttribute)
-        didRemoveAttribute(name);
+        didRemoveAttribute(name, valueBeingRemoved);
 }
 
 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
@@ -2764,21 +2769,21 @@
 
 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    attributeChanged(name, value);
+    attributeChanged(name, nullAtom, value);
     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
     dispatchSubtreeModifiedEvent();
 }
 
-void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
+void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
 {
-    attributeChanged(name, value);
-    InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
+    attributeChanged(name, oldValue, newValue);
+    InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), newValue);
     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
 }
 
-void Element::didRemoveAttribute(const QualifiedName& name)
+void Element::didRemoveAttribute(const QualifiedName& name, const AtomicString& oldValue)
 {
-    attributeChanged(name, nullAtom);
+    attributeChanged(name, oldValue, nullAtom);
     InspectorInstrumentation::didRemoveDOMAttr(&document(), this, name.localName());
     dispatchSubtreeModifiedEvent();
 }
@@ -2979,9 +2984,8 @@
     else
         m_elementData = other.m_elementData->makeUniqueCopy();
 
-    for (const Attribute& attribute : attributesIterator()) {
-        attributeChanged(attribute.name(), attribute.value(), ModifiedByCloning);
-    }
+    for (const Attribute& attribute : attributesIterator())
+        attributeChanged(attribute.name(), nullAtom, attribute.value(), ModifiedByCloning);
 }
 
 void Element::cloneDataFromElement(const Element& other)

Modified: trunk/Source/WebCore/dom/Element.h (164855 => 164856)


--- trunk/Source/WebCore/dom/Element.h	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/dom/Element.h	2014-02-28 07:50:20 UTC (rev 164856)
@@ -290,7 +290,7 @@
     };
 
     // This method is called whenever an attribute is added, changed or removed.
-    virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly);
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
 
     // Only called by the parser immediately after element construction.
@@ -612,8 +612,8 @@
 
     void didAddAttribute(const QualifiedName&, const AtomicString&);
     void willModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
-    void didModifyAttribute(const QualifiedName&, const AtomicString&);
-    void didRemoveAttribute(const QualifiedName&);
+    void didModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
+    void didRemoveAttribute(const QualifiedName&, const AtomicString& oldValue);
 
     void synchronizeAttribute(const QualifiedName&) const;
     void synchronizeAttribute(const AtomicString& localName) const;

Modified: trunk/Source/WebCore/dom/StyledElement.cpp (164855 => 164856)


--- trunk/Source/WebCore/dom/StyledElement.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/dom/StyledElement.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -149,7 +149,7 @@
     return static_cast<MutableStyleProperties&>(*inlineStyle);
 }
 
-void StyledElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
+void StyledElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
 {
     if (name == styleAttr)
         styleAttributeChanged(newValue, reason);
@@ -158,7 +158,7 @@
         setNeedsStyleRecalc(InlineStyleChange);
     }
 
-    Element::attributeChanged(name, newValue, reason);
+    Element::attributeChanged(name, oldValue, newValue, reason);
 }
 
 PropertySetCSSStyleDeclaration* StyledElement::inlineStyleCSSOMWrapper()

Modified: trunk/Source/WebCore/dom/StyledElement.h (164855 => 164856)


--- trunk/Source/WebCore/dom/StyledElement.h	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/dom/StyledElement.h	2014-02-28 07:50:20 UTC (rev 164856)
@@ -69,7 +69,7 @@
     {
     }
 
-    virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) override;
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override;
 
     virtual bool isPresentationAttribute(const QualifiedName&) const { return false; }
 

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (164855 => 164856)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -513,12 +513,13 @@
 
     if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
         ASSERT(elementData());
+        // FIXME: We don't have the old attribute values so we pretend that we didn't have the old values.
         if (const Attribute* height = findAttributeByName(heightAttr))
-            attributeChanged(heightAttr, height->value());
+            attributeChanged(heightAttr, nullAtom, height->value());
         if (const Attribute* width = findAttributeByName(widthAttr))
-            attributeChanged(widthAttr, width->value());
+            attributeChanged(widthAttr, nullAtom, width->value());
         if (const Attribute* align = findAttributeByName(alignAttr))
-            attributeChanged(alignAttr, align->value());
+            attributeChanged(alignAttr, nullAtom, align->value());
     }
 
     if (renderer())

Modified: trunk/Source/WebCore/mathml/MathMLElement.cpp (164855 => 164856)


--- trunk/Source/WebCore/mathml/MathMLElement.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/mathml/MathMLElement.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -132,14 +132,14 @@
     return child.isTextNode() || child.isMathMLElement();
 }
 
-void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
+void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
 {
     if (isSemanticAnnotation() && (name == MathMLNames::srcAttr || name == MathMLNames::encodingAttr)) {
         Element* parent = parentElement();
         if (parent && parent->isMathMLElement() && parent->hasTagName(semanticsTag))
             toMathMLElement(parent)->updateSelectedChild();
     }
-    StyledElement::attributeChanged(name, newValue, reason);
+    StyledElement::attributeChanged(name, oldValue, newValue, reason);
 }
 
 }

Modified: trunk/Source/WebCore/mathml/MathMLElement.h (164855 => 164856)


--- trunk/Source/WebCore/mathml/MathMLElement.h	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/mathml/MathMLElement.h	2014-02-28 07:50:20 UTC (rev 164856)
@@ -59,7 +59,7 @@
 
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
     virtual bool childShouldCreateRenderer(const Node&) const override;
-    virtual void attributeChanged(const QualifiedName&, const AtomicString& newValue, AttributeModificationReason) override;
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason) override;
 
     virtual bool isPresentationAttribute(const QualifiedName&) const override;
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;

Modified: trunk/Source/WebCore/mathml/MathMLSelectElement.cpp (164855 => 164856)


--- trunk/Source/WebCore/mathml/MathMLSelectElement.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/mathml/MathMLSelectElement.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -69,12 +69,12 @@
     MathMLInlineContainerElement::childrenChanged(change);
 }
 
-void MathMLSelectElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
+void MathMLSelectElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
 {
     if (hasLocalName(mactionTag) && (name == MathMLNames::actiontypeAttr || name == MathMLNames::selectionAttr))
         updateSelectedChild();
 
-    MathMLInlineContainerElement::attributeChanged(name, newValue, reason);
+    MathMLInlineContainerElement::attributeChanged(name, oldValue, newValue, reason);
 }
 
 int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild)

Modified: trunk/Source/WebCore/mathml/MathMLSelectElement.h (164855 => 164856)


--- trunk/Source/WebCore/mathml/MathMLSelectElement.h	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/mathml/MathMLSelectElement.h	2014-02-28 07:50:20 UTC (rev 164856)
@@ -43,7 +43,7 @@
 
     virtual void finishParsingChildren() override;
     virtual void childrenChanged(const ChildChange&) override;
-    virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) override;
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override;
     virtual void defaultEventHandler(Event*) override;
     virtual bool willRespondToMouseClickEvents() override;
 

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (164855 => 164856)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2014-02-28 07:50:20 UTC (rev 164856)
@@ -716,9 +716,9 @@
     return false;
 }
 
-void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason)
+void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason)
 {
-    StyledElement::attributeChanged(name, newValue);
+    StyledElement::attributeChanged(name, oldValue, newValue);
 
     if (isIdAttributeName(name))
         document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);

Modified: trunk/Source/WebCore/svg/SVGElement.h (164855 => 164856)


--- trunk/Source/WebCore/svg/SVGElement.h	2014-02-28 06:32:18 UTC (rev 164855)
+++ trunk/Source/WebCore/svg/SVGElement.h	2014-02-28 07:50:20 UTC (rev 164856)
@@ -148,7 +148,7 @@
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
 
     virtual void finishParsingChildren() override;
-    virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) override;
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override;
     virtual bool childShouldCreateRenderer(const Node&) const override;
 
     SVGElementRareData& ensureSVGRareData();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to