Commit b822dab2 authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

Implement KeyframeEffect::setTarget

This CL implements the writable part of KeyframeEffect's target member.
This brings us into line with the spec, except that Chromium still don't
support CSSPseudoElement and so we only allow setting Elements.

Bug: 813902
Test: external/wpt/web-animations/interfaces/KeyframeEffect/target.html
Test: external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js

Change-Id: I91faf22473e7776a8cad6165ff60c5d9ee47a9a6
Reviewed-on: https://chromium-review.googlesource.com/1157002
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579840}
parent 73294c6c
This is a testharness.js-based test.
PASS Effect values reflect changes to font-size on element
PASS Effect values reflect changes to font-size on parent element
PASS Effect values reflect changes to font-size when computed style is not immediately flushed
PASS Effect values reflect changes to font-size from reparenting
FAIL Effect values reflect changes to target element Cannot assign to read only property 'target' of object '#<KeyframeEffect>'
Harness: the test ran to completion.
...@@ -6,7 +6,7 @@ PASS KeyframeEffect interface object name ...@@ -6,7 +6,7 @@ PASS KeyframeEffect interface object name
PASS KeyframeEffect interface: existence and properties of interface prototype object PASS KeyframeEffect interface: existence and properties of interface prototype object
PASS KeyframeEffect interface: existence and properties of interface prototype object's "constructor" property PASS KeyframeEffect interface: existence and properties of interface prototype object's "constructor" property
PASS KeyframeEffect interface: existence and properties of interface prototype object's @@unscopables property PASS KeyframeEffect interface: existence and properties of interface prototype object's @@unscopables property
FAIL KeyframeEffect interface: attribute target assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" PASS KeyframeEffect interface: attribute target
PASS Unscopable handled correctly for target property on KeyframeEffect PASS Unscopable handled correctly for target property on KeyframeEffect
FAIL KeyframeEffect interface: attribute iterationComposite assert_true: The prototype object must have a property "iterationComposite" expected true got false FAIL KeyframeEffect interface: attribute iterationComposite assert_true: The prototype object must have a property "iterationComposite" expected true got false
PASS Unscopable handled correctly for iterationComposite property on KeyframeEffect PASS Unscopable handled correctly for iterationComposite property on KeyframeEffect
......
This is a testharness.js-based test.
FAIL Test setting target before constructing the associated animation Cannot assign to read only property 'target' of object '#<KeyframeEffect>'
FAIL Test setting target from null to a valid target Cannot assign to read only property 'target' of object '#<KeyframeEffect>'
FAIL Test setting target from a valid target to null Cannot assign to read only property 'target' of object '#<KeyframeEffect>'
FAIL Test setting target from a valid target to another target Cannot assign to read only property 'target' of object '#<KeyframeEffect>'
Harness: the test ran to completion.
...@@ -4116,6 +4116,7 @@ interface KeyframeEffect : AnimationEffect ...@@ -4116,6 +4116,7 @@ interface KeyframeEffect : AnimationEffect
method getKeyframes method getKeyframes
method setKeyframes method setKeyframes
setter composite setter composite
setter target
interface LinearAccelerationSensor : Accelerometer interface LinearAccelerationSensor : Accelerometer
attribute @@toStringTag attribute @@toStringTag
method constructor method constructor
......
...@@ -128,6 +128,17 @@ KeyframeEffect::KeyframeEffect(Element* target, ...@@ -128,6 +128,17 @@ KeyframeEffect::KeyframeEffect(Element* target,
KeyframeEffect::~KeyframeEffect() = default; KeyframeEffect::~KeyframeEffect() = default;
void KeyframeEffect::setTarget(Element* target) {
if (target_ == target)
return;
DetachTarget(GetAnimation());
target_ = target;
AttachTarget(GetAnimation());
InvalidateAndNotifyOwner();
}
String KeyframeEffect::composite() const { String KeyframeEffect::composite() const {
return EffectModel::CompositeOperationToString(CompositeInternal()); return EffectModel::CompositeOperationToString(CompositeInternal());
} }
...@@ -191,7 +202,6 @@ void KeyframeEffect::SetKeyframes(StringKeyframeVector keyframes) { ...@@ -191,7 +202,6 @@ void KeyframeEffect::SetKeyframes(StringKeyframeVector keyframes) {
// Changing the keyframes will invalidate any sampled effect, as well as // Changing the keyframes will invalidate any sampled effect, as well as
// potentially affect the effect owner. // potentially affect the effect owner.
if (sampled_effect_)
ClearEffects(); ClearEffects();
InvalidateAndNotifyOwner(); InvalidateAndNotifyOwner();
} }
...@@ -369,8 +379,8 @@ void KeyframeEffect::ApplyEffects() { ...@@ -369,8 +379,8 @@ void KeyframeEffect::ApplyEffects() {
} }
void KeyframeEffect::ClearEffects() { void KeyframeEffect::ClearEffects() {
DCHECK(sampled_effect_); if (!sampled_effect_)
return;
sampled_effect_->Clear(); sampled_effect_->Clear();
sampled_effect_ = nullptr; sampled_effect_ = nullptr;
if (GetAnimation()) if (GetAnimation())
...@@ -388,28 +398,38 @@ void KeyframeEffect::UpdateChildrenAndEffects() const { ...@@ -388,28 +398,38 @@ void KeyframeEffect::UpdateChildrenAndEffects() const {
DCHECK(owner_); DCHECK(owner_);
if (IsInEffect() && !owner_->EffectSuppressed()) if (IsInEffect() && !owner_->EffectSuppressed())
const_cast<KeyframeEffect*>(this)->ApplyEffects(); const_cast<KeyframeEffect*>(this)->ApplyEffects();
else if (sampled_effect_) else
const_cast<KeyframeEffect*>(this)->ClearEffects(); const_cast<KeyframeEffect*>(this)->ClearEffects();
} }
void KeyframeEffect::Attach(AnimationEffectOwner* owner) { void KeyframeEffect::Attach(AnimationEffectOwner* owner) {
if (target_ && owner->GetAnimation()) { AttachTarget(owner->GetAnimation());
target_->EnsureElementAnimations().Animations().insert( AnimationEffect::Attach(owner);
owner->GetAnimation()); }
void KeyframeEffect::Detach() {
DetachTarget(GetAnimation());
AnimationEffect::Detach();
}
void KeyframeEffect::AttachTarget(Animation* animation) {
if (!target_ || !animation)
return;
target_->EnsureElementAnimations().Animations().insert(animation);
target_->SetNeedsAnimationStyleRecalc(); target_->SetNeedsAnimationStyleRecalc();
if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() &&
target_->IsSVGElement()) target_->IsSVGElement())
ToSVGElement(target_)->SetWebAnimationsPending(); ToSVGElement(target_)->SetWebAnimationsPending();
}
AnimationEffect::Attach(owner);
} }
void KeyframeEffect::Detach() { void KeyframeEffect::DetachTarget(Animation* animation) {
if (target_ && GetAnimation()) if (target_ && animation)
target_->GetElementAnimations()->Animations().erase(GetAnimation()); target_->GetElementAnimations()->Animations().erase(animation);
if (sampled_effect_) // If we have sampled this effect previously, we need to purge that state.
// ClearEffects takes care of clearing the cached sampled effect, informing
// the target that it needs to refresh its style, and doing any necessary
// update on the compositor.
ClearEffects(); ClearEffects();
AnimationEffect::Detach();
} }
double KeyframeEffect::CalculateTimeToEffectChange( double KeyframeEffect::CalculateTimeToEffectChange(
......
...@@ -77,6 +77,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { ...@@ -77,6 +77,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
// IDL implementation. // IDL implementation.
Element* target() const { return target_; } Element* target() const { return target_; }
void setTarget(Element*);
String composite() const; String composite() const;
void setComposite(String); void setComposite(String);
Vector<ScriptValue> getKeyframes(ScriptState*); Vector<ScriptValue> getKeyframes(ScriptState*);
...@@ -139,6 +140,8 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { ...@@ -139,6 +140,8 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
void UpdateChildrenAndEffects() const override; void UpdateChildrenAndEffects() const override;
void Attach(AnimationEffectOwner*) override; void Attach(AnimationEffectOwner*) override;
void Detach() override; void Detach() override;
void AttachTarget(Animation*);
void DetachTarget(Animation*);
double CalculateTimeToEffectChange( double CalculateTimeToEffectChange(
bool forwards, bool forwards,
double inherited_time, double inherited_time,
......
...@@ -39,7 +39,7 @@ enum CompositeOperation { "replace", "add", "accumulate" }; ...@@ -39,7 +39,7 @@ enum CompositeOperation { "replace", "add", "accumulate" };
RaisesException=Constructor, RaisesException=Constructor,
RuntimeEnabled=WebAnimationsAPI RuntimeEnabled=WebAnimationsAPI
] interface KeyframeEffect : AnimationEffect { ] interface KeyframeEffect : AnimationEffect {
readonly attribute Element? target; attribute Element? target;
attribute CompositeOperation composite; attribute CompositeOperation composite;
[CallWith=ScriptState] sequence<object> getKeyframes(); [CallWith=ScriptState] sequence<object> getKeyframes();
[CallWith=ScriptState, RaisesException] void setKeyframes(object? keyframes); [CallWith=ScriptState, RaisesException] void setKeyframes(object? keyframes);
......
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