Ignore:
Timestamp:
Jan 3, 2022, 2:00:53 AM (3 years ago)
Author:
[email protected]
Message:

"animation" shorthand should list all longhand values when serializing
https://bugs.webkit.org/show_bug.cgi?id=234792

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Mark 20 new WPT progressions.

  • web-platform-tests/css/css-animations/parsing/animation-shorthand-expected.txt:
  • web-platform-tests/css/css-animations/parsing/animation-valid-expected.txt:
  • web-platform-tests/css/css-animations/style-animation-parsing-expected.txt:

Source/WebCore:

Currently we omit any initial value when serializing the "animation" shorthand. However,
the CSS Animations spec says:

Note that order is also important within each animation definition for distinguishing
<keyframes-name> values from other keywords. When parsing, keywords that are valid for
properties other than animation-name whose values were not found earlier in the shorthand
must be accepted for those properties rather than for animation-name. Furthermore, when
serializing, default values of other properties must be output in at least the cases
necessary to distinguish an animation-name that could be a value of another property,
and may be output in additional cases.

Both Firefox and Chrome always include all longhand values when querying the inline style,
such that <div style="animation: none"> yields "0s ease 0s 1 normal none running none" for
element.style.animation. Currently, Safari only outputs "none".

When parsing the "animation" shorthand in consumeAnimationShorthand(), we now fill in initial
values as if they were explicitly set to their initial value, for instance duration is set to
"0s".

To do this, we refactored code in CSSComputedStyleDeclaration.cpp that dealt with the creation
of CSSValue from various values exposed on Animation such that it may be called from within
CSSPropertyParser.cpp.

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::valueForAnimationDuration):
(WebCore::ComputedStyleExtractor::valueForAnimationDelay):
(WebCore::ComputedStyleExtractor::valueForAnimationIterationCount):
(WebCore::ComputedStyleExtractor::valueForAnimationDirection):
(WebCore::ComputedStyleExtractor::valueForAnimationFillMode):
(WebCore::ComputedStyleExtractor::valueForAnimationPlayState):
(WebCore::ComputedStyleExtractor::valueForAnimationName):
(WebCore::delayValue):
(WebCore::durationValue):
(WebCore::ComputedStyleExtractor::valueForAnimationTimingFunction):
(WebCore::timingFunctionValue):
(WebCore::ComputedStyleExtractor::valueForPropertyInStyle):
(WebCore::createTimingFunctionValue): Deleted.

  • css/CSSComputedStyleDeclaration.h:
  • css/parser/CSSPropertyParser.cpp:

(WebCore::CSSPropertyParser::consumeAnimationShorthand):

LayoutTests:

