OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::V0) | 260 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::V0) |
261 return nullptr; | 261 return nullptr; |
262 } | 262 } |
263 return element.parentOrShadowHostElement(); | 263 return element.parentOrShadowHostElement(); |
264 } | 264 } |
265 | 265 |
266 SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
ontext& context, MatchResult& result) const | 266 SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
ontext& context, MatchResult& result) const |
267 { | 267 { |
268 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; | 268 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; |
269 | 269 |
270 CSSSelector::Relation relation = context.selector->relation(); | 270 CSSSelector::RelationType relation = context.selector->relation(); |
271 | 271 |
272 // Disable :visited matching when we see the first link or try to match anyt
hing else than an ancestors. | 272 // Disable :visited matching when we see the first link or try to match anyt
hing else than an ancestors. |
273 if (!context.isSubSelector && (context.element->isLink() || (relation != CSS
Selector::Descendant && relation != CSSSelector::Child))) | 273 if (!context.isSubSelector && (context.element->isLink() || (relation != CSS
Selector::Descendant && relation != CSSSelector::Child))) |
274 nextContext.visitedMatchType = VisitedMatchDisabled; | 274 nextContext.visitedMatchType = VisitedMatchDisabled; |
275 | 275 |
276 nextContext.inRightmostCompound = false; | 276 nextContext.inRightmostCompound = false; |
277 nextContext.isSubSelector = false; | 277 nextContext.isSubSelector = false; |
278 nextContext.previousElement = context.element; | 278 nextContext.previousElement = context.element; |
279 nextContext.pseudoId = NOPSEUDO; | 279 nextContext.pseudoId = NOPSEUDO; |
280 | 280 |
281 switch (relation) { | 281 switch (relation) { |
282 case CSSSelector::Descendant: | 282 case CSSSelector::Descendant: |
283 if (context.selector->relationIsAffectedByPseudoContent()) { | 283 if (context.selector->relationIsAffectedByPseudoContent()) { |
284 for (Element* element = context.element; element; element = element-
>parentElement()) { | 284 for (Element* element = context.element; element; element = element-
>parentElement()) { |
285 if (matchForPseudoContent(nextContext, *element, result) == Sele
ctorMatches) | 285 if (matchForPseudoContent(nextContext, *element, result) == Sele
ctorMatches) |
286 return SelectorMatches; | 286 return SelectorMatches; |
287 } | 287 } |
288 return SelectorFailsCompletely; | 288 return SelectorFailsCompletely; |
289 } | 289 } |
290 | 290 |
291 if (nextContext.selector->pseudoType() == CSSSelector::PseudoShadow) | 291 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShadow) |
292 return matchForPseudoShadow(nextContext, context.element->containing
ShadowRoot(), result); | 292 return matchForPseudoShadow(nextContext, context.element->containing
ShadowRoot(), result); |
293 | 293 |
294 for (nextContext.element = parentElement(context); nextContext.element;
nextContext.element = parentElement(nextContext)) { | 294 for (nextContext.element = parentElement(context); nextContext.element;
nextContext.element = parentElement(nextContext)) { |
295 Match match = matchSelector(nextContext, result); | 295 Match match = matchSelector(nextContext, result); |
296 if (match == SelectorMatches || match == SelectorFailsCompletely) | 296 if (match == SelectorMatches || match == SelectorFailsCompletely) |
297 return match; | 297 return match; |
298 if (nextSelectorExceedsScope(nextContext)) | 298 if (nextSelectorExceedsScope(nextContext)) |
299 return SelectorFailsCompletely; | 299 return SelectorFailsCompletely; |
300 } | 300 } |
301 return SelectorFailsCompletely; | 301 return SelectorFailsCompletely; |
302 case CSSSelector::Child: | 302 case CSSSelector::Child: |
303 { | 303 { |
304 if (context.selector->relationIsAffectedByPseudoContent()) | 304 if (context.selector->relationIsAffectedByPseudoContent()) |
305 return matchForPseudoContent(nextContext, *context.element, resu
lt); | 305 return matchForPseudoContent(nextContext, *context.element, resu
lt); |
306 | 306 |
307 if (nextContext.selector->pseudoType() == CSSSelector::PseudoShadow) | 307 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShad
ow) |
308 return matchForPseudoShadow(nextContext, context.element->parent
Node(), result); | 308 return matchForPseudoShadow(nextContext, context.element->parent
Node(), result); |
309 | 309 |
310 nextContext.element = parentElement(context); | 310 nextContext.element = parentElement(context); |
311 if (!nextContext.element) | 311 if (!nextContext.element) |
312 return SelectorFailsCompletely; | 312 return SelectorFailsCompletely; |
313 return matchSelector(nextContext, result); | 313 return matchSelector(nextContext, result); |
314 } | 314 } |
315 case CSSSelector::DirectAdjacent: | 315 case CSSSelector::DirectAdjacent: |
316 // Shadow roots can't have sibling elements | 316 // Shadow roots can't have sibling elements |
317 if (nextContext.selector->pseudoType() == CSSSelector::PseudoShadow) | 317 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShadow) |
318 return SelectorFailsCompletely; | 318 return SelectorFailsCompletely; |
319 | 319 |
320 if (m_mode == ResolvingStyle) { | 320 if (m_mode == ResolvingStyle) { |
321 if (ContainerNode* parent = context.element->parentElementOrShadowRo
ot()) | 321 if (ContainerNode* parent = context.element->parentElementOrShadowRo
ot()) |
322 parent->setChildrenAffectedByDirectAdjacentRules(); | 322 parent->setChildrenAffectedByDirectAdjacentRules(); |
323 } | 323 } |
324 nextContext.element = ElementTraversal::previousSibling(*context.element
); | 324 nextContext.element = ElementTraversal::previousSibling(*context.element
); |
325 if (!nextContext.element) | 325 if (!nextContext.element) |
326 return SelectorFailsAllSiblings; | 326 return SelectorFailsAllSiblings; |
327 return matchSelector(nextContext, result); | 327 return matchSelector(nextContext, result); |
328 | 328 |
329 case CSSSelector::IndirectAdjacent: | 329 case CSSSelector::IndirectAdjacent: |
330 // Shadow roots can't have sibling elements | 330 // Shadow roots can't have sibling elements |
331 if (nextContext.selector->pseudoType() == CSSSelector::PseudoShadow) | 331 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShadow) |
332 return SelectorFailsCompletely; | 332 return SelectorFailsCompletely; |
333 | 333 |
334 if (m_mode == ResolvingStyle) { | 334 if (m_mode == ResolvingStyle) { |
335 if (ContainerNode* parent = context.element->parentElementOrShadowRo
ot()) | 335 if (ContainerNode* parent = context.element->parentElementOrShadowRo
ot()) |
336 parent->setChildrenAffectedByIndirectAdjacentRules(); | 336 parent->setChildrenAffectedByIndirectAdjacentRules(); |
337 } | 337 } |
338 nextContext.element = ElementTraversal::previousSibling(*context.element
); | 338 nextContext.element = ElementTraversal::previousSibling(*context.element
); |
339 for (; nextContext.element; nextContext.element = ElementTraversal::prev
iousSibling(*nextContext.element)) { | 339 for (; nextContext.element; nextContext.element = ElementTraversal::prev
iousSibling(*nextContext.element)) { |
340 Match match = matchSelector(nextContext, result); | 340 Match match = matchSelector(nextContext, result); |
341 if (match == SelectorMatches || match == SelectorFailsAllSiblings ||
match == SelectorFailsCompletely) | 341 if (match == SelectorMatches || match == SelectorFailsAllSiblings ||
match == SelectorFailsCompletely) |
342 return match; | 342 return match; |
343 } | 343 } |
344 return SelectorFailsAllSiblings; | 344 return SelectorFailsAllSiblings; |
345 | 345 |
346 case CSSSelector::ShadowPseudo: | 346 case CSSSelector::ShadowPseudo: |
347 { | 347 { |
348 if (!m_isUARule && context.selector->pseudoType() == CSSSelector::Ps
eudoShadow) | 348 if (!m_isUARule && context.selector->getPseudoType() == CSSSelector:
:PseudoShadow) |
349 Deprecation::countDeprecation(context.element->document(), UseCo
unter::CSSSelectorPseudoShadow); | 349 Deprecation::countDeprecation(context.element->document(), UseCo
unter::CSSSelectorPseudoShadow); |
350 // If we're in the same tree-scope as the scoping element, then foll
owing a shadow descendant combinator would escape that and thus the scope. | 350 // If we're in the same tree-scope as the scoping element, then foll
owing a shadow descendant combinator would escape that and thus the scope. |
351 if (context.scope && context.scope->shadowHost() && context.scope->s
hadowHost()->treeScope() == context.element->treeScope()) | 351 if (context.scope && context.scope->shadowHost() && context.scope->s
hadowHost()->treeScope() == context.element->treeScope()) |
352 return SelectorFailsCompletely; | 352 return SelectorFailsCompletely; |
353 | 353 |
354 Element* shadowHost = context.element->shadowHost(); | 354 Element* shadowHost = context.element->shadowHost(); |
355 if (!shadowHost) | 355 if (!shadowHost) |
356 return SelectorFailsCompletely; | 356 return SelectorFailsCompletely; |
357 nextContext.element = shadowHost; | 357 nextContext.element = shadowHost; |
358 return matchSelector(nextContext, result); | 358 return matchSelector(nextContext, result); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 return false; | 430 return false; |
431 } | 431 } |
432 | 432 |
433 static inline bool containsHTMLSpace(const AtomicString& string) | 433 static inline bool containsHTMLSpace(const AtomicString& string) |
434 { | 434 { |
435 if (LIKELY(string.is8Bit())) | 435 if (LIKELY(string.is8Bit())) |
436 return containsHTMLSpaceTemplate<LChar>(string.characters8(), string.len
gth()); | 436 return containsHTMLSpaceTemplate<LChar>(string.characters8(), string.len
gth()); |
437 return containsHTMLSpaceTemplate<UChar>(string.characters16(), string.length
()); | 437 return containsHTMLSpaceTemplate<UChar>(string.characters16(), string.length
()); |
438 } | 438 } |
439 | 439 |
440 static bool attributeValueMatches(const Attribute& attributeItem, CSSSelector::M
atch match, const AtomicString& selectorValue, TextCaseSensitivity caseSensitivi
ty) | 440 static bool attributeValueMatches(const Attribute& attributeItem, CSSSelector::M
atchType match, const AtomicString& selectorValue, TextCaseSensitivity caseSensi
tivity) |
441 { | 441 { |
442 // TODO(esprehn): How do we get here with a null value? | 442 // TODO(esprehn): How do we get here with a null value? |
443 const AtomicString& value = attributeItem.value(); | 443 const AtomicString& value = attributeItem.value(); |
444 if (value.isNull()) | 444 if (value.isNull()) |
445 return false; | 445 return false; |
446 | 446 |
447 switch (match) { | 447 switch (match) { |
448 case CSSSelector::AttributeExact: | 448 case CSSSelector::AttributeExact: |
449 if (caseSensitivity == TextCaseSensitive) | 449 if (caseSensitivity == TextCaseSensitive) |
450 return selectorValue == value; | 450 return selectorValue == value; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 return false; | 495 return false; |
496 return true; | 496 return true; |
497 default: | 497 default: |
498 break; | 498 break; |
499 } | 499 } |
500 | 500 |
501 ASSERT_NOT_REACHED(); | 501 ASSERT_NOT_REACHED(); |
502 return true; | 502 return true; |
503 } | 503 } |
504 | 504 |
505 static bool anyAttributeMatches(Element& element, CSSSelector::Match match, cons
t CSSSelector& selector) | 505 static bool anyAttributeMatches(Element& element, CSSSelector::MatchType match,
const CSSSelector& selector) |
506 { | 506 { |
507 const QualifiedName& selectorAttr = selector.attribute(); | 507 const QualifiedName& selectorAttr = selector.attribute(); |
508 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. | 508 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. |
509 | 509 |
510 // Synchronize the attribute in case it is lazy-computed. | 510 // Synchronize the attribute in case it is lazy-computed. |
511 // Currently all lazy properties have a null namespace, so only pass localNa
me(). | 511 // Currently all lazy properties have a null namespace, so only pass localNa
me(). |
512 element.synchronizeAttribute(selectorAttr.localName()); | 512 element.synchronizeAttribute(selectorAttr.localName()); |
513 | 513 |
514 const AtomicString& selectorValue = selector.value(); | 514 const AtomicString& selectorValue = selector.value(); |
515 TextCaseSensitivity caseSensitivity = (selector.attributeMatchType() == CSSS
elector::CaseInsensitive) ? TextCaseASCIIInsensitive : TextCaseSensitive; | 515 TextCaseSensitivity caseSensitivity = (selector.attributeMatch() == CSSSelec
tor::CaseInsensitive) ? TextCaseASCIIInsensitive : TextCaseSensitive; |
516 | 516 |
517 AttributeCollection attributes = element.attributesWithoutUpdate(); | 517 AttributeCollection attributes = element.attributesWithoutUpdate(); |
518 for (const auto& attributeItem: attributes) { | 518 for (const auto& attributeItem: attributes) { |
519 if (!attributeItem.matches(selectorAttr)) | 519 if (!attributeItem.matches(selectorAttr)) |
520 continue; | 520 continue; |
521 | 521 |
522 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) | 522 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) |
523 return true; | 523 return true; |
524 | 524 |
525 if (caseSensitivity == TextCaseASCIIInsensitive) { | 525 if (caseSensitivity == TextCaseASCIIInsensitive) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 { | 597 { |
598 const CSSSelector& selector = *context.selector; | 598 const CSSSelector& selector = *context.selector; |
599 | 599 |
600 SelectorCheckingContext subContext(context); | 600 SelectorCheckingContext subContext(context); |
601 subContext.isSubSelector = true; | 601 subContext.isSubSelector = true; |
602 ASSERT(selector.selectorList()); | 602 ASSERT(selector.selectorList()); |
603 for (subContext.selector = selector.selectorList()->first(); subContext.sele
ctor; subContext.selector = subContext.selector->tagHistory()) { | 603 for (subContext.selector = selector.selectorList()->first(); subContext.sele
ctor; subContext.selector = subContext.selector->tagHistory()) { |
604 // :not cannot nest. I don't really know why this is a | 604 // :not cannot nest. I don't really know why this is a |
605 // restriction in CSS3, but it is, so let's honor it. | 605 // restriction in CSS3, but it is, so let's honor it. |
606 // the parser enforces that this never occurs | 606 // the parser enforces that this never occurs |
607 ASSERT(subContext.selector->pseudoType() != CSSSelector::PseudoNot); | 607 ASSERT(subContext.selector->getPseudoType() != CSSSelector::PseudoNot); |
608 // We select between :visited and :link when applying. We don't know whi
ch one applied (or not) yet. | 608 // We select between :visited and :link when applying. We don't know whi
ch one applied (or not) yet. |
609 if (subContext.selector->pseudoType() == CSSSelector::PseudoVisited || (
subContext.selector->pseudoType() == CSSSelector::PseudoLink && subContext.visit
edMatchType == VisitedMatchEnabled)) | 609 if (subContext.selector->getPseudoType() == CSSSelector::PseudoVisited |
| (subContext.selector->getPseudoType() == CSSSelector::PseudoLink && subContext
.visitedMatchType == VisitedMatchEnabled)) |
610 return true; | 610 return true; |
611 // context.scope is not available if m_mode == SharingRules. | 611 // context.scope is not available if m_mode == SharingRules. |
612 // We cannot determine whether :host or :scope matches a given element o
r not. | 612 // We cannot determine whether :host or :scope matches a given element o
r not. |
613 if (m_mode == SharingRules && (subContext.selector->isHostPseudoClass()
|| subContext.selector->pseudoType() == CSSSelector::PseudoScope)) | 613 if (m_mode == SharingRules && (subContext.selector->isHostPseudoClass()
|| subContext.selector->getPseudoType() == CSSSelector::PseudoScope)) |
614 return true; | 614 return true; |
615 if (!checkOne(subContext, result)) | 615 if (!checkOne(subContext, result)) |
616 return true; | 616 return true; |
617 } | 617 } |
618 return false; | 618 return false; |
619 } | 619 } |
620 | 620 |
621 bool SelectorChecker::checkPseudoClass(const SelectorCheckingContext& context, M
atchResult& result) const | 621 bool SelectorChecker::checkPseudoClass(const SelectorCheckingContext& context, M
atchResult& result) const |
622 { | 622 { |
623 Element& element = *context.element; | 623 Element& element = *context.element; |
624 const CSSSelector& selector = *context.selector; | 624 const CSSSelector& selector = *context.selector; |
625 | 625 |
626 if (context.hasScrollbarPseudo) { | 626 if (context.hasScrollbarPseudo) { |
627 // CSS scrollbars match a specific subset of pseudo classes, and they ha
ve specialized rules for each | 627 // CSS scrollbars match a specific subset of pseudo classes, and they ha
ve specialized rules for each |
628 // (since there are no elements involved). | 628 // (since there are no elements involved). |
629 return checkScrollbarPseudoClass(context, result); | 629 return checkScrollbarPseudoClass(context, result); |
630 } | 630 } |
631 | 631 |
632 switch (selector.pseudoType()) { | 632 switch (selector.getPseudoType()) { |
633 case CSSSelector::PseudoNot: | 633 case CSSSelector::PseudoNot: |
634 return checkPseudoNot(context, result); | 634 return checkPseudoNot(context, result); |
635 case CSSSelector::PseudoEmpty: | 635 case CSSSelector::PseudoEmpty: |
636 { | 636 { |
637 bool result = true; | 637 bool result = true; |
638 for (Node* n = element.firstChild(); n; n = n->nextSibling()) { | 638 for (Node* n = element.firstChild(); n; n = n->nextSibling()) { |
639 if (n->isElementNode()) { | 639 if (n->isElementNode()) { |
640 result = false; | 640 result = false; |
641 break; | 641 break; |
642 } | 642 } |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 break; | 946 break; |
947 } | 947 } |
948 return false; | 948 return false; |
949 } | 949 } |
950 | 950 |
951 bool SelectorChecker::checkPseudoElement(const SelectorCheckingContext& context,
MatchResult& result) const | 951 bool SelectorChecker::checkPseudoElement(const SelectorCheckingContext& context,
MatchResult& result) const |
952 { | 952 { |
953 const CSSSelector& selector = *context.selector; | 953 const CSSSelector& selector = *context.selector; |
954 Element& element = *context.element; | 954 Element& element = *context.element; |
955 | 955 |
956 switch (selector.pseudoType()) { | 956 switch (selector.getPseudoType()) { |
957 case CSSSelector::PseudoCue: | 957 case CSSSelector::PseudoCue: |
958 { | 958 { |
959 SelectorCheckingContext subContext(context); | 959 SelectorCheckingContext subContext(context); |
960 subContext.isSubSelector = true; | 960 subContext.isSubSelector = true; |
961 subContext.scope = nullptr; | 961 subContext.scope = nullptr; |
962 subContext.treatShadowHostAsNormalScope = false; | 962 subContext.treatShadowHostAsNormalScope = false; |
963 | 963 |
964 for (subContext.selector = selector.selectorList()->first(); subCont
ext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector))
{ | 964 for (subContext.selector = selector.selectorList()->first(); subCont
ext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector))
{ |
965 if (match(subContext)) | 965 if (match(subContext)) |
966 return true; | 966 return true; |
(...skipping 20 matching lines...) Expand all Loading... |
987 return match(subContext); | 987 return match(subContext); |
988 } | 988 } |
989 case CSSSelector::PseudoContent: | 989 case CSSSelector::PseudoContent: |
990 return element.isInShadowTree() && element.isInsertionPoint(); | 990 return element.isInShadowTree() && element.isInsertionPoint(); |
991 case CSSSelector::PseudoShadow: | 991 case CSSSelector::PseudoShadow: |
992 return element.isInShadowTree() && context.previousElement; | 992 return element.isInShadowTree() && context.previousElement; |
993 default: | 993 default: |
994 if (m_mode == SharingRules) | 994 if (m_mode == SharingRules) |
995 return true; | 995 return true; |
996 ASSERT(m_mode != QueryingRules); | 996 ASSERT(m_mode != QueryingRules); |
997 result.dynamicPseudo = CSSSelector::pseudoId(selector.pseudoType()); | 997 result.dynamicPseudo = CSSSelector::pseudoId(selector.getPseudoType()); |
998 ASSERT(result.dynamicPseudo != NOPSEUDO); | 998 ASSERT(result.dynamicPseudo != NOPSEUDO); |
999 return true; | 999 return true; |
1000 } | 1000 } |
1001 } | 1001 } |
1002 | 1002 |
1003 bool SelectorChecker::checkPseudoHost(const SelectorCheckingContext& context, Ma
tchResult& result) const | 1003 bool SelectorChecker::checkPseudoHost(const SelectorCheckingContext& context, Ma
tchResult& result) const |
1004 { | 1004 { |
1005 const CSSSelector& selector = *context.selector; | 1005 const CSSSelector& selector = *context.selector; |
1006 Element& element = *context.element; | 1006 Element& element = *context.element; |
1007 | 1007 |
(...skipping 29 matching lines...) Expand all Loading... |
1037 hostContext.element = nextElement; | 1037 hostContext.element = nextElement; |
1038 if (match(hostContext, subResult)) { | 1038 if (match(hostContext, subResult)) { |
1039 matched = true; | 1039 matched = true; |
1040 // Consider div:host(div:host(div:host(div:host...))). | 1040 // Consider div:host(div:host(div:host(div:host...))). |
1041 maxSpecificity = std::max(maxSpecificity, hostContext.selector->
specificity() + subResult.specificity); | 1041 maxSpecificity = std::max(maxSpecificity, hostContext.selector->
specificity() + subResult.specificity); |
1042 break; | 1042 break; |
1043 } | 1043 } |
1044 hostContext.treatShadowHostAsNormalScope = false; | 1044 hostContext.treatShadowHostAsNormalScope = false; |
1045 hostContext.scope = nullptr; | 1045 hostContext.scope = nullptr; |
1046 | 1046 |
1047 if (selector.pseudoType() == CSSSelector::PseudoHost) | 1047 if (selector.getPseudoType() == CSSSelector::PseudoHost) |
1048 break; | 1048 break; |
1049 | 1049 |
1050 hostContext.inRightmostCompound = false; | 1050 hostContext.inRightmostCompound = false; |
1051 nextElement = FlatTreeTraversal::parentElement(*nextElement); | 1051 nextElement = FlatTreeTraversal::parentElement(*nextElement); |
1052 } while (nextElement); | 1052 } while (nextElement); |
1053 } | 1053 } |
1054 if (matched) { | 1054 if (matched) { |
1055 result.specificity += maxSpecificity; | 1055 result.specificity += maxSpecificity; |
1056 return true; | 1056 return true; |
1057 } | 1057 } |
1058 | 1058 |
1059 // FIXME: this was a fallthrough condition. | 1059 // FIXME: this was a fallthrough condition. |
1060 return false; | 1060 return false; |
1061 } | 1061 } |
1062 | 1062 |
1063 bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c
ontext, MatchResult& result) const | 1063 bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c
ontext, MatchResult& result) const |
1064 { | 1064 { |
1065 const CSSSelector& selector = *context.selector; | 1065 const CSSSelector& selector = *context.selector; |
1066 | 1066 |
1067 if (selector.pseudoType() == CSSSelector::PseudoNot) | 1067 if (selector.getPseudoType() == CSSSelector::PseudoNot) |
1068 return checkPseudoNot(context, result); | 1068 return checkPseudoNot(context, result); |
1069 | 1069 |
1070 // FIXME: This is a temporary hack for resizers and scrollbar corners. Event
ually :window-inactive should become a real | 1070 // FIXME: This is a temporary hack for resizers and scrollbar corners. Event
ually :window-inactive should become a real |
1071 // pseudo class and just apply to everything. | 1071 // pseudo class and just apply to everything. |
1072 if (selector.pseudoType() == CSSSelector::PseudoWindowInactive) | 1072 if (selector.getPseudoType() == CSSSelector::PseudoWindowInactive) |
1073 return !context.element->document().page()->focusController().isActive()
; | 1073 return !context.element->document().page()->focusController().isActive()
; |
1074 | 1074 |
1075 if (!m_scrollbar) | 1075 if (!m_scrollbar) |
1076 return false; | 1076 return false; |
1077 | 1077 |
1078 switch (selector.pseudoType()) { | 1078 switch (selector.getPseudoType()) { |
1079 case CSSSelector::PseudoEnabled: | 1079 case CSSSelector::PseudoEnabled: |
1080 return m_scrollbar->enabled(); | 1080 return m_scrollbar->enabled(); |
1081 case CSSSelector::PseudoDisabled: | 1081 case CSSSelector::PseudoDisabled: |
1082 return !m_scrollbar->enabled(); | 1082 return !m_scrollbar->enabled(); |
1083 case CSSSelector::PseudoHover: | 1083 case CSSSelector::PseudoHover: |
1084 { | 1084 { |
1085 ScrollbarPart hoveredPart = m_scrollbar->hoveredPart(); | 1085 ScrollbarPart hoveredPart = m_scrollbar->hoveredPart(); |
1086 if (m_scrollbarPart == ScrollbarBGPart) | 1086 if (m_scrollbarPart == ScrollbarBGPart) |
1087 return hoveredPart != NoPart; | 1087 return hoveredPart != NoPart; |
1088 if (m_scrollbarPart == TrackBGPart) | 1088 if (m_scrollbarPart == TrackBGPart) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 } | 1143 } |
1144 | 1144 |
1145 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) | 1145 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) |
1146 { | 1146 { |
1147 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) | 1147 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) |
1148 return true; | 1148 return true; |
1149 return element.focused() && isFrameFocused(element); | 1149 return element.focused() && isFrameFocused(element); |
1150 } | 1150 } |
1151 | 1151 |
1152 } // namespace blink | 1152 } // namespace blink |
OLD | NEW |