Title: [228669] releases/WebKitGTK/webkit-2.20/Source/WebCore
Revision
228669
Author
carlo...@webkit.org
Date
2018-02-19 05:17:35 -0800 (Mon, 19 Feb 2018)

Log 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.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog	2018-02-19 13:17:35 UTC (rev 228669)
@@ -1,3 +1,69 @@
+2018-02-08  Antti Koivisto  <an...@apple.com>
+
+        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.
+
 2018-02-08  Zalan Bujtas  <za...@apple.com>
 
         [RenderTreeBuilder] Introduce RenderTreeBuilder to moveChild(ren)To() functions

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.cpp (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.cpp	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.cpp	2018-02-19 13:17:35 UTC (rev 228669)
@@ -168,47 +168,46 @@
     m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
 
     m_classInvalidationRuleSets.clear();
-    m_ancestorAttributeRuleSetsForHTML.clear();
+    m_attributeInvalidationRuleSets.clear();
 
     m_features.shrinkToFit();
 }
 
-const Vector<InvalidationRuleSet>* DocumentRuleSets::classInvalidationRuleSets(const AtomicString& className) const
+static Vector<InvalidationRuleSet>* ensureInvalidationRuleSets(const AtomicString& key, HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>>& ruleSetMap, const HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>>& ruleFeatures)
 {
-    return m_classInvalidationRuleSets.ensure(className, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
-        auto* features = m_features.classRules.get(className);
+    return ruleSetMap.ensure(key, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
+        auto* features = ruleFeatures.get(key);
         if (!features)
             return nullptr;
+
         std::array<std::unique_ptr<RuleSet>, matchElementCount> matchElementArray;
+        std::array<Vector<const CSSSelector*>, matchElementCount> invalidationSelectorArray;
         for (auto& feature : *features) {
-            auto& ruleSet = matchElementArray[static_cast<unsigned>(*feature.matchElement)];
+            auto arrayIndex = static_cast<unsigned>(*feature.matchElement);
+            auto& ruleSet = matchElementArray[arrayIndex];
             if (!ruleSet)
                 ruleSet = std::make_unique<RuleSet>();
             ruleSet->addRule(feature.rule, feature.selectorIndex);
+            if (feature.invalidationSelector)
+                invalidationSelectorArray[arrayIndex].append(feature.invalidationSelector);
         }
         auto invalidationRuleSets = std::make_unique<Vector<InvalidationRuleSet>>();
         for (unsigned i = 0; i < matchElementArray.size(); ++i) {
             if (matchElementArray[i])
-                invalidationRuleSets->append({ static_cast<MatchElement>(i), WTFMove(matchElementArray[i]) });
+                invalidationRuleSets->append({ static_cast<MatchElement>(i), WTFMove(matchElementArray[i]), WTFMove(invalidationSelectorArray[i]) });
         }
         return invalidationRuleSets;
     }).iterator->value.get();
 }
 
-const DocumentRuleSets::AttributeRules* DocumentRuleSets::ancestorAttributeRulesForHTML(const AtomicString& attributeName) const
+const Vector<InvalidationRuleSet>* DocumentRuleSets::classInvalidationRuleSets(const AtomicString& className) const
 {
-    auto addResult = m_ancestorAttributeRuleSetsForHTML.add(attributeName, nullptr);
-    auto& value = addResult.iterator->value;
-    if (addResult.isNewEntry) {
-        if (auto* rules = m_features.ancestorAttributeRulesForHTML.get(attributeName)) {
-            value = std::make_unique<AttributeRules>();
-            value->attributeSelectors.reserveCapacity(rules->selectors.size());
-            for (auto* selector : rules->selectors.values())
-                value->attributeSelectors.uncheckedAppend(selector);
-            value->ruleSet = makeRuleSet(rules->features);
-        }
-    }
-    return value.get();
+    return ensureInvalidationRuleSets(className, m_classInvalidationRuleSets, m_features.classRules);
 }
 
