Changeset 288433 in webkit


Ignore:
Timestamp:
Jan 24, 2022 2:59:39 AM (6 months ago)
Author:
graouts@webkit.org
Message:

[Web Animations] add support for animation-composition CSS property
https://bugs.webkit.org/show_bug.cgi?id=232086
<rdar://problem/84508394>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Mark WPT progressions and import one ::marker WPT test that wasn't imported originally with bug 235443.

  • web-platform-tests/css/css-animations/CSSAnimation-effect.tentative-expected.txt:
  • web-platform-tests/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt:
  • web-platform-tests/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt:
  • web-platform-tests/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt:
  • web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
  • web-platform-tests/css/css-pseudo/parsing/marker-supported-properties-expected.txt:
  • web-platform-tests/css/css-pseudo/parsing/marker-supported-properties.html:
  • web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:

Source/WebCore:

Add support for the "animation-composition" property from the CSS Animations Level 2 specification.
This property sets the "composite" property on the animation's effect and is overridden by use of
the Web Animations API to set that property.

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • animation/CSSAnimation.cpp:

(WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
(WebCore::CSSAnimation::setBindingsEffect):
(WebCore::CSSAnimation::effectCompositeOperationWasSetUsingBindings):

  • animation/CSSAnimation.h:
  • animation/CompositeOperation.cpp: Added.

(WebCore::toCompositeOperation):

  • animation/CompositeOperation.h:
  • animation/CompositeOperationOrAuto.h:

(WebCore::toCompositeOperationOrAuto):

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::getBindingsKeyframes):
(WebCore::KeyframeEffect::getKeyframes):
(WebCore::KeyframeEffect::bindingsComposite const):
(WebCore::KeyframeEffect::setBindingsComposite):

  • animation/KeyframeEffect.h:
  • animation/KeyframeEffect.idl:
  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::valueForAnimationComposition):
(WebCore::ComputedStyleExtractor::addValueForAnimationPropertyToList):
(WebCore::ComputedStyleExtractor::valueForPropertyInStyle):

  • css/CSSProperties.json:
  • css/CSSToStyleMap.cpp:

(WebCore::CSSToStyleMap::mapAnimationCompositeOperation):

  • css/CSSToStyleMap.h:
  • css/CSSValueKeywords.in:
  • css/parser/CSSPropertyParser.cpp:

(WebCore::consumeAnimationValue):
(WebCore::CSSPropertyParser::parseSingleValue):

  • platform/animation/Animation.cpp:

(WebCore::Animation::Animation):

  • platform/animation/Animation.h:

(WebCore::Animation::clearCompositeOperation):
(WebCore::Animation::fillCompositeOperation):
(WebCore::Animation::isCompositeOperationFilled const):

  • platform/animation/AnimationList.cpp:

(WebCore::AnimationList::fillUnsetProperties):

  • style/PropertyAllowlist.cpp:

(WebCore::Style::isValidMarkerStyleProperty):

  • style/StyleResolver.cpp:

(WebCore::Style::Resolver::styleForKeyframe):
(WebCore::Style::Resolver::keyframeStylesForAnimation):

LayoutTests:

Update existing tests to account for the new "animation-composition" CSS property.

  • animations/fill-unset-properties-expected.txt:
  • animations/fill-unset-properties.html:
  • platform/glib/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
  • platform/gtk/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:
  • platform/ios/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
  • platform/ios/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:
