Changeset 286433 in webkit


Ignore:
Timestamp:
Dec 2, 2021 9:36:50 AM (8 months ago)
Author:
Antti Koivisto
Message:

[:has() pseudo-class] Invalidation in non-subject position
https://bugs.webkit.org/show_bug.cgi?id=233758

Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

  • web-platform-tests/css/selectors/invalidation/has-in-adjacent-position-expected.txt: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-adjacent-position.html: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-ancestor-position-expected.txt: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-ancestor-position.html: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-parent-position-expected.txt: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-parent-position.html: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-sibling-position-expected.txt: Added.
  • web-platform-tests/css/selectors/invalidation/has-in-sibling-position.html: Added.

Source/WebCore:

Invalidation for selectors like '.ancestor:has(.foo) #target'.

Tests: imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-adjacent-position.html

imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-ancestor-position.html
imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-parent-position.html
imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-sibling-position.html

  • style/ChildChangeInvalidation.cpp:

(WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
(WebCore::Style::needsTraversal):
(WebCore::Style::needsDescendantTraversal):

  • style/RuleFeature.cpp:

(WebCore::Style::isSiblingOrSubject):
(WebCore::Style::isHasPseudoClassMatchElement):
(WebCore::Style::computeHasPseudoClassMatchElement):
(WebCore::Style::computeSubSelectorMatchElement):

Use new MatchElement::HasNonSubject as a catch-all for cases where :has() is in a non-subject position.
In the future this can be optimized better by computing both the :has match element and the overall
match element separately.

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

(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):

Worst-case invalidation.

Location:
trunk
Files:
8 added
6 edited

Legend:

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

    r286427 r286433  
     12021-12-02  Antti Koivisto  <antti@apple.com>
     2
     3        [:has() pseudo-class] Invalidation in non-subject position
     4        https://bugs.webkit.org/show_bug.cgi?id=233758
     5
     6        Reviewed by Simon Fraser.
     7
     8        * web-platform-tests/css/selectors/invalidation/has-in-adjacent-position-expected.txt: Added.
     9        * web-platform-tests/css/selectors/invalidation/has-in-adjacent-position.html: Added.
     10        * web-platform-tests/css/selectors/invalidation/has-in-ancestor-position-expected.txt: Added.
     11        * web-platform-tests/css/selectors/invalidation/has-in-ancestor-position.html: Added.
     12        * web-platform-tests/css/selectors/invalidation/has-in-parent-position-expected.txt: Added.
     13        * web-platform-tests/css/selectors/invalidation/has-in-parent-position.html: Added.
     14        * web-platform-tests/css/selectors/invalidation/has-in-sibling-position-expected.txt: Added.
     15        * web-platform-tests/css/selectors/invalidation/has-in-sibling-position.html: Added.
     16
    1172021-12-02  Andreu Botella  <andreu@andreubotella.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r286427 r286433  
     12021-12-02  Antti Koivisto  <antti@apple.com>
     2
     3        [:has() pseudo-class] Invalidation in non-subject position
     4        https://bugs.webkit.org/show_bug.cgi?id=233758
     5
     6        Reviewed by Simon Fraser.
     7
     8        Invalidation for selectors like '.ancestor:has(.foo) #target'.
     9
     10        Tests: imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-adjacent-position.html
     11               imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-ancestor-position.html
     12               imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-parent-position.html
     13               imported/w3c/web-platform-tests/css/selectors/invalidation/has-in-sibling-position.html
     14
     15        * style/ChildChangeInvalidation.cpp:
     16        (WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
     17        (WebCore::Style::needsTraversal):
     18        (WebCore::Style::needsDescendantTraversal):
     19        * style/RuleFeature.cpp:
     20        (WebCore::Style::isSiblingOrSubject):
     21        (WebCore::Style::isHasPseudoClassMatchElement):
     22        (WebCore::Style::computeHasPseudoClassMatchElement):
     23        (WebCore::Style::computeSubSelectorMatchElement):
     24
     25        Use new MatchElement::HasNonSubject as a catch-all for cases where :has() is in a non-subject position.
     26        In the future this can be optimized better by computing both the :has match element and the overall
     27        match element separately.
     28
     29        * style/RuleFeature.h:
     30        * style/StyleInvalidator.cpp:
     31        (WebCore::Style::Invalidator::invalidateStyleWithMatchElement):
     32
     33        Worst-case invalidation.
     34
    1352021-12-02  Andreu Botella  <andreu@andreubotella.com>
    236
  • trunk/Source/WebCore/style/ChildChangeInvalidation.cpp

    r286365 r286433  
    7676            if (!isHasPseudoClassMatchElement(invalidationRuleSet.matchElement))
    7777                continue;
    78             if (isDescendant && invalidationRuleSet.matchElement != MatchElement::HasDescendant)
    79                 continue;
     78            if (isDescendant) {
     79                // Elements deeper in the tree can't affect anything except when :has() selector uses descendant combinator.
     80                if (invalidationRuleSet.matchElement != MatchElement::HasDescendant && invalidationRuleSet.matchElement != MatchElement::HasNonSubject)
     81                    continue;
     82            }
    8083            Invalidator::addToMatchElementRuleSets(matchElementRuleSets, invalidationRuleSet);
    8184        }
     
    114117    if (features.usesMatchElement(MatchElement::HasSiblingDescendant))
    115118        return true;
     119    if (features.usesMatchElement(MatchElement::HasNonSubject))
     120        return true;
    116121    return features.usesMatchElement(MatchElement::HasSibling) && childChange.previousSiblingElement;
    117122};
     
    119124static bool needsDescendantTraversal(const RuleFeatureSet& features)
    120125{
     126    if (features.usesMatchElement(MatchElement::HasNonSubject))
     127        return true;
    121128    return features.usesMatchElement(MatchElement::HasDescendant) || features.usesMatchElement(MatchElement::HasSiblingDescendant);
    122129};
  • trunk/Source/WebCore/style/RuleFeature.cpp

    r286365 r286433  
    5454    case MatchElement::HasDescendant:
    5555    case MatchElement::HasSiblingDescendant:
     56    case MatchElement::HasNonSubject:
    5657        return false;
    5758    }
     
    6768    case MatchElement::HasSibling:
    6869    case MatchElement::HasSiblingDescendant:
     70    case MatchElement::HasNonSubject:
    6971        return true;
    7072    default:
     
    158160    case MatchElement::HasSibling:
    159161    case MatchElement::HasSiblingDescendant:
     162    case MatchElement::HasNonSubject:
    160163    case MatchElement::Host:
    161164        ASSERT_NOT_REACHED();
     
    177180            return MatchElement::Host;
    178181
    179         if (type == CSSSelector::PseudoClassHas)
     182        if (type == CSSSelector::PseudoClassHas) {
     183            if (matchElement != MatchElement::Subject)
     184                return MatchElement::HasNonSubject;
    180185            return computeHasPseudoClassMatchElement(childSelector);
     186        }
    181187    }
    182188    if (selector.match() == CSSSelector::PseudoElement) {
  • trunk/Source/WebCore/style/RuleFeature.h

    r286365 r286433  
    3737class RuleData;
    3838
     39// FIXME: Has* values should be separated so we could describe both the :has() argument and its position in the selector.
    3940enum class MatchElement : uint8_t {
    4041    Subject,
     
    5051    HasSibling,
    5152    HasSiblingDescendant,
     53    HasNonSubject, // FIXME: This is a catch-all for cases where :has() is in non-subject position.
    5254    Host
    5355};
  • trunk/Source/WebCore/style/StyleInvalidator.cpp

    r286365 r286433  
    347347        break;
    348348    }
     349    case MatchElement::HasNonSubject: {
     350        SelectorMatchingState selectorMatchingState;
     351        invalidateStyleForDescendants(*element.document().documentElement(), &selectorMatchingState);
     352        break;
     353    }
    349354    case MatchElement::Host:
    350355        invalidateInShadowTreeIfNeeded(element);
Note: See TracChangeset for help on using the changeset viewer.