Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/WebKit/Source/core/css/SelectorChecker.cpp

Issue 2588103003: Rename blink::SelectorChecker::Match enum type to MatchStatus. (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/css/SelectorChecker.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
10 * (http://www.torchmobile.com/) 10 * (http://www.torchmobile.com/)
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 return !ElementTraversal::nextSibling(element, HasTagName(type)); 193 return !ElementTraversal::nextSibling(element, HasTagName(type));
194 } 194 }
195 195
196 // Recursive check of selectors and combinators 196 // Recursive check of selectors and combinators
197 // It can return 4 different values: 197 // It can return 4 different values:
198 // * SelectorMatches - the selector matches the element e 198 // * SelectorMatches - the selector matches the element e
199 // * SelectorFailsLocally - the selector fails for the element e 199 // * SelectorFailsLocally - the selector fails for the element e
200 // * SelectorFailsAllSiblings - the selector fails for e and any sibling of e 200 // * SelectorFailsAllSiblings - the selector fails for e and any sibling of e
201 // * SelectorFailsCompletely - the selector fails for e and any sibling or 201 // * SelectorFailsCompletely - the selector fails for e and any sibling or
202 // ancestor of e 202 // ancestor of e
203 SelectorChecker::Match SelectorChecker::matchSelector( 203 SelectorChecker::MatchStatus SelectorChecker::matchSelector(
204 const SelectorCheckingContext& context, 204 const SelectorCheckingContext& context,
205 MatchResult& result) const { 205 MatchResult& result) const {
206 MatchResult subResult; 206 MatchResult subResult;
207 if (!checkOne(context, subResult)) 207 if (!checkOne(context, subResult))
208 return SelectorFailsLocally; 208 return SelectorFailsLocally;
209 209
210 if (subResult.dynamicPseudo != PseudoIdNone) 210 if (subResult.dynamicPseudo != PseudoIdNone)
211 result.dynamicPseudo = subResult.dynamicPseudo; 211 result.dynamicPseudo = subResult.dynamicPseudo;
212 212
213 if (context.selector->isLastInTagHistory()) { 213 if (context.selector->isLastInTagHistory()) {
214 if (scopeContainsLastMatchedElement(context)) { 214 if (scopeContainsLastMatchedElement(context)) {
215 result.specificity += subResult.specificity; 215 result.specificity += subResult.specificity;
216 return SelectorMatches; 216 return SelectorMatches;
217 } 217 }
218 return SelectorFailsLocally; 218 return SelectorFailsLocally;
219 } 219 }
220 220
221 Match match; 221 MatchStatus match;
222 if (context.selector->relation() != CSSSelector::SubSelector) { 222 if (context.selector->relation() != CSSSelector::SubSelector) {
223 if (nextSelectorExceedsScope(context)) 223 if (nextSelectorExceedsScope(context))
224 return SelectorFailsCompletely; 224 return SelectorFailsCompletely;
225 225
226 if (context.pseudoId != PseudoIdNone && 226 if (context.pseudoId != PseudoIdNone &&
227 context.pseudoId != result.dynamicPseudo) 227 context.pseudoId != result.dynamicPseudo)
228 return SelectorFailsCompletely; 228 return SelectorFailsCompletely;
229 229
230 AutoReset<PseudoId> dynamicPseudoScope(&result.dynamicPseudo, PseudoIdNone); 230 AutoReset<PseudoId> dynamicPseudoScope(&result.dynamicPseudo, PseudoIdNone);
231 match = matchForRelation(context, result); 231 match = matchForRelation(context, result);
232 } else { 232 } else {
233 match = matchForSubSelector(context, result); 233 match = matchForSubSelector(context, result);
234 } 234 }
235 if (match == SelectorMatches) 235 if (match == SelectorMatches)
236 result.specificity += subResult.specificity; 236 result.specificity += subResult.specificity;
237 return match; 237 return match;
238 } 238 }
239 239
240 static inline SelectorChecker::SelectorCheckingContext 240 static inline SelectorChecker::SelectorCheckingContext
241 prepareNextContextForRelation( 241 prepareNextContextForRelation(
242 const SelectorChecker::SelectorCheckingContext& context) { 242 const SelectorChecker::SelectorCheckingContext& context) {
243 SelectorChecker::SelectorCheckingContext nextContext(context); 243 SelectorChecker::SelectorCheckingContext nextContext(context);
244 DCHECK(context.selector->tagHistory()); 244 DCHECK(context.selector->tagHistory());
245 nextContext.selector = context.selector->tagHistory(); 245 nextContext.selector = context.selector->tagHistory();
246 return nextContext; 246 return nextContext;
247 } 247 }
248 248
249 SelectorChecker::Match SelectorChecker::matchForSubSelector( 249 SelectorChecker::MatchStatus SelectorChecker::matchForSubSelector(
250 const SelectorCheckingContext& context, 250 const SelectorCheckingContext& context,
251 MatchResult& result) const { 251 MatchResult& result) const {
252 SelectorCheckingContext nextContext = prepareNextContextForRelation(context); 252 SelectorCheckingContext nextContext = prepareNextContextForRelation(context);
253 253
254 PseudoId dynamicPseudo = result.dynamicPseudo; 254 PseudoId dynamicPseudo = result.dynamicPseudo;
255 nextContext.hasScrollbarPseudo = 255 nextContext.hasScrollbarPseudo =
256 dynamicPseudo != PseudoIdNone && 256 dynamicPseudo != PseudoIdNone &&
257 (m_scrollbar || dynamicPseudo == PseudoIdScrollbarCorner || 257 (m_scrollbar || dynamicPseudo == PseudoIdScrollbarCorner ||
258 dynamicPseudo == PseudoIdResizer); 258 dynamicPseudo == PseudoIdResizer);
259 nextContext.hasSelectionPseudo = dynamicPseudo == PseudoIdSelection; 259 nextContext.hasSelectionPseudo = dynamicPseudo == PseudoIdSelection;
260 nextContext.isSubSelector = true; 260 nextContext.isSubSelector = true;
261 return matchSelector(nextContext, result); 261 return matchSelector(nextContext, result);
262 } 262 }
263 263
264 static inline bool isV0ShadowRoot(const Node* node) { 264 static inline bool isV0ShadowRoot(const Node* node) {
265 return node && node->isShadowRoot() && 265 return node && node->isShadowRoot() &&
266 toShadowRoot(node)->type() == ShadowRootType::V0; 266 toShadowRoot(node)->type() == ShadowRootType::V0;
267 } 267 }
268 268
269 SelectorChecker::Match SelectorChecker::matchForPseudoShadow( 269 SelectorChecker::MatchStatus SelectorChecker::matchForPseudoShadow(
270 const SelectorCheckingContext& context, 270 const SelectorCheckingContext& context,
271 const ContainerNode* node, 271 const ContainerNode* node,
272 MatchResult& result) const { 272 MatchResult& result) const {
273 if (!isV0ShadowRoot(node)) 273 if (!isV0ShadowRoot(node))
274 return SelectorFailsCompletely; 274 return SelectorFailsCompletely;
275 if (!context.previousElement) 275 if (!context.previousElement)
276 return SelectorFailsCompletely; 276 return SelectorFailsCompletely;
277 return matchSelector(context, result); 277 return matchSelector(context, result);
278 } 278 }
279 279
280 static inline Element* parentOrV0ShadowHostElement(const Element& element) { 280 static inline Element* parentOrV0ShadowHostElement(const Element& element) {
281 if (element.parentNode() && element.parentNode()->isShadowRoot()) { 281 if (element.parentNode() && element.parentNode()->isShadowRoot()) {
282 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::V0) 282 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::V0)
283 return nullptr; 283 return nullptr;
284 } 284 }
285 return element.parentOrShadowHostElement(); 285 return element.parentOrShadowHostElement();
286 } 286 }
287 287
288 static inline Element* parentOrOpenShadowHostElement(const Element& element) { 288 static inline Element* parentOrOpenShadowHostElement(const Element& element) {
289 if (element.parentNode() && element.parentNode()->isShadowRoot()) { 289 if (element.parentNode() && element.parentNode()->isShadowRoot()) {
290 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::Open) 290 if (toShadowRoot(element.parentNode())->type() != ShadowRootType::Open)
291 return nullptr; 291 return nullptr;
292 } 292 }
293 return element.parentOrShadowHostElement(); 293 return element.parentOrShadowHostElement();
294 } 294 }
295 295
296 SelectorChecker::Match SelectorChecker::matchForRelation( 296 SelectorChecker::MatchStatus SelectorChecker::matchForRelation(
297 const SelectorCheckingContext& context, 297 const SelectorCheckingContext& context,
298 MatchResult& result) const { 298 MatchResult& result) const {
299 SelectorCheckingContext nextContext = prepareNextContextForRelation(context); 299 SelectorCheckingContext nextContext = prepareNextContextForRelation(context);
300 300
301 CSSSelector::RelationType relation = context.selector->relation(); 301 CSSSelector::RelationType relation = context.selector->relation();
302 302
303 // Disable :visited matching when we see the first link or try to match 303 // Disable :visited matching when we see the first link or try to match
304 // anything else than an ancestors. 304 // anything else than an ancestors.
305 if (!context.isSubSelector && 305 if (!context.isSubSelector &&
306 (context.element->isLink() || 306 (context.element->isLink() ||
(...skipping 16 matching lines...) Expand all
323 } 323 }
324 return SelectorFailsCompletely; 324 return SelectorFailsCompletely;
325 } 325 }
326 326
327 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShadow) 327 if (nextContext.selector->getPseudoType() == CSSSelector::PseudoShadow)
328 return matchForPseudoShadow( 328 return matchForPseudoShadow(
329 nextContext, context.element->containingShadowRoot(), result); 329 nextContext, context.element->containingShadowRoot(), result);
330 330
331 for (nextContext.element = parentElement(context); nextContext.element; 331 for (nextContext.element = parentElement(context); nextContext.element;
332 nextContext.element = parentElement(nextContext)) { 332 nextContext.element = parentElement(nextContext)) {
333 Match match = matchSelector(nextContext, result); 333 MatchStatus match = matchSelector(nextContext, result);
334 if (match == SelectorMatches || match == SelectorFailsCompletely) 334 if (match == SelectorMatches || match == SelectorFailsCompletely)
335 return match; 335 return match;
336 if (nextSelectorExceedsScope(nextContext)) 336 if (nextSelectorExceedsScope(nextContext))
337 return SelectorFailsCompletely; 337 return SelectorFailsCompletely;
338 } 338 }
339 return SelectorFailsCompletely; 339 return SelectorFailsCompletely;
340 case CSSSelector::Child: { 340 case CSSSelector::Child: {
341 if (context.selector->relationIsAffectedByPseudoContent()) 341 if (context.selector->relationIsAffectedByPseudoContent())
342 return matchForPseudoContent(nextContext, *context.element, result); 342 return matchForPseudoContent(nextContext, *context.element, result);
343 343
(...skipping 28 matching lines...) Expand all
372 372
373 if (m_mode == ResolvingStyle) { 373 if (m_mode == ResolvingStyle) {
374 if (ContainerNode* parent = 374 if (ContainerNode* parent =
375 context.element->parentElementOrShadowRoot()) 375 context.element->parentElementOrShadowRoot())
376 parent->setChildrenAffectedByIndirectAdjacentRules(); 376 parent->setChildrenAffectedByIndirectAdjacentRules();
377 } 377 }
378 nextContext.element = ElementTraversal::previousSibling(*context.element); 378 nextContext.element = ElementTraversal::previousSibling(*context.element);
379 for (; nextContext.element; 379 for (; nextContext.element;
380 nextContext.element = 380 nextContext.element =
381 ElementTraversal::previousSibling(*nextContext.element)) { 381 ElementTraversal::previousSibling(*nextContext.element)) {
382 Match match = matchSelector(nextContext, result); 382 MatchStatus match = matchSelector(nextContext, result);
383 if (match == SelectorMatches || match == SelectorFailsAllSiblings || 383 if (match == SelectorMatches || match == SelectorFailsAllSiblings ||
384 match == SelectorFailsCompletely) 384 match == SelectorFailsCompletely)
385 return match; 385 return match;
386 } 386 }
387 return SelectorFailsAllSiblings; 387 return SelectorFailsAllSiblings;
388 388
389 case CSSSelector::ShadowPseudo: { 389 case CSSSelector::ShadowPseudo: {
390 if (!m_isUARule && !m_isQuerySelector && 390 if (!m_isUARule && !m_isQuerySelector &&
391 context.selector->getPseudoType() == CSSSelector::PseudoShadow) 391 context.selector->getPseudoType() == CSSSelector::PseudoShadow)
392 Deprecation::countDeprecation(context.element->document(), 392 Deprecation::countDeprecation(context.element->document(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 return SelectorMatches; 427 return SelectorMatches;
428 } 428 }
429 } 429 }
430 return SelectorFailsCompletely; 430 return SelectorFailsCompletely;
431 } 431 }
432 432
433 for (nextContext.element = parentOrV0ShadowHostElement(*context.element); 433 for (nextContext.element = parentOrV0ShadowHostElement(*context.element);
434 nextContext.element; 434 nextContext.element;
435 nextContext.element = 435 nextContext.element =
436 parentOrV0ShadowHostElement(*nextContext.element)) { 436 parentOrV0ShadowHostElement(*nextContext.element)) {
437 Match match = matchSelector(nextContext, result); 437 MatchStatus match = matchSelector(nextContext, result);
438 if (match == SelectorMatches && context.element->isInShadowTree()) 438 if (match == SelectorMatches && context.element->isInShadowTree())
439 UseCounter::count(context.element->document(), 439 UseCounter::count(context.element->document(),
440 UseCounter::CSSDeepCombinatorAndShadow); 440 UseCounter::CSSDeepCombinatorAndShadow);
441 if (match == SelectorMatches || match == SelectorFailsCompletely) 441 if (match == SelectorMatches || match == SelectorFailsCompletely)
442 return match; 442 return match;
443 if (nextSelectorExceedsScope(nextContext)) 443 if (nextSelectorExceedsScope(nextContext))
444 return SelectorFailsCompletely; 444 return SelectorFailsCompletely;
445 } 445 }
446 return SelectorFailsCompletely; 446 return SelectorFailsCompletely;
447 } 447 }
448 448
449 case CSSSelector::ShadowPiercingDescendant: { 449 case CSSSelector::ShadowPiercingDescendant: {
450 DCHECK(m_isQuerySelector); 450 DCHECK(m_isQuerySelector);
451 UseCounter::count(context.element->document(), 451 UseCounter::count(context.element->document(),
452 UseCounter::CSSShadowPiercingDescendantCombinator); 452 UseCounter::CSSShadowPiercingDescendantCombinator);
453 // TODO(kochi): parentOrOpenShadowHostElement() is necessary because 453 // TODO(kochi): parentOrOpenShadowHostElement() is necessary because
454 // SelectorQuery can pass V0 shadow roots. All closed shadow roots are 454 // SelectorQuery can pass V0 shadow roots. All closed shadow roots are
455 // already filtered out, thus once V0 is removed this logic can use 455 // already filtered out, thus once V0 is removed this logic can use
456 // parentOrShadowHostElement() instead. 456 // parentOrShadowHostElement() instead.
457 for (nextContext.element = 457 for (nextContext.element =
458 parentOrOpenShadowHostElement(*context.element); 458 parentOrOpenShadowHostElement(*context.element);
459 nextContext.element; 459 nextContext.element;
460 nextContext.element = 460 nextContext.element =
461 parentOrOpenShadowHostElement(*nextContext.element)) { 461 parentOrOpenShadowHostElement(*nextContext.element)) {
462 Match match = matchSelector(nextContext, result); 462 MatchStatus match = matchSelector(nextContext, result);
463 if (match == SelectorMatches || match == SelectorFailsCompletely) 463 if (match == SelectorMatches || match == SelectorFailsCompletely)
464 return match; 464 return match;
465 if (nextSelectorExceedsScope(nextContext)) 465 if (nextSelectorExceedsScope(nextContext))
466 break; 466 break;
467 } 467 }
468 return SelectorFailsCompletely; 468 return SelectorFailsCompletely;
469 } 469 }
470 470
471 case CSSSelector::ShadowSlot: { 471 case CSSSelector::ShadowSlot: {
472 const HTMLSlotElement* slot = findSlotElementInScope(context); 472 const HTMLSlotElement* slot = findSlotElementInScope(context);
473 if (!slot) 473 if (!slot)
474 return SelectorFailsCompletely; 474 return SelectorFailsCompletely;
475 475
476 nextContext.element = const_cast<HTMLSlotElement*>(slot); 476 nextContext.element = const_cast<HTMLSlotElement*>(slot);
477 return matchSelector(nextContext, result); 477 return matchSelector(nextContext, result);
478 } 478 }
479 479
480 case CSSSelector::SubSelector: 480 case CSSSelector::SubSelector:
481 break; 481 break;
482 } 482 }
483 NOTREACHED(); 483 NOTREACHED();
484 return SelectorFailsCompletely; 484 return SelectorFailsCompletely;
485 } 485 }
486 486
487 SelectorChecker::Match SelectorChecker::matchForPseudoContent( 487 SelectorChecker::MatchStatus SelectorChecker::matchForPseudoContent(
488 const SelectorCheckingContext& context, 488 const SelectorCheckingContext& context,
489 const Element& element, 489 const Element& element,
490 MatchResult& result) const { 490 MatchResult& result) const {
491 HeapVector<Member<InsertionPoint>, 8> insertionPoints; 491 HeapVector<Member<InsertionPoint>, 8> insertionPoints;
492 collectDestinationInsertionPoints(element, insertionPoints); 492 collectDestinationInsertionPoints(element, insertionPoints);
493 SelectorCheckingContext nextContext(context); 493 SelectorCheckingContext nextContext(context);
494 for (const auto& insertionPoint : insertionPoints) { 494 for (const auto& insertionPoint : insertionPoints) {
495 nextContext.element = insertionPoint; 495 nextContext.element = insertionPoint;
496 // TODO(esprehn): Why does SharingRules have a special case? 496 // TODO(esprehn): Why does SharingRules have a special case?
497 if (m_mode == SharingRules) 497 if (m_mode == SharingRules)
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 } 1313 }
1314 1314
1315 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) { 1315 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) {
1316 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element), 1316 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element),
1317 CSSSelector::PseudoFocus)) 1317 CSSSelector::PseudoFocus))
1318 return true; 1318 return true;
1319 return element.isFocused() && isFrameFocused(element); 1319 return element.isFocused() && isFrameFocused(element);
1320 } 1320 }
1321 1321
1322 } // namespace blink 1322 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/SelectorChecker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698