|
Lines 170-179
SelectorChecker::SelectorChecker(Document& document)
a/Source/WebCore/css/SelectorChecker.cpp_sec1
|
| 170 |
{ |
170 |
{ |
| 171 |
} |
171 |
} |
| 172 |
|
172 |
|
| 173 |
bool SelectorChecker::match(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext, unsigned& specificity) const |
173 |
bool SelectorChecker::match(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext) const |
| 174 |
{ |
174 |
{ |
| 175 |
specificity = 0; |
|
|
| 176 |
|
| 177 |
LocalContext context(selector, element, checkingContext.resolvingMode == SelectorChecker::Mode::QueryingRules ? VisitedMatchType::Disabled : VisitedMatchType::Enabled, checkingContext.pseudoId); |
175 |
LocalContext context(selector, element, checkingContext.resolvingMode == SelectorChecker::Mode::QueryingRules ? VisitedMatchType::Disabled : VisitedMatchType::Enabled, checkingContext.pseudoId); |
| 178 |
|
176 |
|
| 179 |
if (checkingContext.isMatchingHostPseudoClass) { |
177 |
if (checkingContext.isMatchingHostPseudoClass) { |
|
Lines 182-188
bool SelectorChecker::match(const CSSSelector& selector, const Element& element,
a/Source/WebCore/css/SelectorChecker.cpp_sec2
|
| 182 |
} |
180 |
} |
| 183 |
|
181 |
|
| 184 |
PseudoIdSet pseudoIdSet; |
182 |
PseudoIdSet pseudoIdSet; |
| 185 |
MatchResult result = matchRecursively(checkingContext, context, pseudoIdSet, specificity); |
183 |
MatchResult result = matchRecursively(checkingContext, context, pseudoIdSet); |
| 186 |
if (result.match != Match::SelectorMatches) |
184 |
if (result.match != Match::SelectorMatches) |
| 187 |
return false; |
185 |
return false; |
| 188 |
if (checkingContext.pseudoId != PseudoId::None && !pseudoIdSet.has(checkingContext.pseudoId)) |
186 |
if (checkingContext.pseudoId != PseudoId::None && !pseudoIdSet.has(checkingContext.pseudoId)) |
|
Lines 200-221
bool SelectorChecker::match(const CSSSelector& selector, const Element& element,
a/Source/WebCore/css/SelectorChecker.cpp_sec3
|
| 200 |
return true; |
198 |
return true; |
| 201 |
} |
199 |
} |
| 202 |
|
200 |
|
| 203 |
bool SelectorChecker::matchHostPseudoClass(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext, unsigned& specificity) const |
201 |
bool SelectorChecker::matchHostPseudoClass(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext) const |
| 204 |
{ |
202 |
{ |
| 205 |
ASSERT(element.shadowRoot()); |
203 |
ASSERT(element.shadowRoot()); |
| 206 |
ASSERT(selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost); |
204 |
ASSERT(selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost); |
| 207 |
|
205 |
|
| 208 |
specificity = selector.simpleSelectorSpecificity(); |
|
|
| 209 |
|
| 210 |
if (auto* selectorList = selector.selectorList()) { |
206 |
if (auto* selectorList = selector.selectorList()) { |
| 211 |
LocalContext context(*selectorList->first(), element, VisitedMatchType::Enabled, PseudoId::None); |
207 |
LocalContext context(*selectorList->first(), element, VisitedMatchType::Enabled, PseudoId::None); |
| 212 |
context.inFunctionalPseudoClass = true; |
208 |
context.inFunctionalPseudoClass = true; |
| 213 |
context.pseudoElementEffective = false; |
209 |
context.pseudoElementEffective = false; |
| 214 |
PseudoIdSet ignoreDynamicPseudo; |
210 |
PseudoIdSet ignoreDynamicPseudo; |
| 215 |
unsigned subselectorSpecificity = 0; |
211 |
if (matchRecursively(checkingContext, context, ignoreDynamicPseudo).match != Match::SelectorMatches) |
| 216 |
if (matchRecursively(checkingContext, context, ignoreDynamicPseudo, subselectorSpecificity).match != Match::SelectorMatches) |
|
|
| 217 |
return false; |
212 |
return false; |
| 218 |
specificity = CSSSelector::addSpecificities(specificity, subselectorSpecificity); |
|
|
| 219 |
} |
213 |
} |
| 220 |
return true; |
214 |
return true; |
| 221 |
} |
215 |
} |
|
Lines 263-274
static SelectorChecker::LocalContext localContextForParent(const SelectorChecker
a/Source/WebCore/css/SelectorChecker.cpp_sec4
|
| 263 |
// * SelectorFailsLocally - the selector fails for the element e |
257 |
// * SelectorFailsLocally - the selector fails for the element e |
| 264 |
// * SelectorFailsAllSiblings - the selector fails for e and any sibling of e |
258 |
// * SelectorFailsAllSiblings - the selector fails for e and any sibling of e |
| 265 |
// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e |
259 |
// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e |
| 266 |
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext& checkingContext, const LocalContext& context, PseudoIdSet& dynamicPseudoIdSet, unsigned& specificity) const |
260 |
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext& checkingContext, const LocalContext& context, PseudoIdSet& dynamicPseudoIdSet) const |
| 267 |
{ |
261 |
{ |
| 268 |
MatchType matchType = MatchType::Element; |
262 |
MatchType matchType = MatchType::Element; |
| 269 |
|
263 |
|
| 270 |
// The first selector has to match. |
264 |
// The first selector has to match. |
| 271 |
if (!checkOne(checkingContext, context, matchType, specificity)) |
265 |
if (!checkOne(checkingContext, context, matchType)) |
| 272 |
return MatchResult::fails(Match::SelectorFailsLocally); |
266 |
return MatchResult::fails(Match::SelectorFailsLocally); |
| 273 |
|
267 |
|
| 274 |
if (context.selector->match() == CSSSelector::PseudoElement) { |
268 |
if (context.selector->match() == CSSSelector::PseudoElement) { |
|
Lines 336-348
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec5
|
| 336 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
330 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
| 337 |
for (; nextContext.element; nextContext = localContextForParent(nextContext)) { |
331 |
for (; nextContext.element; nextContext = localContextForParent(nextContext)) { |
| 338 |
PseudoIdSet ignoreDynamicPseudo; |
332 |
PseudoIdSet ignoreDynamicPseudo; |
| 339 |
unsigned descendantsSpecificity = 0; |
333 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo); |
| 340 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, descendantsSpecificity); |
|
|
| 341 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
334 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
| 342 |
|
335 |
|
| 343 |
if (result.match == Match::SelectorMatches) |
|
|
| 344 |
specificity = CSSSelector::addSpecificities(specificity, descendantsSpecificity); |
| 345 |
|
| 346 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsCompletely) |
336 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsCompletely) |
| 347 |
return MatchResult::updateWithMatchType(result, matchType); |
337 |
return MatchResult::updateWithMatchType(result, matchType); |
| 348 |
} |
338 |
} |
|
Lines 355-367
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec6
|
| 355 |
return MatchResult::fails(Match::SelectorFailsCompletely); |
345 |
return MatchResult::fails(Match::SelectorFailsCompletely); |
| 356 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
346 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
| 357 |
PseudoIdSet ignoreDynamicPseudo; |
347 |
PseudoIdSet ignoreDynamicPseudo; |
| 358 |
unsigned childSpecificity = 0; |
348 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo); |
| 359 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, childSpecificity); |
|
|
| 360 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
349 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
| 361 |
|
350 |
|
| 362 |
if (result.match == Match::SelectorMatches) |
|
|
| 363 |
specificity = CSSSelector::addSpecificities(specificity, childSpecificity); |
| 364 |
|
| 365 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsCompletely) |
351 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsCompletely) |
| 366 |
return MatchResult::updateWithMatchType(result, matchType); |
352 |
return MatchResult::updateWithMatchType(result, matchType); |
| 367 |
return MatchResult::fails(Match::SelectorFailsAllSiblings); |
353 |
return MatchResult::fails(Match::SelectorFailsAllSiblings); |
|
Lines 381-393
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec7
|
| 381 |
nextContext.element = previousElement; |
367 |
nextContext.element = previousElement; |
| 382 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
368 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
| 383 |
PseudoIdSet ignoreDynamicPseudo; |
369 |
PseudoIdSet ignoreDynamicPseudo; |
| 384 |
unsigned adjacentSpecificity = 0; |
370 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo); |
| 385 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, adjacentSpecificity); |
|
|
| 386 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
371 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
| 387 |
|
372 |
|
| 388 |
if (result.match == Match::SelectorMatches) |
|
|
| 389 |
specificity = CSSSelector::addSpecificities(specificity, adjacentSpecificity); |
| 390 |
|
| 391 |
return MatchResult::updateWithMatchType(result, matchType); |
373 |
return MatchResult::updateWithMatchType(result, matchType); |
| 392 |
} |
374 |
} |
| 393 |
case CSSSelector::IndirectAdjacent: { |
375 |
case CSSSelector::IndirectAdjacent: { |
|
Lines 400-412
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec8
|
| 400 |
addStyleRelation(checkingContext, *nextContext.element, Style::Relation::AffectsNextSibling); |
382 |
addStyleRelation(checkingContext, *nextContext.element, Style::Relation::AffectsNextSibling); |
| 401 |
|
383 |
|
| 402 |
PseudoIdSet ignoreDynamicPseudo; |
384 |
PseudoIdSet ignoreDynamicPseudo; |
| 403 |
unsigned indirectAdjacentSpecificity = 0; |
385 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo); |
| 404 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, indirectAdjacentSpecificity); |
|
|
| 405 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
386 |
ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); |
| 406 |
|
387 |
|
| 407 |
if (result.match == Match::SelectorMatches) |
|
|
| 408 |
specificity = CSSSelector::addSpecificities(specificity, indirectAdjacentSpecificity); |
| 409 |
|
| 410 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsAllSiblings || result.match == Match::SelectorFailsCompletely) |
388 |
if (result.match == Match::SelectorMatches || result.match == Match::SelectorFailsAllSiblings || result.match == Match::SelectorFailsCompletely) |
| 411 |
return MatchResult::updateWithMatchType(result, matchType); |
389 |
return MatchResult::updateWithMatchType(result, matchType); |
| 412 |
}; |
390 |
}; |
|
Lines 424-434
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec9
|
| 424 |
&& !(nextContext.hasScrollbarPseudo && nextContext.selector->match() == CSSSelector::PseudoClass)) |
402 |
&& !(nextContext.hasScrollbarPseudo && nextContext.selector->match() == CSSSelector::PseudoClass)) |
| 425 |
return MatchResult::fails(Match::SelectorFailsCompletely); |
403 |
return MatchResult::fails(Match::SelectorFailsCompletely); |
| 426 |
|
404 |
|
| 427 |
unsigned subselectorSpecificity = 0; |
405 |
MatchResult result = matchRecursively(checkingContext, nextContext, dynamicPseudoIdSet); |
| 428 |
MatchResult result = matchRecursively(checkingContext, nextContext, dynamicPseudoIdSet, subselectorSpecificity); |
|
|
| 429 |
|
| 430 |
if (result.match == Match::SelectorMatches) |
| 431 |
specificity = CSSSelector::addSpecificities(specificity, subselectorSpecificity); |
| 432 |
|
406 |
|
| 433 |
return MatchResult::updateWithMatchType(result, matchType); |
407 |
return MatchResult::updateWithMatchType(result, matchType); |
| 434 |
} |
408 |
} |
|
Lines 443-453
SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext&
a/Source/WebCore/css/SelectorChecker.cpp_sec10
|
| 443 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
417 |
nextContext.firstSelectorOfTheFragment = nextContext.selector; |
| 444 |
nextContext.isSubjectOrAdjacentElement = false; |
418 |
nextContext.isSubjectOrAdjacentElement = false; |
| 445 |
PseudoIdSet ignoreDynamicPseudo; |
419 |
PseudoIdSet ignoreDynamicPseudo; |
| 446 |
unsigned shadowDescendantSpecificity = 0; |
420 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo); |
| 447 |
MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, shadowDescendantSpecificity); |
|
|
| 448 |
|
| 449 |
if (result.match == Match::SelectorMatches) |
| 450 |
specificity = CSSSelector::addSpecificities(specificity, shadowDescendantSpecificity); |
| 451 |
|
421 |
|
| 452 |
return MatchResult::updateWithMatchType(result, matchType); |
422 |
return MatchResult::updateWithMatchType(result, matchType); |
| 453 |
} |
423 |
} |
|
Lines 651-663
static inline bool tagMatches(const Element& element, const CSSSelector& simpleS
a/Source/WebCore/css/SelectorChecker.cpp_sec11
|
| 651 |
return namespaceURI == starAtom() || namespaceURI == element.namespaceURI(); |
621 |
return namespaceURI == starAtom() || namespaceURI == element.namespaceURI(); |
| 652 |
} |
622 |
} |
| 653 |
|
623 |
|
| 654 |
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalContext& context, MatchType& matchType, unsigned& specificity) const |
624 |
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalContext& context, MatchType& matchType) const |
| 655 |
{ |
625 |
{ |
| 656 |
const Element& element = *context.element; |
626 |
const Element& element = *context.element; |
| 657 |
const CSSSelector& selector = *context.selector; |
627 |
const CSSSelector& selector = *context.selector; |
| 658 |
|
628 |
|
| 659 |
specificity = CSSSelector::addSpecificities(specificity, selector.simpleSelectorSpecificity()); |
|
|
| 660 |
|
| 661 |
if (context.mayMatchHostPseudoClass) { |
629 |
if (context.mayMatchHostPseudoClass) { |
| 662 |
// :host doesn't combine with anything except pseudo elements. |
630 |
// :host doesn't combine with anything except pseudo elements. |
| 663 |
bool isHostPseudoClass = selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost; |
631 |
bool isHostPseudoClass = selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost; |
|
Lines 704-711
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec12
|
| 704 |
subcontext.firstSelectorOfTheFragment = selectorList->first(); |
672 |
subcontext.firstSelectorOfTheFragment = selectorList->first(); |
| 705 |
PseudoIdSet ignoreDynamicPseudo; |
673 |
PseudoIdSet ignoreDynamicPseudo; |
| 706 |
|
674 |
|
| 707 |
unsigned ignoredSpecificity; |
675 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo).match == Match::SelectorMatches) { |
| 708 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches) { |
|
|
| 709 |
ASSERT(!ignoreDynamicPseudo); |
676 |
ASSERT(!ignoreDynamicPseudo); |
| 710 |
return false; |
677 |
return false; |
| 711 |
} |
678 |
} |
|
Lines 833-839
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec13
|
| 833 |
case CSSSelector::PseudoClassMatches: |
800 |
case CSSSelector::PseudoClassMatches: |
| 834 |
{ |
801 |
{ |
| 835 |
bool hasMatchedAnything = false; |
802 |
bool hasMatchedAnything = false; |
| 836 |
unsigned maxSpecificity = 0; |
|
|
| 837 |
|
803 |
|
| 838 |
MatchType localMatchType = MatchType::VirtualPseudoElementOnly; |
804 |
MatchType localMatchType = MatchType::VirtualPseudoElementOnly; |
| 839 |
for (const CSSSelector* subselector = selector.selectorList()->first(); subselector; subselector = CSSSelectorList::next(subselector)) { |
805 |
for (const CSSSelector* subselector = selector.selectorList()->first(); subselector; subselector = CSSSelectorList::next(subselector)) { |
|
Lines 844-869
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec14
|
| 844 |
subcontext.firstSelectorOfTheFragment = subselector; |
810 |
subcontext.firstSelectorOfTheFragment = subselector; |
| 845 |
subcontext.pseudoId = PseudoId::None; |
811 |
subcontext.pseudoId = PseudoId::None; |
| 846 |
PseudoIdSet localDynamicPseudoIdSet; |
812 |
PseudoIdSet localDynamicPseudoIdSet; |
| 847 |
unsigned localSpecificity = 0; |
813 |
MatchResult result = matchRecursively(checkingContext, subcontext, localDynamicPseudoIdSet); |
| 848 |
MatchResult result = matchRecursively(checkingContext, subcontext, localDynamicPseudoIdSet, localSpecificity); |
|
|
| 849 |
|
814 |
|
| 850 |
// Pseudo elements are not valid inside :is()/:matches() |
815 |
// Pseudo elements are not valid inside :is()/:matches() |
| 851 |
if (localDynamicPseudoIdSet) |
816 |
if (localDynamicPseudoIdSet) |
| 852 |
continue; |
817 |
continue; |
| 853 |
|
818 |
|
| 854 |
if (result.match == Match::SelectorMatches) { |
819 |
if (result.match == Match::SelectorMatches) { |
| 855 |
maxSpecificity = std::max(maxSpecificity, localSpecificity); |
|
|
| 856 |
|
| 857 |
if (result.matchType == MatchType::Element) |
820 |
if (result.matchType == MatchType::Element) |
| 858 |
localMatchType = MatchType::Element; |
821 |
localMatchType = MatchType::Element; |
| 859 |
|
822 |
|
| 860 |
hasMatchedAnything = true; |
823 |
hasMatchedAnything = true; |
| 861 |
} |
824 |
} |
| 862 |
} |
825 |
} |
| 863 |
if (hasMatchedAnything) { |
826 |
if (hasMatchedAnything) |
| 864 |
matchType = localMatchType; |
827 |
matchType = localMatchType; |
| 865 |
specificity = CSSSelector::addSpecificities(specificity, maxSpecificity); |
|
|
| 866 |
} |
| 867 |
return hasMatchedAnything; |
828 |
return hasMatchedAnything; |
| 868 |
} |
829 |
} |
| 869 |
case CSSSelector::PseudoClassPlaceholderShown: |
830 |
case CSSSelector::PseudoClassPlaceholderShown: |
|
Lines 881-897
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec15
|
| 881 |
break; // FIXME: Add the support for specifying relations on ShadowRoot. |
842 |
break; // FIXME: Add the support for specifying relations on ShadowRoot. |
| 882 |
|
843 |
|
| 883 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
844 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
| 884 |
unsigned selectorListSpecificity; |
845 |
if (!matchSelectorList(checkingContext, context, element, *selectorList)) |
| 885 |
if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity)) |
|
|
| 886 |
return false; |
846 |
return false; |
| 887 |
specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); |
|
|
| 888 |
} |
847 |
} |
| 889 |
|
848 |
|
| 890 |
int count = 1; |
849 |
int count = 1; |
| 891 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
850 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
| 892 |
for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { |
851 |
for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { |
| 893 |
unsigned ignoredSpecificity; |
852 |
if (matchSelectorList(checkingContext, context, *sibling, *selectorList)) |
| 894 |
if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity)) |
|
|
| 895 |
++count; |
853 |
++count; |
| 896 |
} |
854 |
} |
| 897 |
} else { |
855 |
} else { |
|
Lines 921-930
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec16
|
| 921 |
if (is<Element>(parent)) { |
879 |
if (is<Element>(parent)) { |
| 922 |
auto& parentElement = downcast<Element>(*parent); |
880 |
auto& parentElement = downcast<Element>(*parent); |
| 923 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
881 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
| 924 |
unsigned selectorListSpecificity; |
882 |
if (!matchSelectorList(checkingContext, context, element, *selectorList)) |
| 925 |
if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity)) |
|
|
| 926 |
return false; |
883 |
return false; |
| 927 |
specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); |
|
|
| 928 |
|
884 |
|
| 929 |
addStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules); |
885 |
addStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules); |
| 930 |
} else { |
886 |
} else { |
|
Lines 939-946
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec17
|
| 939 |
int count = 1; |
895 |
int count = 1; |
| 940 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
896 |
if (const CSSSelectorList* selectorList = selector.selectorList()) { |
| 941 |
for (Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) { |
897 |
for (Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) { |
| 942 |
unsigned ignoredSpecificity; |
898 |
if (matchSelectorList(checkingContext, context, *sibling, *selectorList)) |
| 943 |
if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity)) |
|
|
| 944 |
++count; |
899 |
++count; |
| 945 |
} |
900 |
} |
| 946 |
} else |
901 |
} else |
|
Lines 974-981
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec18
|
| 974 |
for (subcontext.selector = selector.selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) { |
929 |
for (subcontext.selector = selector.selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) { |
| 975 |
subcontext.firstSelectorOfTheFragment = subcontext.selector; |
930 |
subcontext.firstSelectorOfTheFragment = subcontext.selector; |
| 976 |
PseudoIdSet ignoreDynamicPseudo; |
931 |
PseudoIdSet ignoreDynamicPseudo; |
| 977 |
unsigned ingoredSpecificity = 0; |
932 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo).match == Match::SelectorMatches) |
| 978 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, ingoredSpecificity).match == Match::SelectorMatches) |
|
|
| 979 |
return true; |
933 |
return true; |
| 980 |
} |
934 |
} |
| 981 |
} |
935 |
} |
|
Lines 1090-1100
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec19
|
| 1090 |
case CSSSelector::PseudoClassHost: { |
1044 |
case CSSSelector::PseudoClassHost: { |
| 1091 |
if (!context.mayMatchHostPseudoClass) |
1045 |
if (!context.mayMatchHostPseudoClass) |
| 1092 |
return false; |
1046 |
return false; |
| 1093 |
unsigned hostSpecificity; |
1047 |
return matchHostPseudoClass(selector, element, checkingContext); |
| 1094 |
if (!matchHostPseudoClass(selector, element, checkingContext, hostSpecificity)) |
|
|
| 1095 |
return false; |
| 1096 |
specificity = CSSSelector::addSpecificities(specificity, hostSpecificity); |
| 1097 |
return true; |
| 1098 |
} |
1048 |
} |
| 1099 |
case CSSSelector::PseudoClassDefined: |
1049 |
case CSSSelector::PseudoClassDefined: |
| 1100 |
return isDefinedElement(element); |
1050 |
return isDefinedElement(element); |
|
Lines 1147-1154
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec20
|
| 1147 |
subcontext.inFunctionalPseudoClass = true; |
1097 |
subcontext.inFunctionalPseudoClass = true; |
| 1148 |
subcontext.pseudoElementEffective = false; |
1098 |
subcontext.pseudoElementEffective = false; |
| 1149 |
PseudoIdSet ignoredDynamicPseudo; |
1099 |
PseudoIdSet ignoredDynamicPseudo; |
| 1150 |
unsigned ignoredSpecificity = 0; |
1100 |
if (matchRecursively(checkingContext, subcontext, ignoredDynamicPseudo).match == Match::SelectorMatches) |
| 1151 |
if (matchRecursively(checkingContext, subcontext, ignoredDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches) |
|
|
| 1152 |
return true; |
1101 |
return true; |
| 1153 |
} |
1102 |
} |
| 1154 |
return false; |
1103 |
return false; |
|
Lines 1204-1212
bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
a/Source/WebCore/css/SelectorChecker.cpp_sec21
|
| 1204 |
return true; |
1153 |
return true; |
| 1205 |
} |
1154 |
} |
| 1206 |
|
1155 |
|
| 1207 |
bool SelectorChecker::matchSelectorList(CheckingContext& checkingContext, const LocalContext& context, const Element& element, const CSSSelectorList& selectorList, unsigned& specificity) const |
1156 |
bool SelectorChecker::matchSelectorList(CheckingContext& checkingContext, const LocalContext& context, const Element& element, const CSSSelectorList& selectorList) const |
| 1208 |
{ |
1157 |
{ |
| 1209 |
specificity = 0; |
|
|
| 1210 |
bool hasMatchedAnything = false; |
1158 |
bool hasMatchedAnything = false; |
| 1211 |
|
1159 |
|
| 1212 |
for (const CSSSelector* subselector = selectorList.first(); subselector; subselector = CSSSelectorList::next(subselector)) { |
1160 |
for (const CSSSelector* subselector = selectorList.first(); subselector; subselector = CSSSelectorList::next(subselector)) { |
|
Lines 1217-1228
bool SelectorChecker::matchSelectorList(CheckingContext& checkingContext, const
a/Source/WebCore/css/SelectorChecker.cpp_sec22
|
| 1217 |
subcontext.pseudoElementEffective = false; |
1165 |
subcontext.pseudoElementEffective = false; |
| 1218 |
subcontext.firstSelectorOfTheFragment = subselector; |
1166 |
subcontext.firstSelectorOfTheFragment = subselector; |
| 1219 |
PseudoIdSet ignoreDynamicPseudo; |
1167 |
PseudoIdSet ignoreDynamicPseudo; |
| 1220 |
unsigned localSpecificity = 0; |
1168 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo).match == Match::SelectorMatches) { |
| 1221 |
if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, localSpecificity).match == Match::SelectorMatches) { |
|
|
| 1222 |
ASSERT(!ignoreDynamicPseudo); |
1169 |
ASSERT(!ignoreDynamicPseudo); |
| 1223 |
|
1170 |
|
| 1224 |
hasMatchedAnything = true; |
1171 |
hasMatchedAnything = true; |
| 1225 |
specificity = std::max(specificity, localSpecificity); |
|
|
| 1226 |
} |
1172 |
} |
| 1227 |
} |
1173 |
} |
| 1228 |
return hasMatchedAnything; |
1174 |
return hasMatchedAnything; |