Changeset 290457 in webkit


Ignore:
Timestamp:
Feb 24, 2022 1:19:40 PM (5 months ago)
Author:
Oriol Brufau
Message:

[css-cascade] Support 'revert' in @keyframes
https://bugs.webkit.org/show_bug.cgi?id=237073

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Expect tests to pass.

  • web-platform-tests/css/css-cascade/revert-val-006-expected.txt:
  • web-platform-tests/css/css-cascade/revert-val-007-expected.txt:
  • web-platform-tests/css/css-cascade/revert-val-008-expected.txt:
  • web-platform-tests/css/css-cascade/revert-val-010-expected.txt:

Source/WebCore:

Resolver::styleForKeyframe was constructing a RenderStyle with only the
styles specified in the @keyframes. But not taking into account the UA
and user rules that affect the element meant that 'revert' was broken.
Since Builder::applyProperty didn't find the declarations from other
origins, 'revert' just behaved as 'unset'.

This patch solves it by detecting if the @keyframes has a 'revert' value
and in that case it collects the UA and user rules so that it can be
resolved properly.

Tests: imported/w3c/web-platform-tests/css/css-cascade/revert-val-006.html

imported/w3c/web-platform-tests/css/css-cascade/revert-val-007.html
imported/w3c/web-platform-tests/css/css-cascade/revert-val-008.html
imported/w3c/web-platform-tests/css/css-cascade/revert-val-010.html

  • style/ElementRuleCollector.cpp:

(WebCore::Style::ElementRuleCollector::addAuthorKeyframeRules):

  • style/ElementRuleCollector.h:
  • style/StyleResolver.cpp:

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

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r290454 r290457  
     12022-02-24  Oriol Brufau  <obrufau@igalia.com>
     2
     3        [css-cascade] Support 'revert' in @keyframes
     4        https://bugs.webkit.org/show_bug.cgi?id=237073
     5
     6        Reviewed by Darin Adler.
     7
     8        Expect tests to pass.
     9
     10        * web-platform-tests/css/css-cascade/revert-val-006-expected.txt:
     11        * web-platform-tests/css/css-cascade/revert-val-007-expected.txt:
     12        * web-platform-tests/css/css-cascade/revert-val-008-expected.txt:
     13        * web-platform-tests/css/css-cascade/revert-val-010-expected.txt:
     14
    1152022-02-24  Alan Bujtas  <zalan@apple.com>
    216
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-val-006-expected.txt

    r287909 r290457  
    11
    2 FAIL The revert keyword works with @keyframes assert_equals: expected "21.440001px" but got "0px"
     2PASS The revert keyword works with @keyframes
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-val-007-expected.txt

    r287909 r290457  
    11
    2 FAIL A @keyframe animation with revert works when applied to multiple identical elements assert_equals: expected "21.440001px" but got "0px"
     2PASS A @keyframe animation with revert works when applied to multiple identical elements
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-val-008-expected.txt

    r264522 r290457  
    11
    2 FAIL The revert keyword works in the final frame of a web animation assert_between_exclusive: expected a number greater than 21 and less than 42 but got 15
     2PASS The revert keyword works in the final frame of a web animation
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-val-010-expected.txt

    r287549 r290457  
    11
    2 FAIL The revert works when appearing in setKeyframes assert_equals: expected 42 but got 31
     2PASS The revert works when appearing in setKeyframes
    33
  • trunk/Source/WebCore/ChangeLog

    r290456 r290457  
     12022-02-24  Oriol Brufau  <obrufau@igalia.com>
     2
     3        [css-cascade] Support 'revert' in @keyframes
     4        https://bugs.webkit.org/show_bug.cgi?id=237073
     5
     6        Reviewed by Darin Adler.
     7
     8        Resolver::styleForKeyframe was constructing a RenderStyle with only the
     9        styles specified in the @keyframes. But not taking into account the UA
     10        and user rules that affect the element meant that 'revert' was broken.
     11        Since Builder::applyProperty didn't find the declarations from other
     12        origins, 'revert' just behaved as 'unset'.
     13
     14        This patch solves it by detecting if the @keyframes has a 'revert' value
     15        and in that case it collects the UA and user rules so that it can be
     16        resolved properly.
     17
     18        Tests: imported/w3c/web-platform-tests/css/css-cascade/revert-val-006.html
     19               imported/w3c/web-platform-tests/css/css-cascade/revert-val-007.html
     20               imported/w3c/web-platform-tests/css/css-cascade/revert-val-008.html
     21               imported/w3c/web-platform-tests/css/css-cascade/revert-val-010.html
     22
     23        * style/ElementRuleCollector.cpp:
     24        (WebCore::Style::ElementRuleCollector::addAuthorKeyframeRules):
     25        * style/ElementRuleCollector.h:
     26        * style/StyleResolver.cpp:
     27        (WebCore::Style::Resolver::styleForKeyframe):
     28
    1292022-02-24  Devin Rousso  <drousso@apple.com>
    230
  • trunk/Source/WebCore/style/ElementRuleCollector.cpp

    r290257 r290457  
    3030#include "ElementRuleCollector.h"
    3131
     32#include "CSSKeyframeRule.h"
    3233#include "CSSRuleList.h"
    3334#include "CSSSelector.h"
     
    650651}
    651652
     653void ElementRuleCollector::addAuthorKeyframeRules(const StyleRuleKeyframe& keyframe)
     654{
     655    ASSERT(m_result.authorDeclarations.isEmpty());
     656    m_result.authorDeclarations.append({ &keyframe.properties(), SelectorChecker::MatchAll, propertyAllowlistForPseudoId(m_pseudoElementRequest.pseudoId) });
     657}
     658
    652659}
    653660} // namespace WebCore
  • trunk/Source/WebCore/style/ElementRuleCollector.h

    r290257 r290457  
    9494    bool didMatchUncommonAttributeSelector() const { return m_didMatchUncommonAttributeSelector; }
    9595
     96    void addAuthorKeyframeRules(const StyleRuleKeyframe&);
     97
    9698private:
    9799    void addElementStyleProperties(const StyleProperties*, bool isCacheable = true, FromStyleAttribute = FromStyleAttribute::No);
  • trunk/Source/WebCore/style/StyleResolver.cpp

    r289181 r290457  
    278278std::unique_ptr<RenderStyle> Resolver::styleForKeyframe(const Element& element, const RenderStyle& elementStyle, const ResolutionContext& context, const StyleRuleKeyframe& keyframe, KeyframeValue& keyframeValue)
    279279{
    280     MatchResult result;
    281     result.authorDeclarations.append({ &keyframe.properties(), SelectorChecker::MatchAll, propertyAllowlistForPseudoId(elementStyle.styleType()) });
    282 
    283     auto state = State(element, nullptr, context.documentElementStyle);
    284 
    285     state.setStyle(RenderStyle::clonePtr(elementStyle));
    286     state.setParentStyle(RenderStyle::clonePtr(context.parentStyle ? *context.parentStyle : elementStyle));
    287 
    288     Builder builder(*state.style(), builderContext(state), result, CascadeLevel::Author);
    289     builder.applyAllProperties();
    290 
    291     Adjuster adjuster(document(), *state.parentStyle(), nullptr, nullptr);
    292     adjuster.adjust(*state.style(), state.userAgentAppearanceStyle());
    293 
    294280    // Add all the animating properties to the keyframe.
    295281    unsigned propertyCount = keyframe.properties().propertyCount();
     282    bool hasRevert = false;
    296283    for (unsigned i = 0; i < propertyCount; ++i) {
    297         auto property = CSSProperty::resolveDirectionAwareProperty(keyframe.properties().propertyAt(i).id(), elementStyle.direction(), elementStyle.writingMode());
     284        auto propertyReference = keyframe.properties().propertyAt(i);
     285        auto property = CSSProperty::resolveDirectionAwareProperty(propertyReference.id(), elementStyle.direction(), elementStyle.writingMode());
    298286        // The animation-composition and animation-timing-function within keyframes are special
    299287        // because they are not animated; they just describe the composite operation and timing
     
    301289        if (property != CSSPropertyAnimationTimingFunction && property != CSSPropertyAnimationComposition)
    302290            keyframeValue.addProperty(property);
    303     }
     291        if (auto* value = propertyReference.value(); value && value->isRevertValue())
     292            hasRevert = true;
     293    }
     294
     295    auto state = State(element, nullptr, context.documentElementStyle);
     296
     297    state.setStyle(RenderStyle::clonePtr(elementStyle));
     298    state.setParentStyle(RenderStyle::clonePtr(context.parentStyle ? *context.parentStyle : elementStyle));
     299
     300    ElementRuleCollector collector(element, m_ruleSets, context.selectorMatchingState);
     301    collector.setPseudoElementRequest({ elementStyle.styleType() });
     302    if (hasRevert) {
     303        // In the animation origin, 'revert' rolls back the cascaded value to the user level.
     304        // Therefore, we need to collect UA and user rules.
     305        collector.setMedium(&m_mediaQueryEvaluator);
     306        collector.matchUARules();
     307        collector.matchUserRules();
     308    }
     309    collector.addAuthorKeyframeRules(keyframe);
     310    Builder builder(*state.style(), builderContext(state), collector.matchResult(), CascadeLevel::Author);
     311    builder.applyAllProperties();
     312
     313    Adjuster adjuster(document(), *state.parentStyle(), nullptr, nullptr);
     314    adjuster.adjust(*state.style(), state.userAgentAppearanceStyle());
    304315
    305316    return state.takeStyle();
Note: See TracChangeset for help on using the changeset viewer.