Skip to content
Permalink
Browse files
[web-animations] support custom properties in Animation.commitStyles()
https://bugs.webkit.org/show_bug.cgi?id=242007

Reviewed by Dean Jackson.

We add a new KeyframeEffect::animatedCustomProperties() method to access the list of custom properties
affected by this effect. Then, in WebAnimation::commitStyles(), we account for those properties to commit
them onto the target element's inline style.

This yields an additional WPT PASS result in web-animations/interfaces/Animation/commitStyles.html.

* LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/commitStyles-expected.txt:
* Source/WebCore/animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::animatedCustomProperties):
* Source/WebCore/animation/KeyframeEffect.h:
* Source/WebCore/animation/WebAnimation.cpp:
(WebCore::WebAnimation::commitStyles):

Canonical link: https://commits.webkit.org/251858@main
  • Loading branch information
graouts committed Jun 26, 2022
1 parent d869a0c commit 8161c9767ffb3605893aed55edd55e82b2deb387
Showing 4 changed files with 50 additions and 11 deletions.
@@ -6,7 +6,7 @@ PASS Commits logical properties
PASS Commits logical properties as physical properties
PASS Commits values calculated mid-interval
PASS Commits variable references as their computed values
FAIL Commits custom variables assert_approx_equals: expected 0.8 +/- 0.0001 but got 0.5
PASS Commits custom variables
FAIL Commits em units as pixel values assert_approx_equals: expected 100 +/- 0.0001 but got 0
FAIL Commits relative line-height assert_equals: line-height is committed as a relative value expected "1.5" but got "15px"
PASS Commits transforms
@@ -904,6 +904,21 @@ const HashSet<CSSPropertyID>& KeyframeEffect::animatedProperties()
return m_animatedProperties;
}

const HashSet<AtomString>& KeyframeEffect::animatedCustomProperties()
{
if (!m_blendingKeyframes.isEmpty())
return m_blendingKeyframes.customProperties();

if (m_animatedCustomProperties.isEmpty()) {
for (auto& keyframe : m_parsedKeyframes) {
for (auto keyframeCustomProperty : keyframe.customStyleStrings.keys())
m_animatedCustomProperties.add(keyframeCustomProperty);
}
}

return m_animatedCustomProperties;
}

bool KeyframeEffect::animatesProperty(CSSPropertyID property) const
{
if (!m_blendingKeyframes.isEmpty())
@@ -949,6 +964,7 @@ void KeyframeEffect::setBlendingKeyframes(KeyframeList& blendingKeyframes)

m_blendingKeyframes = WTFMove(blendingKeyframes);
m_animatedProperties.clear();
m_animatedCustomProperties.clear();

computedNeedsForcedLayout();
computeStackingContextImpact();
@@ -160,6 +160,7 @@ class KeyframeEffect : public AnimationEffect
void computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle, const Style::ResolutionContext&);
const KeyframeList& blendingKeyframes() const { return m_blendingKeyframes; }
const HashSet<CSSPropertyID>& animatedProperties();
const HashSet<AtomString>& animatedCustomProperties();
const HashSet<CSSPropertyID>& inheritedProperties() const { return m_inheritedProperties; }
bool animatesProperty(CSSPropertyID) const;

@@ -254,6 +255,7 @@ class KeyframeEffect : public AnimationEffect
AtomString m_keyframesName;
KeyframeList m_blendingKeyframes { emptyAtom() };
HashSet<CSSPropertyID> m_animatedProperties;
HashSet<AtomString> m_animatedCustomProperties;
HashSet<CSSPropertyID> m_inheritedProperties;
Vector<ParsedKeyframe> m_parsedKeyframes;
Vector<AcceleratedAction> m_pendingAcceleratedActions;
@@ -1478,13 +1478,15 @@ ExceptionOr<void> WebAnimation::commitStyles()
inlineStyle->setCssText(styledElement.getAttribute(HTMLNames::styleAttr));

auto& keyframeStack = styledElement.ensureKeyframeEffectStack(PseudoId::None);
// During iteration resolve() could clear the underlying properties so we use a copy
auto properties = effect->animatedProperties();
// 2.5 For each property, property, in targeted properties:
for (auto property : properties) {
// FIXME: handle custom properties (https://bugs.webkit.org/show_bug.cgi?id=242007).
if (property == CSSPropertyCustom)
continue;

auto effectAnimatesProperty = [](KeyframeEffect& effect, std::variant<CSSPropertyID, AtomString> property) {
return WTF::switchOn(property,
[&] (CSSPropertyID propertyId) { return effect.animatedProperties().contains(propertyId); },
[&] (AtomString customProperty) { return effect.animatedCustomProperties().contains(customProperty); }
);
};

auto commitProperty = [&](std::variant<CSSPropertyID, AtomString> property) {
// 1. Let partialEffectStack be a copy of the effect stack for property on target.
// 2. If animation's replace state is removed, add all animation effects associated with animation whose effect target is target and which include
// property as a target property to partialEffectStack.
@@ -1500,16 +1502,35 @@ ExceptionOr<void> WebAnimation::commitStyles()
for (const auto& effectInStack : keyframeStack.sortedEffects()) {
if (effectInStack->animation() != this && !compareAnimationsByCompositeOrder(*effectInStack->animation(), *this))
break;
if (effectInStack->animatedProperties().contains(property))
if (effectAnimatesProperty(*effectInStack, property))
effectInStack->animation()->resolve(*animatedStyle, { nullptr });
if (effectInStack->animation() == this)
break;
}
if (m_replaceState == ReplaceState::Removed)
effect->animation()->resolve(*animatedStyle, { nullptr });
if (auto cssValue = computedStyleExtractor.valueForPropertyInStyle(*animatedStyle, property, renderer))
inlineStyle->setPropertyInternal(property, cssValue->cssText(), false);
WTF::switchOn(property,
[&] (CSSPropertyID propertyId) {
if (auto cssValue = computedStyleExtractor.valueForPropertyInStyle(*animatedStyle, propertyId, renderer))
inlineStyle->setPropertyInternal(propertyId, cssValue->cssText(), false);
},
[&] (AtomString customProperty) {
if (auto cssValue = computedStyleExtractor.customPropertyValue(customProperty))
inlineStyle->setProperty(customProperty, cssValue->cssText(), emptyString());
}
);
};

// During iteration resolve() could clear the underlying properties so we use a copy
auto properties = effect->animatedProperties();
// 2.5 For each property, property, in targeted properties:
for (auto property : properties) {
if (property != CSSPropertyCustom)
commitProperty(property);
}
auto customProperties = effect->animatedCustomProperties();
for (auto customProperty : customProperties)
commitProperty(customProperty);

styledElement.setAttribute(HTMLNames::styleAttr, AtomString { inlineStyle->cssText() });

0 comments on commit 8161c97

Please sign in to comment.