Diff
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-inner-at-rules-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-inner-at-rules-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-inner-at-rules-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,5 +1,5 @@
-FAIL @keyframes is defined regardless of evaluation assert_equals: expected "true" but got ""
+PASS @keyframes is defined regardless of evaluation
FAIL @property is defined regardless of evaluation assert_equals: expected "20px" but got "1em"
PASS @layer order respected regardless of evaluation
PASS @font-face is defined regardless of evaluation
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-longhand-animation-type-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-longhand-animation-type-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-longhand-animation-type-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,5 +1,5 @@
-FAIL Reference variable is applied assert_equals: expected "PASS" but got "FAIL"
+PASS Reference variable is applied
PASS container-name is not animatable
PASS container-type is not animatable
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/at-property-animation-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/at-property-animation-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/at-property-animation-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,6 +1,6 @@
-FAIL @keyframes works with @property assert_equals: expected "150px" but got ""
-FAIL @keyframes picks up the latest @property in the document assert_equals: expected "rgb(150, 150, 150)" but got ""
+FAIL @keyframes works with @property assert_equals: expected "150px" but got "200px"
+FAIL @keyframes picks up the latest @property in the document assert_equals: expected "rgb(150, 150, 150)" but got "rgb(200, 200, 200)"
FAIL Ongoing animation picks up redeclared custom property assert_equals: expected "0px" but got ""
FAIL Ongoing animation matches new keyframes against the current registration assert_equals: expected "0px" but got ""
FAIL Ongoing animation picks up redeclared intial value assert_equals: expected "200px" but got ""
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/font-size-animation-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/font-size-animation-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/font-size-animation-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,3 +1,3 @@
-FAIL Animating font-size handled identically for standard and custom properties assert_equals: expected "0px" but got "250px"
+FAIL Animating font-size handled identically for standard and custom properties assert_equals: expected "400px" but got "250px"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-revert-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-revert-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-revert-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,6 +1,6 @@
PASS Inherited registered custom property can be reverted
PASS Non-inherited registered custom property can be reverted
-FAIL Non-inherited registered custom property can be reverted in animation assert_equals: expected "50px" but got "0px"
-FAIL Inherited registered custom property can be reverted in animation assert_equals: expected "50px" but got "0px"
+FAIL Non-inherited registered custom property can be reverted in animation assert_equals: expected "50px" but got "100px"
+FAIL Inherited registered custom property can be reverted in animation assert_equals: expected "50px" but got "100px"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-from-to-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-from-to-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-from-to-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,7 +1,7 @@
This text should animate from blue to green over a period of 1 second.
-FAIL Verify CSS variable value before animation assert_equals: --value is blue before animation runs expected "blue" but got "red"
+PASS Verify CSS variable value before animation
FAIL Verify substituted color value before animation assert_equals: color is blue before animation runs expected "rgb(0, 0, 255)" but got "rgb(255, 0, 0)"
-FAIL Verify CSS variable value after animation assert_equals: --value is green after animation runs expected "green" but got "red"
+PASS Verify CSS variable value after animation
FAIL Verify substituted color value after animation assert_equals: color is green after animation runs expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-over-transition-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-over-transition-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-over-transition-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,7 +1,7 @@
This text should animate from blue to green over a period of 1 second. The transition is not visible because the animation overrides it.
-FAIL Verify CSS variable value before animation assert_equals: --value is blue before animation runs expected "blue" but got "red"
+PASS Verify CSS variable value before animation
FAIL Verify substituted color value before animation assert_equals: color is blue before animation runs expected "rgb(0, 0, 255)" but got "rgb(255, 0, 0)"
-FAIL Verify CSS variable value after animation assert_equals: --value is green after animation runs expected "green" but got "black"
+PASS Verify CSS variable value after animation
FAIL Verify substituted color value after animation assert_equals: color is green after animation runs expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-to-only-expected.txt (295727 => 295728)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-to-only-expected.txt 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-variables/variable-animation-to-only-expected.txt 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1,5 +1,5 @@
This text should animate from blue to green over a period of 1 second.
PASS Verify CSS variable value before animation
-FAIL Verify CSS variable value after animation assert_equals: --value is green after animation runs expected "green" but got "blue"
+PASS Verify CSS variable value after animation
Modified: trunk/Source/WebCore/animation/CSSPropertyAnimation.cpp (295727 => 295728)
--- trunk/Source/WebCore/animation/CSSPropertyAnimation.cpp 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/animation/CSSPropertyAnimation.cpp 2022-06-22 13:36:56 UTC (rev 295728)
@@ -3666,7 +3666,7 @@
void CSSPropertyAnimation::blendProperties(const CSSPropertyBlendingClient* client, CSSPropertyID property, RenderStyle& destination, const RenderStyle& from, const RenderStyle& to, double progress, CompositeOperation compositeOperation)
{
- ASSERT(property != CSSPropertyInvalid);
+ ASSERT(property != CSSPropertyInvalid && property != CSSPropertyCustom);
AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(property);
if (wrapper) {
@@ -3686,6 +3686,15 @@
}
}
+void CSSPropertyAnimation::blendCustomProperty(const AtomString& customProperty, RenderStyle& destination, const RenderStyle& from, const RenderStyle& to, double progress)
+{
+ const auto& source = progress < 0.5 ? from : to;
+ if (auto nonInheritedValue = source.nonInheritedCustomProperties().get(customProperty))
+ destination.setNonInheritedCustomPropertyValue(customProperty, CSSCustomPropertyValue::create(*nonInheritedValue));
+ else if (auto inheritedValue = source.inheritedCustomProperties().get(customProperty))
+ destination.setInheritedCustomPropertyValue(customProperty, CSSCustomPropertyValue::create(*inheritedValue));
+}
+
bool CSSPropertyAnimation::isPropertyAnimatable(CSSPropertyID property)
{
return CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(property);
Modified: trunk/Source/WebCore/animation/CSSPropertyAnimation.h (295727 => 295728)
--- trunk/Source/WebCore/animation/CSSPropertyAnimation.h 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/animation/CSSPropertyAnimation.h 2022-06-22 13:36:56 UTC (rev 295728)
@@ -48,6 +48,7 @@
static int getNumProperties();
static void blendProperties(const CSSPropertyBlendingClient*, CSSPropertyID, RenderStyle& destination, const RenderStyle& from, const RenderStyle& to, double progress, CompositeOperation);
+ static void blendCustomProperty(const AtomString&, RenderStyle& destination, const RenderStyle& from, const RenderStyle& to, double progress);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (295727 => 295728)
--- trunk/Source/WebCore/animation/KeyframeEffect.cpp 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp 2022-06-22 13:36:56 UTC (rev 295728)
@@ -1399,7 +1399,14 @@
KeyframeValue propertySpecificKeyframeWithZeroOffset(0, RenderStyle::clonePtr(targetStyle));
KeyframeValue propertySpecificKeyframeWithOneOffset(1, RenderStyle::clonePtr(targetStyle));
- for (auto cssPropertyId : properties) {
+ auto keyframeContainsProperty = [](const KeyframeValue& keyframe, std::variant<CSSPropertyID, AtomString> property) {
+ return WTF::switchOn(property,
+ [&] (CSSPropertyID propertyId) { return keyframe.containsProperty(propertyId); },
+ [&] (AtomString customProperty) { return keyframe.containsCustomProperty(customProperty); }
+ );
+ };
+
+ auto blendProperty = [&](std::variant<CSSPropertyID, AtomString> property) {
// 1. If iteration progress is unresolved abort this procedure.
// 2. Let target property be the longhand property for which the effect value is to be calculated.
// 3. If animation type of the target property is not animatable abort this procedure since the effect cannot be applied.
@@ -1413,7 +1420,7 @@
Vector<const KeyframeValue*> propertySpecificKeyframes;
for (auto& keyframe : m_blendingKeyframes) {
auto offset = keyframe.key();
- if (!keyframe.containsProperty(cssPropertyId))
+ if (!keyframeContainsProperty(keyframe, property))
continue;
if (!offset)
numberOfKeyframesWithZeroOffset++;
@@ -1424,7 +1431,7 @@
// 7. If property-specific keyframes is empty, return underlying value.
if (propertySpecificKeyframes.isEmpty())
- continue;
+ return;
auto hasImplicitZeroKeyframe = !numberOfKeyframesWithZeroOffset;
auto hasImplicitOneKeyframe = !numberOfKeyframesWithOneOffset;
@@ -1500,29 +1507,35 @@
// 3. Replace the property value of target property on keyframe with the result of combining underlying value
// (Va) and value to combine (Vb) using the procedure for the composite operation to use corresponding to the
// target property’s animation type.
- if (CSSPropertyAnimation::isPropertyAdditiveOrCumulative(cssPropertyId)) {
- // Only do this for the 0 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
- // for composition" which really means we don't want to do anything but rather just use the underlying style which
- // is already set on startKeyframe.
- if (!startKeyframe.key() && !hasImplicitZeroKeyframe) {
- auto startKeyframeCompositeOperation = startKeyframe.compositeOperation().value_or(m_compositeOperation);
- if (startKeyframeCompositeOperation != CompositeOperation::Replace)
- CSSPropertyAnimation::blendProperties(this, cssPropertyId, startKeyframeStyle, targetStyle, *startKeyframe.style(), 1, startKeyframeCompositeOperation);
- }
+ if (std::holds_alternative<CSSPropertyID>(property)) {
+ auto cssPropertyId = std::get<CSSPropertyID>(property);
+ if (CSSPropertyAnimation::isPropertyAdditiveOrCumulative(cssPropertyId)) {
+ // Only do this for the 0 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
+ // for composition" which really means we don't want to do anything but rather just use the underlying style which
+ // is already set on startKeyframe.
+ if (!startKeyframe.key() && !hasImplicitZeroKeyframe) {
+ auto startKeyframeCompositeOperation = startKeyframe.compositeOperation().value_or(m_compositeOperation);
+ if (startKeyframeCompositeOperation != CompositeOperation::Replace)
+ CSSPropertyAnimation::blendProperties(this, cssPropertyId, startKeyframeStyle, targetStyle, *startKeyframe.style(), 1, startKeyframeCompositeOperation);
+ }
- // Only do this for the 1 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
- // for composition" which really means we don't want to do anything but rather just use the underlying style which
- // is already set on endKeyframe.
- if (endKeyframe.key() == 1 && !hasImplicitOneKeyframe) {
- auto endKeyframeCompositeOperation = endKeyframe.compositeOperation().value_or(m_compositeOperation);
- if (endKeyframeCompositeOperation != CompositeOperation::Replace)
- CSSPropertyAnimation::blendProperties(this, cssPropertyId, endKeyframeStyle, targetStyle, *endKeyframe.style(), 1, endKeyframeCompositeOperation);
+ // Only do this for the 1 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
+ // for composition" which really means we don't want to do anything but rather just use the underlying style which
+ // is already set on endKeyframe.
+ if (endKeyframe.key() == 1 && !hasImplicitOneKeyframe) {
+ auto endKeyframeCompositeOperation = endKeyframe.compositeOperation().value_or(m_compositeOperation);
+ if (endKeyframeCompositeOperation != CompositeOperation::Replace)
+ CSSPropertyAnimation::blendProperties(this, cssPropertyId, endKeyframeStyle, targetStyle, *endKeyframe.style(), 1, endKeyframeCompositeOperation);
+ }
}
}
// 13. If there is only one keyframe in interval endpoints return the property value of target property on that keyframe.
if (intervalEndpoints.size() == 1) {
- CSSPropertyAnimation::blendProperties(this, cssPropertyId, targetStyle, startKeyframeStyle, startKeyframeStyle, 0, CompositeOperation::Replace);
+ WTF::switchOn(property,
+ [&] (CSSPropertyID propertyId) { CSSPropertyAnimation::blendProperties(this, propertyId, targetStyle, startKeyframeStyle, startKeyframeStyle, 0, CompositeOperation::Replace); },
+ [&] (AtomString customProperty) { CSSPropertyAnimation::blendCustomProperty(customProperty, targetStyle, startKeyframeStyle, startKeyframeStyle, 0); }
+ );
return;
}
@@ -1547,8 +1560,19 @@
// 18. Return the result of applying the interpolation procedure defined by the animation type of the target property, to the values of the target
// property specified on the two keyframes in interval endpoints taking the first such value as Vstart and the second as Vend and using transformed
// distance as the interpolation parameter p.
- CSSPropertyAnimation::blendProperties(this, cssPropertyId, targetStyle, startKeyframeStyle, endKeyframeStyle, transformedDistance, CompositeOperation::Replace);
+ WTF::switchOn(property,
+ [&] (CSSPropertyID propertyId) { CSSPropertyAnimation::blendProperties(this, propertyId, targetStyle, startKeyframeStyle, endKeyframeStyle, transformedDistance, CompositeOperation::Replace); },
+ [&] (AtomString customProperty) { CSSPropertyAnimation::blendCustomProperty(customProperty, targetStyle, startKeyframeStyle, endKeyframeStyle, transformedDistance); }
+ );
+ };
+
+ for (auto cssPropertyId : properties) {
+ if (cssPropertyId != CSSPropertyCustom)
+ blendProperty(cssPropertyId);
}
+
+ for (auto customProperty : m_blendingKeyframes.customProperties())
+ blendProperty(customProperty);
}
TimingFunction* KeyframeEffect::timingFunctionForBlendingKeyframe(const KeyframeValue& keyframe) const
Modified: trunk/Source/WebCore/rendering/style/KeyframeList.cpp (295727 => 295728)
--- trunk/Source/WebCore/rendering/style/KeyframeList.cpp 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/rendering/style/KeyframeList.cpp 2022-06-22 13:36:56 UTC (rev 295728)
@@ -77,8 +77,11 @@
if (!inserted)
m_keyframes.append(WTFMove(keyframe));
- for (auto& property : m_keyframes[i].properties())
+ auto& insertedKeyframe = m_keyframes[i];
+ for (auto& property : insertedKeyframe.properties())
m_properties.add(property);
+ for (auto& customProperty : insertedKeyframe.customProperties())
+ m_customProperties.add(customProperty);
}
bool KeyframeList::hasImplicitKeyframes() const
@@ -92,6 +95,8 @@
KeyframeValue keyframeValue(keyframe.key(), RenderStyle::clonePtr(*keyframe.style()));
for (auto propertyId : keyframe.properties())
keyframeValue.addProperty(propertyId);
+ for (auto& customProperty : keyframe.customProperties())
+ keyframeValue.addCustomProperty(customProperty);
keyframeValue.setTimingFunction(keyframe.timingFunction());
keyframeValue.setCompositeOperation(keyframe.compositeOperation());
insert(WTFMove(keyframeValue));
@@ -210,6 +215,9 @@
bool KeyframeList::containsAnimatableProperty() const
{
+ if (!m_customProperties.isEmpty())
+ return true;
+
for (auto cssPropertyId : m_properties) {
if (CSSPropertyAnimation::isPropertyAnimatable(cssPropertyId))
return true;
Modified: trunk/Source/WebCore/rendering/style/KeyframeList.h (295727 => 295728)
--- trunk/Source/WebCore/rendering/style/KeyframeList.h 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/rendering/style/KeyframeList.h 2022-06-22 13:36:56 UTC (rev 295728)
@@ -29,6 +29,7 @@
#include <wtf/Vector.h>
#include <wtf/HashSet.h>
#include <wtf/text/AtomString.h>
+#include <wtf/text/AtomStringHash.h>
namespace WebCore {
@@ -52,6 +53,10 @@
bool containsProperty(CSSPropertyID prop) const { return m_properties.contains(prop); }
const HashSet<CSSPropertyID>& properties() const { return m_properties; }
+ void addCustomProperty(const AtomString& customProperty) { m_customProperties.add(customProperty); }
+ bool containsCustomProperty(const AtomString& customProperty) const { return m_customProperties.contains(customProperty); }
+ const HashSet<AtomString>& customProperties() const { return m_customProperties; }
+
double key() const { return m_key; }
void setKey(double key) { m_key = key; }
@@ -67,6 +72,7 @@
private:
double m_key;
HashSet<CSSPropertyID> m_properties; // The properties specified in this keyframe.
+ HashSet<AtomString> m_customProperties; // The custom properties being animated.
std::unique_ptr<RenderStyle> m_style;
RefPtr<TimingFunction> m_timingFunction;
std::optional<CompositeOperation> m_compositeOperation;
@@ -92,6 +98,10 @@
const HashSet<CSSPropertyID>& properties() const { return m_properties; }
bool containsAnimatableProperty() const;
+ void addCustomProperty(const AtomString& customProperty) { m_customProperties.add(customProperty); }
+ bool containsCustomProperty(const AtomString& customProperty) const { return m_customProperties.contains(customProperty); }
+ const HashSet<AtomString>& customProperties() const { return m_customProperties; }
+
void clear();
bool isEmpty() const { return m_keyframes.isEmpty(); }
size_t size() const { return m_keyframes.size(); }
@@ -110,6 +120,7 @@
AtomString m_animationName;
Vector<KeyframeValue> m_keyframes; // Kept sorted by key.
HashSet<CSSPropertyID> m_properties; // The properties being animated.
+ HashSet<AtomString> m_customProperties; // The custom properties being animated.
};
} // namespace WebCore
Modified: trunk/Source/WebCore/style/StyleResolver.cpp (295727 => 295728)
--- trunk/Source/WebCore/style/StyleResolver.cpp 2022-06-22 12:41:33 UTC (rev 295727)
+++ trunk/Source/WebCore/style/StyleResolver.cpp 2022-06-22 13:36:56 UTC (rev 295728)
@@ -286,10 +286,15 @@
// The animation-composition and animation-timing-function within keyframes are special
// because they are not animated; they just describe the composite operation and timing
// function between this keyframe and the next.
- if (property != CSSPropertyAnimationTimingFunction && property != CSSPropertyAnimationComposition)
+ bool isAnimatableValue = property != CSSPropertyAnimationTimingFunction && property != CSSPropertyAnimationComposition;
+ if (isAnimatableValue)
keyframeValue.addProperty(property);
- if (auto* value = propertyReference.value(); value && value->isRevertValue())
- hasRevert = true;
+ if (auto* value = propertyReference.value()) {
+ if (isAnimatableValue && value->isCustomPropertyValue())
+ keyframeValue.addCustomProperty(downcast<CSSCustomPropertyValue>(*value).name());
+ if (value->isRevertValue())
+ hasRevert = true;
+ }
}
auto state = State(element, nullptr, context.documentElementStyle);