Changeset 209352 in webkit


Ignore:
Timestamp:
Dec 5, 2016 2:42:28 PM (7 years ago)
Author:
Antti Koivisto
Message:

keyframes do not work when defined inside a style in a shadowRoot
https://bugs.webkit.org/show_bug.cgi?id=164608
<rdar://problem/29210251>

Reviewed by Darin Adler.

Source/WebCore:

With :host and ::slotted rules a keyframe animation affecting an element can be
defined in a style scope different from the element's own scope. Style resolver
loses the scope information when building the RenderStyle so there is no way
to find out the correct scope.

Fix by passing style scope through to style builder and including a scope association
with the animation name. Find the correct scope when resolving keyframes.

Test: fast/shadow-dom/shadow-host-animation.html

  • css/CSSToStyleMap.cpp:

(WebCore::CSSToStyleMap::mapAnimationName):

Include scope with the name.

  • css/ElementRuleCollector.cpp:

(WebCore::MatchRequest::MatchRequest):
(WebCore::ElementRuleCollector::addMatchedRule):
(WebCore::ElementRuleCollector::sortAndTransferMatchedRules):
(WebCore::ElementRuleCollector::matchAuthorRules):
(WebCore::ElementRuleCollector::matchAuthorShadowPseudoElementRules):
(WebCore::ElementRuleCollector::matchHostPseudoClassRules):
(WebCore::ElementRuleCollector::matchSlottedPseudoElementRules):
(WebCore::ElementRuleCollector::collectMatchingRulesForList):

Replace treeContextOrdinal int with Style::ScopeOrdinal enum carrying the same information.
Simplify the code removing unnecessary use of MatchRequest struct.

(WebCore::compareRules):

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

(WebCore::StyleResolver::MatchResult::addMatchedProperties):
(WebCore::StyleResolver::CascadedProperties::setPropertyInternal):
(WebCore::StyleResolver::CascadedProperties::set):
(WebCore::StyleResolver::CascadedProperties::setDeferred):

Pass styleScopeOrdinal through the cascade mechanism

(WebCore::cascadeLevelForIndex):
(WebCore::StyleResolver::CascadedProperties::addMatch):
(WebCore::StyleResolver::CascadedProperties::addImportantMatches):
(WebCore::StyleResolver::CascadedProperties::Property::apply):

Set styleScopeOrdinal in State when applying style.

(WebCore::StyleResolver::CascadedProperties::addStyleProperties): Deleted.

Move the code to the only caller.

  • css/StyleResolver.h:

(WebCore::StyleResolver::State::styleScopeOrdinal):
(WebCore::StyleResolver::State::setStyleScopeOrdinal):

  • page/animation/CompositeAnimation.cpp:

(WebCore::KeyframeAnimation::KeyframeAnimation):
(WebCore::KeyframeAnimation::resolveKeyframeStyles):

Find the correct scope for resolving keyframes based on the scope ordinal.

  • platform/animation/Animation.cpp:
  • platform/animation/Animation.h:

Add m_nameStyleScopeOrdinal that tells the scope where the name is defined.

  • style/StyleScope.cpp:

(WebCore::Style::Scope::forOrdinal):

Find the scope for ordinal.

  • style/StyleScope.h:

Define ScopeOrdinal types.

(WebCore::Style::operator++):

LayoutTests:

  • fast/shadow-dom/shadow-host-animation-expected.html: Added.
  • fast/shadow-dom/shadow-host-animation.html: Added.
