Commit e182edf8 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

FindKeyframesRules should use originating element.

It's only using the TreeScope to find @keyframes in which case using the
originating element for pseudo elements should work. Even better when
the originating element is a shadow host, so that we look up :host rules
from the shadow tree for :host::before { animation-name: anim }.

Bug: 961941
Change-Id: I38edec156eaaa7cfb3680762b135323deae00a68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2162988Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#762791}
parent fa8eabc4
...@@ -92,7 +92,7 @@ namespace { ...@@ -92,7 +92,7 @@ namespace {
// properties. // properties.
StringKeyframeVector ProcessKeyframesRule( StringKeyframeVector ProcessKeyframesRule(
const StyleRuleKeyframes* keyframes_rule, const StyleRuleKeyframes* keyframes_rule,
const Element* element_for_scoping, const Document& document,
const ComputedStyle* parent_style, const ComputedStyle* parent_style,
TimingFunction* default_timing_function) { TimingFunction* default_timing_function) {
StringKeyframeVector keyframes; StringKeyframeVector keyframes;
...@@ -139,8 +139,7 @@ StringKeyframeVector ProcessKeyframesRule( ...@@ -139,8 +139,7 @@ StringKeyframeVector ProcessKeyframesRule(
for (const CSSProperty* property : specified_properties_for_use_counter) { for (const CSSProperty* property : specified_properties_for_use_counter) {
DCHECK(isValidCSSPropertyID(property->PropertyID())); DCHECK(isValidCSSPropertyID(property->PropertyID()));
element_for_scoping->GetDocument().CountAnimatedProperty( document.CountAnimatedProperty(property->PropertyID());
property->PropertyID());
} }
std::stable_sort(keyframes.begin(), keyframes.end(), std::stable_sort(keyframes.begin(), keyframes.end(),
...@@ -198,11 +197,8 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( ...@@ -198,11 +197,8 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// abort this procedure. In this case no animation is generated, and any // abort this procedure. In this case no animation is generated, and any
// existing animation matching name is canceled. // existing animation matching name is canceled.
// When the animating element is null, use its parent for scoping purposes.
const Element* element_for_scoping =
animating_element ? animating_element : &element;
const StyleRuleKeyframes* keyframes_rule = const StyleRuleKeyframes* keyframes_rule =
resolver->FindKeyframesRule(element_for_scoping, name); resolver->FindKeyframesRule(&element, name);
DCHECK(keyframes_rule); DCHECK(keyframes_rule);
// 3. Let keyframes be an empty sequence of keyframe objects. // 3. Let keyframes be an empty sequence of keyframe objects.
...@@ -220,7 +216,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( ...@@ -220,7 +216,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// the offset specified in the keyframe selector, and iterate over the // the offset specified in the keyframe selector, and iterate over the
// result in reverse applying the following steps: // result in reverse applying the following steps:
StringKeyframeVector sorted_keyframes = StringKeyframeVector sorted_keyframes =
ProcessKeyframesRule(keyframes_rule, element_for_scoping, parent_style, ProcessKeyframesRule(keyframes_rule, element.GetDocument(), parent_style,
default_timing_function); default_timing_function);
for (wtf_size_t i = sorted_keyframes.size(); i > 0; --i) { for (wtf_size_t i = sorted_keyframes.size(); i > 0; --i) {
...@@ -350,7 +346,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( ...@@ -350,7 +346,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
auto* model = MakeGarbageCollected<StringKeyframeEffectModel>( auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(
keyframes, EffectModel::kCompositeReplace, &start_keyframe->Easing()); keyframes, EffectModel::kCompositeReplace, &start_keyframe->Easing());
if (animation_index > 0 && model->HasSyntheticKeyframes()) { if (animation_index > 0 && model->HasSyntheticKeyframes()) {
UseCounter::Count(element_for_scoping->GetDocument(), UseCounter::Count(element.GetDocument(),
WebFeature::kCSSAnimationsStackedNeutralKeyframe); WebFeature::kCSSAnimationsStackedNeutralKeyframe);
} }
return model; return model;
...@@ -520,8 +516,6 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, ...@@ -520,8 +516,6 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
const CSSAnimationData* animation_data = style.Animations(); const CSSAnimationData* animation_data = style.Animations();
const CSSAnimations* css_animations = const CSSAnimations* css_animations =
element_animations ? &element_animations->CssAnimations() : nullptr; element_animations ? &element_animations->CssAnimations() : nullptr;
const Element* element_for_scoping =
animating_element ? animating_element : &element;
Vector<bool> cancel_running_animation_flags( Vector<bool> cancel_running_animation_flags(
css_animations ? css_animations->running_animations_.size() : 0); css_animations ? css_animations->running_animations_.size() : 0);
...@@ -553,7 +547,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, ...@@ -553,7 +547,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
timing.timing_function = Timing().timing_function; timing.timing_function = Timing().timing_function;
StyleRuleKeyframes* keyframes_rule = StyleRuleKeyframes* keyframes_rule =
resolver->FindKeyframesRule(element_for_scoping, name); resolver->FindKeyframesRule(&element, name);
if (!keyframes_rule) if (!keyframes_rule)
continue; // Cancel the animation if there's no style rule for it. continue; // Cancel the animation if there's no style rule for it.
......
<!doctype html>
<title>CSS Test: @keyframes applies to :host::before/::after.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
<div id="host"></div>
<script>
test(function() {
host.attachShadow({ mode: "open" }).innerHTML = `
<style>
@keyframes myanim {
from { background: red; }
to { background: green; }
}
:host::before, :host::after {
content: "";
display: block;
width: 100px;
height: 100px;
background: blue;
animation: myanim 10s infinite step-end;
}
</style>
`;
assert_equals(getComputedStyle(document.getElementById('host'), "::before").backgroundColor, "rgb(255, 0, 0)");
assert_equals(getComputedStyle(document.getElementById('host'), "::after").backgroundColor, "rgb(255, 0, 0)");
}, "@keyframes applies to the shadow host");
</script>
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