Add the initial longhand values for some non-WPT tests that expected them to be
absent in the shorthand serialization.

  • fast/css/longhand-overrides-shorthand-prefixing.html:
  • fast/css/transform-inline-style-remove-expected.txt:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r287487 r287534  
    13461346}
    13471347
     1348Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationDuration(double duration)
     1349{
     1350    return CSSValuePool::singleton().createValue(duration, CSSUnitType::CSS_S);
     1351}
     1352
     1353Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationDelay(double delay)
     1354{
     1355    return CSSValuePool::singleton().createValue(delay, CSSUnitType::CSS_S);
     1356}
     1357
     1358Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationIterationCount(double iterationCount)
     1359{
     1360    if (iterationCount == Animation::IterationCountInfinite)
     1361        return CSSValuePool::singleton().createIdentifierValue(CSSValueInfinite);
     1362    return CSSValuePool::singleton().createValue(iterationCount, CSSUnitType::CSS_NUMBER);
     1363}
     1364
     1365Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationDirection(Animation::AnimationDirection direction)
     1366{
     1367    switch (direction) {
     1368    case Animation::AnimationDirectionNormal:
     1369        return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
     1370    case Animation::AnimationDirectionAlternate:
     1371        return CSSValuePool::singleton().createIdentifierValue(CSSValueAlternate);
     1372    case Animation::AnimationDirectionReverse:
     1373        return CSSValuePool::singleton().createIdentifierValue(CSSValueReverse);
     1374    case Animation::AnimationDirectionAlternateReverse:
     1375        return CSSValuePool::singleton().createIdentifierValue(CSSValueAlternateReverse);
     1376    }
     1377}
     1378
     1379Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationFillMode(AnimationFillMode fillMode)
     1380{
     1381    switch (fillMode) {
     1382    case AnimationFillMode::None:
     1383        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
     1384    case AnimationFillMode::Forwards:
     1385        return CSSValuePool::singleton().createIdentifierValue(CSSValueForwards);
     1386    case AnimationFillMode::Backwards:
     1387        return CSSValuePool::singleton().createIdentifierValue(CSSValueBackwards);
     1388    case AnimationFillMode::Both:
     1389        return CSSValuePool::singleton().createIdentifierValue(CSSValueBoth);
     1390    }
     1391}
     1392
     1393Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationPlayState(AnimationPlayState playState)
     1394{
     1395    switch (playState) {
     1396    case AnimationPlayState::Playing:
     1397        return CSSValuePool::singleton().createIdentifierValue(CSSValueRunning);
     1398    case AnimationPlayState::Paused:
     1399        return CSSValuePool::singleton().createIdentifierValue(CSSValuePaused);
     1400    }
     1401}
     1402
     1403Ref<CSSPrimitiveValue> ComputedStyleExtractor::valueForAnimationName(const Animation::Name& name)
     1404{
     1405    if (name.isIdentifier)
     1406        return CSSValuePool::singleton().createCustomIdent(name.string);
     1407    return CSSValuePool::singleton().createValue(name.string, CSSUnitType::CSS_STRING);
     1408}
     1409
    13481410static Ref<CSSValueList> delayValue(const AnimationList* animationList)
    13491411{
    1350     auto& cssValuePool = CSSValuePool::singleton();
    13511412    auto list = CSSValueList::createCommaSeparated();
    13521413    if (animationList) {
    13531414        for (size_t i = 0; i < animationList->size(); ++i)
    1354             list->append(cssValuePool.createValue(animationList->animation(i).delay(), CSSUnitType::CSS_S));
     1415            list->append(ComputedStyleExtractor::valueForAnimationDelay(animationList->animation(i).delay()));
    13551416    } else {
    13561417        // Note that initialAnimationDelay() is used for both transitions and animations
    1357         list->append(cssValuePool.createValue(Animation::initialDelay(), CSSUnitType::CSS_S));
     1418        list->append(ComputedStyleExtractor::valueForAnimationDelay(Animation::initialDelay()));
    13581419    }
    13591420    return list;
     
    13621423static Ref<CSSValueList> durationValue(const AnimationList* animationList)
    13631424{
    1364     auto& cssValuePool = CSSValuePool::singleton();
    13651425    auto list = CSSValueList::createCommaSeparated();
    13661426    if (animationList) {
    13671427        for (size_t i = 0; i < animationList->size(); ++i)
    1368             list->append(cssValuePool.createValue(animationList->animation(i).duration(), CSSUnitType::CSS_S));
     1428            list->append(ComputedStyleExtractor::valueForAnimationDuration(animationList->animation(i).duration()));
    13691429    } else {
    13701430        // Note that initialAnimationDuration() is used for both transitions and animations
    1371         list->append(cssValuePool.createValue(Animation::initialDuration(), CSSUnitType::CSS_S));
     1431        list->append(ComputedStyleExtractor::valueForAnimationDuration(Animation::initialDuration()));
    13721432    }
    13731433    return list;
    13741434}
    13751435
    1376 static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunction)
     1436Ref<CSSValue> ComputedStyleExtractor::valueForAnimationTimingFunction(const TimingFunction& timingFunction)
    13771437{
    13781438    switch (timingFunction.type()) {
     
    14191479    if (animationList) {
    14201480        for (size_t i = 0; i < animationList->size(); ++i)
    1421             list->append(createTimingFunctionValue(*animationList->animation(i).timingFunction()));
     1481            list->append(ComputedStyleExtractor::valueForAnimationTimingFunction(*animationList->animation(i).timingFunction()));
    14221482    } else
    14231483        // Note that initialAnimationTimingFunction() is used for both transitions and animations
    1424         list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
     1484        list->append(ComputedStyleExtractor::valueForAnimationTimingFunction(Animation::initialTimingFunction()));
    14251485    return list;
    14261486}
     
    35133573            const AnimationList* t = style.animations();
    35143574            if (t) {
    3515                 for (size_t i = 0; i < t->size(); ++i) {
    3516                     switch (t->animation(i).direction()) {
    3517                     case Animation::AnimationDirectionNormal:
    3518                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
    3519                         break;
    3520                     case Animation::AnimationDirectionAlternate:
    3521                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
    3522                         break;
    3523                     case Animation::AnimationDirectionReverse:
    3524                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
    3525                         break;
    3526                     case Animation::AnimationDirectionAlternateReverse:
    3527                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
    3528                         break;
    3529                     }
    3530                 }
     3575                for (size_t i = 0; i < t->size(); ++i)
     3576                    list->append(valueForAnimationDirection(t->animation(i).direction()));
    35313577            } else
    35323578                list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
     
    35393585            const AnimationList* t = style.animations();
    35403586            if (t) {
    3541                 for (size_t i = 0; i < t->size(); ++i) {
    3542                     switch (t->animation(i).fillMode()) {
    3543                     case AnimationFillMode::None:
    3544                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
    3545                         break;
    3546                     case AnimationFillMode::Forwards:
    3547                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
    3548                         break;
    3549                     case AnimationFillMode::Backwards:
    3550                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
    3551                         break;
    3552                     case AnimationFillMode::Both:
    3553                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
    3554                         break;
    3555                     }
    3556                 }
     3587                for (size_t i = 0; i < t->size(); ++i)
     3588                    list->append(valueForAnimationFillMode(t->animation(i).fillMode()));
    35573589            } else
    35583590                list->append(cssValuePool.createIdentifierValue(CSSValueNone));
     
    35633595            const AnimationList* t = style.animations();
    35643596            if (t) {
    3565                 for (size_t i = 0; i < t->size(); ++i) {
    3566                     double iterationCount = t->animation(i).iterationCount();
    3567                     if (iterationCount == Animation::IterationCountInfinite)
    3568                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
    3569                     else
    3570                         list->append(cssValuePool.createValue(iterationCount, CSSUnitType::CSS_NUMBER));
    3571                 }
     3597                for (size_t i = 0; i < t->size(); ++i)
     3598                    list->append(valueForAnimationIterationCount(t->animation(i).iterationCount()));
    35723599            } else
    35733600                list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSUnitType::CSS_NUMBER));
     
    35783605            const AnimationList* t = style.animations();
    35793606            if (t) {
    3580                 for (size_t i = 0; i < t->size(); ++i) {
    3581                     auto& name = t->animation(i).name();
    3582                     if (name.isIdentifier)
    3583                         list->append(cssValuePool.createCustomIdent(name.string));
    3584                     else
    3585                         list->append(cssValuePool.createValue(name.string, CSSUnitType::CSS_STRING));
    3586                 }
     3607                for (size_t i = 0; i < t->size(); ++i)
     3608                    list->append(valueForAnimationName(t->animation(i).name()));
    35873609            } else
    35883610                list->append(cssValuePool.createIdentifierValue(CSSValueNone));
     
    35933615            const AnimationList* t = style.animations();
    35943616            if (t) {
    3595                 for (size_t i = 0; i < t->size(); ++i) {
    3596                     switch (t->animation(i).playState()) {
    3597                     case AnimationPlayState::Playing:
    3598                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
    3599                         break;
    3600                     case AnimationPlayState::Paused:
    3601                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
    3602                         break;
    3603                     }
    3604                 }
     3617                for (size_t i = 0; i < t->size(); ++i)
     3618                    list->append(valueForAnimationPlayState(t->animation(i).playState()));
    36053619            } else
    36063620                list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
     
    38163830                    list->append(createTransitionPropertyValue(animation));
    38173831                    list->append(cssValuePool.createValue(animation.duration(), CSSUnitType::CSS_S));
    3818                     list->append(createTimingFunctionValue(*animation.timingFunction()));
     3832                    list->append(valueForAnimationTimingFunction(*animation.timingFunction()));
    38193833                    list->append(cssValuePool.createValue(animation.delay(), CSSUnitType::CSS_S));
    38203834                    transitionsList->append(WTFMove(list));
     
    38273841            list->append(cssValuePool.createIdentifierValue(CSSValueAll));
    38283842            list->append(cssValuePool.createValue(Animation::initialDuration(), CSSUnitType::CSS_S));
    3829             list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
     3843            list->append(valueForAnimationTimingFunction(Animation::initialTimingFunction()));
    38303844            list->append(cssValuePool.createValue(Animation::initialDelay(), CSSUnitType::CSS_S));
    38313845            return list;
Note: See TracChangeset for help on using the changeset viewer.