Location:
trunk
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r209349 r209352  
     12016-12-05  Antti Koivisto  <antti@apple.com>
     2
     3        keyframes do not work when defined inside a style in a shadowRoot
     4        https://bugs.webkit.org/show_bug.cgi?id=164608
     5        <rdar://problem/29210251>
     6
     7        Reviewed by Darin Adler.
     8
     9        * fast/shadow-dom/shadow-host-animation-expected.html: Added.
     10        * fast/shadow-dom/shadow-host-animation.html: Added.
     11
    1122016-12-05  Ryan Haddad  <ryanhaddad@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r209351 r209352  
     12016-12-05  Antti Koivisto  <antti@apple.com>
     2
     3        keyframes do not work when defined inside a style in a shadowRoot
     4        https://bugs.webkit.org/show_bug.cgi?id=164608
     5        <rdar://problem/29210251>
     6
     7        Reviewed by Darin Adler.
     8
     9        With :host and ::slotted rules a keyframe animation affecting an element can be
     10        defined in a style scope different from the element's own scope. Style resolver
     11        loses the scope information when building the RenderStyle so there is no way
     12        to find out the correct scope.
     13
     14        Fix by passing style scope through to style builder and including a scope association
     15        with the animation name. Find the correct scope when resolving keyframes.
     16
     17        Test: fast/shadow-dom/shadow-host-animation.html
     18
     19        * css/CSSToStyleMap.cpp:
     20        (WebCore::CSSToStyleMap::mapAnimationName):
     21
     22            Include scope with the name.
     23
     24        * css/ElementRuleCollector.cpp:
     25        (WebCore::MatchRequest::MatchRequest):
     26        (WebCore::ElementRuleCollector::addMatchedRule):
     27        (WebCore::ElementRuleCollector::sortAndTransferMatchedRules):
     28        (WebCore::ElementRuleCollector::matchAuthorRules):
     29        (WebCore::ElementRuleCollector::matchAuthorShadowPseudoElementRules):
     30        (WebCore::ElementRuleCollector::matchHostPseudoClassRules):
     31        (WebCore::ElementRuleCollector::matchSlottedPseudoElementRules):
     32        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
     33
     34            Replace treeContextOrdinal int with Style::ScopeOrdinal enum carrying the same information.
     35            Simplify the code removing unnecessary use of MatchRequest struct.
     36
     37        (WebCore::compareRules):
     38        * css/ElementRuleCollector.h:
     39        * css/StyleResolver.cpp:
     40        (WebCore::StyleResolver::MatchResult::addMatchedProperties):
     41        (WebCore::StyleResolver::CascadedProperties::setPropertyInternal):
     42        (WebCore::StyleResolver::CascadedProperties::set):
     43        (WebCore::StyleResolver::CascadedProperties::setDeferred):
     44
     45            Pass styleScopeOrdinal through the cascade mechanism
     46
     47        (WebCore::cascadeLevelForIndex):
     48        (WebCore::StyleResolver::CascadedProperties::addMatch):
     49        (WebCore::StyleResolver::CascadedProperties::addImportantMatches):
     50        (WebCore::StyleResolver::CascadedProperties::Property::apply):
     51
     52            Set styleScopeOrdinal in State when applying style.
     53
     54        (WebCore::StyleResolver::CascadedProperties::addStyleProperties): Deleted.
     55
     56            Move the code to the only caller.
     57
     58        * css/StyleResolver.h:
     59        (WebCore::StyleResolver::State::styleScopeOrdinal):
     60        (WebCore::StyleResolver::State::setStyleScopeOrdinal):
     61        * page/animation/CompositeAnimation.cpp:
     62        (WebCore::KeyframeAnimation::KeyframeAnimation):
     63        (WebCore::KeyframeAnimation::resolveKeyframeStyles):
     64
     65            Find the correct scope for resolving keyframes based on the scope ordinal.
     66
     67        * platform/animation/Animation.cpp:
     68        * platform/animation/Animation.h:
     69
     70            Add m_nameStyleScopeOrdinal that tells the scope where the name is defined.
     71
     72        * style/StyleScope.cpp:
     73        (WebCore::Style::Scope::forOrdinal):
     74
     75            Find the scope for ordinal.
     76
     77        * style/StyleScope.h:
     78
     79            Define ScopeOrdinal types.
     80
     81        (WebCore::Style::operator++):
     82
    1832016-12-05  Dave Hyatt  <hyatt@apple.com>
    284
  • trunk/Source/WebCore/css/CSSToStyleMap.cpp

    r209325 r209352  
    413413        layer.setIsNoneAnimation(true);
    414414    else
    415         layer.setName(primitiveValue.stringValue());
     415        layer.setName(primitiveValue.stringValue(), m_resolver->state().styleScopeOrdinal());
    416416}
    417417
  • trunk/Source/WebCore/css/ElementRuleCollector.cpp

    r208841 r209352  
    6969class MatchRequest {
    7070public:
    71     MatchRequest(const RuleSet* ruleSet, bool includeEmptyRules = false, int treeContextOrdinal = 0)
     71    MatchRequest(const RuleSet* ruleSet, bool includeEmptyRules = false, Style::ScopeOrdinal styleScopeOrdinal = Style::ScopeOrdinal::Element)
    7272        : ruleSet(ruleSet)
    7373        , includeEmptyRules(includeEmptyRules)
    74         , treeContextOrdinal(treeContextOrdinal)
     74        , styleScopeOrdinal(styleScopeOrdinal)
    7575    {
    7676    }
    7777    const RuleSet* ruleSet;
    7878    const bool includeEmptyRules;
    79     int treeContextOrdinal;
     79    Style::ScopeOrdinal styleScopeOrdinal;
    8080};
    8181
     
    109109}
    110110
    111 inline void ElementRuleCollector::addMatchedRule(const RuleData& ruleData, unsigned specificity, int treeContextOrdinal, StyleResolver::RuleRange& ruleRange)
     111inline void ElementRuleCollector::addMatchedRule(const RuleData& ruleData, unsigned specificity, Style::ScopeOrdinal styleScopeOrdinal, StyleResolver::RuleRange& ruleRange)
    112112{
    113113    // Update our first/last rule indices in the matched rules array.
     
    116116        ruleRange.firstRuleIndex = ruleRange.lastRuleIndex;
    117117
    118     m_matchedRules.append({ &ruleData, specificity, treeContextOrdinal });
     118    m_matchedRules.append({ &ruleData, specificity, styleScopeOrdinal });
    119119}
    120120
     
    194194
    195195    for (const MatchedRule& matchedRule : m_matchedRules) {
    196         m_result.addMatchedProperties(matchedRule.ruleData->rule()->properties(), matchedRule.ruleData->rule(), matchedRule.ruleData->linkMatchType(), matchedRule.ruleData->propertyWhitelistType(), matchedRule.treeContextOrdinal);
     196        m_result.addMatchedProperties(matchedRule.ruleData->rule()->properties(), matchedRule.ruleData->rule(), matchedRule.ruleData->linkMatchType(), matchedRule.ruleData->propertyWhitelistType(), matchedRule.styleScopeOrdinal);
    197197    }
    198198}
     
    205205    StyleResolver::RuleRange ruleRange = m_result.ranges.authorRuleRange();
    206206
    207     // Match global author rules.
    208     MatchRequest matchRequest(&m_authorStyle, includeEmptyRules);
    209     collectMatchingRules(matchRequest, ruleRange);
    210     collectMatchingRulesForRegion(matchRequest, ruleRange);
     207    {
     208        MatchRequest matchRequest(&m_authorStyle, includeEmptyRules);
     209        collectMatchingRules(matchRequest, ruleRange);
     210        collectMatchingRulesForRegion(matchRequest, ruleRange);
     211    }
    211212
    212213    auto* parent = m_element.parentElement();
    213214    if (parent && parent->shadowRoot())
    214         matchSlottedPseudoElementRules(matchRequest, ruleRange);
     215        matchSlottedPseudoElementRules(includeEmptyRules, ruleRange);
    215216
    216217    if (m_element.shadowRoot() && m_pseudoStyleRequest.pseudoId == NOPSEUDO)
    217         matchHostPseudoClassRules(matchRequest, ruleRange);
     218        matchHostPseudoClassRules(includeEmptyRules, ruleRange);
    218219
    219220    if (m_element.isInShadowTree())
    220         matchAuthorShadowPseudoElementRules(matchRequest, ruleRange);
     221        matchAuthorShadowPseudoElementRules(includeEmptyRules, ruleRange);
    221222
    222223    sortAndTransferMatchedRules();
    223224}
    224225
    225 void ElementRuleCollector::matchAuthorShadowPseudoElementRules(const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
     226void ElementRuleCollector::matchAuthorShadowPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange& ruleRange)
    226227{
    227228    ASSERT(m_element.isInShadowTree());
     
    231232    // Look up shadow pseudo elements also from the host scope author style as they are web-exposed.
    232233    auto& hostAuthorRules = Style::Scope::forNode(*shadowRoot.host()).resolver().ruleSets().authorStyle();
    233     MatchRequest hostAuthorRequest { &hostAuthorRules, matchRequest.includeEmptyRules, matchRequest.treeContextOrdinal - 1 };
     234    MatchRequest hostAuthorRequest { &hostAuthorRules, includeEmptyRules, Style::ScopeOrdinal::ContainingHost };
    234235    collectMatchingShadowPseudoElementRules(hostAuthorRequest, ruleRange);
    235236}
    236237
    237 void ElementRuleCollector::matchHostPseudoClassRules(MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
     238void ElementRuleCollector::matchHostPseudoClassRules(bool includeEmptyRules, StyleResolver::RuleRange& ruleRange)
    238239{
    239240    ASSERT(m_element.shadowRoot());
    240 
    241     matchRequest.treeContextOrdinal++;
    242241
    243242    auto& shadowAuthorStyle = m_element.shadowRoot()->styleScope().resolver().ruleSets().authorStyle();
     
    250249
    251250    for (auto& ruleData : shadowHostRules) {
    252         if (ruleData.rule()->properties().isEmpty() && !matchRequest.includeEmptyRules)
     251        if (ruleData.rule()->properties().isEmpty() && !includeEmptyRules)
    253252            continue;
    254253        auto& selector = *ruleData.selector();
     
    256255        if (!selectorChecker.matchHostPseudoClass(selector, m_element, context, specificity))
    257256            continue;
    258         addMatchedRule(ruleData, specificity, matchRequest.treeContextOrdinal, ruleRange);
    259     }
    260 }
    261 
    262 void ElementRuleCollector::matchSlottedPseudoElementRules(MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
    263 {
    264     auto* maybeSlotted = &m_element;
    265     for (auto* hostShadowRoot = m_element.parentNode()->shadowRoot(); hostShadowRoot; hostShadowRoot = maybeSlotted->parentNode()->shadowRoot()) {
    266         auto* slot = hostShadowRoot->findAssignedSlot(*maybeSlotted);
    267         if (!slot)
    268             return;
    269 
    270         matchRequest.treeContextOrdinal++;
    271 
    272         // In nested case the slot may itself be assigned to a slot. Collect ::slotted rules from all the nested trees.
    273         maybeSlotted = slot;
    274         if (!hostShadowRoot->styleScope().resolver().ruleSets().isAuthorStyleDefined())
     257        addMatchedRule(ruleData, specificity, Style::ScopeOrdinal::Shadow, ruleRange);
     258    }
     259}
     260
     261void ElementRuleCollector::matchSlottedPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange& ruleRange)
     262{
     263    auto* slot = m_element.assignedSlot();
     264    auto styleScopeOrdinal = Style::ScopeOrdinal::FirstSlot;
     265
     266    for (; slot; slot = slot->assignedSlot(), ++styleScopeOrdinal) {
     267        auto& styleScope = Style::Scope::forNode(*slot);
     268        if (!styleScope.resolver().ruleSets().isAuthorStyleDefined())
    275269            continue;
    276270        // Find out if there are any ::slotted rules in the shadow tree matching the current slot.
    277271        // FIXME: This is really part of the slot style and could be cached when resolving it.
    278         ElementRuleCollector collector(*slot, hostShadowRoot->styleScope().resolver().ruleSets().authorStyle(), nullptr);
    279         auto slottedPseudoElementRules = collector.collectSlottedPseudoElementRulesForSlot(matchRequest.includeEmptyRules);
     272        ElementRuleCollector collector(*slot, styleScope.resolver().ruleSets().authorStyle(), nullptr);
     273        auto slottedPseudoElementRules = collector.collectSlottedPseudoElementRulesForSlot(includeEmptyRules);
    280274        if (!slottedPseudoElementRules)
    281275            continue;
     
    283277        SetForScope<bool> change(m_isMatchingSlottedPseudoElements, true);
    284278
    285         MatchRequest scopeMatchRequest(nullptr, matchRequest.includeEmptyRules, matchRequest.treeContextOrdinal);
     279        MatchRequest scopeMatchRequest(nullptr, includeEmptyRules, styleScopeOrdinal);
    286280        collectMatchingRulesForList(slottedPseudoElementRules.get(), scopeMatchRequest, ruleRange);
    287281
     
    508502        unsigned specificity;
    509503        if (ruleMatches(ruleData, specificity))
    510             addMatchedRule(ruleData, specificity, matchRequest.treeContextOrdinal, ruleRange);
     504            addMatchedRule(ruleData, specificity, matchRequest.styleScopeOrdinal, ruleRange);
    511505    }
    512506}
     
    514508static inline bool compareRules(MatchedRule r1, MatchedRule r2)
    515509{
    516     // For normal properties the earlier tree wins. This may be reversed by !important which is handled when resolving cascade.
    517     if (r1.treeContextOrdinal != r2.treeContextOrdinal)
    518         return r1.treeContextOrdinal > r2.treeContextOrdinal;
     510    // For normal properties the earlier scope wins. This may be reversed by !important which is handled when resolving cascade.
     511    if (r1.styleScopeOrdinal != r2.styleScopeOrdinal)
     512        return r1.styleScopeOrdinal > r2.styleScopeOrdinal;
    519513
    520514    if (r1.specificity != r2.specificity)
  • trunk/Source/WebCore/css/ElementRuleCollector.h

    r208668 r209352  
    4141    const RuleData* ruleData;
    4242    unsigned specificity;   
    43     int treeContextOrdinal;
     43    Style::ScopeOrdinal styleScopeOrdinal;
    4444};
    4545
     
    7676
    7777    void matchUARules(RuleSet*);
    78     void matchAuthorShadowPseudoElementRules(const MatchRequest&, StyleResolver::RuleRange&);
    79     void matchHostPseudoClassRules(MatchRequest&, StyleResolver::RuleRange&);
    80     void matchSlottedPseudoElementRules(MatchRequest&, StyleResolver::RuleRange&);
     78    void matchAuthorShadowPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
     79    void matchHostPseudoClassRules(bool includeEmptyRules, StyleResolver::RuleRange&);
     80    void matchSlottedPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
    8181
    8282    void collectMatchingShadowPseudoElementRules(const MatchRequest&, StyleResolver::RuleRange&);
     
    9191    void sortAndTransferMatchedRules();
    9292
    93     void addMatchedRule(const RuleData&, unsigned specificity, int treeContextOrdinal, StyleResolver::RuleRange&);
     93    void addMatchedRule(const RuleData&, unsigned specificity, Style::ScopeOrdinal, StyleResolver::RuleRange&);
    9494
    9595    const Element& m_element;
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r209001 r209352  
    188188}
    189189
    190 void StyleResolver::MatchResult::addMatchedProperties(const StyleProperties& properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType, int treeContextOrdinal)
     190void StyleResolver::MatchResult::addMatchedProperties(const StyleProperties& properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType, Style::ScopeOrdinal styleScopeOrdinal)
    191191{
    192192    m_matchedProperties.grow(m_matchedProperties.size() + 1);
     
    195195    newProperties.linkMatchType = linkMatchType;
    196196    newProperties.whitelistType = propertyWhitelistType;
    197     newProperties.treeContextOrdinal = treeContextOrdinal;
     197    newProperties.styleScopeOrdinal = styleScopeOrdinal;
    198198    matchedRules.append(rule);
    199199
    200     // Ordinal is relative to the currently matched element
    201     if (treeContextOrdinal)
     200    if (styleScopeOrdinal != Style::ScopeOrdinal::Element)
    202201        isCacheable = false;
    203202
     
    20612060}
    20622061
    2063 void StyleResolver::CascadedProperties::setPropertyInternal(Property& property, CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel)
     2062void StyleResolver::CascadedProperties::setPropertyInternal(Property& property, CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel, Style::ScopeOrdinal styleScopeOrdinal)
    20642063{
    20652064    ASSERT(linkMatchType <= SelectorChecker::MatchAll);
    20662065    property.id = id;
    20672066    property.level = cascadeLevel;
     2067    property.styleScopeOrdinal = styleScopeOrdinal;
    20682068    if (linkMatchType == SelectorChecker::MatchAll) {
    20692069        property.cssValue[0] = &cssValue;
     
    20742074}
    20752075
    2076 void StyleResolver::CascadedProperties::set(CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel)
     2076void StyleResolver::CascadedProperties::set(CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel, Style::ScopeOrdinal styleScopeOrdinal)
    20772077{
    20782078    if (CSSProperty::isDirectionAwareProperty(id))
     
    20912091            property.id = id;
    20922092            memset(property.cssValue, 0, sizeof(property.cssValue));
    2093             setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel);
     2093            setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel, styleScopeOrdinal);
    20942094            customProperties().set(customValue.name(), property);
    20952095        } else {
    20962096            Property property = customProperties().get(customValue.name());
    2097             setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel);
     2097            setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel, styleScopeOrdinal);
    20982098            customProperties().set(customValue.name(), property);
    20992099        }
     
    21042104        memset(property.cssValue, 0, sizeof(property.cssValue));
    21052105    m_propertyIsPresent.set(id);
    2106     setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel);
    2107 }
    2108 
    2109 void StyleResolver::CascadedProperties::setDeferred(CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel)
     2106    setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel, styleScopeOrdinal);
     2107}
     2108
     2109void StyleResolver::CascadedProperties::setDeferred(CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel, Style::ScopeOrdinal styleScopeOrdinal)
    21102110{
    21112111    ASSERT(!CSSProperty::isDirectionAwareProperty(id));
     
    21142114    Property property;
    21152115    memset(property.cssValue, 0, sizeof(property.cssValue));
    2116     setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel);
     2116    setPropertyInternal(property, id, cssValue, linkMatchType, cascadeLevel, styleScopeOrdinal);
    21172117    m_deferredProperties.append(property);
    21182118}
    21192119
    2120 void StyleResolver::CascadedProperties::addStyleProperties(const StyleProperties& properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType, unsigned linkMatchType, CascadeLevel cascadeLevel)
    2121 {
    2122     for (unsigned i = 0, count = properties.propertyCount(); i < count; ++i) {
    2123         auto current = properties.propertyAt(i);
     2120static CascadeLevel cascadeLevelForIndex(const StyleResolver::MatchResult& matchResult, int index)
     2121{
     2122    if (index >= matchResult.ranges.firstUARule && index <= matchResult.ranges.lastUARule)
     2123        return UserAgentLevel;
     2124    if (index >= matchResult.ranges.firstUserRule && index <= matchResult.ranges.lastUserRule)
     2125        return UserLevel;
     2126    return AuthorLevel;
     2127}
     2128
     2129void StyleResolver::CascadedProperties::addMatch(const MatchResult& matchResult, unsigned index, bool isImportant, bool inheritedOnly)
     2130{
     2131    auto& matchedProperties = matchResult.matchedProperties()[index];
     2132    auto& styleProperties = *matchedProperties.properties;
     2133
     2134    auto propertyWhitelistType = static_cast<PropertyWhitelistType>(matchedProperties.whitelistType);
     2135    auto cascadeLevel = cascadeLevelForIndex(matchResult, index);
     2136
     2137    for (unsigned i = 0, count = styleProperties.propertyCount(); i < count; ++i) {
     2138        auto current = styleProperties.propertyAt(i);
    21242139        if (isImportant != current.isImportant())
    21252140            continue;
     
    21402155
    21412156        if (shouldApplyPropertyInParseOrder(propertyID))
    2142             setDeferred(propertyID, *current.value(), linkMatchType, cascadeLevel);
     2157            setDeferred(propertyID, *current.value(), matchedProperties.linkMatchType, cascadeLevel, matchedProperties.styleScopeOrdinal);
    21432158        else
    2144             set(propertyID, *current.value(), linkMatchType, cascadeLevel);
    2145     }
    2146 }
    2147 
    2148 static CascadeLevel cascadeLevelForIndex(const StyleResolver::MatchResult& matchResult, int index)
    2149 {
    2150     if (index >= matchResult.ranges.firstUARule && index <= matchResult.ranges.lastUARule)
    2151         return UserAgentLevel;
    2152     if (index >= matchResult.ranges.firstUserRule && index <= matchResult.ranges.lastUserRule)
    2153         return UserLevel;
    2154     return AuthorLevel;
    2155 }
    2156 
    2157 void StyleResolver::CascadedProperties::addMatch(const MatchResult& matchResult, unsigned index, bool isImportant, bool inheritedOnly)
    2158 {
    2159     const MatchedProperties& matchedProperties = matchResult.matchedProperties()[index];
    2160 
    2161     auto propertyWhitelistType = static_cast<PropertyWhitelistType>(matchedProperties.whitelistType);
    2162     auto cascadeLevel = cascadeLevelForIndex(matchResult, index);
    2163 
    2164     addStyleProperties(*matchedProperties.properties, isImportant, inheritedOnly, propertyWhitelistType, matchedProperties.linkMatchType, cascadeLevel);
     2159            set(propertyID, *current.value(), matchedProperties.linkMatchType, cascadeLevel, matchedProperties.styleScopeOrdinal);
     2160    }
    21652161}
    21662162
     
    21902186    struct IndexAndOrdinal {
    21912187        int index;
    2192         int ordinal;
     2188        Style::ScopeOrdinal ordinal;
    21932189    };
    21942190    Vector<IndexAndOrdinal> shadowTreeMatches;
     
    22002196            continue;
    22012197
    2202         if (matchedProperties.treeContextOrdinal) {
    2203             shadowTreeMatches.append({ i, matchedProperties.treeContextOrdinal });
     2198        if (matchedProperties.styleScopeOrdinal != Style::ScopeOrdinal::Element) {
     2199            shadowTreeMatches.append({ i, matchedProperties.styleScopeOrdinal });
    22042200            continue;
    22052201        }
     
    22312227    State& state = resolver.state();
    22322228    state.setCascadeLevel(level);
     2229    state.setStyleScopeOrdinal(styleScopeOrdinal);
    22332230
    22342231    if (cssValue[SelectorChecker::MatchDefault]) {
  • trunk/Source/WebCore/css/StyleResolver.h

    r208915 r209352  
    3333#include "SelectorChecker.h"
    3434#include "StylePendingResources.h"
     35#include "StyleScope.h"
    3536#include <bitset>
    3637#include <memory>
     
    251252        uint16_t linkMatchType;
    252253        uint16_t whitelistType;
    253         int treeContextOrdinal;
     254        Style::ScopeOrdinal styleScopeOrdinal;
    254255    };
    255256
     
    262263        const Vector<MatchedProperties, 64>& matchedProperties() const { return m_matchedProperties; }
    263264
    264         void addMatchedProperties(const StyleProperties&, StyleRule* = nullptr, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone, int treeContextOrdinal = 0);
     265        void addMatchedProperties(const StyleProperties&, StyleRule* = nullptr, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone, Style::ScopeOrdinal = Style::ScopeOrdinal::Element);
    265266    private:
    266267        Vector<MatchedProperties, 64> m_matchedProperties;
     
    277278            CSSPropertyID id;
    278279            CascadeLevel level;
     280            Style::ScopeOrdinal styleScopeOrdinal;
    279281            CSSValue* cssValue[3];
    280282        };
     
    285287        void addNormalMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false);
    286288        void addImportantMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false);
    287 
    288         void set(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel);
    289         void setDeferred(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel);
    290289
    291290        void applyDeferredProperties(StyleResolver&, const MatchResult*);
     
    297296    private:
    298297        void addMatch(const MatchResult&, unsigned index, bool isImportant, bool inheritedOnly);
    299         void addStyleProperties(const StyleProperties&, bool isImportant, bool inheritedOnly, PropertyWhitelistType, unsigned linkMatchType, CascadeLevel);
    300         static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel);
     298        void set(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal);
     299        void setDeferred(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal);
     300        static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal);
    301301
    302302        Property m_properties[numCSSProperties + 2];
     
    405405        CascadeLevel cascadeLevel() const { return m_cascadeLevel; }
    406406        void setCascadeLevel(CascadeLevel level) { m_cascadeLevel = level; }
    407        
     407        Style::ScopeOrdinal styleScopeOrdinal() const { return m_styleScopeOrdinal; }
     408        void setStyleScopeOrdinal(Style::ScopeOrdinal styleScopeOrdinal) { m_styleScopeOrdinal = styleScopeOrdinal; }
     409
    408410        CascadedProperties* authorRollback() const { return m_authorRollback.get(); }
    409411        CascadedProperties* userRollback() const { return m_userRollback.get(); }
     
    440442       
    441443        CascadeLevel m_cascadeLevel { UserAgentLevel };
     444        Style::ScopeOrdinal m_styleScopeOrdinal { Style::ScopeOrdinal::Element };
    442445        std::unique_ptr<CascadedProperties> m_authorRollback;
    443446        std::unique_ptr<CascadedProperties> m_userRollback;
  • trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp

    r208314 r209352  
    4040#include "StylePendingResources.h"
    4141#include "StyleResolver.h"
     42#include "StyleScope.h"
    4243#include "WillChangeData.h"
    4344
     
    364365    auto& element = *m_object->element();
    365366
    366     element.styleResolver().keyframeStylesForAnimation(*m_object->element(), m_unanimatedStyle.get(), m_keyframes);
     367    if (auto* styleScope = Style::Scope::forOrdinal(element, m_animation->nameStyleScopeOrdinal()))
     368        styleScope->resolver().keyframeStylesForAnimation(*m_object->element(), m_unanimatedStyle.get(), m_keyframes);
    367369
    368370    // Ensure resource loads for all the frames.
  • trunk/Source/WebCore/platform/animation/Animation.cpp

    r194819 r209352  
    6060    : RefCounted<Animation>()
    6161    , m_name(o.m_name)
     62    , m_nameStyleScopeOrdinal(o.m_nameStyleScopeOrdinal)
    6263    , m_property(o.m_property)
    6364    , m_mode(o.m_mode)
     
    9192{
    9293    m_name = o.m_name;
     94    m_nameStyleScopeOrdinal = o.m_nameStyleScopeOrdinal;
    9395    m_property = o.m_property;
    9496    m_mode = o.m_mode;
     
    131133{
    132134    bool result = m_name == other.m_name
     135        && m_nameStyleScopeOrdinal == other.m_nameStyleScopeOrdinal
    133136        && m_property == other.m_property
    134137        && m_mode == other.m_mode
  • trunk/Source/WebCore/platform/animation/Animation.h

    r186894 r209352  
    3333#include "CSSPropertyNames.h"
    3434#include "RenderStyleConstants.h"
     35#include "StyleScope.h"
    3536#include "TimingFunction.h"
    3637#include <wtf/PassRefPtr.h>
     
    136137    double iterationCount() const { return m_iterationCount; }
    137138    const String& name() const { return m_name; }
     139    Style::ScopeOrdinal nameStyleScopeOrdinal() const { return m_nameStyleScopeOrdinal; }
    138140    EAnimPlayState playState() const { return static_cast<EAnimPlayState>(m_playState); }
    139141    CSSPropertyID property() const { return m_property; }
     
    149151    void setFillMode(unsigned f) { m_fillMode = f; m_fillModeSet = true; }
    150152    void setIterationCount(double c) { m_iterationCount = c; m_iterationCountSet = true; }
    151     void setName(const String& n) { m_name = n; m_nameSet = true; }
     153    void setName(const String& name, Style::ScopeOrdinal scope = Style::ScopeOrdinal::Element)
     154    {
     155        m_name = name;
     156        m_nameStyleScopeOrdinal = scope;
     157        m_nameSet = true;
     158    }
    152159    void setPlayState(EAnimPlayState d) { m_playState = d; m_playStateSet = true; }
    153160    void setProperty(CSSPropertyID t) { m_property = t; m_propertySet = true; }
     
    177184   
    178185    String m_name;
     186    Style::ScopeOrdinal m_nameStyleScopeOrdinal { Style::ScopeOrdinal::Element };
    179187    CSSPropertyID m_property;
    180188    AnimationMode m_mode;
  • trunk/Source/WebCore/style/StyleScope.cpp

    r208982 r209352  
    3535#include "HTMLIFrameElement.h"
    3636#include "HTMLLinkElement.h"
     37#include "HTMLSlotElement.h"
    3738#include "HTMLStyleElement.h"
    3839#include "InspectorInstrumentation.h"
     
    125126        return shadowRoot->styleScope();
    126127    return node.document().styleScope();
     128}
     129
     130Scope* Scope::forOrdinal(Element& element, ScopeOrdinal ordinal)
     131{
     132    switch (ordinal) {
     133    case ScopeOrdinal::Element:
     134        return &forNode(element);
     135    case ScopeOrdinal::ContainingHost: {
     136        auto* containingShadowRoot = element.containingShadowRoot();
     137        if (!containingShadowRoot)
     138            return nullptr;
     139        return &forNode(*containingShadowRoot->host());
     140    }
     141    case ScopeOrdinal::Shadow: {
     142        auto* shadowRoot = element.shadowRoot();
     143        if (!shadowRoot)
     144            return nullptr;
     145        return &shadowRoot->styleScope();
     146    }
     147    default: {
     148        ASSERT(ordinal >= ScopeOrdinal::FirstSlot);
     149        auto slotIndex = ScopeOrdinal::FirstSlot;
     150        for (auto* slot = element.assignedSlot(); slot; slot = slot->assignedSlot(), ++slotIndex) {
     151            if (slotIndex == ordinal)
     152                return &forNode(*slot);
     153        }
     154        return nullptr;
     155    }
     156    }
    127157}
    128158
  • trunk/Source/WebCore/style/StyleScope.h

    r208985 r209352  
    4141class CSSStyleSheet;
    4242class Document;
     43class Element;
    4344class Node;
    4445class StyleResolver;
     
    5051
    5152namespace Style {
     53
     54// This is used to identify style scopes that can affect an element.
     55// Scopes are in tree-of-trees order. Styles from earlier scopes win over later ones (modulo !important).
     56enum class ScopeOrdinal : int {
     57    ContainingHost = -1, // Author-exposed UA pseudo classes from the host tree scope.
     58    Element = 0, // Normal rules in the same tree where the element is.
     59    FirstSlot = 1, // ::slotted rules in the parent's shadow tree. Values greater than FirstSlot indicate subsequent slots in the chain.
     60    Shadow = std::numeric_limits<int>::max(), // :host rules in element's own shadow tree.
     61};
    5262
    5363class Scope {
     
    103113
    104114    static Scope& forNode(Node&);
     115    static Scope* forOrdinal(Element&, ScopeOrdinal);
    105116
    106117private:
     
    165176}
    166177
     178inline ScopeOrdinal& operator++(ScopeOrdinal& ordinal)
     179{
     180    ASSERT(ordinal < ScopeOrdinal::Shadow);
     181    return ordinal = static_cast<ScopeOrdinal>(static_cast<int>(ordinal) + 1);
     182}
     183
    167184}
    168185}
Note: See TracChangeset for help on using the changeset viewer.