+const Vector<InvalidationRuleSet>* DocumentRuleSets::attributeInvalidationRuleSets(const AtomicString& attributeName) const
+{
+    return ensureInvalidationRuleSets(attributeName, m_attributeInvalidationRuleSets, m_features.attributeRules);
+}
+
 } // namespace WebCore

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.h (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.h	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/css/DocumentRuleSets.h	2018-02-19 13:17:35 UTC (rev 228669)
@@ -41,6 +41,7 @@
 struct InvalidationRuleSet {
     MatchElement matchElement;
     std::unique_ptr<RuleSet> ruleSet;
+    Vector<const CSSSelector*> invalidationSelectors;
 
     WTF_MAKE_FAST_ALLOCATED;
 };
@@ -59,15 +60,8 @@
     RuleSet* uncommonAttribute() const { return m_uncommonAttributeRuleSet.get(); }
 
     const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomicString& className) const;
+    const Vector<InvalidationRuleSet>* attributeInvalidationRuleSets(const AtomicString& attributeName) const;
 
-    struct AttributeRules {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        Vector<const CSSSelector*> attributeSelectors;
-        std::unique_ptr<RuleSet> ruleSet;
-    };
-    const AttributeRules* ancestorAttributeRulesForHTML(const AtomicString&) const;
-
     void setIsForShadowScope() { m_isForShadowScope = true; }
 
     void setUsesSharedUserStyle(bool b) { m_usesSharedUserStyle = b; }
@@ -99,7 +93,7 @@
     mutable std::unique_ptr<RuleSet> m_siblingRuleSet;
     mutable std::unique_ptr<RuleSet> m_uncommonAttributeRuleSet;
     mutable HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_classInvalidationRuleSets;
-    mutable HashMap<AtomicString, std::unique_ptr<AttributeRules>> m_ancestorAttributeRuleSetsForHTML;
+    mutable HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_attributeInvalidationRuleSets;
 };
 
 inline const RuleFeatureSet& DocumentRuleSets::features() const

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.cpp (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.cpp	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.cpp	2018-02-19 13:17:35 UTC (rev 228669)
@@ -130,8 +130,7 @@
             auto& localName = selector->attribute().localName();
             attributeCanonicalLocalNamesInRules.add(canonicalLocalName);
             attributeLocalNamesInRules.add(localName);
-            if (matchElement == MatchElement::Parent || matchElement == MatchElement::Ancestor)
-                selectorFeatures.attributeSelectorsMatchingAncestors.append(selector);
+            selectorFeatures.attributes.append(std::make_pair(selector, matchElement));
         } else if (selector->match() == CSSSelector::PseudoElement) {
             switch (selector->pseudoElementType()) {
             case CSSSelector::PseudoElementFirstLine:
@@ -164,13 +163,6 @@
     } while (selector);
 }
 
-static RuleFeatureSet::AttributeRules::SelectorKey makeAttributeSelectorKey(const CSSSelector& selector)
-{
-    bool caseInsensitive = selector.attributeValueMatchingIsCaseInsensitive();
-    unsigned matchAndCase = static_cast<unsigned>(selector.match()) << 1 | (caseInsensitive ? 1 : 0);
-    return std::make_pair(selector.attributeCanonicalLocalName().impl(), std::make_pair(selector.value().impl(), matchAndCase));
-}
-
 void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
 {
     SelectorFeatures selectorFeatures;
@@ -179,6 +171,7 @@
         siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     if (ruleData.containsUncommonAttributeSelector())
         uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
+
     for (auto& nameAndMatch : selectorFeatures.classes) {
         classRules.ensure(nameAndMatch.first, [] {
             return std::make_unique<Vector<RuleFeature>>();
@@ -186,15 +179,15 @@
         if (nameAndMatch.second == MatchElement::Host)
             classesAffectingHost.add(nameAndMatch.first);
     }
-    for (auto* selector : selectorFeatures.attributeSelectorsMatchingAncestors) {
-        // Hashing by attributeCanonicalLocalName makes this HTML specific.
-        auto addResult = ancestorAttributeRulesForHTML.ensure(selector->attributeCanonicalLocalName(), [] {
-            return std::make_unique<AttributeRules>();
-        });
-        auto& rules = *addResult.iterator->value;
-        rules.features.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
-        // Deduplicate selectors.
-        rules.selectors.add(makeAttributeSelectorKey(*selector), selector);
+
+    for (auto& selectorAndMatch : selectorFeatures.attributes) {
+        auto* selector = selectorAndMatch.first;
+        auto matchElement = selectorAndMatch.second;
+        attributeRules.ensure(selector->attribute().localName().convertToASCIILowercase(), [] {
+            return std::make_unique<Vector<RuleFeature>>();
+        }).iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), matchElement, selector));
+        if (matchElement == MatchElement::Host)
+            attributesAffectingHost.add(selector->attribute().localName().convertToASCIILowercase());
     }
 }
 