Location:
trunk
Files:
37 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r288429 r288433  
     12022-01-24  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] add support for animation-composition CSS property
     4        https://bugs.webkit.org/show_bug.cgi?id=232086
     5        <rdar://problem/84508394>
     6
     7        Reviewed by Darin Adler.
     8
     9        Update existing tests to account for the new "animation-composition" CSS property.
     10
     11        * animations/fill-unset-properties-expected.txt:
     12        * animations/fill-unset-properties.html:
     13        * platform/glib/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
     14        * platform/gtk/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:
     15        * platform/ios/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
     16        * platform/ios/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:
     17
    1182022-01-23  Matt Woodrow  <mattwoodrow@apple.com>
    219
  • trunk/LayoutTests/animations/fill-unset-properties-expected.txt

    r287678 r288433  
    1111Testing animationIterationCount: PASS
    1212Testing animationTimingFunction: PASS
     13Testing animationComposition: PASS
    1314
  • trunk/LayoutTests/animations/fill-unset-properties.html

    r287678 r288433  
    2121    animation-iteration-count: 1, 2, 3;
    2222    animation-timing-function: linear;
     23    animation-composition: add, replace, accumulate;
    2324}
    2425@keyframes a { }
     
    4445      { 'property': 'animationPlayState', 'value': 'running, paused, running' },
    4546      { 'property': 'animationIterationCount', 'value': '1, 2, 3' },
    46       { 'property': 'animationTimingFunction', 'value': 'linear' }
     47      { 'property': 'animationTimingFunction', 'value': 'linear' },
     48      { 'property': 'animationComposition', 'value': 'add, replace, accumulate' }
    4749    ];
    4850   
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r288427 r288433  
     12022-01-24  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] add support for animation-composition CSS property
     4        https://bugs.webkit.org/show_bug.cgi?id=232086
     5        <rdar://problem/84508394>
     6
     7        Reviewed by Darin Adler.
     8
     9        Mark WPT progressions and import one ::marker WPT test that wasn't imported originally with bug 235443.
     10
     11        * web-platform-tests/css/css-animations/CSSAnimation-effect.tentative-expected.txt:
     12        * web-platform-tests/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt:
     13        * web-platform-tests/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt:
     14        * web-platform-tests/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt:
     15        * web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
     16        * web-platform-tests/css/css-pseudo/parsing/marker-supported-properties-expected.txt:
     17        * web-platform-tests/css/css-pseudo/parsing/marker-supported-properties.html:
     18        * web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt:
     19
    1202022-01-23  Sam Weinig  <weinig@apple.com>
    221
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-effect.tentative-expected.txt

    r288402 r288433  
    66PASS CSS animation events are dispatched at the original element even after setting an effect with a different target element
    77PASS After replacing a finished animation's effect with a longer one it fires an animationstart event
    8 FAIL Setting animation-composition sets the composite property on the effect assert_equals: expected "add" but got "replace"
     8PASS Setting animation-composition sets the composite property on the effect
    99PASS Replacing the effect of a CSSAnimation causes subsequent changes to corresponding animation-* properties to be ignored
    1010
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt

    r288402 r288433  
    66PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing is specified on some keyframes
    77PASS KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is set on the effect using animation-composition on the element
    8 FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on each keyframe assert_equals: value of 'composite' on ComputedKeyframe #0 expected "replace" but got "auto"
    9 FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on some keyframes assert_equals: value of 'composite' on ComputedKeyframe #0 expected "add" but got "auto"
     8PASS KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on each keyframe
     9PASS KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on some keyframes
    1010PASS KeyframeEffect.getKeyframes() returns expected frames for a simple animation that specifies a single shorthand property
    1111PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a 0% keyframe and no 100% keyframe
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt

    r288402 r288433  
    11
    2 FAIL Property animation-composition value 'replace, add, accumulate' assert_true: animation-composition doesn't seem to be supported in the computed style expected true got false
     2PASS Property animation-composition value 'replace, add, accumulate'
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt

    r288402 r288433  
    11
    2 FAIL e.style['animation-composition'] = "replace" should set the property value assert_not_equals: property should be set got disallowed value ""
    3 FAIL e.style['animation-composition'] = "add" should set the property value assert_not_equals: property should be set got disallowed value ""
    4 FAIL e.style['animation-composition'] = "accumulate" should set the property value assert_not_equals: property should be set got disallowed value ""
    5 FAIL e.style['animation-composition'] = "replace, add, accumulate" should set the property value assert_not_equals: property should be set got disallowed value ""
     2PASS e.style['animation-composition'] = "replace" should set the property value
     3PASS e.style['animation-composition'] = "add" should set the property value
     4PASS e.style['animation-composition'] = "accumulate" should set the property value
     5PASS e.style['animation-composition'] = "replace, add, accumulate" should set the property value
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt

    r287712 r288433  
    1010PASS all
    1111PASS alt
     12PASS animation-composition
    1213PASS animation-delay
    1314PASS animation-direction
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/parsing/marker-supported-properties-expected.txt

    r288009 r288433  
    3535PASS Property animation-play-state value 'paused' in ::marker
    3636PASS Property animation-timing-function value 'linear' in ::marker
     37PASS Property animation-composition value 'add' in ::marker
    3738PASS Property transition value 'display 1s linear 2s' in ::marker
    3839PASS Property transition-delay value '1s' in ::marker
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/parsing/marker-supported-properties.html

    r288009 r288433  
    6262test_pseudo_computed_value("::marker", "animation-play-state", "paused");
    6363test_pseudo_computed_value("::marker", "animation-timing-function", "linear");
     64test_pseudo_computed_value("::marker", "animation-composition", "add");
    6465
    6566// ::marker supports transition properties.
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt

    r287487 r288433  
    11
    22PASS getComputedStyle returns no style for detached element
    3 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 395
    4 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 395
    5 FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 395
    6 FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 395
     3FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 396
     4FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 396
     5FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 396
     6FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 396
    77PASS getComputedStyle returns no style for shadow tree outside of flattened tree
    88
  • trunk/LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt

    r287958 r288433  
    1010PASS all
    1111PASS alt
     12PASS animation-composition
    1213PASS animation-delay
    1314PASS animation-direction
  • trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt

    r287487 r288433  
    11
    22PASS getComputedStyle returns no style for detached element
    3 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 392
    4 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 392
    5 FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 392
    6 FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 392
     3FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 393
     4FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 393
     5FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 393
     6FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 393
    77PASS getComputedStyle returns no style for shadow tree outside of flattened tree
    88
  • trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt

    r287712 r288433  
    99PASS all
    1010PASS alt
     11PASS animation-composition
    1112PASS animation-delay
    1213PASS animation-direction
  • trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/css/cssom/getComputedStyle-detached-subtree-expected.txt

    r287487 r288433  
    11
    22PASS getComputedStyle returns no style for detached element
    3 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 397
    4 FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 397
    5 FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 397
    6 FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 397
     3FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) assert_equals: expected 0 but got 398
     4FAIL getComputedStyle returns no style for element in non-rendered iframe (display: none) from iframe's window assert_equals: expected 0 but got 398
     5FAIL getComputedStyle returns no style for element outside the flat tree assert_equals: expected 0 but got 398
     6FAIL getComputedStyle returns no style for descendant outside the flat tree assert_equals: expected 0 but got 398
    77PASS getComputedStyle returns no style for shadow tree outside of flattened tree
    88
  • trunk/Source/WebCore/ChangeLog

    r288432 r288433  
     12022-01-24  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] add support for animation-composition CSS property
     4        https://bugs.webkit.org/show_bug.cgi?id=232086
     5        <rdar://problem/84508394>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add support for the "animation-composition" property from the CSS Animations Level 2 specification.
     10        This property sets the "composite" property on the animation's effect and is overridden by use of
     11        the Web Animations API to set that property.
     12
     13        * Sources.txt:
     14        * WebCore.xcodeproj/project.pbxproj:
     15        * animation/CSSAnimation.cpp:
     16        (WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
     17        (WebCore::CSSAnimation::setBindingsEffect):
     18        (WebCore::CSSAnimation::effectCompositeOperationWasSetUsingBindings):
     19        * animation/CSSAnimation.h:
     20        * animation/CompositeOperation.cpp: Added.
     21        (WebCore::toCompositeOperation):
     22        * animation/CompositeOperation.h:
     23        * animation/CompositeOperationOrAuto.h:
     24        (WebCore::toCompositeOperationOrAuto):
     25        * animation/KeyframeEffect.cpp:
     26        (WebCore::KeyframeEffect::getBindingsKeyframes):
     27        (WebCore::KeyframeEffect::getKeyframes):
     28        (WebCore::KeyframeEffect::bindingsComposite const):
     29        (WebCore::KeyframeEffect::setBindingsComposite):
     30        * animation/KeyframeEffect.h:
     31        * animation/KeyframeEffect.idl:
     32        * css/CSSComputedStyleDeclaration.cpp:
     33        (WebCore::valueForAnimationComposition):
     34        (WebCore::ComputedStyleExtractor::addValueForAnimationPropertyToList):
     35        (WebCore::ComputedStyleExtractor::valueForPropertyInStyle):
     36        * css/CSSProperties.json:
     37        * css/CSSToStyleMap.cpp:
     38        (WebCore::CSSToStyleMap::mapAnimationCompositeOperation):
     39        * css/CSSToStyleMap.h:
     40        * css/CSSValueKeywords.in:
     41        * css/parser/CSSPropertyParser.cpp:
     42        (WebCore::consumeAnimationValue):
     43        (WebCore::CSSPropertyParser::parseSingleValue):
     44        * platform/animation/Animation.cpp:
     45        (WebCore::Animation::Animation):
     46        * platform/animation/Animation.h:
     47        (WebCore::Animation::clearCompositeOperation):
     48        (WebCore::Animation::fillCompositeOperation):
     49        (WebCore::Animation::isCompositeOperationFilled const):
     50        * platform/animation/AnimationList.cpp:
     51        (WebCore::AnimationList::fillUnsetProperties):
     52        * style/PropertyAllowlist.cpp:
     53        (WebCore::Style::isValidMarkerStyleProperty):
     54        * style/StyleResolver.cpp:
     55        (WebCore::Style::Resolver::styleForKeyframe):
     56        (WebCore::Style::Resolver::keyframeStylesForAnimation):
     57
    1582022-01-24  Said Abou-Hallawa  <said@apple.com>
    259
  • trunk/Source/WebCore/Sources.txt

    r288432 r288433  
    476476animation/CSSPropertyAnimation.cpp
    477477animation/CSSTransition.cpp
     478animation/CompositeOperation.cpp
    478479animation/CustomEffect.cpp
    479480animation/DeclarativeAnimation.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r288432 r288433  
    1118211182                718C7F561DD385C500B733C8 /* status-label.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = "status-label.css"; sourceTree = "<group>"; };
    1118311183                718C7F571DD385C500B733C8 /* status-label.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "status-label.js"; sourceTree = "<group>"; };
     11184                718F2486279DE9EF00C3204D /* CompositeOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompositeOperation.cpp; sourceTree = "<group>"; };
    1118411185                7199B94A2551F0E100494A57 /* StyleContentAlignmentData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleContentAlignmentData.cpp; sourceTree = "<group>"; };
    1118511186                7199B94F2552103E00494A57 /* StyleSelfAlignmentData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSelfAlignmentData.cpp; sourceTree = "<group>"; };
     
    2444224443                                71025EC91F99F096004A250C /* AnimationTimeline.idl */,
    2444324444                                7156BC9F21CA350600534397 /* BasicEffectTiming.h */,
     24445                                718F2486279DE9EF00C3204D /* CompositeOperation.cpp */,
    2444424446                                71247E351FEA5F81008C08CE /* CompositeOperation.h */,
    2444524447                                71247E361FEA5F81008C08CE /* CompositeOperation.idl */,
  • trunk/Source/WebCore/animation/CSSAnimation.cpp

    r287877 r288433  
    2828
    2929#include "Animation.h"
     30#include "AnimationEffect.h"
    3031#include "AnimationEvent.h"
    3132#include "InspectorInstrumentation.h"
     
    110111    if (!m_overriddenProperties.contains(Property::Duration))
    111112        animationEffect->setIterationDuration(Seconds(animation.duration()));
     113
     114    if (!m_overriddenProperties.contains(Property::CompositeOperation)) {
     115        if (is<KeyframeEffect>(animationEffect))
     116            downcast<KeyframeEffect>(*animationEffect).setComposite(animation.compositeOperation());
     117    }
    112118
    113119    animationEffect->updateStaticTimingProperties();
     
    169175        m_overriddenProperties.add(Property::Delay);
    170176        m_overriddenProperties.add(Property::FillMode);
     177        m_overriddenProperties.add(Property::CompositeOperation);
    171178    }
    172179}
     
    243250}
    244251
     252void CSSAnimation::effectCompositeOperationWasSetUsingBindings()
     253{
     254    m_overriddenProperties.add(Property::CompositeOperation);
     255}
     256
    245257void CSSAnimation::keyframesRuleDidChange()
    246258{
  • trunk/Source/WebCore/animation/CSSAnimation.h

    r287707 r288433  
    4747    void effectTimingWasUpdatedUsingBindings(OptionalEffectTiming);
    4848    void effectKeyframesWereSetUsingBindings();
     49    void effectCompositeOperationWasSetUsingBindings();
    4950    void keyframesRuleDidChange();
    5051    void updateKeyframesIfNeeded(const RenderStyle* oldStyle, const RenderStyle& newStyle, const Style::ResolutionContext&);
     
    7172        Delay = 1 << 6,
    7273        FillMode = 1 << 7,
    73         Keyframes = 1 << 8
     74        Keyframes = 1 << 8,
     75        CompositeOperation = 1 << 9
    7476    };
    7577
  • trunk/Source/WebCore/animation/CompositeOperation.cpp

    r288432 r288433  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "CompositeOperation.h"
     28
     29#include "CSSPrimitiveValue.h"
     30#include "CSSValue.h"
     31#include "CSSValueKeywords.h"
    2732
    2833namespace WebCore {
    2934
    30 enum class CompositeOperationOrAuto : uint8_t { Replace, Add, Accumulate, Auto };
     35std::optional<CompositeOperation> toCompositeOperation(const CSSValue& value)
     36{
     37    if (!is<CSSPrimitiveValue>(value))
     38        return std::nullopt;
     39
     40    switch (downcast<CSSPrimitiveValue>(value).valueID()) {
     41    case CSSValueAdd:
     42        return CompositeOperation::Add;
     43    case CSSValueAccumulate:
     44        return CompositeOperation::Accumulate;
     45    case CSSValueReplace:
     46        return CompositeOperation::Replace;
     47    default:
     48        return std::nullopt;
     49    }
     50}
    3151
    3252} // namespace WebCore
  • trunk/Source/WebCore/animation/CompositeOperation.h

    r239820 r288433  
    2626#pragma once
    2727
     28#include <optional>
     29
    2830namespace WebCore {
     31
     32class CSSValue;
    2933
    3034enum class CompositeOperation : uint8_t { Replace, Add, Accumulate };
    3135
     36std::optional<CompositeOperation> toCompositeOperation(const CSSValue&);
     37
    3238} // namespace WebCore
  • trunk/Source/WebCore/animation/CompositeOperationOrAuto.h

    r239820 r288433  
    2626#pragma once
    2727
     28#include "CompositeOperation.h"
     29
    2830namespace WebCore {
    2931
    3032enum class CompositeOperationOrAuto : uint8_t { Replace, Add, Accumulate, Auto };
    3133
     34constexpr CompositeOperationOrAuto toCompositeOperationOrAuto(CompositeOperation operation)
     35{
     36    switch (operation) {
     37    case CompositeOperation::Replace:
     38        return CompositeOperationOrAuto::Replace;
     39    case CompositeOperation::Add:
     40        return CompositeOperationOrAuto::Add;
     41    case CompositeOperation::Accumulate:
     42        return CompositeOperationOrAuto::Accumulate;
     43    }
     44}
     45
    3246} // namespace WebCore
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r288423 r288433  
    597597}
    598598
    599 Vector<Strong<JSObject>> KeyframeEffect::getBindingsKeyframes(JSGlobalObject& lexicalGlobalObject)
     599Vector<Strong<JSObject>> KeyframeEffect::getBindingsKeyframes(JSGlobalObject& lexicalGlobalObject, Document& document)
    600600{
    601601    if (is<DeclarativeAnimation>(animation()))
    602602        downcast<DeclarativeAnimation>(*animation()).flushPendingStyleChanges();
    603     return getKeyframes(lexicalGlobalObject);
    604 }
    605 
    606 Vector<Strong<JSObject>> KeyframeEffect::getKeyframes(JSGlobalObject& lexicalGlobalObject)
     603    return getKeyframes(lexicalGlobalObject, document);
     604}
     605
     606Vector<Strong<JSObject>> KeyframeEffect::getKeyframes(JSGlobalObject& lexicalGlobalObject, Document& document)
    607607{
    608608    // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffectreadonly-getkeyframes
     609
     610    auto supportsCompositeOperation = document.settings().webAnimationsCompositeOperationsEnabled();
    609611
    610612    auto lock = JSLockHolder { &lexicalGlobalObject };
     
    700702            // For CSS transitions, all keyframes should return "linear" since the effect's global timing function applies.
    701703            computedKeyframe.easing = is<CSSTransition>(animation()) ? "linear" : timingFunctionForBlendingKeyframe(keyframe)->cssText();
     704
     705            if (supportsCompositeOperation) {
     706                if (auto compositeOperation = keyframe.compositeOperation())
     707                    computedKeyframe.composite = toCompositeOperationOrAuto(*compositeOperation);
     708            }
    702709
    703710            auto outputKeyframe = convertDictionaryToJS(lexicalGlobalObject, *jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject), computedKeyframe);
     
    774781            computedKeyframe.easing = timingFunctionForKeyframeAtIndex(i)->cssText();
    775782
    776             auto* scriptExecutionContext = jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject)->scriptExecutionContext();
    777             if (is<Document>(scriptExecutionContext)) {
    778                 if (downcast<Document>(*scriptExecutionContext).settings().webAnimationsCompositeOperationsEnabled())
    779                     computedKeyframe.composite = parsedKeyframe.composite;
    780             }
     783            if (supportsCompositeOperation)
     784                computedKeyframe.composite = parsedKeyframe.composite;
    781785
    782786            auto outputKeyframe = convertDictionaryToJS(lexicalGlobalObject, *jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject), computedKeyframe);
     
    22222226}
    22232227
     2228CompositeOperation KeyframeEffect::bindingsComposite() const
     2229{
     2230    if (is<DeclarativeAnimation>(animation()))
     2231        downcast<DeclarativeAnimation>(*animation()).flushPendingStyleChanges();
     2232    return composite();
     2233}
     2234
     2235void KeyframeEffect::setBindingsComposite(CompositeOperation compositeOperation)
     2236{
     2237    setComposite(compositeOperation);
     2238    if (is<CSSAnimation>(animation()))
     2239        downcast<CSSAnimation>(*animation()).effectCompositeOperationWasSetUsingBindings();
     2240}
     2241
    22242242} // namespace WebCore
  • trunk/Source/WebCore/animation/KeyframeEffect.h

    r287707 r288433  
    115115    const std::optional<const Styleable> targetStyleable() const;
    116116
    117     Vector<JSC::Strong<JSC::JSObject>> getBindingsKeyframes(JSC::JSGlobalObject&);
    118     Vector<JSC::Strong<JSC::JSObject>> getKeyframes(JSC::JSGlobalObject&);
     117    Vector<JSC::Strong<JSC::JSObject>> getBindingsKeyframes(JSC::JSGlobalObject&, Document&);
     118    Vector<JSC::Strong<JSC::JSObject>> getKeyframes(JSC::JSGlobalObject&, Document&);
    119119    ExceptionOr<void> setBindingsKeyframes(JSC::JSGlobalObject&, JSC::Strong<JSC::JSObject>&&);
    120120    ExceptionOr<void> setKeyframes(JSC::JSGlobalObject&, JSC::Strong<JSC::JSObject>&&);
     
    124124    CompositeOperation composite() const { return m_compositeOperation; }
    125125    void setComposite(CompositeOperation compositeOperation) { m_compositeOperation = compositeOperation; }
     126    CompositeOperation bindingsComposite() const;
     127    void setBindingsComposite(CompositeOperation);
    126128
    127129    void getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle);
  • trunk/Source/WebCore/animation/KeyframeEffect.idl

    r283463 r288433  
    3636    attribute CSSOMString? pseudoElement;
    3737    [EnabledBySetting=WebAnimationsCompositeOperationsEnabled] attribute IterationCompositeOperation iterationComposite;
    38     [EnabledBySetting=WebAnimationsCompositeOperationsEnabled] attribute CompositeOperation composite;
    39     [CallWith=GlobalObject, ImplementedAs=getBindingsKeyframes] sequence<object> getKeyframes();
     38    [EnabledBySetting=WebAnimationsCompositeOperationsEnabled, ImplementedAs=bindingsComposite] attribute CompositeOperation composite;
     39    [CallWith=GlobalObject&Document, ImplementedAs=getBindingsKeyframes] sequence<object> getKeyframes();
    4040    [CallWith=GlobalObject, ImplementedAs=setBindingsKeyframes] undefined setKeyframes(object? keyframes);
    4141};
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r288200 r288433  
    13791379}
    13801380
     1381static Ref<CSSPrimitiveValue> valueForAnimationComposition(CompositeOperation operation)
     1382{
     1383    switch (operation) {
     1384    case CompositeOperation::Add:
     1385        return CSSValuePool::singleton().createIdentifierValue(CSSValueAdd);
     1386    case CompositeOperation::Accumulate:
     1387        return CSSValuePool::singleton().createIdentifierValue(CSSValueAccumulate);
     1388    case CompositeOperation::Replace:
     1389        return CSSValuePool::singleton().createIdentifierValue(CSSValueReplace);
     1390    }
     1391}
     1392
    13811393static Ref<CSSPrimitiveValue> valueForAnimationPlayState(AnimationPlayState playState)
    13821394{
     
    14591471    } else if (property == CSSPropertyAnimationName)
    14601472        list.append(valueForAnimationName(animation ? animation->name() : Animation::initialName()));
    1461     else if (property == CSSPropertyTransitionProperty) {
     1473    else if (property == CSSPropertyAnimationComposition) {
     1474        if (!animation || !animation->isCompositeOperationFilled())
     1475            list.append(valueForAnimationComposition(animation ? animation->compositeOperation() : Animation::initialCompositeOperation()));
     1476    } else if (property == CSSPropertyTransitionProperty) {
    14621477        if (animation) {
    14631478            if (!animation->isPropertyFilled())
     
    35563571        case CSSPropertyAnimation:
    35573572            return animationShorthandValue(propertyID, style.animations());
     3573        case CSSPropertyAnimationComposition:
    35583574        case CSSPropertyAnimationDelay:
    35593575        case CSSPropertyAnimationDirection:
  • trunk/Source/WebCore/css/CSSProperties.json

    r287712 r288433  
    917917            }
    918918        },
     919        "animation-composition": {
     920            "values": [
     921                "add",
     922                "accumulate",
     923                "replace"
     924            ],
     925            "animatable": true,
     926            "codegen-properties": {
     927                "name-for-methods": "CompositeOperation",
     928                "settings-flag": "webAnimationsCompositeOperationsEnabled"
     929            },
     930            "specification": {
     931                "category": "css-animations",
     932                "url": "https://drafts.csswg.org/css-animations-2/#animation-composition"
     933            },
     934            "status": {
     935                "status": "experimental"
     936            }
     937        },
    919938        "animation-delay": {
    920939            "animatable": true,
  • trunk/Source/WebCore/css/CSSToStyleMap.cpp

    r286795 r288433  
    3838#include "CSSTimingFunctionValue.h"
    3939#include "CSSValueKeywords.h"
     40#include "CompositeOperation.h"
    4041#include "FillLayer.h"
    4142#include "Pair.h"
     
    461462    else if (auto timingFunction = TimingFunction::createFromCSSValue(value))
    462463        animation.setTimingFunction(WTFMove(timingFunction));
     464}
     465
     466void CSSToStyleMap::mapAnimationCompositeOperation(Animation& animation, const CSSValue& value)
     467{
     468    if (value.treatAsInitialValue(CSSPropertyAnimationComposition))
     469        animation.setCompositeOperation(Animation::initialCompositeOperation());
     470    else if (auto compositeOperation = toCompositeOperation(value))
     471        animation.setCompositeOperation(*compositeOperation);
    463472}
    464473
  • trunk/Source/WebCore/css/CSSToStyleMap.h

    r282143 r288433  
    6969    void mapAnimationProperty(Animation&, const CSSValue&);
    7070    void mapAnimationTimingFunction(Animation&, const CSSValue&);
     71    void mapAnimationCompositeOperation(Animation&, const CSSValue&);
    7172
    7273    void mapNinePieceImage(CSSPropertyID, CSSValue*, NinePieceImage&);
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r287663 r288433  
    10341034
    10351035//
     1036// animation-composition
     1037//
     1038// add
     1039accumulate
     1040replace
     1041
     1042//
    10361043// CSS_PROP_ZOOM
    10371044//
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r288184 r288433  
    15741574    case CSSPropertyAnimationPlayState:
    15751575        return consumeIdent<CSSValueRunning, CSSValuePaused>(range);
     1576    case CSSPropertyAnimationComposition:
     1577        return consumeIdent<CSSValueAccumulate, CSSValueAdd, CSSValueReplace>(range);
    15761578    case CSSPropertyTransitionProperty:
    15771579        return consumeTransitionProperty(range);
     
    43354337    case CSSPropertyAnimationName:
    43364338    case CSSPropertyAnimationPlayState:
     4339    case CSSPropertyAnimationComposition:
    43374340    case CSSPropertyTransitionProperty:
    43384341    case CSSPropertyAnimationTimingFunction:
  • trunk/Source/WebCore/platform/animation/Animation.cpp

    r287708 r288433  
    5757    , m_propertyFilled(false)
    5858    , m_timingFunctionFilled(false)
     59    , m_compositeOperationFilled(false)
    5960{
    6061}
     
    9293    , m_propertyFilled(o.m_propertyFilled)
    9394    , m_timingFunctionFilled(o.m_timingFunctionFilled)
     95    , m_compositeOperationFilled(o.m_compositeOperationFilled)
    9496{
    9597}
  • trunk/Source/WebCore/platform/animation/Animation.h

    r288085 r288433  
    8080    void clearProperty() { m_propertySet = false; m_propertyFilled = false; }
    8181    void clearTimingFunction() { m_timingFunctionSet = false; m_timingFunctionFilled = false; }
    82     void clearCompositeOperation() { m_compositeOperationSet = false; }
     82    void clearCompositeOperation() { m_compositeOperationSet = false; m_compositeOperationFilled = false; }
    8383
    8484    void clearAll()
     
    168168    void fillProperty(TransitionProperty property) { setProperty(property); m_propertyFilled = true; }
    169169    void fillTimingFunction(RefPtr<TimingFunction>&& timingFunction) { setTimingFunction(WTFMove(timingFunction)); m_timingFunctionFilled = true; }
     170    void fillCompositeOperation(CompositeOperation compositeOperation) { setCompositeOperation(compositeOperation); m_compositeOperationFilled = true; }
    170171
    171172    bool isDelayFilled() const { return m_delayFilled; }
     
    177178    bool isPropertyFilled() const { return m_propertyFilled; }
    178179    bool isTimingFunctionFilled() const { return m_timingFunctionFilled; }
     180    bool isCompositeOperationFilled() const { return m_compositeOperationFilled; }
    179181
    180182    // return true if all members of this class match (excluding m_next)
     
    235237    bool m_propertyFilled : 1;
    236238    bool m_timingFunctionFilled : 1;
     239    bool m_compositeOperationFilled : 1;
    237240
    238241public:
  • trunk/Source/WebCore/platform/animation/AnimationList.cpp

    r287678 r288433  
    5959    FILL_UNSET_PROPERTY(isTimingFunctionSet, timingFunction, fillTimingFunction);
    6060    FILL_UNSET_PROPERTY(isPropertySet, property, fillProperty);
     61    FILL_UNSET_PROPERTY(isCompositeOperationSet, compositeOperation, fillCompositeOperation);
    6162}
    6263
  • trunk/Source/WebCore/style/PropertyAllowlist.cpp

    r287487 r288433  
    8989    case CSSPropertyAnimationFillMode:
    9090    case CSSPropertyAnimationPlayState:
     91    case CSSPropertyAnimationComposition:
    9192    case CSSPropertyAnimationName:
    9293    case CSSPropertyTransitionDuration:
  • trunk/Source/WebCore/style/StyleResolver.cpp

    r287828 r288433  
    4141#include "CSSStyleSheet.h"
    4242#include "CachedResourceLoader.h"
     43#include "CompositeOperation.h"
    4344#include "ElementRuleCollector.h"
    4445#include "Frame.h"
     
    294295    for (unsigned i = 0; i < propertyCount; ++i) {
    295296        CSSPropertyID property = keyframe->properties().propertyAt(i).id();
    296         // Timing-function within keyframes is special, because it is not animated; it just
    297         // describes the timing function between this keyframe and the next.
    298         if (property != CSSPropertyAnimationTimingFunction)
     297        // The animation-composition and animation-timing-function within keyframes are special
     298        // because they are not animated; they just describe the composite operation and timing
     299        // function between this keyframe and the next.
     300        if (property != CSSPropertyAnimationTimingFunction && property != CSSPropertyAnimationComposition)
    299301            keyframeValue.addProperty(property);
    300302    }
     
    397399            if (auto timingFunctionCSSValue = keyframeRule->properties().getPropertyCSSValue(CSSPropertyAnimationTimingFunction))
    398400                keyframeValue.setTimingFunction(TimingFunction::createFromCSSValue(*timingFunctionCSSValue.get()));
     401            if (auto compositeOperationCSSValue = keyframeRule->properties().getPropertyCSSValue(CSSPropertyAnimationComposition)) {
     402                if (auto compositeOperation = toCompositeOperation(*compositeOperationCSSValue))
     403                    keyframeValue.setCompositeOperation(*compositeOperation);
     404            }
    399405            list.insert(WTFMove(keyframeValue));
    400406        }
Note: See TracChangeset for help on using the changeset viewer.