| 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 |