Changeset 228669 in webkit


Ignore:
Timestamp:
Feb 19, 2018 5:17:35 AM (6 years ago)
Author:
Carlos Garcia Campos
Message:

Merge r228285 - Use invalidation rulesets for attribute selectors
https://bugs.webkit.org/show_bug.cgi?id=182569

Reviewed by Zalan Bujtas.

Attribute change style invalidation should use invalidation rulesets, similarly how class change invalidation already does.
We'll invalidate fewer unnecessary elements immediately and enable more significant future gains.

  • css/DocumentRuleSets.cpp:

(WebCore::DocumentRuleSets::collectFeatures const):
(WebCore::DocumentRuleSets::classInvalidationRuleSets const):
(WebCore::DocumentRuleSets::attributeInvalidationRuleSets const):

Make and cache invalidation RuleSets for an attribute.

(WebCore::DocumentRuleSets::ancestorAttributeRulesForHTML const): Deleted.

  • css/DocumentRuleSets.h:
  • css/RuleFeature.cpp:

(WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):

Collect attribute selectors along with match elements.

(WebCore::RuleFeatureSet::collectFeatures):
(WebCore::RuleFeatureSet::add):
(WebCore::RuleFeatureSet::registerContentAttribute):

Separate hash to deal with invalidation of content:attr(foo) special case.

(WebCore::RuleFeatureSet::clear):
(WebCore::RuleFeatureSet::shrinkToFit):
(WebCore::makeAttributeSelectorKey): Deleted.

  • css/RuleFeature.h:

(WebCore::RuleFeature::RuleFeature):

  • css/StyleBuilderCustom.h:

(WebCore::StyleBuilderCustom::applyValueContent):
(WebCore::StyleBuilderCustom::applyValueAlt):

Use registerContentAttribute()

  • html/HTMLEmbedElement.cpp:

(WebCore::hasTypeOrSrc):
(WebCore::HTMLEmbedElement::parseAttribute):

Invalidate style if both type and src attributes go missing as this changes result of rendererIsNeeded().
This was previously relying on any attribute change invalidating style.

(WebCore::HTMLEmbedElement::rendererIsNeeded):

  • style/AttributeChangeInvalidation.cpp:

(WebCore::Style::AttributeChangeInvalidation::invalidateStyle):

Collect the invalidation rulesets for this attribute change.
Also check if any attribute selector actually changes state, unlike with classes attribute changes may
often not lead to a selector becoming non-matching.

(WebCore::Style::AttributeChangeInvalidation::invalidateStyleWithRuleSets):
(WebCore::Style::AttributeChangeInvalidation::invalidateDescendants): Deleted.

  • style/AttributeChangeInvalidation.h:

(WebCore::Style::AttributeChangeInvalidation::AttributeChangeInvalidation):
(WebCore::Style::AttributeChangeInvalidation::~AttributeChangeInvalidation):

  • style/ClassChangeInvalidation.cpp:

(WebCore::Style::ClassChangeInvalidation::computeInvalidation):

Should not bail on shadow tree invalidation as we may also need to invalidate siblings.

