Changeset 284973 in webkit


Ignore:
Timestamp:
Oct 28, 2021 1:59:03 AM (9 months ago)
Author:
Antti Koivisto
Message:

Support ::before and ::after pseudo elements after ::slotted
https://bugs.webkit.org/show_bug.cgi?id=178237

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

Update the tests from WPT repo.

  • web-platform-tests/css/css-scoping/host-context-parsing-expected.txt: Added.
  • web-platform-tests/css/css-scoping/host-context-parsing.html: Added.
  • web-platform-tests/css/css-scoping/host-parsing-expected.txt: Added.
  • web-platform-tests/css/css-scoping/host-parsing.html: Added.
  • web-platform-tests/css/css-scoping/keyframes-001-expected.txt:
  • web-platform-tests/css/css-scoping/shadow-shared-style-cache-001-expected.txt: Added.
  • web-platform-tests/css/css-scoping/shadow-shared-style-cache-001.html: Added.
  • web-platform-tests/css/css-scoping/slotted-link-expected.txt:
  • web-platform-tests/css/css-scoping/slotted-parsing-expected.txt:
  • web-platform-tests/css/css-scoping/slotted-parsing.html:
  • web-platform-tests/css/css-scoping/w3c-import.log:

Source/WebCore:

Change the way we resolve ::slotted to improve compatibility. We now traverse through the assigned slot chain in
a single pass, similar to ::part matching.

  • css/CSSSelector.cpp:

(WebCore::CSSSelector::selectorText const):

  • css/CSSSelector.h:

Add a new selection relation ShadowSlotted, similar to the existing ShadowDescendant and ShadowPartDescendant,
for switching scopes during selector matching.

  • css/SelectorChecker.cpp:

(WebCore::SelectorChecker::matchRecursively const):

Find the right scope to continue matching on ShadowSlotted relation. Pass in the scope ordinal to find the scope.

(WebCore::SelectorChecker::checkOne const):

Match the ::slotted() element.

  • css/SelectorChecker.h:
  • css/SelectorFilter.cpp:

(WebCore::collectSelectorHashes):

  • css/parser/CSSParserSelector.h:

(WebCore::CSSParserSelector::needsImplicitShadowCombinatorForMatching const):

  • css/parser/CSSSelectorParser.cpp:

(WebCore::isPseudoClassValidAfterPseudoElement):
(WebCore::isTreeAbidingPseudoElement):

Add a spec-termed helper.

(WebCore::isSimpleSelectorValidAfterPseudoElement):
(WebCore::CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator):

Insert ShadowSlotted relation for ::slotted().

  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
(WebCore::SelectorCompiler::constructFragmentsInternal):

  • style/ElementRuleCollector.cpp:

(WebCore::Style::ElementRuleCollector::clearMatchedRules):
(WebCore::Style::ElementRuleCollector::matchSlottedPseudoElementRules):

Simply get the rules from scopes in the assinged slot chaing and match against them.
No need for two passes.

(WebCore::Style::ElementRuleCollector::ruleMatches):
(WebCore::Style::ElementRuleCollector::collectMatchingRulesForList):
(WebCore::Style::ElementRuleCollector::collectSlottedPseudoElementRulesForSlot): Deleted.

Not needed anymore.

(WebCore::Style::findSlottedPseudoElementSelector): Deleted.

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

(WebCore::Style::RuleFeatureSet::computeNextMatchElement):

LayoutTests:

Location:
trunk
Files:
6 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r284972 r284973  
     12021-10-28  Antti Koivisto  <antti@apple.com>
     2
     3        Support ::before and ::after pseudo elements after ::slotted
     4        https://bugs.webkit.org/show_bug.cgi?id=178237
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * TestExpectations:
     9
    1102021-10-28  Carlos Garcia Campos  <cgarcia@igalia.com>
    211
  • trunk/LayoutTests/TestExpectations

    r284921 r284973  
    30983098imported/w3c/web-platform-tests/css/css-display/run-in/run-in-text-between-005.xht [ ImageOnlyFailure ]
    30993099imported/w3c/web-platform-tests/css/css-pseudo/placeholder-input-number.html [ ImageOnlyFailure ]
    3100 imported/w3c/web-platform-tests/css/css-scoping/slotted-with-pseudo-element.html [ ImageOnlyFailure ]
    31013100imported/w3c/web-platform-tests/css/css-text-decor/text-emphasis-color-001.xht [ ImageOnlyFailure ]
    31023101imported/w3c/web-platform-tests/css/css-text-decor/text-emphasis-position-above-left-001.xht [ ImageOnlyFailure ]
     
    32093208webkit.org/b/190032 compositing/layer-creation/translate-transition-overlap.html [ Failure ]
    32103209webkit.org/b/190032 imported/w3c/web-platform-tests/css/css-logical/animation-003.tentative.html [ Failure ]
    3211 webkit.org/b/190032 imported/w3c/web-platform-tests/css/css-scoping/keyframes-001.html [ Failure ]
    32123210
    32133211# FIXME: Need to implement MediaRecorder dataavailable event to support these testcases
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r284961 r284973  
     12021-10-28  Antti Koivisto  <antti@apple.com>
     2
     3        Support ::before and ::after pseudo elements after ::slotted
     4        https://bugs.webkit.org/show_bug.cgi?id=178237
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Update the tests from WPT repo.
     9
     10        * web-platform-tests/css/css-scoping/host-context-parsing-expected.txt: Added.
     11        * web-platform-tests/css/css-scoping/host-context-parsing.html: Added.
     12        * web-platform-tests/css/css-scoping/host-parsing-expected.txt: Added.
     13        * web-platform-tests/css/css-scoping/host-parsing.html: Added.
     14        * web-platform-tests/css/css-scoping/keyframes-001-expected.txt:
     15        * web-platform-tests/css/css-scoping/shadow-shared-style-cache-001-expected.txt: Added.
     16        * web-platform-tests/css/css-scoping/shadow-shared-style-cache-001.html: Added.
     17        * web-platform-tests/css/css-scoping/slotted-link-expected.txt:
     18        * web-platform-tests/css/css-scoping/slotted-parsing-expected.txt:
     19        * web-platform-tests/css/css-scoping/slotted-parsing.html:
     20        * web-platform-tests/css/css-scoping/w3c-import.log:
     21
    1222021-10-27  Kiet Ho  <tho22@apple.com>
    223
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/keyframes-001-expected.txt

    r264522 r284973  
    11
    2 FAIL @keyframes applies in the shadow tree assert_equals: expected 1 but got 0
     2PASS @keyframes applies in the shadow tree
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/slotted-link-expected.txt

    r232903 r284973  
    11This link should be green.
    22
    3 FAIL Check that we match :link and not :visited for slotted anchor. assert_equals: Unvisited link should be green. expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
     3PASS Check that we match :link and not :visited for slotted anchor.
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/slotted-parsing-expected.txt

    r267650 r284973  
    88PASS "::slotted(*):host(div)" should be an invalid selector
    99PASS "::slotted(*):hover" should be an invalid selector
    10 PASS "::slotted(*):is(:hover)" should be an invalid selector
    11 PASS "::slotted(*):where(:hover)" should be an invalid selector
    12 PASS "::slotted(*):is(#id)" should be an invalid selector
    13 PASS "::slotted(*):where(#id)" should be an invalid selector
    1410PASS "::slotted(*):read-only" should be an invalid selector
    1511PASS "::slotted(*)::slotted(*)" should be an invalid selector
     
    2016PASS "::slotted([attr]:hover)" should be a valid selector
    2117PASS "::slotted(:not(.a))" should be a valid selector
    22 FAIL "::slotted(*)::before" should be a valid selector The string did not match the expected pattern.
    23 FAIL "::slotted(*)::after" should be a valid selector The string did not match the expected pattern.
     18FAIL "::slotted(*):is()" should be a valid selector The string did not match the expected pattern.
     19FAIL "::slotted(*):is(:hover)" should be a valid selector The string did not match the expected pattern.
     20FAIL "::slotted(*):is(#id)" should be a valid selector The string did not match the expected pattern.
     21FAIL "::slotted(*):where()" should be a valid selector The string did not match the expected pattern.
     22FAIL "::slotted(*):where(:hover)" should be a valid selector The string did not match the expected pattern.
     23FAIL "::slotted(*):where(#id)" should be a valid selector The string did not match the expected pattern.
     24PASS "::slotted(*)::before" should be a valid selector
     25PASS "::slotted(*)::after" should be a valid selector
    2426FAIL "::slotted(*)::placeholder" should be a valid selector The string did not match the expected pattern.
    25 FAIL "::slotted(*)::marker" should be a valid selector The string did not match the expected pattern.
     27PASS "::slotted(*)::marker" should be a valid selector
    2628PASS "::slotted(*)::first-line" should be an invalid selector
    2729PASS "::slotted(*)::first-letter" should be an invalid selector
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/slotted-parsing.html

    r264522 r284973  
    1818  test_invalid_selector("::slotted(*):host(div)");
    1919  test_invalid_selector("::slotted(*):hover");
    20   test_invalid_selector("::slotted(*):is(:hover)");
    21   test_invalid_selector("::slotted(*):where(:hover)");
    22   test_invalid_selector("::slotted(*):is(#id)");
    23   test_invalid_selector("::slotted(*):where(#id)");
    2420  test_invalid_selector("::slotted(*):read-only");
    2521  test_invalid_selector("::slotted(*)::slotted(*)");
     
    3127  test_valid_selector("::slotted([attr]:hover)");
    3228  test_valid_selector("::slotted(:not(.a))");
     29
     30  test_valid_selector("::slotted(*):is()");
     31  test_valid_selector("::slotted(*):is(:hover)", "::slotted(*):is()");
     32  test_valid_selector("::slotted(*):is(#id)", "::slotted(*):is()");
     33
     34  test_valid_selector("::slotted(*):where()");
     35  test_valid_selector("::slotted(*):where(:hover)", "::slotted(*):where()");
     36  test_valid_selector("::slotted(*):where(#id)", "::slotted(*):where()");
    3337
    3438  // Allow tree-abiding pseudo elements after ::slotted
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/w3c-import.log

    r281692 r284973  
    5353/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/css-scoping-shadow-with-rules-no-style-leak.html
    5454/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/css-scoping-shadow-with-rules.html
     55/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-context-parsing.html
    5556/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-context-specificity-001-expected.html
    5657/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-context-specificity-001.html
     
    7071/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-nested-001-expected.html
    7172/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-nested-001.html
     73/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-parsing.html
    7274/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-slotted-001-expected.html
    7375/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/host-slotted-001.html
     
    126128/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/shadow-root-insert-into-document-expected.html
    127129/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/shadow-root-insert-into-document.html
     130/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/shadow-shared-style-cache-001.html
    128131/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/slot-non-html-display-value.html
    129132/LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/slotted-invalidation.html
  • trunk/Source/WebCore/ChangeLog

    r284972 r284973  
     12021-10-28  Antti Koivisto  <antti@apple.com>
     2
     3        Support ::before and ::after pseudo elements after ::slotted
     4        https://bugs.webkit.org/show_bug.cgi?id=178237
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Change the way we resolve ::slotted to improve compatibility. We now traverse through the assigned slot chain in
     9        a single pass, similar to ::part matching.
     10
     11        * css/CSSSelector.cpp:
     12        (WebCore::CSSSelector::selectorText const):
     13        * css/CSSSelector.h:
     14
     15        Add a new selection relation ShadowSlotted, similar to the existing ShadowDescendant and ShadowPartDescendant,
     16        for switching scopes during selector matching.
     17
     18        * css/SelectorChecker.cpp:
     19        (WebCore::SelectorChecker::matchRecursively const):
     20
     21        Find the right scope to continue matching on ShadowSlotted relation. Pass in the scope ordinal to find the scope.
     22
     23        (WebCore::SelectorChecker::checkOne const):
     24
     25        Match the ::slotted() element.
     26
     27        * css/SelectorChecker.h:
     28        * css/SelectorFilter.cpp:
     29        (WebCore::collectSelectorHashes):
     30        * css/parser/CSSParserSelector.h:
     31        (WebCore::CSSParserSelector::needsImplicitShadowCombinatorForMatching const):
     32        * css/parser/CSSSelectorParser.cpp:
     33        (WebCore::isPseudoClassValidAfterPseudoElement):
     34        (WebCore::isTreeAbidingPseudoElement):
     35
     36        Add a spec-termed helper.
     37
     38        (WebCore::isSimpleSelectorValidAfterPseudoElement):
     39        (WebCore::CSSSelectorParser::splitCompoundAtImplicitShadowCrossingCombinator):
     40
     41        Insert ShadowSlotted relation for ::slotted().
     42
     43        * cssjit/SelectorCompiler.cpp:
     44        (WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
     45        (WebCore::SelectorCompiler::constructFragmentsInternal):
     46        * style/ElementRuleCollector.cpp:
     47        (WebCore::Style::ElementRuleCollector::clearMatchedRules):
     48        (WebCore::Style::ElementRuleCollector::matchSlottedPseudoElementRules):
     49
     50        Simply get the rules from scopes in the assinged slot chaing and match against them.
     51        No need for two passes.
     52
     53        (WebCore::Style::ElementRuleCollector::ruleMatches):
     54        (WebCore::Style::ElementRuleCollector::collectMatchingRulesForList):
     55        (WebCore::Style::ElementRuleCollector::collectSlottedPseudoElementRulesForSlot): Deleted.
     56
     57        Not needed anymore.
     58
     59        (WebCore::Style::findSlottedPseudoElementSelector): Deleted.
     60        * style/ElementRuleCollector.h:
     61        * style/RuleFeature.cpp:
     62        (WebCore::Style::RuleFeatureSet::computeNextMatchElement):
     63
    1642021-10-28  Carlos Garcia Campos  <cgarcia@igalia.com>
    265
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r284865 r284973  
    824824        case CSSSelector::ShadowDescendant:
    825825        case CSSSelector::ShadowPartDescendant:
     826        case CSSSelector::ShadowSlotted:
    826827            builder.append(rightSide);
    827828            return tagHistory->selectorText(builder.toString());
  • trunk/Source/WebCore/css/CSSSelector.h

    r284865 r284973  
    8888            IndirectAdjacent,
    8989            ShadowDescendant,
    90             ShadowPartDescendant
     90            ShadowPartDescendant,
     91            ShadowSlotted
    9192        };
    9293
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r284865 r284973  
    409409        }
    410410    case CSSSelector::ShadowDescendant:
    411     case CSSSelector::ShadowPartDescendant:
    412         {
    413             // When matching foo::part(bar) we skip directly to the tree of element 'foo'.
    414             auto* shadowHost = relation == CSSSelector::ShadowPartDescendant ? checkingContext.shadowHostInPartRuleScope : context.element->shadowHost();
    415             if (!shadowHost)
    416                 return MatchResult::fails(Match::SelectorFailsCompletely);
    417             nextContext.element = shadowHost;
    418             nextContext.firstSelectorOfTheFragment = nextContext.selector;
    419             nextContext.isSubjectOrAdjacentElement = false;
    420             PseudoIdSet ignoreDynamicPseudo;
    421             MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo);
    422 
    423             return MatchResult::updateWithMatchType(result, matchType);
    424         }
     411    case CSSSelector::ShadowPartDescendant: {
     412        // When matching foo::part(bar) we skip directly to the tree of element 'foo'.
     413        auto* shadowHost = relation == CSSSelector::ShadowPartDescendant ? checkingContext.shadowHostInPartRuleScope : context.element->shadowHost();
     414        if (!shadowHost)
     415            return MatchResult::fails(Match::SelectorFailsCompletely);
     416        nextContext.element = shadowHost;
     417        nextContext.firstSelectorOfTheFragment = nextContext.selector;
     418        nextContext.isSubjectOrAdjacentElement = false;
     419        PseudoIdSet ignoreDynamicPseudo;
     420        MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo);
     421
     422        return MatchResult::updateWithMatchType(result, matchType);
     423    }
     424    case CSSSelector::ShadowSlotted: {
     425        auto* slot = context.element->assignedSlot();
     426        if (!slot)
     427            return MatchResult::fails(Match::SelectorFailsCompletely);
     428        // We continue matching in the scope where this rule came from.
     429        auto scopeDepth = static_cast<int>(checkingContext.styleScopeOrdinal);
     430        while (--scopeDepth && slot->assignedSlot())
     431            slot = slot->assignedSlot();
     432        if (scopeDepth)
     433            return MatchResult::fails(Match::SelectorFailsCompletely);
     434
     435        nextContext.element = slot;
     436        nextContext.firstSelectorOfTheFragment = nextContext.selector;
     437        nextContext.isSubjectOrAdjacentElement = false;
     438        PseudoIdSet ignoreDynamicPseudo;
     439        MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo);
     440
     441        return MatchResult::updateWithMatchType(result, matchType);
     442    }
    425443    }
    426444
     
    11511169        }
    11521170#endif
    1153         case CSSSelector::PseudoElementSlotted:
    1154             // We see ::slotted() pseudo elements when collecting slotted rules from the slot shadow tree only.
    1155             ASSERT(checkingContext.resolvingMode == Mode::CollectingRules);
    1156             return is<HTMLSlotElement>(element);
    1157 
     1171        case CSSSelector::PseudoElementSlotted: {
     1172            if (!context.element->assignedSlot())
     1173                return false;
     1174            auto* subselector = context.selector->selectorList()->first();
     1175            LocalContext subcontext(context);
     1176            subcontext.selector = subselector;
     1177            subcontext.firstSelectorOfTheFragment = subselector;
     1178            subcontext.pseudoElementEffective = false;
     1179            subcontext.inFunctionalPseudoClass = true;
     1180            PseudoIdSet ignoredDynamicPseudo;
     1181            return matchRecursively(checkingContext, subcontext, ignoredDynamicPseudo).match == Match::SelectorMatches;
     1182        }
    11581183        case CSSSelector::PseudoElementPart: {
    11591184            auto translatePartNameToRuleScope = [&](AtomString partName) {
  • trunk/Source/WebCore/css/SelectorChecker.h

    r278253 r284973  
    3131#include "Element.h"
    3232#include "StyleRelations.h"
     33#include "StyleScopeOrdinal.h"
    3334
    3435namespace WebCore {
     
    9697        bool isMatchingHostPseudoClass { false };
    9798        const Element* shadowHostInPartRuleScope { nullptr };
     99        Style::ScopeOrdinal styleScopeOrdinal { Style::ScopeOrdinal::Element };
    98100
    99101        // FIXME: It would be nicer to have a separate object for return values. This requires some more work in the selector compiler.
  • trunk/Source/WebCore/css/SelectorFilter.cpp

    r284865 r284973  
    196196        case CSSSelector::ShadowDescendant:
    197197        case CSSSelector::ShadowPartDescendant:
     198        case CSSSelector::ShadowSlotted:
    198199            skipOverSubselectors = true;
    199200            break;
  • trunk/Source/WebCore/css/parser/CSSParserSelector.h

    r284865 r284973  
    104104#endif
    105105            || pseudoElementType() == CSSSelector::PseudoElementPart
     106            || pseudoElementType() == CSSSelector::PseudoElementSlotted
    106107            || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed);
    107108}
  • trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp

    r284865 r284973  
    344344    case CSSSelector::PseudoElementPart:
    345345        return !isTreeStructuralPseudoClass(pseudoClass);
     346    case CSSSelector::PseudoElementSlotted:
     347        // FIXME: A WPT indicates :is/:where should be parsed but reduce to nothing as their content is not legal in the context.
     348        return false;
    346349    case CSSSelector::PseudoElementResizer:
    347350    case CSSSelector::PseudoElementScrollbar:
     
    362365}
    363366
     367static bool isTreeAbidingPseudoElement(CSSSelector::PseudoElementType pseudoElementType)
     368{
     369    switch (pseudoElementType) {
     370    // FIXME: This list should also include ::placeholder and ::file-selector-button
     371    case CSSSelector::PseudoElementBefore:
     372    case CSSSelector::PseudoElementAfter:
     373    case CSSSelector::PseudoElementMarker:
     374        return true;
     375    default:
     376        return false;
     377    }
     378}
     379
    364380static bool isSimpleSelectorValidAfterPseudoElement(const CSSParserSelector& simpleSelector, CSSSelector::PseudoElementType compoundPseudoElement)
    365381{
     
    368384    if (compoundPseudoElement == CSSSelector::PseudoElementPart) {
    369385        if (simpleSelector.match() == CSSSelector::PseudoElement && simpleSelector.pseudoElementType() != CSSSelector::PseudoElementPart)
     386            return true;
     387    }
     388    if (compoundPseudoElement == CSSSelector::PseudoElementSlotted) {
     389        if (simpleSelector.match() == CSSSelector::PseudoElement && isTreeAbidingPseudoElement(simpleSelector.pseudoElementType()))
    370390            return true;
    371391    }
     
    10601080    bool isPart = splitAfter->tagHistory()->match() == CSSSelector::PseudoElement && splitAfter->tagHistory()->pseudoElementType() == CSSSelector::PseudoElementPart;
    10611081
     1082    // ::slotted() combines with other pseudo elements.
     1083    bool isSlotted = splitAfter->tagHistory()->match() == CSSSelector::PseudoElement && splitAfter->tagHistory()->pseudoElementType() == CSSSelector::PseudoElementSlotted;
     1084
    10621085    std::unique_ptr<CSSParserSelector> secondCompound;
    10631086    if (context.mode == UASheetMode || isPart) {
     
    10691092        secondCompound = splitAfter->releaseTagHistory();
    10701093
    1071     secondCompound->appendTagHistory(isPart ? CSSSelector::ShadowPartDescendant : CSSSelector::ShadowDescendant, WTFMove(compoundSelector));
     1094    auto relation = [&] {
     1095        if (isSlotted)
     1096            return CSSSelector::ShadowSlotted;
     1097        if (isPart)
     1098            return CSSSelector::ShadowPartDescendant;
     1099        return CSSSelector::ShadowDescendant;
     1100    }();
     1101    secondCompound->appendTagHistory(relation, WTFMove(compoundSelector));
    10721102    return secondCompound;
    10731103}
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r284865 r284973  
    502502    case CSSSelector::ShadowDescendant:
    503503    case CSSSelector::ShadowPartDescendant:
     504    case CSSSelector::ShadowSlotted:
    504505        ASSERT_NOT_REACHED();
    505506    }
     
    13271328            return FunctionType::CannotCompile;
    13281329
     1330        if (relation == CSSSelector::ShadowSlotted)
     1331            return FunctionType::CannotCompile;
     1332
    13291333        if (relation == CSSSelector::DirectAdjacent || relation == CSSSelector::IndirectAdjacent) {
    13301334            FunctionType relationFunctionType = FunctionType::SelectorCheckerWithCheckingContext;
  • trunk/Source/WebCore/style/ElementRuleCollector.cpp

    r284466 r284973  
    121121{
    122122    m_matchedRules.clear();
    123     m_keepAliveSlottedPseudoElementRules.clear();
    124123    m_matchedRuleTransferIndex = 0;
    125124}
     
    284283        if (!styleScope.resolver().ruleSets().isAuthorStyleDefined())
    285284            continue;
    286         // Find out if there are any ::slotted rules in the shadow tree matching the current slot.
    287         // FIXME: This is really part of the slot style and could be cached when resolving it.
    288         ElementRuleCollector collector(*slot, styleScope.resolver().ruleSets().authorStyle(), nullptr);
    289         auto slottedPseudoElementRules = collector.collectSlottedPseudoElementRulesForSlot();
    290         if (!slottedPseudoElementRules)
    291             continue;
    292         // Match in the current scope.
    293         SetForScope<bool> change(m_isMatchingSlottedPseudoElements, true);
    294 
    295         MatchRequest scopeMatchRequest(nullptr, styleScopeOrdinal);
    296         collectMatchingRulesForList(slottedPseudoElementRules.get(), scopeMatchRequest);
    297 
    298         m_keepAliveSlottedPseudoElementRules.append(WTFMove(slottedPseudoElementRules));
     285
     286        auto& scopeAuthorRules = styleScope.resolver().ruleSets().authorStyle();
     287
     288        MatchRequest scopeMatchRequest(&scopeAuthorRules, styleScopeOrdinal);
     289        collectMatchingRulesForList(&scopeAuthorRules.slottedPseudoElementRules(), scopeMatchRequest);
    299290    }
    300291}
     
    348339}
    349340
    350 std::unique_ptr<RuleSet::RuleDataVector> ElementRuleCollector::collectSlottedPseudoElementRulesForSlot()
    351 {
    352     ASSERT(is<HTMLSlotElement>(element()));
    353 
    354     clearMatchedRules();
    355 
    356     m_mode = SelectorChecker::Mode::CollectingRules;
    357 
    358     // Match global author rules.
    359     MatchRequest matchRequest(m_authorStyle.ptr());
    360     collectMatchingRulesForList(&m_authorStyle->slottedPseudoElementRules(), matchRequest);
    361 
    362     if (m_matchedRules.isEmpty())
    363         return { };
    364 
    365     auto ruleDataVector = makeUnique<RuleSet::RuleDataVector>();
    366     ruleDataVector->reserveInitialCapacity(m_matchedRules.size());
    367     for (auto& matchedRule : m_matchedRules)
    368         ruleDataVector->uncheckedAppend(*matchedRule.ruleData);
    369 
    370     return ruleDataVector;
    371 }
    372 
    373341void ElementRuleCollector::matchUserRules()
    374342{
     
    408376}
    409377
    410 static const CSSSelector* findSlottedPseudoElementSelector(const CSSSelector* selector)
    411 {
    412     for (; selector; selector = selector->tagHistory()) {
    413         if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementSlotted) {
    414             if (auto* list = selector->selectorList())
    415                 return list->first();
    416             break;
    417         }
    418     };
    419     return nullptr;
    420 }
    421 
    422 inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, unsigned& specificity)
     378inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, unsigned& specificity, ScopeOrdinal styleScopeOrdinal)
    423379{
    424380    // We know a sufficiently simple single part selector matches simply because we found it from the rule hash when filtering the RuleSet.
     
    476432    context.isMatchingHostPseudoClass = m_isMatchingHostPseudoClass;
    477433    context.shadowHostInPartRuleScope = m_shadowHostInPartRuleScope.get();
     434    context.styleScopeOrdinal = styleScopeOrdinal;
    478435
    479436    bool selectorMatches;
     
    486443    {
    487444        auto* selector = ruleData.selector();
    488         auto* selectorForMatching = selector;
    489         if (m_isMatchingSlottedPseudoElements) {
    490             selectorForMatching = findSlottedPseudoElementSelector(ruleData.selector());
    491             if (!selectorForMatching)
    492                 return false;
    493         }
    494445        // Slow path.
    495446        SelectorChecker selectorChecker(element().document());
    496         selectorMatches = selectorChecker.match(*selectorForMatching, element(), context);
     447        selectorMatches = selectorChecker.match(*selector, element(), context);
    497448        if (selectorMatches)
    498449            specificity = selector->computeSpecificity();
     
    536487
    537488        unsigned specificity;
    538         if (ruleMatches(ruleData, specificity))
     489        if (ruleMatches(ruleData, specificity, matchRequest.styleScopeOrdinal))
    539490            addMatchedRule(ruleData, specificity, matchRequest);
    540491    }
  • trunk/Source/WebCore/style/ElementRuleCollector.h

    r284466 r284973  
    136136
    137137    void collectMatchingShadowPseudoElementRules(const MatchRequest&);
    138     std::unique_ptr<RuleSet::RuleDataVector> collectSlottedPseudoElementRulesForSlot();
    139138
    140139    void collectMatchingRules(const MatchRequest&);
    141140    void collectMatchingRulesForList(const RuleSet::RuleDataVector*, const MatchRequest&);
    142     bool ruleMatches(const RuleData&, unsigned& specificity);
     141    bool ruleMatches(const RuleData&, unsigned& specificity, ScopeOrdinal);
    143142
    144143    void sortMatchedRules();
     
    164163    PseudoElementRequest m_pseudoElementRequest { PseudoId::None };
    165164    SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
    166     bool m_isMatchingSlottedPseudoElements { false };
    167165    bool m_isMatchingHostPseudoClass { false };
    168166    RefPtr<const Element> m_shadowHostInPartRuleScope;
    169     Vector<std::unique_ptr<RuleSet::RuleDataVector>> m_keepAliveSlottedPseudoElementRules;
    170167
    171168    Vector<MatchedRule, 64> m_matchedRules;
  • trunk/Source/WebCore/style/RuleFeature.cpp

    r284865 r284973  
    8787        case CSSSelector::ShadowPartDescendant:
    8888            return MatchElement::Host;
     89        case CSSSelector::ShadowSlotted:
     90            // FIXME: Implement accurate invalidation.
     91            return matchElement;
    8992        };
    9093    }
     
    101104    case CSSSelector::ShadowPartDescendant:
    102105        return MatchElement::Host;
     106    case CSSSelector::ShadowSlotted:
     107        // FIXME: Implement accurate invalidation.
     108        return matchElement;
    103109    };
    104110    ASSERT_NOT_REACHED();
Note: See TracChangeset for help on using the changeset viewer.