@@ -204,6 +197,7 @@
     idsMatchingAncestorsInRules.add(other.idsMatchingAncestorsInRules.begin(), other.idsMatchingAncestorsInRules.end());
     attributeCanonicalLocalNamesInRules.add(other.attributeCanonicalLocalNamesInRules.begin(), other.attributeCanonicalLocalNamesInRules.end());
     attributeLocalNamesInRules.add(other.attributeLocalNamesInRules.begin(), other.attributeLocalNamesInRules.end());
+    contentAttributeNamesInRules.add(other.contentAttributeNamesInRules.begin(), other.contentAttributeNamesInRules.end());
     siblingRules.appendVector(other.siblingRules);
     uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
     for (auto& keyValuePair : other.classRules) {
@@ -213,19 +207,24 @@
     }
     classesAffectingHost.add(other.classesAffectingHost.begin(), other.classesAffectingHost.end());
 
-    for (auto& keyValuePair : other.ancestorAttributeRulesForHTML) {
-        auto addResult = ancestorAttributeRulesForHTML.ensure(keyValuePair.key, [] {
-            return std::make_unique<AttributeRules>();
-        });
-        auto& rules = *addResult.iterator->value;
-        rules.features.appendVector(keyValuePair.value->features);
-        for (auto& selectorPair : keyValuePair.value->selectors)
-            rules.selectors.add(selectorPair.key, selectorPair.value);
+    for (auto& keyValuePair : other.attributeRules) {
+        attributeRules.ensure(keyValuePair.key, [] {
+            return std::make_unique<Vector<RuleFeature>>();
+        }).iterator->value->appendVector(*keyValuePair.value);
     }
+    attributesAffectingHost.add(other.attributesAffectingHost.begin(), other.attributesAffectingHost.end());
+
     usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
     usesFirstLetterRules = usesFirstLetterRules || other.usesFirstLetterRules;
 }
 
+void RuleFeatureSet::registerContentAttribute(const AtomicString& attributeName)
+{
+    contentAttributeNamesInRules.add(attributeName.convertToASCIILowercase());
+    attributeCanonicalLocalNamesInRules.add(attributeName);
+    attributeLocalNamesInRules.add(attributeName);
+}
+
 void RuleFeatureSet::clear()
 {
     idsInRules.clear();
@@ -232,11 +231,13 @@
     idsMatchingAncestorsInRules.clear();
     attributeCanonicalLocalNamesInRules.clear();
     attributeLocalNamesInRules.clear();
+    contentAttributeNamesInRules.clear();
     siblingRules.clear();
     uncommonAttributeRules.clear();
     classRules.clear();
     classesAffectingHost.clear();
-    ancestorAttributeRulesForHTML.clear();
+    attributeRules.clear();
+    attributesAffectingHost.clear();
     usesFirstLineRules = false;
     usesFirstLetterRules = false;
 }
@@ -247,8 +248,8 @@
     uncommonAttributeRules.shrinkToFit();
     for (auto& rules : classRules.values())
         rules->shrinkToFit();
-    for (auto& rules : ancestorAttributeRulesForHTML.values())
-        rules->features.shrinkToFit();
+    for (auto& rules : attributeRules.values())
+        rules->shrinkToFit();
 }
 
 } // namespace WebCore

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.h (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.h	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/css/RuleFeature.h	2018-02-19 13:17:35 UTC (rev 228669)
@@ -37,15 +37,17 @@
 constexpr unsigned matchElementCount = static_cast<unsigned>(MatchElement::Host) + 1;
 
 struct RuleFeature {
-    RuleFeature(StyleRule* rule, unsigned selectorIndex, std::optional<MatchElement> matchElement = std::nullopt)
+    RuleFeature(StyleRule* rule, unsigned selectorIndex, std::optional<MatchElement> matchElement = std::nullopt, const CSSSelector* invalidationSelector = nullptr)
         : rule(rule)
         , selectorIndex(selectorIndex)
         , matchElement(matchElement)
+        , invalidationSelector(invalidationSelector)
     {
     }
     StyleRule* rule;
     unsigned selectorIndex;
     std::optional<MatchElement> matchElement;
+    const CSSSelector* invalidationSelector;
 };
 
 struct RuleFeatureSet {
@@ -53,25 +55,21 @@
     void clear();
     void shrinkToFit();
     void collectFeatures(const RuleData&);
+    void registerContentAttribute(const AtomicString&);
 
     HashSet<AtomicString> idsInRules;
     HashSet<AtomicString> idsMatchingAncestorsInRules;
     HashSet<AtomicString> attributeCanonicalLocalNamesInRules;
     HashSet<AtomicString> attributeLocalNamesInRules;
+    HashSet<AtomicString> contentAttributeNamesInRules;
     Vector<RuleFeature> siblingRules;
     Vector<RuleFeature> uncommonAttributeRules;
     
     HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> classRules;
+    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> attributeRules;
     HashSet<AtomicString> classesAffectingHost;
+    HashSet<AtomicString> attributesAffectingHost;
 
-    struct AttributeRules {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        using SelectorKey = std::pair<AtomicStringImpl*, std::pair<AtomicStringImpl*, unsigned>>;
-        HashMap<SelectorKey, const CSSSelector*> selectors;
-        Vector<RuleFeature> features;
-    };
-    HashMap<AtomicString, std::unique_ptr<AttributeRules>> ancestorAttributeRulesForHTML;
     bool usesFirstLineRules { false };
     bool usesFirstLetterRules { false };
 
@@ -83,7 +81,7 @@
         bool hasSiblingSelector { false };
 
         Vector<std::pair<AtomicString, MatchElement>, 32> classes;
-        Vector<const CSSSelector*> attributeSelectorsMatchingAncestors;
+        Vector<std::pair<const CSSSelector*, MatchElement>, 32> attributes;
     };
     void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject);
 };

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/css/StyleBuilderCustom.h (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/css/StyleBuilderCustom.h	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/css/StyleBuilderCustom.h	2018-02-19 13:17:35 UTC (rev 228669)
@@ -1423,8 +1423,7 @@
             styleResolver.style()->setContent(value.isNull() ? emptyAtom() : value.impl(), didSet);
             didSet = true;
             // Register the fact that the attribute value affects the style.
-            styleResolver.ruleSets().mutableFeatures().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
-            styleResolver.ruleSets().mutableFeatures().attributeLocalNamesInRules.add(attr.localName().impl());
+            styleResolver.ruleSets().mutableFeatures().registerContentAttribute(attr.localName());
         } else if (contentValue.isCounter()) {
             auto* counterValue = contentValue.counterValue();
             EListStyleType listStyleType = NoneListStyle;
@@ -1821,8 +1820,7 @@
         styleResolver.style()->setContentAltText(value.isNull() ? emptyAtom() : value);
 
         // Register the fact that the attribute value affects the style.
-        styleResolver.ruleSets().mutableFeatures().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
-        styleResolver.ruleSets().mutableFeatures().attributeLocalNamesInRules.add(attr.localName().impl());
+        styleResolver.ruleSets().mutableFeatures().registerContentAttribute(attr.localName());
     } else
         styleResolver.style()->setContentAltText(emptyAtom());
 }

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/html/HTMLEmbedElement.cpp (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/html/HTMLEmbedElement.cpp	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/html/HTMLEmbedElement.cpp	2018-02-19 13:17:35 UTC (rev 228669)
@@ -105,6 +105,11 @@
         HTMLPlugInImageElement::collectStyleForPresentationAttribute(name, value, style);
 }
 