Location:
releases/WebKitGTK/webkit-2.20/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog

    r228668 r228669  
     12018-02-08  Antti Koivisto  <antti@apple.com>
     2
     3        Use invalidation rulesets for attribute selectors
     4        https://bugs.webkit.org/show_bug.cgi?id=182569
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Attribute change style invalidation should use invalidation rulesets, similarly how class change invalidation already does.
     9        We'll invalidate fewer unnecessary elements immediately and enable more significant future gains.
     10
     11        * css/DocumentRuleSets.cpp:
     12        (WebCore::DocumentRuleSets::collectFeatures const):
     13        (WebCore::DocumentRuleSets::classInvalidationRuleSets const):
     14        (WebCore::DocumentRuleSets::attributeInvalidationRuleSets const):
     15
     16        Make and cache invalidation RuleSets for an attribute.
     17
     18        (WebCore::DocumentRuleSets::ancestorAttributeRulesForHTML const): Deleted.
     19        * css/DocumentRuleSets.h:
     20        * css/RuleFeature.cpp:
     21        (WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
     22
     23        Collect attribute selectors along with match elements.
     24
     25        (WebCore::RuleFeatureSet::collectFeatures):
     26        (WebCore::RuleFeatureSet::add):
     27        (WebCore::RuleFeatureSet::registerContentAttribute):
     28
     29        Separate hash to deal with invalidation of content:attr(foo) special case.
     30
     31        (WebCore::RuleFeatureSet::clear):
     32        (WebCore::RuleFeatureSet::shrinkToFit):
     33        (WebCore::makeAttributeSelectorKey): Deleted.
     34        * css/RuleFeature.h:
     35        (WebCore::RuleFeature::RuleFeature):
     36        * css/StyleBuilderCustom.h:
     37        (WebCore::StyleBuilderCustom::applyValueContent):
     38        (WebCore::StyleBuilderCustom::applyValueAlt):
     39
     40        Use registerContentAttribute()
     41
     42        * html/HTMLEmbedElement.cpp:
     43        (WebCore::hasTypeOrSrc):
     44        (WebCore::HTMLEmbedElement::parseAttribute):
     45
     46            Invalidate style if both type and src attributes go missing as this changes result of rendererIsNeeded().
     47            This was previously relying on any attribute change invalidating style.
     48
     49        (WebCore::HTMLEmbedElement::rendererIsNeeded):
     50        * style/AttributeChangeInvalidation.cpp:
     51        (WebCore::Style::AttributeChangeInvalidation::invalidateStyle):
     52
     53        Collect the invalidation rulesets for this attribute change.
     54        Also check if any attribute selector actually changes state, unlike with classes attribute changes may
     55        often not lead to a selector becoming non-matching.
     56
     57        (WebCore::Style::AttributeChangeInvalidation::invalidateStyleWithRuleSets):
     58        (WebCore::Style::AttributeChangeInvalidation::invalidateDescendants): Deleted.
     59        * style/AttributeChangeInvalidation.h:
     60        (WebCore::Style::AttributeChangeInvalidation::AttributeChangeInvalidation):
     61        (WebCore::Style::AttributeChangeInvalidation::~AttributeChangeInvalidation):
     62        * style/ClassChangeInvalidation.cpp:
     63        (WebCore::Style::ClassChangeInvalidation::computeInvalidation):
     64
     65        Should not bail on shadow tree invalidation as we may also need to invalidate siblings.
     66
    1672018-02-08  Zalan Bujtas  <zalan@apple.com>
    268
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.cpp

    r227787 r228669  
    169169
    170170    m_classInvalidationRuleSets.clear();
    171     m_ancestorAttributeRuleSetsForHTML.clear();
     171    m_attributeInvalidationRuleSets.clear();
    172172
    173173    m_features.shrinkToFit();
    174174}
    175175
    176 const Vector<InvalidationRuleSet>* DocumentRuleSets::classInvalidationRuleSets(const AtomicString& className) const
    177 {
    178     return m_classInvalidationRuleSets.ensure(className, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
    179         auto* features = m_features.classRules.get(className);
     176static Vector<InvalidationRuleSet>* ensureInvalidationRuleSets(const AtomicString& key, HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>>& ruleSetMap, const HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>>& ruleFeatures)
     177{
     178    return ruleSetMap.ensure(key, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
     179        auto* features = ruleFeatures.get(key);
    180180        if (!features)
    181181            return nullptr;
     182
    182183        std::array<std::unique_ptr<RuleSet>, matchElementCount> matchElementArray;
     184        std::array<Vector<const CSSSelector*>, matchElementCount> invalidationSelectorArray;
    183185        for (auto& feature : *features) {
    184             auto& ruleSet = matchElementArray[static_cast<unsigned>(*feature.matchElement)];
     186            auto arrayIndex = static_cast<unsigned>(*feature.matchElement);
     187            auto& ruleSet = matchElementArray[arrayIndex];
    185188            if (!ruleSet)
    186189                ruleSet = std::make_unique<RuleSet>();
    187190            ruleSet->addRule(feature.rule, feature.selectorIndex);
     191            if (feature.invalidationSelector)
     192                invalidationSelectorArray[arrayIndex].append(feature.invalidationSelector);
    188193        }
    189194        auto invalidationRuleSets = std::make_unique<Vector<InvalidationRuleSet>>();
    190195        for (unsigned i = 0; i < matchElementArray.size(); ++i) {
    191196            if (matchElementArray[i])
    192                 invalidationRuleSets->append({ static_cast<MatchElement>(i), WTFMove(matchElementArray[i]) });
     197                invalidationRuleSets->append({ static_cast<MatchElement>(i), WTFMove(matchElementArray[i]), WTFMove(invalidationSelectorArray[i]) });
    193198        }
    194199        return invalidationRuleSets;
     
    196201}
    197202
    198 const DocumentRuleSets::AttributeRules* DocumentRuleSets::ancestorAttributeRulesForHTML(const AtomicString& attributeName) const
    199 {
    200     auto addResult = m_ancestorAttributeRuleSetsForHTML.add(attributeName, nullptr);
    201     auto& value = addResult.iterator->value;
    202     if (addResult.isNewEntry) {
    203         if (auto* rules = m_features.ancestorAttributeRulesForHTML.get(attributeName)) {
    204             value = std::make_unique<AttributeRules>();
    205             value->attributeSelectors.reserveCapacity(rules->selectors.size());
    206             for (auto* selector : rules->selectors.values())
    207                 value->attributeSelectors.uncheckedAppend(selector);
    208             value->ruleSet = makeRuleSet(rules->features);
    209         }
    210     }
    211     return value.get();
     203const Vector<InvalidationRuleSet>* DocumentRuleSets::classInvalidationRuleSets(const AtomicString& className) const
     204{
     205    return ensureInvalidationRuleSets(className, m_classInvalidationRuleSets, m_features.classRules);
     206}
     207
     208const Vector<InvalidationRuleSet>* DocumentRuleSets::attributeInvalidationRuleSets(const AtomicString& attributeName) const
     209{
     210    return ensureInvalidationRuleSets(attributeName, m_attributeInvalidationRuleSets, m_features.attributeRules);
    212211}
    213212
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.h

    r227787 r228669  
    4242    MatchElement matchElement;
    4343    std::unique_ptr<RuleSet> ruleSet;
     44    Vector<const CSSSelector*> invalidationSelectors;
    4445
    4546    WTF_MAKE_FAST_ALLOCATED;
     
    6061
    6162    const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomicString& className) const;
    62 
    63     struct AttributeRules {
    64         WTF_MAKE_FAST_ALLOCATED;
    65     public:
    66         Vector<const CSSSelector*> attributeSelectors;
    67         std::unique_ptr<RuleSet> ruleSet;
    68     };
    69     const AttributeRules* ancestorAttributeRulesForHTML(const AtomicString&) const;
     63    const Vector<InvalidationRuleSet>* attributeInvalidationRuleSets(const AtomicString& attributeName) const;
    7064
    7165    void setIsForShadowScope() { m_isForShadowScope = true; }
     
    10094    mutable std::unique_ptr<RuleSet> m_uncommonAttributeRuleSet;
    10195    mutable HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_classInvalidationRuleSets;
    102     mutable HashMap<AtomicString, std::unique_ptr<AttributeRules>> m_ancestorAttributeRuleSetsForHTML;
     96    mutable HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_attributeInvalidationRuleSets;
    10397};
    10498
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.cpp

    r227956 r228669  
    131131            attributeCanonicalLocalNamesInRules.add(canonicalLocalName);
    132132            attributeLocalNamesInRules.add(localName);
    133             if (matchElement == MatchElement::Parent || matchElement == MatchElement::Ancestor)
    134                 selectorFeatures.attributeSelectorsMatchingAncestors.append(selector);
     133            selectorFeatures.attributes.append(std::make_pair(selector, matchElement));
    135134        } else if (selector->match() == CSSSelector::PseudoElement) {
    136135            switch (selector->pseudoElementType()) {
     
    165164}
    166165
    167 static RuleFeatureSet::AttributeRules::SelectorKey makeAttributeSelectorKey(const CSSSelector& selector)
    168 {
    169     bool caseInsensitive = selector.attributeValueMatchingIsCaseInsensitive();
    170     unsigned matchAndCase = static_cast<unsigned>(selector.match()) << 1 | (caseInsensitive ? 1 : 0);
    171     return std::make_pair(selector.attributeCanonicalLocalName().impl(), std::make_pair(selector.value().impl(), matchAndCase));
    172 }
    173 
    174166void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
    175167{
     
    180172    if (ruleData.containsUncommonAttributeSelector())
    181173        uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     174
    182175    for (auto& nameAndMatch : selectorFeatures.classes) {
    183176        classRules.ensure(nameAndMatch.first, [] {
     
    187180            classesAffectingHost.add(nameAndMatch.first);
    188181    }
    189     for (auto* selector : selectorFeatures.attributeSelectorsMatchingAncestors) {
    190         // Hashing by attributeCanonicalLocalName makes this HTML specific.
    191         auto addResult = ancestorAttributeRulesForHTML.ensure(selector->attributeCanonicalLocalName(), [] {
    192             return std::make_unique<AttributeRules>();
    193         });
    194         auto& rules = *addResult.iterator->value;
    195         rules.features.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
    196         // Deduplicate selectors.
    197         rules.selectors.add(makeAttributeSelectorKey(*selector), selector);
     182
     183    for (auto& selectorAndMatch : selectorFeatures.attributes) {
     184        auto* selector = selectorAndMatch.first;
     185        auto matchElement = selectorAndMatch.second;
     186        attributeRules.ensure(selector->attribute().localName().convertToASCIILowercase(), [] {
     187            return std::make_unique<Vector<RuleFeature>>();
     188        }).iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), matchElement, selector));
     189        if (matchElement == MatchElement::Host)
     190            attributesAffectingHost.add(selector->attribute().localName().convertToASCIILowercase());
    198191    }
    199192}
     
    205198    attributeCanonicalLocalNamesInRules.add(other.attributeCanonicalLocalNamesInRules.begin(), other.attributeCanonicalLocalNamesInRules.end());
    206199    attributeLocalNamesInRules.add(other.attributeLocalNamesInRules.begin(), other.attributeLocalNamesInRules.end());
     200    contentAttributeNamesInRules.add(other.contentAttributeNamesInRules.begin(), other.contentAttributeNamesInRules.end());
    207201    siblingRules.appendVector(other.siblingRules);
    208202    uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
     
    214208    classesAffectingHost.add(other.classesAffectingHost.begin(), other.classesAffectingHost.end());
    215209
    216     for (auto& keyValuePair : other.ancestorAttributeRulesForHTML) {
    217         auto addResult = ancestorAttributeRulesForHTML.ensure(keyValuePair.key, [] {
    218             return std::make_unique<AttributeRules>();
    219         });
    220         auto& rules = *addResult.iterator->value;
    221         rules.features.appendVector(keyValuePair.value->features);
    222         for (auto& selectorPair : keyValuePair.value->selectors)
    223             rules.selectors.add(selectorPair.key, selectorPair.value);
    224     }
     210    for (auto& keyValuePair : other.attributeRules) {
     211        attributeRules.ensure(keyValuePair.key, [] {
     212            return std::make_unique<Vector<RuleFeature>>();
     213        }).iterator->value->appendVector(*keyValuePair.value);
     214    }
     215    attributesAffectingHost.add(other.attributesAffectingHost.begin(), other.attributesAffectingHost.end());
     216
    225217    usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
    226218    usesFirstLetterRules = usesFirstLetterRules || other.usesFirstLetterRules;
     219}
     220
     221void RuleFeatureSet::registerContentAttribute(const AtomicString& attributeName)
     222{
     223    contentAttributeNamesInRules.add(attributeName.convertToASCIILowercase());
     224    attributeCanonicalLocalNamesInRules.add(attributeName);
     225    attributeLocalNamesInRules.add(attributeName);
    227226}
    228227
     
    233232    attributeCanonicalLocalNamesInRules.clear();
    234233    attributeLocalNamesInRules.clear();
     234    contentAttributeNamesInRules.clear();
    235235    siblingRules.clear();
    236236    uncommonAttributeRules.clear();
    237237    classRules.clear();
    238238    classesAffectingHost.clear();
    239     ancestorAttributeRulesForHTML.clear();
     239    attributeRules.clear();
     240    attributesAffectingHost.clear();
    240241    usesFirstLineRules = false;
    241242    usesFirstLetterRules = false;
     
    248249    for (auto& rules : classRules.values())
    249250        rules->shrinkToFit();
    250     for (auto& rules : ancestorAttributeRulesForHTML.values())
    251         rules->features.shrinkToFit();
     251    for (auto& rules : attributeRules.values())
     252        rules->shrinkToFit();
    252253}
    253254
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.h

    r227956 r228669  
    3838
    3939struct RuleFeature {
    40     RuleFeature(StyleRule* rule, unsigned selectorIndex, std::optional<MatchElement> matchElement = std::nullopt)
     40    RuleFeature(StyleRule* rule, unsigned selectorIndex, std::optional<MatchElement> matchElement = std::nullopt, const CSSSelector* invalidationSelector = nullptr)
    4141        : rule(rule)
    4242        , selectorIndex(selectorIndex)
    4343        , matchElement(matchElement)
     44        , invalidationSelector(invalidationSelector)
    4445    {
    4546    }
     
    4748    unsigned selectorIndex;
    4849    std::optional<MatchElement> matchElement;
     50    const CSSSelector* invalidationSelector;
    4951};
    5052
     
    5456    void shrinkToFit();
    5557    void collectFeatures(const RuleData&);
     58    void registerContentAttribute(const AtomicString&);
    5659
    5760    HashSet<AtomicString> idsInRules;
     
    5962    HashSet<AtomicString> attributeCanonicalLocalNamesInRules;
    6063    HashSet<AtomicString> attributeLocalNamesInRules;
     64    HashSet<AtomicString> contentAttributeNamesInRules;
    6165    Vector<RuleFeature> siblingRules;
    6266    Vector<RuleFeature> uncommonAttributeRules;
    6367   
    6468    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> classRules;
     69    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> attributeRules;
    6570    HashSet<AtomicString> classesAffectingHost;
     71    HashSet<AtomicString> attributesAffectingHost;
    6672
    67     struct AttributeRules {
    68         WTF_MAKE_FAST_ALLOCATED;
    69     public:
    70         using SelectorKey = std::pair<AtomicStringImpl*, std::pair<AtomicStringImpl*, unsigned>>;
    71         HashMap<SelectorKey, const CSSSelector*> selectors;
    72         Vector<RuleFeature> features;
    73     };
    74     HashMap<AtomicString, std::unique_ptr<AttributeRules>> ancestorAttributeRulesForHTML;
    7573    bool usesFirstLineRules { false };
    7674    bool usesFirstLetterRules { false };
     
    8482
    8583        Vector<std::pair<AtomicString, MatchElement>, 32> classes;
    86         Vector<const CSSSelector*> attributeSelectorsMatchingAncestors;
     84        Vector<std::pair<const CSSSelector*, MatchElement>, 32> attributes;
    8785    };
    8886    void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject);
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/css/StyleBuilderCustom.h

    r227676 r228669  
    14241424            didSet = true;
    14251425            // Register the fact that the attribute value affects the style.
    1426             styleResolver.ruleSets().mutableFeatures().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
    1427             styleResolver.ruleSets().mutableFeatures().attributeLocalNamesInRules.add(attr.localName().impl());
     1426            styleResolver.ruleSets().mutableFeatures().registerContentAttribute(attr.localName());
    14281427        } else if (contentValue.isCounter()) {
    14291428            auto* counterValue = contentValue.counterValue();
     
    18221821
    18231822        // Register the fact that the attribute value affects the style.
    1824         styleResolver.ruleSets().mutableFeatures().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
    1825         styleResolver.ruleSets().mutableFeatures().attributeLocalNamesInRules.add(attr.localName().impl());
     1823        styleResolver.ruleSets().mutableFeatures().registerContentAttribute(attr.localName());
    18261824    } else
    18271825        styleResolver.style()->setContentAltText(emptyAtom());
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/html/HTMLEmbedElement.cpp

    r224320 r228669  
    106106}
    107107
     108static bool hasTypeOrSrc(const HTMLEmbedElement& embed)
     109{
     110    return embed.hasAttributeWithoutSynchronization(typeAttr) || embed.hasAttributeWithoutSynchronization(srcAttr);
     111}
     112
    108113void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
    109114{
     
    113118        // code is that HTMLObjectElement does setNeedsWidgetUpdate(true). Consider moving
    114119        // this up to the HTMLPlugInImageElement to be shared.
     120        if (renderer() && !hasTypeOrSrc(*this))
     121            invalidateStyle();
    115122    } else if (name == codeAttr) {
    116123        m_url = stripLeadingAndTrailingHTMLSpaces(value);
     
    120127        m_url = stripLeadingAndTrailingHTMLSpaces(value);
    121128        updateImageLoaderWithNewURLSoon();
     129        if (renderer() && !hasTypeOrSrc(*this))
     130            invalidateStyle();
    122131        // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
    123132    } else
     
    192201bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
    193202{
    194     if (!hasAttributeWithoutSynchronization(typeAttr) && !hasAttributeWithoutSynchronization(srcAttr))
     203    if (!hasTypeOrSrc(*this))
    195204        return false;
    196205
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.cpp

    r220204 r228669  
    4747    bool isHTML = m_element.isHTMLElement();
    4848
    49     bool mayAffectStyle = false;
     49    bool shouldInvalidateCurrent = false;
    5050    bool mayAffectStyleInShadowTree = false;
    5151
     52    auto attributeNameForLookups = attributeName.localName().convertToASCIILowercase();
     53
    5254    traverseRuleFeatures(m_element, [&] (const RuleFeatureSet& features, bool mayAffectShadowTree) {
    53         if (!mayBeAffectedByAttributeChange(features, isHTML, attributeName))
    54             return;
    55         mayAffectStyle = true;
    56         if (mayAffectShadowTree)
     55        if (mayAffectShadowTree && mayBeAffectedByAttributeChange(features, isHTML, attributeName))
    5756            mayAffectStyleInShadowTree = true;
     57        if (features.attributesAffectingHost.contains(attributeNameForLookups))
     58            shouldInvalidateCurrent = true;
     59        else if (features.contentAttributeNamesInRules.contains(attributeNameForLookups))
     60            shouldInvalidateCurrent = true;
    5861    });
    59 
    60     if (!mayAffectStyle)
    61         return;
    62 
    63     if (!isHTML) {
    64         m_element.invalidateStyleForSubtree();
    65         return;
    66     }
    6762
    6863    if (mayAffectStyleInShadowTree) {
    6964        // FIXME: More fine-grained invalidation.
    7065        m_element.invalidateStyleForSubtree();
    71         return;
    7266    }
    7367
    74     m_element.invalidateStyle();
     68    if (shouldInvalidateCurrent)
     69        m_element.invalidateStyle();
    7570
    76     if (!childrenOfType<Element>(m_element).first())
     71    auto& ruleSets = m_element.styleResolver().ruleSets();
     72
     73    auto* invalidationRuleSets = ruleSets.attributeInvalidationRuleSets(attributeNameForLookups);
     74    if (!invalidationRuleSets)
    7775        return;
    7876
    79     auto& ruleSets = m_element.styleResolver().ruleSets();
    80     auto* attributeRules = ruleSets.ancestorAttributeRulesForHTML(attributeName.localName());
    81     if (!attributeRules)
    82         return;
    83 
    84     // Check if descendants may be affected by this attribute change.
    85     for (auto* selector : attributeRules->attributeSelectors) {
    86         bool oldMatches = oldValue.isNull() ? false : SelectorChecker::attributeSelectorMatches(m_element, attributeName, oldValue, *selector);
    87         bool newMatches = newValue.isNull() ? false : SelectorChecker::attributeSelectorMatches(m_element, attributeName, newValue, *selector);
    88 
    89         if (oldMatches != newMatches) {
    90             m_descendantInvalidationRuleSet = attributeRules->ruleSet.get();
    91             return;
     77    for (auto& invalidationRuleSet : *invalidationRuleSets) {
     78        for (auto* selector : invalidationRuleSet.invalidationSelectors) {
     79            bool oldMatches = !oldValue.isNull() && SelectorChecker::attributeSelectorMatches(m_element, attributeName, oldValue, *selector);
     80            bool newMatches = !newValue.isNull() && SelectorChecker::attributeSelectorMatches(m_element, attributeName, newValue, *selector);
     81            if (oldMatches != newMatches) {
     82                m_invalidationRuleSets.append(&invalidationRuleSet);
     83                break;
     84            }
    9285        }
    9386    }
    9487}
    9588
    96 void AttributeChangeInvalidation::invalidateDescendants()
     89void AttributeChangeInvalidation::invalidateStyleWithRuleSets()
    9790{
    98     if (!m_descendantInvalidationRuleSet)
    99         return;
    100     Invalidator invalidator(*m_descendantInvalidationRuleSet);
    101     invalidator.invalidateStyle(m_element);
     91    for (auto* invalidationRuleSet : m_invalidationRuleSets) {
     92        Invalidator invalidator(*invalidationRuleSet->ruleSet);
     93        invalidator.invalidateStyleWithMatchElement(m_element, invalidationRuleSet->matchElement);
     94    }
    10295}
     96
    10397
    10498}
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.h

    r208668 r228669  
    3030namespace WebCore {
    3131
    32 class RuleSet;
     32struct InvalidationRuleSet;
    3333
    3434namespace Style {
     
    4141private:
    4242    void invalidateStyle(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    43     void invalidateDescendants();
     43    void invalidateStyleWithRuleSets();
    4444
    4545    const bool m_isEnabled;
    4646    Element& m_element;
    4747
    48     const RuleSet* m_descendantInvalidationRuleSet { nullptr };
     48    Vector<const InvalidationRuleSet*, 4> m_invalidationRuleSets;
    4949};
    5050
     
    5656        return;
    5757    invalidateStyle(attributeName, oldValue, newValue);
    58     invalidateDescendants();
     58    invalidateStyleWithRuleSets();
    5959}
    6060
     
    6363    if (!m_isEnabled)
    6464        return;
    65     invalidateDescendants();
     65    invalidateStyleWithRuleSets();
    6666}
    6767   
  • releases/WebKitGTK/webkit-2.20/Source/WebCore/style/ClassChangeInvalidation.cpp

    r227787 r228669  
    103103        // FIXME: We should do fine-grained invalidation for shadow tree.
    104104        m_element.invalidateStyleForSubtree();
    105         return;
    106105    }
    107106
Note: See TracChangeset for help on using the changeset viewer.