Commit 0f24a5ef authored by rune@opera.com's avatar rune@opera.com

Single code path for updating invalidation sets.

Allow all selectors to update invalidation sets using updateInvalidationSets
and never fall back to a separate wholeSubtree loop in
collectFeaturesFromSelector. The method for finding the InvalidationSetMode
is dropped completely.

With this change we are now at a point were a whole subtree invalidation is
only necessary for these cases:

1. There are no recognized features in the rightmost compound selector

 - A universal selector: ".a *"
 - Only contains pseudo classes or elements that are not considered
   features:

   ".a ::before", ".a :first-child", etc.

2. The invalidation set component is immediately left of an adjacent
   combinator:

   ".a + .b", ".a ~ .b"

3. The selector has a ::first-letter or ::first-line pseudo

   These are currently depending on style recalc or layout below the
   element they are pseudo elements for.

3. There is a :host-context() in the rightmost compound selector

   :host-context sub-selectors match ascendants of the :host element for
   which we are resolving style, so ":host-context(.a)" is effectively the
   same as ".a :host" which falls under no recognized features in the
   rightmost compound in point 1.

Points 1, 3, and 4 are now handled through
InvalidationSetFeatures::forceSubtree set as a result of feature extraction.
Point 2 is handled by updating InvalidationSetFeatures::adjacent as we
progress past selector combinators.

RuleFeaturesSet::collectFeaturesFromSelector is now back to how it was
before we introduced invalidation sets (without the feature hash sets).
Now, it only counts adjacent combinators and sets a flag when finding
::first-line, so it is possible to squash it into the same method as
updateInvalidationSets() to have a single pass over the selector when
finding rule features (if we want to do that).

The lowered expected node count in the :host-context test is due to the
fact that we only fall back to subtree invalidation when present in the
rightmost compound. ::first-letter/::first-line are always in the rightmost
compound, and :host-context() doesn't need subtree invalidation when in
other compounds. ":host-context(.a) .b" is effectively ".a :host .b".

R=chrishtr@chromium.org
BUG=335247

Review URL: https://codereview.chromium.org/726503003

git-svn-id: svn://svn.chromium.org/blink/trunk@185354 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8e1c34db
...@@ -38,7 +38,7 @@ test(function(){ ...@@ -38,7 +38,7 @@ test(function(){
assert_equals(getComputedStyle(inner, "").backgroundColor, transparent, "Background color before class change."); assert_equals(getComputedStyle(inner, "").backgroundColor, transparent, "Background color before class change.");
t2.className = "t2"; t2.className = "t2";
if (window.internals) if (window.internals)
assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 8, "Element recalc count on class change."); assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 2, "Element recalc count on class change.");
assert_equals(getComputedStyle(inner, "").backgroundColor, green, "Background color after class change."); assert_equals(getComputedStyle(inner, "").backgroundColor, green, "Background color after class change.");
}, "Matching id descendant of :host-context with class."); }, "Matching id descendant of :host-context with class.");
......
...@@ -125,23 +125,14 @@ private: ...@@ -125,23 +125,14 @@ private:
unsigned maxDirectAdjacentSelectors; unsigned maxDirectAdjacentSelectors;
}; };
enum InvalidationSetMode { void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&);
AddFeatures,
UseLocalStyleChange,
UseSubtreeStyleChange
};
static InvalidationSetMode invalidationSetModeForSelector(const CSSSelector&);
void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, InvalidationSetMode);
void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, InvalidationSetMode);
DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className); DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className);
DescendantInvalidationSet& ensureAttributeInvalidationSet(const AtomicString& attributeName); DescendantInvalidationSet& ensureAttributeInvalidationSet(const AtomicString& attributeName);
DescendantInvalidationSet& ensureIdInvalidationSet(const AtomicString& attributeName); DescendantInvalidationSet& ensureIdInvalidationSet(const AtomicString& attributeName);
DescendantInvalidationSet& ensurePseudoInvalidationSet(CSSSelector::PseudoType); DescendantInvalidationSet& ensurePseudoInvalidationSet(CSSSelector::PseudoType);
InvalidationSetMode updateInvalidationSets(const CSSSelector&); void updateInvalidationSets(const CSSSelector&);
struct InvalidationSetFeatures { struct InvalidationSetFeatures {
InvalidationSetFeatures() InvalidationSetFeatures()
...@@ -149,7 +140,11 @@ private: ...@@ -149,7 +140,11 @@ private:
, treeBoundaryCrossing(false) , treeBoundaryCrossing(false)
, adjacent(false) , adjacent(false)
, insertionPointCrossing(false) , insertionPointCrossing(false)
, forceSubtree(false)
{ } { }
bool useSubtreeInvalidation() const { return forceSubtree || adjacent; }
Vector<AtomicString> classes; Vector<AtomicString> classes;
Vector<AtomicString> attributes; Vector<AtomicString> attributes;
AtomicString id; AtomicString id;
...@@ -158,10 +153,14 @@ private: ...@@ -158,10 +153,14 @@ private:
bool treeBoundaryCrossing; bool treeBoundaryCrossing;
bool adjacent; bool adjacent;
bool insertionPointCrossing; bool insertionPointCrossing;
bool forceSubtree;
}; };
static void extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&); static bool extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
const CSSSelector* extractInvalidationSetFeatures(const CSSSelector&, InvalidationSetFeatures&, bool negated);
enum UseFeaturesType { UseFeatures, ForceSubtree };
std::pair<const CSSSelector*, UseFeaturesType> extractInvalidationSetFeatures(const CSSSelector&, InvalidationSetFeatures&, bool negated);
void addFeaturesToInvalidationSet(DescendantInvalidationSet&, const InvalidationSetFeatures&); void addFeaturesToInvalidationSet(DescendantInvalidationSet&, const InvalidationSetFeatures&);
void addFeaturesToInvalidationSets(const CSSSelector&, InvalidationSetFeatures&); void addFeaturesToInvalidationSets(const CSSSelector&, InvalidationSetFeatures&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment