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();