Changeset 286135 in webkit
- Timestamp:
- Nov 23, 2021 7:47:54 AM (8 months ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/attribute-or-elemental-selectors-in-has-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/style/RuleFeature.cpp (modified) (6 diffs)
-
Source/WebCore/style/RuleFeature.h (modified) (2 diffs)
-
Source/WebCore/style/StyleInvalidator.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r286094 r286135 1 2021-11-23 Antti Koivisto <antti@apple.com> 2 3 [:has() pseudo-class] Basic invalidation support 4 https://bugs.webkit.org/show_bug.cgi?id=233443 5 6 Reviewed by Alan Bujtas. 7 8 * web-platform-tests/css/selectors/invalidation/attribute-or-elemental-selectors-in-has-expected.txt: 9 1 10 2021-11-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 11 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/attribute-or-elemental-selectors-in-has-expected.txt
r285921 r286135 3 3 PASS initial_color: div#div_child.color 4 4 PASS initial_color: div#div_grandchild.color 5 FAIL add .child to #div_child: div#div_subject.color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" 5 PASS add .child to #div_child: div#div_subject.color 6 6 PASS remove .child from #div_child: div#div_subject.color 7 7 PASS add .child to #div_grandchild: div#div_subject.color 8 8 PASS remove .child from #div_grandchild: div#div_subject.color 9 FAIL add .descendant to #div_child: div#div_subject.color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" 9 PASS add .descendant to #div_child: div#div_subject.color 10 10 PASS remove .descendant from #div_child: div#div_subject.color 11 FAIL add .descendant to #div_grandchild: div#div_subject.color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" 11 PASS add .descendant to #div_grandchild: div#div_subject.color 12 12 PASS remove .descendant from #div_grandchild: div#div_subject.color 13 FAIL set descendant to #div_grandchild[attrname]: div#div_subject.color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" 13 PASS set descendant to #div_grandchild[attrname]: div#div_subject.color 14 14 PASS clear #div_grandchild[attrname]: div#div_subject.color 15 15 FAIL change #div_grandchild to #div_descendant: div#div_subject.color assert_equals: expected "rgb(255, 255, 0)" but got "rgb(128, 128, 128)" -
trunk/Source/WebCore/ChangeLog
r286134 r286135 1 2021-11-23 Antti Koivisto <antti@apple.com> 2 3 [:has() pseudo-class] Basic invalidation support 4 https://bugs.webkit.org/show_bug.cgi?id=233443 5 6 Reviewed by Alan Bujtas. 7 8 Adde RuleSet based invalidation for :has(). This covers class/attribute/pseudo-class cases. 9 10 There is also a basic optimization that limits the invalidation scope based on :has() selector 11 matching child/descedant/sibling. 12 13 * style/RuleFeature.cpp: 14 (WebCore::Style::isSiblingOrSubject): 15 (WebCore::Style::isHasPseudoClassMatchElement): 16 (WebCore::Style::RuleFeatureSet::computeNextMatchElement): 17 (WebCore::Style::RuleFeatureSet::computeSubSelectorMatchElement): 18 19 Add new MatchElement types for :has and compute the value. This enables automatic 20 creation of the required invalidation rule sets. 21 22 (WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector): 23 * style/RuleFeature.h: 24 * style/StyleInvalidator.cpp: 25 (WebCore::Style::Invalidator::invalidateStyleWithMatchElement): 26 27 Traverse appropriate parent/ancestors/siblings to invalidate. 28 1 29 2021-11-23 Antti Koivisto <antti@apple.com> 2 30 -
trunk/Source/WebCore/style/RuleFeature.cpp
r284973 r286135 44 44 case MatchElement::DirectSibling: 45 45 case MatchElement::AnySibling: 46 case MatchElement::HasSibling: 46 47 case MatchElement::Host: 47 48 return true; … … 50 51 case MatchElement::ParentSibling: 51 52 case MatchElement::AncestorSibling: 53 case MatchElement::HasChild: 54 case MatchElement::HasDescendant: 52 55 return false; 53 56 } 54 57 ASSERT_NOT_REACHED(); 55 58 return false; 59 } 60 61 static bool isHasPseudoClassMatchElement(MatchElement matchElement) 62 { 63 switch (matchElement) { 64 case MatchElement::HasSibling: 65 case MatchElement::HasChild: 66 case MatchElement::HasDescendant: 67 return true; 68 default: 69 return false; 70 } 56 71 } 57 72 … … 68 83 MatchElement RuleFeatureSet::computeNextMatchElement(MatchElement matchElement, CSSSelector::RelationType relation) 69 84 { 85 if (isHasPseudoClassMatchElement(matchElement)) 86 return matchElement; 87 70 88 if (isSiblingOrSubject(matchElement)) { 71 89 switch (relation) { … … 112 130 }; 113 131 114 MatchElement RuleFeatureSet::computeSubSelectorMatchElement(MatchElement matchElement, const CSSSelector& selector) 115 { 116 ASSERT(selector.selectorList()); 117 132 MatchElement RuleFeatureSet::computeSubSelectorMatchElement(MatchElement matchElement, const CSSSelector& selector, const CSSSelector& childSelector) 133 { 118 134 if (selector.match() == CSSSelector::PseudoClass) { 119 135 auto type = selector.pseudoClassType(); … … 125 141 if (type == CSSSelector::PseudoClassHost) 126 142 return MatchElement::Host; 143 144 if (type == CSSSelector::PseudoClassHas) { 145 auto hasMatchElement = MatchElement::Subject; 146 for (auto* simpleSelector = &childSelector; simpleSelector->tagHistory(); simpleSelector = simpleSelector->tagHistory()) 147 hasMatchElement = computeNextMatchElement(hasMatchElement, simpleSelector->relation()); 148 149 if (hasMatchElement == MatchElement::Parent) 150 return MatchElement::HasChild; 151 if (isSiblingOrSubject(hasMatchElement)) 152 return MatchElement::HasSibling; 153 return MatchElement::HasDescendant; 154 } 127 155 } 128 156 if (selector.match() == CSSSelector::PseudoElement) { … … 169 197 170 198 if (const CSSSelectorList* selectorList = selector->selectorList()) { 171 auto subSelectorMatchElement = computeSubSelectorMatchElement(matchElement, *selector);172 173 199 for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) { 200 auto subSelectorMatchElement = computeSubSelectorMatchElement(matchElement, *selector, *subSelector); 174 201 if (!selectorFeatures.hasSiblingSelector && selector->isSiblingSelector()) 175 202 selectorFeatures.hasSiblingSelector = true; -
trunk/Source/WebCore/style/RuleFeature.h
r284857 r286135 37 37 class RuleData; 38 38 39 enum class MatchElement : uint8_t { Subject, Parent, Ancestor, DirectSibling, IndirectSibling, AnySibling, ParentSibling, AncestorSibling, H ost };39 enum class MatchElement : uint8_t { Subject, Parent, Ancestor, DirectSibling, IndirectSibling, AnySibling, ParentSibling, AncestorSibling, HasChild, HasDescendant, HasSibling, Host }; 40 40 constexpr unsigned matchElementCount = static_cast<unsigned>(MatchElement::Host) + 1; 41 41 … … 88 88 private: 89 89 static MatchElement computeNextMatchElement(MatchElement, CSSSelector::RelationType); 90 static MatchElement computeSubSelectorMatchElement(MatchElement, const CSSSelector& );90 static MatchElement computeSubSelectorMatchElement(MatchElement, const CSSSelector&, const CSSSelector& childSelector); 91 91 92 92 struct SelectorFeatures { -
trunk/Source/WebCore/style/StyleInvalidator.cpp
r285630 r286135 305 305 break; 306 306 } 307 case MatchElement::HasChild: { 308 if (auto* parent = element.parentElement()) 309 invalidateIfNeeded(*parent, nullptr); 310 break; 311 } 312 case MatchElement::HasDescendant: { 313 Vector<Element*, 16> ancestors; 314 for (auto* parent = element.parentElement(); parent; parent = parent->parentElement()) 315 ancestors.append(parent); 316 317 SelectorMatchingState selectorMatchingState; 318 for (auto* ancestor : makeReversedRange(ancestors)) { 319 invalidateIfNeeded(*ancestor, &selectorMatchingState); 320 selectorMatchingState.selectorFilter.pushParent(ancestor); 321 } 322 break; 323 } 324 case MatchElement::HasSibling: { 325 SelectorMatchingState selectorMatchingState; 326 for (auto* sibling = element.previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { 327 selectorMatchingState.selectorFilter.popParentsUntil(element.parentElement()); 328 invalidateStyleForDescendants(*sibling, &selectorMatchingState); 329 } 330 break; 331 } 307 332 case MatchElement::Host: 308 333 invalidateInShadowTreeIfNeeded(element);
Note: See TracChangeset
for help on using the changeset viewer.