⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287818 in webkit


Ignore:
Timestamp:
Jan 9, 2022, 1:01:48 AM (5 years ago)
Author:
Antti Koivisto
Message:

Use IsNegation bit for more efficient pseudo-class style invalidation
https://bugs.webkit.org/show_bug.cgi?id=235003

Reviewed by Simon Fraser.

We now know if a given invalidation ruleset is for negated context. We can use this to avoid
unnecessary traversal in pseudo-class invalidation, similar to what we already do with classes.

  • dom/Document.cpp:

(WebCore::Document::updateHoverActiveState):

  • dom/Element.cpp:

(WebCore::Element::setActive):
(WebCore::Element::setFocus):
(WebCore::Element::setHasFocusWithin):
(WebCore::Element::setHovered):
(WebCore::Element::setBeingDragged):

Provide the value for invalidation.

  • html/HTMLFieldSetElement.cpp:

(WebCore::HTMLFieldSetElement::addInvalidDescendant):
(WebCore::HTMLFieldSetElement::removeInvalidDescendant):

  • html/HTMLFormControlElement.cpp:

(WebCore::HTMLFormControlElement::setAncestorDisabled):
(WebCore::HTMLFormControlElement::parseAttribute):
(WebCore::HTMLFormControlElement::updateValidity):

  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::registerInvalidAssociatedFormControl):
(WebCore::HTMLFormElement::removeInvalidAssociatedFormControlIfNeeded):

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::setChecked):

  • html/HTMLOptGroupElement.cpp:

(WebCore::HTMLOptGroupElement::parseAttribute):

  • html/HTMLOptionElement.cpp:

(WebCore::HTMLOptionElement::parseAttribute):
(WebCore::HTMLOptionElement::setSelectedState):

  • page/EventHandler.cpp:

(WebCore::EventHandler::internalKeyEvent):

  • style/PseudoClassChangeInvalidation.cpp:

(WebCore::Style::PseudoClassChangeInvalidation::computeInvalidation):
(WebCore::Style::PseudoClassChangeInvalidation::collectRuleSets):

Setting a pseudo-class can only make a regular selector (not inside :not()) start matching.
Setting a pseudo-class can only make a negated selector (inside :not()) stop matching.
We only need to invalidate for the first case after the mutation has happened and for the second
case before it happens.

The cases are reversed when pseudo-class is unset.

(WebCore::Style::PseudoClassChangeInvalidation::invalidateBeforeChange):
(WebCore::Style::PseudoClassChangeInvalidation::invalidateAfterChange):
(WebCore::Style::PseudoClassChangeInvalidation::invalidateStyleWithRuleSets): Deleted.

  • style/PseudoClassChangeInvalidation.h:

(WebCore::Style::emplace):

Add a helper since std::optional::emplace() is awkward to use with std::initializer_list.

(WebCore::Style::PseudoClassChangeInvalidation::PseudoClassChangeInvalidation):
(WebCore::Style::PseudoClassChangeInvalidation::~PseudoClassChangeInvalidation):

