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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 SelectorChecker::SelectorChecker(Document& document, Mode mode) | 64 SelectorChecker::SelectorChecker(Document& document, Mode mode) |
65 : m_strictParsing(!document.inQuirksMode()) | 65 : m_strictParsing(!document.inQuirksMode()) |
66 , m_mode(mode) | 66 , m_mode(mode) |
67 { | 67 { |
68 } | 68 } |
69 | 69 |
70 static bool matchesCustomPseudoElement(const Element* element, const CSSSelector
& selector) | 70 static bool matchesCustomPseudoElement(const Element* element, const CSSSelector
& selector) |
71 { | 71 { |
72 ShadowRoot* root = element->containingShadowRoot(); | 72 ShadowRoot* root = element->containingShadowRoot(); |
73 if (!root || root->type() != ShadowRoot::UserAgentShadowRoot) | 73 if (!root || root->type() != ShadowRoot::ClosedShadowRoot) |
74 return false; | 74 return false; |
75 | 75 |
76 if (element->shadowPseudoId() != selector.value()) | 76 if (element->shadowPseudoId() != selector.value()) |
77 return false; | 77 return false; |
78 | 78 |
79 return true; | 79 return true; |
80 } | 80 } |
81 | 81 |
82 static Element* parentElement(const SelectorChecker::SelectorCheckingContext& co
ntext) | 82 static Element* parentElement(const SelectorChecker::SelectorCheckingContext& co
ntext) |
83 { | 83 { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 } | 187 } |
188 | 188 |
189 static inline SelectorChecker::SelectorCheckingContext prepareNextContextForRela
tion(const SelectorChecker::SelectorCheckingContext& context) | 189 static inline SelectorChecker::SelectorCheckingContext prepareNextContextForRela
tion(const SelectorChecker::SelectorCheckingContext& context) |
190 { | 190 { |
191 SelectorChecker::SelectorCheckingContext nextContext(context); | 191 SelectorChecker::SelectorCheckingContext nextContext(context); |
192 ASSERT(context.selector->tagHistory()); | 192 ASSERT(context.selector->tagHistory()); |
193 nextContext.selector = context.selector->tagHistory(); | 193 nextContext.selector = context.selector->tagHistory(); |
194 return nextContext; | 194 return nextContext; |
195 } | 195 } |
196 | 196 |
197 static inline bool isAuthorShadowRoot(const Node* node) | 197 static inline bool isOpenShadowRoot(const Node* node) |
198 { | 198 { |
199 return node && node->isShadowRoot() && toShadowRoot(node)->type() == ShadowR
oot::AuthorShadowRoot; | 199 return node && node->isShadowRoot() && toShadowRoot(node)->type() == ShadowR
oot::OpenShadowRoot; |
200 } | 200 } |
201 | 201 |
202 template<typename SiblingTraversalStrategy> | 202 template<typename SiblingTraversalStrategy> |
203 SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorChecki
ngContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, Ma
tchResult* result) const | 203 SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorChecki
ngContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, Ma
tchResult* result) const |
204 { | 204 { |
205 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; | 205 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; |
206 | 206 |
207 PseudoId dynamicPseudo = result ? result->dynamicPseudo : NOPSEUDO; | 207 PseudoId dynamicPseudo = result ? result->dynamicPseudo : NOPSEUDO; |
208 // a selector is invalid if something follows a pseudo-element | 208 // a selector is invalid if something follows a pseudo-element |
209 // We make an exception for scrollbar pseudo elements and allow a set of pse
udo classes (but nothing else) | 209 // We make an exception for scrollbar pseudo elements and allow a set of pse
udo classes (but nothing else) |
210 // to follow the pseudo elements. | 210 // to follow the pseudo elements. |
211 nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO && (context.scrol
lbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER); | 211 nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO && (context.scrol
lbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER); |
212 nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION; | 212 nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION; |
213 if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == Colle
ctingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO | 213 if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == Colle
ctingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO |
214 && !nextContext.hasSelectionPseudo | 214 && !nextContext.hasSelectionPseudo |
215 && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() ==
CSSSelector::PseudoClass)) | 215 && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() ==
CSSSelector::PseudoClass)) |
216 return SelectorFailsCompletely; | 216 return SelectorFailsCompletely; |
217 | 217 |
218 nextContext.isSubSelector = true; | 218 nextContext.isSubSelector = true; |
219 return match(nextContext, siblingTraversalStrategy, result); | 219 return match(nextContext, siblingTraversalStrategy, result); |
220 } | 220 } |
221 | 221 |
222 static bool selectorMatchesShadowRoot(const CSSSelector* selector) | 222 static bool selectorMatchesShadowRoot(const CSSSelector* selector) |
223 { | 223 { |
224 return selector && selector->isShadowPseudoElement(); | 224 return selector && selector->isShadowPseudoElement(); |
225 } | 225 } |
226 | 226 |
227 static inline Element* parentOrShadowHostButDisallowEscapingUserAgentShadowTree(
const Element& element) | 227 static inline Element* parentOrShadowHostButDisallowEscapingClosedShadowTree(con
st Element& element) |
228 { | 228 { |
229 ContainerNode* parent = element.parentOrShadowHostNode(); | 229 ContainerNode* parent = element.parentOrShadowHostNode(); |
230 if (!parent) | 230 if (!parent) |
231 return nullptr; | 231 return nullptr; |
232 if (parent->isShadowRoot()) | 232 if (parent->isShadowRoot()) |
233 return (toShadowRoot(parent)->type() == ShadowRoot::UserAgentShadowRoot)
? nullptr : toShadowRoot(parent)->host(); | 233 return (toShadowRoot(parent)->type() == ShadowRoot::ClosedShadowRoot) ?
nullptr : toShadowRoot(parent)->host(); |
234 if (!parent->isElementNode()) | 234 if (!parent->isElementNode()) |
235 return nullptr; | 235 return nullptr; |
236 return toElement(parent); | 236 return toElement(parent); |
237 } | 237 } |
238 | 238 |
239 template<typename SiblingTraversalStrategy> | 239 template<typename SiblingTraversalStrategy> |
240 SelectorChecker::Match SelectorChecker::matchForPseudoShadow(const ContainerNode
* node, const SelectorCheckingContext& context, const SiblingTraversalStrategy&
siblingTraversalStrategy, MatchResult* result) const | 240 SelectorChecker::Match SelectorChecker::matchForPseudoShadow(const ContainerNode
* node, const SelectorCheckingContext& context, const SiblingTraversalStrategy&
siblingTraversalStrategy, MatchResult* result) const |
241 { | 241 { |
242 if (!isAuthorShadowRoot(node)) | 242 if (!isOpenShadowRoot(node)) |
243 return SelectorFailsCompletely; | 243 return SelectorFailsCompletely; |
244 return match(context, siblingTraversalStrategy, result); | 244 return match(context, siblingTraversalStrategy, result); |
245 } | 245 } |
246 | 246 |
247 template<typename SiblingTraversalStrategy> | 247 template<typename SiblingTraversalStrategy> |
248 SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
ontext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, Match
Result* result) const | 248 SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
ontext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, Match
Result* result) const |
249 { | 249 { |
250 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; | 250 SelectorCheckingContext nextContext = prepareNextContextForRelation(context)
; |
251 nextContext.previousElement = context.element; | 251 nextContext.previousElement = context.element; |
252 | 252 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 nextContext.element = shadowHost; | 344 nextContext.element = shadowHost; |
345 nextContext.isSubSelector = false; | 345 nextContext.isSubSelector = false; |
346 nextContext.elementStyle = 0; | 346 nextContext.elementStyle = 0; |
347 return this->match(nextContext, siblingTraversalStrategy, result); | 347 return this->match(nextContext, siblingTraversalStrategy, result); |
348 } | 348 } |
349 | 349 |
350 case CSSSelector::ShadowDeep: | 350 case CSSSelector::ShadowDeep: |
351 { | 351 { |
352 nextContext.isSubSelector = false; | 352 nextContext.isSubSelector = false; |
353 nextContext.elementStyle = 0; | 353 nextContext.elementStyle = 0; |
354 for (nextContext.element = parentOrShadowHostButDisallowEscapingUser
AgentShadowTree(*context.element); nextContext.element; nextContext.element = pa
rentOrShadowHostButDisallowEscapingUserAgentShadowTree(*nextContext.element)) { | 354 for (nextContext.element = parentOrShadowHostButDisallowEscapingClos
edShadowTree(*context.element); nextContext.element; nextContext.element = paren
tOrShadowHostButDisallowEscapingClosedShadowTree(*nextContext.element)) { |
355 Match match = this->match(nextContext, siblingTraversalStrategy,
result); | 355 Match match = this->match(nextContext, siblingTraversalStrategy,
result); |
356 if (match == SelectorMatches || match == SelectorFailsCompletely
) | 356 if (match == SelectorMatches || match == SelectorFailsCompletely
) |
357 return match; | 357 return match; |
358 if (nextSelectorExceedsScope(nextContext)) | 358 if (nextSelectorExceedsScope(nextContext)) |
359 return SelectorFailsCompletely; | 359 return SelectorFailsCompletely; |
360 } | 360 } |
361 return SelectorFailsCompletely; | 361 return SelectorFailsCompletely; |
362 } | 362 } |
363 | 363 |
364 case CSSSelector::SubSelector: | 364 case CSSSelector::SubSelector: |
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 return isHTMLSelectElement(element) && !toHTMLSelectElement(element).usesMen
uList(); | 1186 return isHTMLSelectElement(element) && !toHTMLSelectElement(element).usesMen
uList(); |
1187 } | 1187 } |
1188 | 1188 |
1189 template | 1189 template |
1190 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst DOMSiblingTraversalStrategy&, MatchResult*) const; | 1190 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst DOMSiblingTraversalStrategy&, MatchResult*) const; |
1191 | 1191 |
1192 template | 1192 template |
1193 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const; | 1193 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, co
nst ShadowDOMSiblingTraversalStrategy&, MatchResult*) const; |
1194 | 1194 |
1195 } | 1195 } |
OLD | NEW |