Commit ff29b230 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Make baseVal attribute synchronization explicit

This moves the |base_value_updated_| flag from the "primitive type"
version of SVGAnimatedProperty to SVGAnimatedPropertyBase, and sets it
in BaseValueChanged. The flag is cleared in SynchronizeAttribute.
This allows some code to be simplified. It also avoids synchronizations
triggered by just having created the tear-off object like in the bug.

Bug: 873470
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I59f30dd69286dc0799a583eb6a52c41022b0af91
Reviewed-on: https://chromium-review.googlesource.com/1188305
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585852}
parent ff1335d9
<!DOCTYPE html>
<title>Getting a property should not update the corresponding attribute</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<svg>
<rect width="100" height="50" fill="green" transform="scale(1)"/>
</svg>
<script>
test(function() {
var rect = document.querySelector('rect');
var clone = rect.cloneNode(true);
clone.systemLanguage;
clone.transform.baseVal.getItem(0).setTranslate(0, 50);
rect.parentNode.appendChild(clone);
assert_false(clone.hasAttribute('systemLanguage'));
});
</script>
...@@ -44,6 +44,7 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase( ...@@ -44,6 +44,7 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase(
// property enum. CSS properties that don't fit in this bitfield are never // property enum. CSS properties that don't fit in this bitfield are never
// used here. See static_assert in header. // used here. See static_assert in header.
css_property_id_(static_cast<unsigned>(css_property_id)), css_property_id_(static_cast<unsigned>(css_property_id)),
base_value_needs_synchronization_(false),
context_element_(context_element), context_element_(context_element),
attribute_name_(attribute_name) { attribute_name_(attribute_name) {
DCHECK(context_element_); DCHECK(context_element_);
...@@ -62,14 +63,24 @@ void SVGAnimatedPropertyBase::AnimationEnded() { ...@@ -62,14 +63,24 @@ void SVGAnimatedPropertyBase::AnimationEnded() {
SynchronizeAttribute(); SynchronizeAttribute();
} }
bool SVGAnimatedPropertyBase::NeedsSynchronizeAttribute() const {
// DOM attribute synchronization is only needed if a change has been made
// through JavaScript (via a tear-off or primitive) or the property is being
// animated. This prevents unnecessary attribute creation on the target
// element.
return base_value_needs_synchronization_ || IsAnimating();
}
void SVGAnimatedPropertyBase::SynchronizeAttribute() { void SVGAnimatedPropertyBase::SynchronizeAttribute() {
AtomicString value(CurrentValueBase()->ValueAsString()); AtomicString value(CurrentValueBase()->ValueAsString());
context_element_->SetSynchronizedLazyAttribute(attribute_name_, value); context_element_->SetSynchronizedLazyAttribute(attribute_name_, value);
base_value_needs_synchronization_ = false;
} }
void SVGAnimatedPropertyBase::BaseValueChanged() { void SVGAnimatedPropertyBase::BaseValueChanged() {
DCHECK(context_element_); DCHECK(context_element_);
DCHECK(attribute_name_ != QualifiedName::Null()); DCHECK(attribute_name_ != QualifiedName::Null());
base_value_needs_synchronization_ = true;
context_element_->InvalidateSVGAttributes(); context_element_->InvalidateSVGAttributes();
context_element_->SvgAttributeBaseValChanged(attribute_name_); context_element_->SvgAttributeBaseValChanged(attribute_name_);
} }
......
...@@ -58,7 +58,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin { ...@@ -58,7 +58,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
virtual void AnimationEnded(); virtual void AnimationEnded();
virtual SVGParsingError AttributeChanged(const String&) = 0; virtual SVGParsingError AttributeChanged(const String&) = 0;
virtual bool NeedsSynchronizeAttribute() = 0; virtual bool NeedsSynchronizeAttribute() const;
virtual void SynchronizeAttribute(); virtual void SynchronizeAttribute();
AnimatedPropertyType GetType() const { AnimatedPropertyType GetType() const {
...@@ -99,6 +99,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin { ...@@ -99,6 +99,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
const unsigned type_ : 5; const unsigned type_ : 5;
const unsigned css_property_id_ : kCssPropertyBits; const unsigned css_property_id_ : kCssPropertyBits;
unsigned base_value_needs_synchronization_ : 1;
TraceWrapperMember<SVGElement> context_element_; TraceWrapperMember<SVGElement> context_element_;
const QualifiedName& attribute_name_; const QualifiedName& attribute_name_;
DISALLOW_COPY_AND_ASSIGN(SVGAnimatedPropertyBase); DISALLOW_COPY_AND_ASSIGN(SVGAnimatedPropertyBase);
...@@ -172,18 +173,6 @@ template <typename Property, ...@@ -172,18 +173,6 @@ template <typename Property,
typename PrimitiveType = typename Property::PrimitiveType> typename PrimitiveType = typename Property::PrimitiveType>
class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> { class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
public: public:
bool NeedsSynchronizeAttribute() override {
// DOM attribute synchronization is only needed if tear-off is being touched
// from javascript or the property is being animated. This prevents
// unnecessary attribute creation on target element.
return base_value_updated_ || this->IsAnimating();
}
void SynchronizeAttribute() override {
SVGAnimatedPropertyBase::SynchronizeAttribute();
base_value_updated_ = false;
}
// SVGAnimated* DOM Spec implementations: // SVGAnimated* DOM Spec implementations:
// baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM // baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM
...@@ -192,7 +181,6 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> { ...@@ -192,7 +181,6 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
void setBaseVal(PrimitiveType value, ExceptionState&) { void setBaseVal(PrimitiveType value, ExceptionState&) {
this->BaseValue()->SetValue(value); this->BaseValue()->SetValue(value);
base_value_updated_ = true;
this->BaseValueChanged(); this->BaseValueChanged();
} }
...@@ -209,10 +197,7 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> { ...@@ -209,10 +197,7 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
: SVGAnimatedPropertyCommon<Property>(context_element, : SVGAnimatedPropertyCommon<Property>(context_element,
attribute_name, attribute_name,
initial_value, initial_value,
css_property_id), css_property_id) {}
base_value_updated_(false) {}
bool base_value_updated_;
}; };
// Implementation of SVGAnimatedProperty which uses tear-off value types. // Implementation of SVGAnimatedProperty which uses tear-off value types.
...@@ -242,13 +227,6 @@ class SVGAnimatedProperty<Property, TearOffType, void> ...@@ -242,13 +227,6 @@ class SVGAnimatedProperty<Property, TearOffType, void>
UpdateAnimValTearOffIfNeeded(); UpdateAnimValTearOffIfNeeded();
} }
bool NeedsSynchronizeAttribute() override {
// DOM attribute synchronization is only needed if tear-off is being touched
// from javascript or the property is being animated. This prevents
// unnecessary attribute creation on target element.
return base_val_tear_off_ || this->IsAnimating();
}
// SVGAnimated* DOM Spec implementations: // SVGAnimated* DOM Spec implementations:
// baseVal()/animVal() are only to be used from SVG DOM implementation. // baseVal()/animVal() are only to be used from SVG DOM implementation.
...@@ -316,12 +294,6 @@ class SVGAnimatedProperty<Property, void, void> ...@@ -316,12 +294,6 @@ class SVGAnimatedProperty<Property, void, void>
initial_value, css_property_id); initial_value, css_property_id);
} }
bool NeedsSynchronizeAttribute() override {
// DOM attribute synchronization is only needed if the property is being
// animated.
return this->IsAnimating();
}
protected: protected:
SVGAnimatedProperty(SVGElement* context_element, SVGAnimatedProperty(SVGElement* context_element,
const QualifiedName& attribute_name, const QualifiedName& attribute_name,
......
...@@ -51,7 +51,7 @@ void SVGAnimatedAngle::Trace(blink::Visitor* visitor) { ...@@ -51,7 +51,7 @@ void SVGAnimatedAngle::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor); ScriptWrappable::Trace(visitor);
} }
bool SVGAnimatedAngle::NeedsSynchronizeAttribute() { bool SVGAnimatedAngle::NeedsSynchronizeAttribute() const {
return orient_type_->NeedsSynchronizeAttribute() || return orient_type_->NeedsSynchronizeAttribute() ||
SVGAnimatedProperty<SVGAngle>::NeedsSynchronizeAttribute(); SVGAnimatedProperty<SVGAngle>::NeedsSynchronizeAttribute();
} }
......
...@@ -55,7 +55,7 @@ class SVGAnimatedAngle final : public ScriptWrappable, ...@@ -55,7 +55,7 @@ class SVGAnimatedAngle final : public ScriptWrappable,
} }
// SVGAnimatedPropertyBase: // SVGAnimatedPropertyBase:
bool NeedsSynchronizeAttribute() override; bool NeedsSynchronizeAttribute() const override;
void SynchronizeAttribute() override; void SynchronizeAttribute() override;
void SetAnimatedValue(SVGPropertyBase*) override; void SetAnimatedValue(SVGPropertyBase*) override;
......
...@@ -73,7 +73,7 @@ void SVGAnimatedIntegerOptionalInteger::AnimationEnded() { ...@@ -73,7 +73,7 @@ void SVGAnimatedIntegerOptionalInteger::AnimationEnded() {
second_integer_->AnimationEnded(); second_integer_->AnimationEnded();
} }
bool SVGAnimatedIntegerOptionalInteger::NeedsSynchronizeAttribute() { bool SVGAnimatedIntegerOptionalInteger::NeedsSynchronizeAttribute() const {
return first_integer_->NeedsSynchronizeAttribute() || return first_integer_->NeedsSynchronizeAttribute() ||
second_integer_->NeedsSynchronizeAttribute(); second_integer_->NeedsSynchronizeAttribute();
} }
......
...@@ -60,7 +60,7 @@ class SVGAnimatedIntegerOptionalInteger ...@@ -60,7 +60,7 @@ class SVGAnimatedIntegerOptionalInteger
} }
void SetAnimatedValue(SVGPropertyBase*) override; void SetAnimatedValue(SVGPropertyBase*) override;
bool NeedsSynchronizeAttribute() override; bool NeedsSynchronizeAttribute() const override;
void AnimationEnded() override; void AnimationEnded() override;
SVGAnimatedInteger* FirstInteger() { return first_integer_.Get(); } SVGAnimatedInteger* FirstInteger() { return first_integer_.Get(); }
......
...@@ -60,7 +60,7 @@ void SVGAnimatedNumberOptionalNumber::AnimationEnded() { ...@@ -60,7 +60,7 @@ void SVGAnimatedNumberOptionalNumber::AnimationEnded() {
second_number_->AnimationEnded(); second_number_->AnimationEnded();
} }
bool SVGAnimatedNumberOptionalNumber::NeedsSynchronizeAttribute() { bool SVGAnimatedNumberOptionalNumber::NeedsSynchronizeAttribute() const {
return first_number_->NeedsSynchronizeAttribute() || return first_number_->NeedsSynchronizeAttribute() ||
second_number_->NeedsSynchronizeAttribute(); second_number_->NeedsSynchronizeAttribute();
} }
......
...@@ -60,7 +60,7 @@ class SVGAnimatedNumberOptionalNumber ...@@ -60,7 +60,7 @@ class SVGAnimatedNumberOptionalNumber
} }
void SetAnimatedValue(SVGPropertyBase*) override; void SetAnimatedValue(SVGPropertyBase*) override;
bool NeedsSynchronizeAttribute() override; bool NeedsSynchronizeAttribute() const override;
void AnimationEnded() override; void AnimationEnded() override;
SVGAnimatedNumber* FirstNumber() { return first_number_.Get(); } SVGAnimatedNumber* FirstNumber() { return first_number_.Get(); }
......
...@@ -77,10 +77,6 @@ void SVGStaticStringList::AnimationEnded() { ...@@ -77,10 +77,6 @@ void SVGStaticStringList::AnimationEnded() {
NOTREACHED(); NOTREACHED();
} }
bool SVGStaticStringList::NeedsSynchronizeAttribute() {
return tear_off_;
}
SVGStringListTearOff* SVGStaticStringList::TearOff() { SVGStringListTearOff* SVGStaticStringList::TearOff() {
if (!tear_off_) { if (!tear_off_) {
tear_off_ = tear_off_ =
......
...@@ -62,7 +62,6 @@ class SVGStaticStringList final ...@@ -62,7 +62,6 @@ class SVGStaticStringList final
SVGPropertyBase* CreateAnimatedValue() override; SVGPropertyBase* CreateAnimatedValue() override;
void SetAnimatedValue(SVGPropertyBase*) override; void SetAnimatedValue(SVGPropertyBase*) override;
void AnimationEnded() override; void AnimationEnded() override;
bool NeedsSynchronizeAttribute() override;
SVGParsingError AttributeChanged(const String&) override; SVGParsingError AttributeChanged(const String&) override;
......
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