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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 // * SelectorFailsAllSiblings - the selector fails for e and any sibling of e | 139 // * SelectorFailsAllSiblings - the selector fails for e and any sibling of e |
140 // * SelectorFailsCompletely - the selector fails for e and any sibling or ance
stor of e | 140 // * SelectorFailsCompletely - the selector fails for e and any sibling or ance
stor of e |
141 template<typename SiblingTraversalStrategy> | 141 template<typename SiblingTraversalStrategy> |
142 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con
text, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* res
ult) const | 142 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con
text, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* res
ult) const |
143 { | 143 { |
144 // first selector has to match | 144 // first selector has to match |
145 unsigned specificity = 0; | 145 unsigned specificity = 0; |
146 if (!checkOne(context, siblingTraversalStrategy, &specificity)) | 146 if (!checkOne(context, siblingTraversalStrategy, &specificity)) |
147 return SelectorFailsLocally; | 147 return SelectorFailsLocally; |
148 | 148 |
149 if (context.selector->m_match == CSSSelector::PseudoElement) { | 149 if (context.selector->match() == CSSSelector::PseudoElement) { |
150 if (context.selector->isCustomPseudoElement()) { | 150 if (context.selector->isCustomPseudoElement()) { |
151 if (!matchesCustomPseudoElement(context.element, *context.selector)) | 151 if (!matchesCustomPseudoElement(context.element, *context.selector)) |
152 return SelectorFailsLocally; | 152 return SelectorFailsLocally; |
153 } else if (context.selector->isContentPseudoElement()) { | 153 } else if (context.selector->isContentPseudoElement()) { |
154 if (!context.element->isInShadowTree() || !context.element->isInsert
ionPoint()) | 154 if (!context.element->isInShadowTree() || !context.element->isInsert
ionPoint()) |
155 return SelectorFailsLocally; | 155 return SelectorFailsLocally; |
156 } else if (context.selector->isShadowPseudoElement()) { | 156 } else if (context.selector->isShadowPseudoElement()) { |
157 if (!context.element->isInShadowTree() || !context.previousElement) | 157 if (!context.element->isInShadowTree() || !context.previousElement) |
158 return SelectorFailsCompletely; | 158 return SelectorFailsCompletely; |
159 } else { | 159 } else { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; | 224 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; |
225 | 225 |
226 PseudoId dynamicPseudo = result ? result->dynamicPseudo : NOPSEUDO; | 226 PseudoId dynamicPseudo = result ? result->dynamicPseudo : NOPSEUDO; |
227 // a selector is invalid if something follows a pseudo-element | 227 // a selector is invalid if something follows a pseudo-element |
228 // We make an exception for scrollbar pseudo elements and allow a set of pse
udo classes (but nothing else) | 228 // We make an exception for scrollbar pseudo elements and allow a set of pse
udo classes (but nothing else) |
229 // to follow the pseudo elements. | 229 // to follow the pseudo elements. |
230 nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO && (context.scrol
lbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER); | 230 nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO && (context.scrol
lbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER); |
231 nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION; | 231 nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION; |
232 if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == Colle
ctingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO | 232 if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == Colle
ctingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO |
233 && !nextContext.hasSelectionPseudo | 233 && !nextContext.hasSelectionPseudo |
234 && !(nextContext.hasScrollbarPseudo && nextContext.selector->m_match ==
CSSSelector::PseudoClass)) | 234 && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() ==
CSSSelector::PseudoClass)) |
235 return SelectorFailsCompletely; | 235 return SelectorFailsCompletely; |
236 | 236 |
237 nextContext.isSubSelector = true; | 237 nextContext.isSubSelector = true; |
238 return match(nextContext, siblingTraversalStrategy, result); | 238 return match(nextContext, siblingTraversalStrategy, result); |
239 } | 239 } |
240 | 240 |
241 static bool selectorMatchesShadowRoot(const CSSSelector* selector) | 241 static bool selectorMatchesShadowRoot(const CSSSelector* selector) |
242 { | 242 { |
243 return selector && selector->isShadowPseudoElement(); | 243 return selector && selector->isShadowPseudoElement(); |
244 } | 244 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 Element& element = *context.element; | 533 Element& element = *context.element; |
534 ASSERT(context.selector); | 534 ASSERT(context.selector); |
535 const CSSSelector& selector = *context.selector; | 535 const CSSSelector& selector = *context.selector; |
536 | 536 |
537 bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.b
ehaviorAtBoundary, context.scope); | 537 bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.b
ehaviorAtBoundary, context.scope); |
538 | 538 |
539 // Only :host and :ancestor should match the host: http://drafts.csswg.org/c
ss-scoping/#host-element | 539 // Only :host and :ancestor should match the host: http://drafts.csswg.org/c
ss-scoping/#host-element |
540 if (elementIsHostInItsShadowTree && !selector.isHostPseudoClass()) | 540 if (elementIsHostInItsShadowTree && !selector.isHostPseudoClass()) |
541 return false; | 541 return false; |
542 | 542 |
543 if (selector.m_match == CSSSelector::Tag) | 543 if (selector.match() == CSSSelector::Tag) |
544 return SelectorChecker::tagMatches(element, selector.tagQName()); | 544 return SelectorChecker::tagMatches(element, selector.tagQName()); |
545 | 545 |
546 if (selector.m_match == CSSSelector::Class) | 546 if (selector.match() == CSSSelector::Class) |
547 return element.hasClass() && element.classNames().contains(selector.valu
e()); | 547 return element.hasClass() && element.classNames().contains(selector.valu
e()); |
548 | 548 |
549 if (selector.m_match == CSSSelector::Id) | 549 if (selector.match() == CSSSelector::Id) |
550 return element.hasID() && element.idForStyleResolution() == selector.val
ue(); | 550 return element.hasID() && element.idForStyleResolution() == selector.val
ue(); |
551 | 551 |
552 if (selector.isAttributeSelector()) | 552 if (selector.isAttributeSelector()) |
553 return anyAttributeMatches(element, static_cast<CSSSelector::Match>(sele
ctor.m_match), selector); | 553 return anyAttributeMatches(element, selector.match(), selector); |
554 | 554 |
555 if (selector.m_match == CSSSelector::PseudoClass) { | 555 if (selector.match() == CSSSelector::PseudoClass) { |
556 // Handle :not up front. | 556 // Handle :not up front. |
557 if (selector.pseudoType() == CSSSelector::PseudoNot) { | 557 if (selector.pseudoType() == CSSSelector::PseudoNot) { |
558 SelectorCheckingContext subContext(context); | 558 SelectorCheckingContext subContext(context); |
559 subContext.isSubSelector = true; | 559 subContext.isSubSelector = true; |
560 ASSERT(selector.selectorList()); | 560 ASSERT(selector.selectorList()); |
561 for (subContext.selector = selector.selectorList()->first(); subCont
ext.selector; subContext.selector = subContext.selector->tagHistory()) { | 561 for (subContext.selector = selector.selectorList()->first(); subCont
ext.selector; subContext.selector = subContext.selector->tagHistory()) { |
562 // :not cannot nest. I don't really know why this is a | 562 // :not cannot nest. I don't really know why this is a |
563 // restriction in CSS3, but it is, so let's honor it. | 563 // restriction in CSS3, but it is, so let's honor it. |
564 // the parser enforces that this never occurs | 564 // the parser enforces that this never occurs |
565 ASSERT(subContext.selector->pseudoType() != CSSSelector::PseudoN
ot); | 565 ASSERT(subContext.selector->pseudoType() != CSSSelector::PseudoN
ot); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 case CSSSelector::PseudoCornerPresent: | 990 case CSSSelector::PseudoCornerPresent: |
991 return false; | 991 return false; |
992 | 992 |
993 case CSSSelector::PseudoUnknown: | 993 case CSSSelector::PseudoUnknown: |
994 case CSSSelector::PseudoNotParsed: | 994 case CSSSelector::PseudoNotParsed: |
995 default: | 995 default: |
996 ASSERT_NOT_REACHED(); | 996 ASSERT_NOT_REACHED(); |
997 break; | 997 break; |
998 } | 998 } |
999 return false; | 999 return false; |
1000 } else if (selector.m_match == CSSSelector::PseudoElement && selector.pseudo
Type() == CSSSelector::PseudoCue) { | 1000 } else if (selector.match() == CSSSelector::PseudoElement && selector.pseudo
Type() == CSSSelector::PseudoCue) { |
1001 SelectorCheckingContext subContext(context); | 1001 SelectorCheckingContext subContext(context); |
1002 subContext.isSubSelector = true; | 1002 subContext.isSubSelector = true; |
1003 subContext.behaviorAtBoundary = StaysWithinTreeScope; | 1003 subContext.behaviorAtBoundary = StaysWithinTreeScope; |
1004 | 1004 |
1005 const CSSSelector* contextSelector = context.selector; | 1005 const CSSSelector* contextSelector = context.selector; |
1006 ASSERT(contextSelector); | 1006 ASSERT(contextSelector); |
1007 for (subContext.selector = contextSelector->selectorList()->first(); sub
Context.selector; subContext.selector = CSSSelectorList::next(*subContext.select
or)) { | 1007 for (subContext.selector = contextSelector->selectorList()->first(); sub
Context.selector; subContext.selector = CSSSelectorList::next(*subContext.select
or)) { |
1008 if (match(subContext, siblingTraversalStrategy) == SelectorMatches) | 1008 if (match(subContext, siblingTraversalStrategy) == SelectorMatches) |
1009 return true; | 1009 return true; |
1010 } | 1010 } |
1011 return false; | 1011 return false; |
1012 } | 1012 } |
1013 // ### add the rest of the checks... | 1013 // ### add the rest of the checks... |
1014 return true; | 1014 return true; |
1015 } | 1015 } |
1016 | 1016 |
1017 bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c
ontext, Document* document, const CSSSelector& selector) const | 1017 bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c
ontext, Document* document, const CSSSelector& selector) const |
1018 { | 1018 { |
1019 RenderScrollbar* scrollbar = context.scrollbar; | 1019 RenderScrollbar* scrollbar = context.scrollbar; |
1020 ScrollbarPart part = context.scrollbarPart; | 1020 ScrollbarPart part = context.scrollbarPart; |
1021 | 1021 |
1022 // FIXME: This is a temporary hack for resizers and scrollbar corners. Event
ually :window-inactive should become a real | 1022 // FIXME: This is a temporary hack for resizers and scrollbar corners. Event
ually :window-inactive should become a real |
1023 // pseudo class and just apply to everything. | 1023 // pseudo class and just apply to everything. |
1024 if (selector.pseudoType() == CSSSelector::PseudoWindowInactive) | 1024 if (selector.pseudoType() == CSSSelector::PseudoWindowInactive) |
1025 return !document->page()->focusController().isActive(); | 1025 return !document->page()->focusController().isActive(); |
1026 | 1026 |
1027 if (!scrollbar) | 1027 if (!scrollbar) |
1028 return false; | 1028 return false; |
1029 | 1029 |
1030 ASSERT(selector.m_match == CSSSelector::PseudoClass); | 1030 ASSERT(selector.match() == CSSSelector::PseudoClass); |
1031 switch (selector.pseudoType()) { | 1031 switch (selector.pseudoType()) { |
1032 case CSSSelector::PseudoEnabled: | 1032 case CSSSelector::PseudoEnabled: |
1033 return scrollbar->enabled(); | 1033 return scrollbar->enabled(); |
1034 case CSSSelector::PseudoDisabled: | 1034 case CSSSelector::PseudoDisabled: |
1035 return !scrollbar->enabled(); | 1035 return !scrollbar->enabled(); |
1036 case CSSSelector::PseudoHover: | 1036 case CSSSelector::PseudoHover: |
1037 { | 1037 { |
1038 ScrollbarPart hoveredPart = scrollbar->hoveredPart(); | 1038 ScrollbarPart hoveredPart = scrollbar->hoveredPart(); |
1039 if (part == ScrollbarBGPart) | 1039 if (part == ScrollbarBGPart) |
1040 return hoveredPart != NoPart; | 1040 return hoveredPart != NoPart; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 return element.focused() && isFrameFocused(element); | 1149 return element.focused() && isFrameFocused(element); |
1150 } | 1150 } |
1151 | 1151 |
1152 template | 1152 template |
1153 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst DOMSiblingTraversalStrategy&, MatchResult*) const; | 1153 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst DOMSiblingTraversalStrategy&, MatchResult*) const; |
1154 | 1154 |
1155 template | 1155 template |
1156 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const; | 1156 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const; |
1157 | 1157 |
1158 } | 1158 } |
OLD | NEW |