Location:
trunk/Source/WebCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r287817 r287818  
     12022-01-09  Antti Koivisto  <antti@apple.com>
     2
     3        Use IsNegation bit for more efficient pseudo-class style invalidation
     4        https://bugs.webkit.org/show_bug.cgi?id=235003
     5
     6        Reviewed by Simon Fraser.
     7
     8        We now know if a given invalidation ruleset is for negated context. We can use this to avoid
     9        unnecessary traversal in pseudo-class invalidation, similar to what we already do with classes.
     10
     11        * dom/Document.cpp:
     12        (WebCore::Document::updateHoverActiveState):
     13        * dom/Element.cpp:
     14        (WebCore::Element::setActive):
     15        (WebCore::Element::setFocus):
     16        (WebCore::Element::setHasFocusWithin):
     17        (WebCore::Element::setHovered):
     18        (WebCore::Element::setBeingDragged):
     19
     20        Provide the value for invalidation.
     21
     22        * html/HTMLFieldSetElement.cpp:
     23        (WebCore::HTMLFieldSetElement::addInvalidDescendant):
     24        (WebCore::HTMLFieldSetElement::removeInvalidDescendant):
     25        * html/HTMLFormControlElement.cpp:
     26        (WebCore::HTMLFormControlElement::setAncestorDisabled):
     27        (WebCore::HTMLFormControlElement::parseAttribute):
     28        (WebCore::HTMLFormControlElement::updateValidity):
     29        * html/HTMLFormElement.cpp:
     30        (WebCore::HTMLFormElement::registerInvalidAssociatedFormControl):
     31        (WebCore::HTMLFormElement::removeInvalidAssociatedFormControlIfNeeded):
     32        * html/HTMLInputElement.cpp:
     33        (WebCore::HTMLInputElement::setChecked):
     34        * html/HTMLOptGroupElement.cpp:
     35        (WebCore::HTMLOptGroupElement::parseAttribute):
     36        * html/HTMLOptionElement.cpp:
     37        (WebCore::HTMLOptionElement::parseAttribute):
     38        (WebCore::HTMLOptionElement::setSelectedState):
     39        * page/EventHandler.cpp:
     40        (WebCore::EventHandler::internalKeyEvent):
     41        * style/PseudoClassChangeInvalidation.cpp:
     42        (WebCore::Style::PseudoClassChangeInvalidation::computeInvalidation):
     43        (WebCore::Style::PseudoClassChangeInvalidation::collectRuleSets):
     44
     45        Setting a pseudo-class can only make a regular selector (not inside :not()) start matching.
     46        Setting a pseudo-class can only make a negated selector (inside :not()) stop matching.
     47        We only need to invalidate for the first case after the mutation has happened and for the second
     48        case before it happens.
     49
     50        The cases are reversed when pseudo-class is unset.
     51
     52        (WebCore::Style::PseudoClassChangeInvalidation::invalidateBeforeChange):
     53        (WebCore::Style::PseudoClassChangeInvalidation::invalidateAfterChange):
     54        (WebCore::Style::PseudoClassChangeInvalidation::invalidateStyleWithRuleSets): Deleted.
     55        * style/PseudoClassChangeInvalidation.h:
     56        (WebCore::Style::emplace):
     57
     58        Add a helper since std::optional::emplace() is awkward to use with std::initializer_list.
     59
     60        (WebCore::Style::PseudoClassChangeInvalidation::PseudoClassChangeInvalidation):
     61        (WebCore::Style::PseudoClassChangeInvalidation::~PseudoClassChangeInvalidation):
     62
    1632022-01-08  Simon Fraser  <simon.fraser@apple.com>
    264
  • trunk/Source/WebCore/dom/Document.cpp

    r287802 r287818  
    74587458    }
    74597459
    7460     auto changeState = [](auto& elements, auto pseudoClassType, auto&& setter) {
     7460    auto changeState = [](auto& elements, auto pseudoClassType, auto value, auto&& setter) {
    74617461        if (elements.isEmpty())
    74627462            return;
    74637463
    7464         Style::PseudoClassChangeInvalidation styleInvalidation { *elements.last(), pseudoClassType, Style::InvalidationScope::Descendants };
     7464        Style::PseudoClassChangeInvalidation styleInvalidation { *elements.last(), pseudoClassType, value, Style::InvalidationScope::Descendants };
    74657465
    74667466        // We need to do descendant invalidation for each shadow tree separately as the style is per-scope.
     
    74687468        for (auto& element : elements) {
    74697469            if (hasShadowRootParent(*element))
    7470                 shadowDescendantStyleInvalidations.append({ *element, pseudoClassType, Style::InvalidationScope::Descendants });
     7470                shadowDescendantStyleInvalidations.append({ *element, pseudoClassType, value, Style::InvalidationScope::Descendants });
    74717471        }
    74727472
     
    74757475    };
    74767476
    7477     changeState(elementsToClearActive, CSSSelector::PseudoClassActive, [](auto& element) {
     7477    changeState(elementsToClearActive, CSSSelector::PseudoClassActive, false, [](auto& element) {
    74787478        element.setActive(false, false, Style::InvalidationScope::SelfChildrenAndSiblings);
    74797479    });
    7480     changeState(elementsToSetActive, CSSSelector::PseudoClassActive, [](auto& element) {
     7480    changeState(elementsToSetActive, CSSSelector::PseudoClassActive, true, [](auto& element) {
    74817481        element.setActive(true, false, Style::InvalidationScope::SelfChildrenAndSiblings);
    74827482    });
    7483     changeState(elementsToClearHover, CSSSelector::PseudoClassHover, [](auto& element) {
     7483    changeState(elementsToClearHover, CSSSelector::PseudoClassHover, false, [](auto& element) {
    74847484        element.setHovered(false, Style::InvalidationScope::SelfChildrenAndSiblings);
    74857485    });
    7486     changeState(elementsToSetHover, CSSSelector::PseudoClassHover, [](auto& element) {
     7486    changeState(elementsToSetHover, CSSSelector::PseudoClassHover, true, [](auto& element) {
    74877487        element.setHovered(true, Style::InvalidationScope::SelfChildrenAndSiblings);
    74887488    });
  • trunk/Source/WebCore/dom/Element.cpp

    r287803 r287818  
    792792}
    793793
    794 void Element::setActive(bool flag, bool pause, Style::InvalidationScope invalidationScope)
    795 {
    796     if (flag == active())
     794void Element::setActive(bool value, bool pause, Style::InvalidationScope invalidationScope)
     795{
     796    if (value == active())
    797797        return;
    798798    {
    799         Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassActive, invalidationScope);
    800         document().userActionElements().setActive(*this, flag);
     799        Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassActive, value, invalidationScope);
     800        document().userActionElements().setActive(*this, value);
    801801    }
    802802
     
    844844}
    845845
    846 void Element::setFocus(bool flag, FocusVisibility visibility)
    847 {
    848     if (flag == focused())
     846void Element::setFocus(bool value, FocusVisibility visibility)
     847{
     848    if (value == focused())
    849849        return;
    850850   
    851     Style::PseudoClassChangeInvalidation focusStyleInvalidation(*this, { CSSSelector::PseudoClassFocus, CSSSelector::PseudoClassFocusVisible });
    852     document().userActionElements().setFocused(*this, flag);
     851    Style::PseudoClassChangeInvalidation focusStyleInvalidation(*this, { { CSSSelector::PseudoClassFocus, value }, { CSSSelector::PseudoClassFocusVisible, value } });
     852    document().userActionElements().setFocused(*this, value);
    853853
    854854    // Shadow host with a slot that contain focused element is not considered focused.
    855855    for (auto* root = containingShadowRoot(); root; root = root->host()->containingShadowRoot()) {
    856         root->setContainsFocusedElement(flag);
     856        root->setContainsFocusedElement(value);
    857857        root->host()->invalidateStyle();
    858858    }
    859859
    860860    for (auto* element = this; element; element = element->parentElementInComposedTree())
    861         element->setHasFocusWithin(flag);
    862 
    863     setHasFocusVisible(flag && (visibility == FocusVisibility::Visible || shouldAlwaysHaveFocusVisibleWhenFocused(*this)));
    864 }
    865 
    866 void Element::setHasFocusVisible(bool flag)
     861        element->setHasFocusWithin(value);
     862
     863    setHasFocusVisible(value && (visibility == FocusVisibility::Visible || shouldAlwaysHaveFocusVisibleWhenFocused(*this)));
     864}
     865
     866void Element::setHasFocusVisible(bool value)
    867867{
    868868    if (!document().settings().focusVisibleEnabled())
     
    870870
    871871#if ASSERT_ENABLED
    872     ASSERT(!flag || focused());
    873     ASSERT(!focused() || !shouldAlwaysHaveFocusVisibleWhenFocused(*this) || flag);
     872    ASSERT(!value || focused());
     873    ASSERT(!focused() || !shouldAlwaysHaveFocusVisibleWhenFocused(*this) || value);
    874874#endif
    875875
    876     if (hasFocusVisible() == flag)
    877         return;
    878 
    879     document().userActionElements().setHasFocusVisible(*this, flag);
    880 }
    881 
    882 void Element::setHasFocusWithin(bool flag)
    883 {
    884     if (hasFocusWithin() == flag)
     876    if (hasFocusVisible() == value)
     877        return;
     878
     879    document().userActionElements().setHasFocusVisible(*this, value);
     880}
     881
     882void Element::setHasFocusWithin(bool value)
     883{
     884    if (hasFocusWithin() == value)
    885885        return;
    886886    {
    887         Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusWithin);
    888         document().userActionElements().setHasFocusWithin(*this, flag);
    889     }
    890 }
    891 
    892 void Element::setHovered(bool flag, Style::InvalidationScope invalidationScope)
    893 {
    894     if (flag == hovered())
     887        Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusWithin, value);
     888        document().userActionElements().setHasFocusWithin(*this, value);
     889    }
     890}
     891
     892void Element::setHovered(bool value, Style::InvalidationScope invalidationScope)
     893{
     894    if (value == hovered())
    895895        return;
    896896    {
    897         Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassHover, invalidationScope);
    898         document().userActionElements().setHovered(*this, flag);
     897        Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassHover, value, invalidationScope);
     898        document().userActionElements().setHovered(*this, value);
    899899    }
    900900
     
    903903}
    904904
    905 void Element::setBeingDragged(bool flag)
    906 {
    907     if (flag == isBeingDragged())
    908         return;
    909 
    910     Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassDrag);
    911     document().userActionElements().setBeingDragged(*this, flag);
     905void Element::setBeingDragged(bool value)
     906{
     907    if (value == isBeingDragged())
     908        return;
     909
     910    Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassDrag, value);
     911    document().userActionElements().setBeingDragged(*this, value);
    912912}
    913913
  • trunk/Source/WebCore/html/HTMLFieldSetElement.cpp

    r287551 r287818  
    184184    std::optional<Style::PseudoClassChangeInvalidation> styleInvalidation;
    185185    if (m_invalidDescendants.computesEmpty())
    186         styleInvalidation.emplace(*this, std::initializer_list<CSSSelector::PseudoClassType> { CSSSelector::PseudoClassValid, CSSSelector::PseudoClassInvalid });
     186        emplace(styleInvalidation, *this, { { CSSSelector::PseudoClassValid, false }, { CSSSelector::PseudoClassInvalid, true } });
    187187
    188188    m_invalidDescendants.add(invalidFormControlElement);
     
    196196    std::optional<Style::PseudoClassChangeInvalidation> styleInvalidation;
    197197    if (m_invalidDescendants.computeSize() == 1)
    198         styleInvalidation.emplace(*this, std::initializer_list<CSSSelector::PseudoClassType> { CSSSelector::PseudoClassValid, CSSSelector::PseudoClassInvalid });
     198        emplace(styleInvalidation, *this, { { CSSSelector::PseudoClassValid, true }, { CSSSelector::PseudoClassInvalid, false } });
    199199
    200200    m_invalidDescendants.remove(formControlElement);
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r287551 r287818  
    148148        return;
    149149
    150     Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { CSSSelector::PseudoClassDisabled, CSSSelector::PseudoClassEnabled });
     150    Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClassDisabled, isDisabled }, { CSSSelector::PseudoClassEnabled, !isDisabled } });
    151151
    152152    m_disabledByAncestorFieldset = isDisabled;
     
    162162            bool newDisabled = !value.isNull();
    163163            if (m_disabled != newDisabled) {
    164                 Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { CSSSelector::PseudoClassDisabled, CSSSelector::PseudoClassEnabled });
     164                Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClassDisabled, newDisabled }, { CSSSelector::PseudoClassEnabled, !newDisabled } });
    165165                m_disabled = newDisabled;
    166166                disabledAttributeChanged();
     
    533533
    534534    if (newIsValid != m_isValid) {
    535         Style::PseudoClassChangeInvalidation styleInvalidation(*this, { CSSSelector::PseudoClassValid, CSSSelector::PseudoClassInvalid });
     535        Style::PseudoClassChangeInvalidation styleInvalidation(*this, { { CSSSelector::PseudoClassValid, newIsValid }, { CSSSelector::PseudoClassInvalid, !newIsValid } });
    536536
    537537        m_isValid = newIsValid;
  • trunk/Source/WebCore/html/HTMLFormElement.cpp

    r287551 r287818  
    669669    std::optional<Style::PseudoClassChangeInvalidation> styleInvalidation;
    670670    if (m_invalidAssociatedFormControls.computesEmpty())
    671         styleInvalidation.emplace(*this, std::initializer_list<CSSSelector::PseudoClassType> { CSSSelector::PseudoClassValid, CSSSelector::PseudoClassInvalid });
     671        emplace(styleInvalidation, *this, { { CSSSelector::PseudoClassValid, false }, { CSSSelector::PseudoClassInvalid, true } });
    672672
    673673    m_invalidAssociatedFormControls.add(const_cast<HTMLFormControlElement&>(formControlElement));
     
    681681    std::optional<Style::PseudoClassChangeInvalidation> styleInvalidation;
    682682    if (m_invalidAssociatedFormControls.computeSize() == 1)
    683         styleInvalidation.emplace(*this, std::initializer_list<CSSSelector::PseudoClassType> { CSSSelector::PseudoClassValid, CSSSelector::PseudoClassInvalid });
     683        emplace(styleInvalidation, *this, { { CSSSelector::PseudoClassValid, true }, { CSSSelector::PseudoClassInvalid, false } });
    684684
    685685    m_invalidAssociatedFormControls.remove(formControlElement);
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r287551 r287818  
    976976}
    977977
    978 void HTMLInputElement::setChecked(bool nowChecked)
    979 {
    980     if (checked() == nowChecked)
     978void HTMLInputElement::setChecked(bool isChecked)
     979{
     980    if (checked() == isChecked)
    981981        return;
    982982
    983     m_inputType->willUpdateCheckedness(nowChecked);
    984 
    985     Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked);
     983    m_inputType->willUpdateCheckedness(isChecked);
     984
     985    Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked, isChecked);
    986986
    987987    m_dirtyCheckednessFlag = true;
    988     m_isChecked = nowChecked;
     988    m_isChecked = isChecked;
    989989
    990990    if (RadioButtonGroups* buttons = radioButtonGroups())
  • trunk/Source/WebCore/html/HTMLOptGroupElement.cpp

    r287540 r287818  
    9090        bool newDisabled = !value.isNull();
    9191        if (m_isDisabled != newDisabled) {
    92             Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { CSSSelector::PseudoClassDisabled, CSSSelector::PseudoClassEnabled });
     92            Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClassDisabled, newDisabled }, { CSSSelector::PseudoClassEnabled, !newDisabled } });
    9393
    9494            Vector<Style::PseudoClassChangeInvalidation> optionInvalidation;
    9595            for (auto& descendant : descendantsOfType<HTMLOptionElement>(*this))
    96                 optionInvalidation.append({ descendant, { CSSSelector::PseudoClassDisabled, CSSSelector::PseudoClassEnabled } });
     96                optionInvalidation.append({ descendant, { { CSSSelector::PseudoClassDisabled, newDisabled }, { CSSSelector::PseudoClassEnabled, !newDisabled } } });
    9797
    9898            m_isDisabled = newDisabled;
  • trunk/Source/WebCore/html/HTMLOptionElement.cpp

    r287540 r287818  
    179179        bool newDisabled = !value.isNull();
    180180        if (m_disabled != newDisabled) {
    181             Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { CSSSelector::PseudoClassDisabled, CSSSelector::PseudoClassEnabled });
     181            Style::PseudoClassChangeInvalidation disabledInvalidation(*this, { { CSSSelector::PseudoClassDisabled, newDisabled },  { CSSSelector::PseudoClassEnabled, !newDisabled } });
    182182            m_disabled = newDisabled;
    183183            if (renderer() && renderer()->style().hasEffectiveAppearance())
     
    186186    } else if (name == selectedAttr) {
    187187        // FIXME: Use PseudoClassChangeInvalidation in other elements that implement matchesDefaultPseudoClass().
    188         Style::PseudoClassChangeInvalidation defaultInvalidation(*this, CSSSelector::PseudoClassDefault);
     188        Style::PseudoClassChangeInvalidation defaultInvalidation(*this, CSSSelector::PseudoClassDefault, !value.isNull());
    189189        m_isDefault = !value.isNull();
    190190
     
    234234        return;
    235235
    236     Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked);
     236    Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked, selected);
    237237
    238238    m_isSelected = selected;
  • trunk/Source/WebCore/page/EventHandler.cpp

    r287731 r287818  
    36413641
    36423642        if (element.focused() && userHasInteractedViaKeyword) {
    3643             Style::PseudoClassChangeInvalidation focusVisibleStyleInvalidation(element, CSSSelector::PseudoClassFocusVisible);
     3643            Style::PseudoClassChangeInvalidation focusVisibleStyleInvalidation(element, CSSSelector::PseudoClassFocusVisible, true);
    36443644            element.setHasFocusVisible(true);
    36453645        }
  • trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp

    r286598 r287818  
    5252};
    5353
    54 void PseudoClassChangeInvalidation::computeInvalidation(CSSSelector::PseudoClassType pseudoClass, InvalidationScope invalidationScope)
     54void PseudoClassChangeInvalidation::computeInvalidation(CSSSelector::PseudoClassType pseudoClass, bool value, InvalidationScope invalidationScope)
    5555{
    5656    bool shouldInvalidateCurrent = false;
     
    7373
    7474    for (auto& key : makePseudoClassInvalidationKeys(pseudoClass, m_element))
    75         collectRuleSets(key, invalidationScope);
     75        collectRuleSets(key, value, invalidationScope);
    7676}
    7777
    78 void PseudoClassChangeInvalidation::collectRuleSets(const PseudoClassInvalidationKey& key, InvalidationScope invalidationScope)
     78void PseudoClassChangeInvalidation::collectRuleSets(const PseudoClassInvalidationKey& key, bool value, InvalidationScope invalidationScope)
    7979{
    8080    auto& ruleSets = m_element.styleResolver().ruleSets();
     
    101101            continue;
    102102
    103         Invalidator::addToMatchElementRuleSets(m_matchElementRuleSets, invalidationRuleSet);
     103        bool invalidateBeforeChange = invalidationRuleSet.isNegation == IsNegation::Yes ? value : !value;
     104        if (invalidateBeforeChange)
     105            Invalidator::addToMatchElementRuleSets(m_beforeChangeRuleSets, invalidationRuleSet);
     106        else
     107            Invalidator::addToMatchElementRuleSets(m_afterChangeRuleSets, invalidationRuleSet);
    104108    }
    105109}
    106110
    107 void PseudoClassChangeInvalidation::invalidateStyleWithRuleSets()
     111void PseudoClassChangeInvalidation::invalidateBeforeChange()
    108112{
    109     Invalidator::invalidateWithMatchElementRuleSets(m_element, m_matchElementRuleSets);
     113    Invalidator::invalidateWithMatchElementRuleSets(m_element, m_beforeChangeRuleSets);
    110114}
     115
     116void PseudoClassChangeInvalidation::invalidateAfterChange()
     117{
     118    Invalidator::invalidateWithMatchElementRuleSets(m_element, m_afterChangeRuleSets);
     119}
     120
    111121
    112122}
  • trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h

    r287540 r287818  
    3636class PseudoClassChangeInvalidation {
    3737public:
    38     PseudoClassChangeInvalidation(Element&, CSSSelector::PseudoClassType, InvalidationScope = InvalidationScope::All);
    39     PseudoClassChangeInvalidation(Element&, std::initializer_list<CSSSelector::PseudoClassType>, InvalidationScope = InvalidationScope::All);
     38    PseudoClassChangeInvalidation(Element&, CSSSelector::PseudoClassType, bool value, InvalidationScope = InvalidationScope::All);
     39    PseudoClassChangeInvalidation(Element&, std::initializer_list<std::pair<CSSSelector::PseudoClassType, bool>>);
    4040
    4141    ~PseudoClassChangeInvalidation();
    4242
    4343private:
    44     void computeInvalidation(CSSSelector::PseudoClassType, Style::InvalidationScope);
    45     void collectRuleSets(const PseudoClassInvalidationKey&, InvalidationScope);
    46     void invalidateStyleWithRuleSets();
     44    void computeInvalidation(CSSSelector::PseudoClassType, bool value, Style::InvalidationScope);
     45    void collectRuleSets(const PseudoClassInvalidationKey&, bool value, InvalidationScope);
     46    void invalidateBeforeChange();
     47    void invalidateAfterChange();
    4748
    4849    const bool m_isEnabled;
    4950    Element& m_element;
    5051
    51     Invalidator::MatchElementRuleSets m_matchElementRuleSets;
     52    Invalidator::MatchElementRuleSets m_beforeChangeRuleSets;
     53    Invalidator::MatchElementRuleSets m_afterChangeRuleSets;
    5254};
    5355
    54 inline PseudoClassChangeInvalidation::PseudoClassChangeInvalidation(Element& element, CSSSelector::PseudoClassType pseudoClassType, Style::InvalidationScope invalidationScope)
     56inline void emplace(std::optional<PseudoClassChangeInvalidation>& invalidation, Element& element, std::initializer_list<std::pair<CSSSelector::PseudoClassType, bool>> pseudoClasses)
     57{
     58    invalidation.emplace(element, pseudoClasses);
     59}
     60
     61inline PseudoClassChangeInvalidation::PseudoClassChangeInvalidation(Element& element, CSSSelector::PseudoClassType pseudoClass, bool value, Style::InvalidationScope invalidationScope)
    5562    : m_isEnabled(element.needsStyleInvalidation())
    5663    , m_element(element)
     
    5966    if (!m_isEnabled)
    6067        return;
    61     computeInvalidation(pseudoClassType, invalidationScope);
    62     invalidateStyleWithRuleSets();
     68    computeInvalidation(pseudoClass, value, invalidationScope);
     69    invalidateBeforeChange();
    6370}
    6471
    65 inline PseudoClassChangeInvalidation::PseudoClassChangeInvalidation(Element& element, std::initializer_list<CSSSelector::PseudoClassType> pseudoClasses, Style::InvalidationScope invalidationScope)
     72inline PseudoClassChangeInvalidation::PseudoClassChangeInvalidation(Element& element, std::initializer_list<std::pair<CSSSelector::PseudoClassType, bool>> pseudoClasses)
    6673    : m_isEnabled(element.needsStyleInvalidation())
    6774    , m_element(element)
     
    7077        return;
    7178    for (auto pseudoClass : pseudoClasses)
    72         computeInvalidation(pseudoClass, invalidationScope);
    73     invalidateStyleWithRuleSets();
     79        computeInvalidation(pseudoClass.first, pseudoClass.second, Style::InvalidationScope::All);
     80    invalidateBeforeChange();
    7481}
    7582
     
    7885    if (!m_isEnabled)
    7986        return;
    80     invalidateStyleWithRuleSets();
     87    invalidateAfterChange();
    8188}
    8289
Note: See TracChangeset for help on using the changeset viewer.