+static bool hasTypeOrSrc(const HTMLEmbedElement& embed)
+{
+    return embed.hasAttributeWithoutSynchronization(typeAttr) || embed.hasAttributeWithoutSynchronization(srcAttr);
+}
+
 void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == typeAttr) {
@@ -112,6 +117,8 @@
         // FIXME: The only difference between this and HTMLObjectElement's corresponding
         // code is that HTMLObjectElement does setNeedsWidgetUpdate(true). Consider moving
         // this up to the HTMLPlugInImageElement to be shared.
+        if (renderer() && !hasTypeOrSrc(*this))
+            invalidateStyle();
     } else if (name == codeAttr) {
         m_url = stripLeadingAndTrailingHTMLSpaces(value);
         // FIXME: Why no call to updateImageLoaderWithNewURLSoon?
@@ -119,6 +126,8 @@
     } else if (name == srcAttr) {
         m_url = stripLeadingAndTrailingHTMLSpaces(value);
         updateImageLoaderWithNewURLSoon();
+        if (renderer() && !hasTypeOrSrc(*this))
+            invalidateStyle();
         // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
     } else
         HTMLPlugInImageElement::parseAttribute(name, value);
@@ -191,7 +200,7 @@
 
 bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
 {
-    if (!hasAttributeWithoutSynchronization(typeAttr) && !hasAttributeWithoutSynchronization(srcAttr))
+    if (!hasTypeOrSrc(*this))
         return false;
 
     if (isImageType())

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.cpp (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.cpp	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.cpp	2018-02-19 13:17:35 UTC (rev 228669)
@@ -46,60 +46,54 @@
 
     bool isHTML = m_element.isHTMLElement();
 
-    bool mayAffectStyle = false;
+    bool shouldInvalidateCurrent = false;
     bool mayAffectStyleInShadowTree = false;
 
+    auto attributeNameForLookups = attributeName.localName().convertToASCIILowercase();
+
     traverseRuleFeatures(m_element, [&] (const RuleFeatureSet& features, bool mayAffectShadowTree) {
-        if (!mayBeAffectedByAttributeChange(features, isHTML, attributeName))
-            return;
-        mayAffectStyle = true;
-        if (mayAffectShadowTree)
+        if (mayAffectShadowTree && mayBeAffectedByAttributeChange(features, isHTML, attributeName))
             mayAffectStyleInShadowTree = true;
+        if (features.attributesAffectingHost.contains(attributeNameForLookups))
+            shouldInvalidateCurrent = true;
+        else if (features.contentAttributeNamesInRules.contains(attributeNameForLookups))
+            shouldInvalidateCurrent = true;
     });
 
-    if (!mayAffectStyle)
-        return;
-
-    if (!isHTML) {
-        m_element.invalidateStyleForSubtree();
-        return;
-    }
-
     if (mayAffectStyleInShadowTree) {
         // FIXME: More fine-grained invalidation.
         m_element.invalidateStyleForSubtree();
-        return;
     }
 
-    m_element.invalidateStyle();
+    if (shouldInvalidateCurrent)
+        m_element.invalidateStyle();
 
-    if (!childrenOfType<Element>(m_element).first())
-        return;
+    auto& ruleSets = m_element.styleResolver().ruleSets();
 
-    auto& ruleSets = m_element.styleResolver().ruleSets();
-    auto* attributeRules = ruleSets.ancestorAttributeRulesForHTML(attributeName.localName());
-    if (!attributeRules)
+    auto* invalidationRuleSets = ruleSets.attributeInvalidationRuleSets(attributeNameForLookups);
+    if (!invalidationRuleSets)
         return;
 
-    // Check if descendants may be affected by this attribute change.
-    for (auto* selector : attributeRules->attributeSelectors) {
-        bool oldMatches = oldValue.isNull() ? false : SelectorChecker::attributeSelectorMatches(m_element, attributeName, oldValue, *selector);
-        bool newMatches = newValue.isNull() ? false : SelectorChecker::attributeSelectorMatches(m_element, attributeName, newValue, *selector);
-
-        if (oldMatches != newMatches) {
-            m_descendantInvalidationRuleSet = attributeRules->ruleSet.get();
-            return;
+    for (auto& invalidationRuleSet : *invalidationRuleSets) {
+        for (auto* selector : invalidationRuleSet.invalidationSelectors) {
+            bool oldMatches = !oldValue.isNull() && SelectorChecker::attributeSelectorMatches(m_element, attributeName, oldValue, *selector);
+            bool newMatches = !newValue.isNull() && SelectorChecker::attributeSelectorMatches(m_element, attributeName, newValue, *selector);
+            if (oldMatches != newMatches) {
+                m_invalidationRuleSets.append(&invalidationRuleSet);
+                break;
+            }
         }
     }
 }
 
-void AttributeChangeInvalidation::invalidateDescendants()
+void AttributeChangeInvalidation::invalidateStyleWithRuleSets()
 {
-    if (!m_descendantInvalidationRuleSet)
-        return;
-    Invalidator invalidator(*m_descendantInvalidationRuleSet);
-    invalidator.invalidateStyle(m_element);
+    for (auto* invalidationRuleSet : m_invalidationRuleSets) {
+        Invalidator invalidator(*invalidationRuleSet->ruleSet);
+        invalidator.invalidateStyleWithMatchElement(m_element, invalidationRuleSet->matchElement);
+    }
 }
 
+
 }
 }

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.h (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.h	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/style/AttributeChangeInvalidation.h	2018-02-19 13:17:35 UTC (rev 228669)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class RuleSet;
+struct InvalidationRuleSet;
 
 namespace Style {
 
@@ -40,12 +40,12 @@
 
 private:
     void invalidateStyle(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
-    void invalidateDescendants();
+    void invalidateStyleWithRuleSets();
 
     const bool m_isEnabled;
     Element& m_element;
 
-    const RuleSet* m_descendantInvalidationRuleSet { nullptr };
+    Vector<const InvalidationRuleSet*, 4> m_invalidationRuleSets;
 };
 
 inline AttributeChangeInvalidation::AttributeChangeInvalidation(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
@@ -55,7 +55,7 @@
     if (!m_isEnabled)
         return;
     invalidateStyle(attributeName, oldValue, newValue);
-    invalidateDescendants();
+    invalidateStyleWithRuleSets();
 }
 
 inline AttributeChangeInvalidation::~AttributeChangeInvalidation()
@@ -62,7 +62,7 @@
 {
     if (!m_isEnabled)
         return;
-    invalidateDescendants();
+    invalidateStyleWithRuleSets();
 }
     
 }

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/style/ClassChangeInvalidation.cpp (228668 => 228669)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/style/ClassChangeInvalidation.cpp	2018-02-19 13:17:27 UTC (rev 228668)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/style/ClassChangeInvalidation.cpp	2018-02-19 13:17:35 UTC (rev 228669)
@@ -102,7 +102,6 @@
     if (mayAffectStyleInShadowTree) {
         // FIXME: We should do fine-grained invalidation for shadow tree.
         m_element.invalidateStyleForSubtree();
-        return;
     }
 
     if (shouldInvalidateCurrent)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to