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 {
// properties.
StringKeyframeVector ProcessKeyframesRule(
const StyleRuleKeyframes* keyframes_rule,
const Element* element_for_scoping,
const Document& document,
const ComputedStyle* parent_style,
TimingFunction* default_timing_function) {
StringKeyframeVector keyframes;
......@@ -139,8 +139,7 @@ StringKeyframeVector ProcessKeyframesRule(
for (const CSSProperty* property : specified_properties_for_use_counter) {
DCHECK(isValidCSSPropertyID(property->PropertyID()));
element_for_scoping->GetDocument().CountAnimatedProperty(
property->PropertyID());
document.CountAnimatedProperty(property->PropertyID());
}
std::stable_sort(keyframes.begin(), keyframes.end(),
......@@ -198,11 +197,8 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// abort this procedure. In this case no animation is generated, and any
// 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 =
resolver->FindKeyframesRule(element_for_scoping, name);
resolver->FindKeyframesRule(&element, name);
DCHECK(keyframes_rule);
// 3. Let keyframes be an empty sequence of keyframe objects.
......@@ -220,7 +216,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// the offset specified in the keyframe selector, and iterate over the
// result in reverse applying the following steps:
StringKeyframeVector sorted_keyframes =
ProcessKeyframesRule(keyframes_rule, element_for_scoping, parent_style,
ProcessKeyframesRule(keyframes_rule, element.GetDocument(), parent_style,
default_timing_function);
for (wtf_size_t i = sorted_keyframes.size(); i > 0; --i) {
......@@ -350,7 +346,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(
keyframes, EffectModel::kCompositeReplace, &start_keyframe->Easing());
if (animation_index > 0 && model->HasSyntheticKeyframes()) {
UseCounter::Count(element_for_scoping->GetDocument(),
UseCounter::Count(element.GetDocument(),
WebFeature::kCSSAnimationsStackedNeutralKeyframe);
}
return model;
......@@ -520,8 +516,6 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
const CSSAnimationData* animation_data = style.Animations();
const CSSAnimations* css_animations =
element_animations ? &element_animations->CssAnimations() : nullptr;
const Element* element_for_scoping =
animating_element ? animating_element : &element;
Vector<bool> cancel_running_animation_flags(
css_animations ? css_animations->running_animations_.size() : 0);
......@@ -553,7 +547,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
timing.timing_function = Timing().timing_function;
StyleRuleKeyframes* keyframes_rule =
resolver->FindKeyframesRule(element_for_scoping, name);
resolver->FindKeyframesRule(&element, name);
if (!keyframes_rule)
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