OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/css/parser/CSSSelectorParser.h" | 6 #include "core/css/parser/CSSSelectorParser.h" |
7 | 7 |
8 #include "core/css/CSSSelectorList.h" | 8 #include "core/css/CSSSelectorList.h" |
9 #include "core/css/StyleSheetContents.h" | 9 #include "core/css/StyleSheetContents.h" |
10 #include "core/frame/UseCounter.h" | 10 #include "core/frame/UseCounter.h" |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 if (m_defaultNamespace != starAtom || specifiers->crossesTreeScopes()) | 526 if (m_defaultNamespace != starAtom || specifiers->crossesTreeScopes()) |
527 rewriteSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIs
ForNamespaceRule*/true); | 527 rewriteSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIs
ForNamespaceRule*/true); |
528 } | 528 } |
529 | 529 |
530 void CSSSelectorParser::rewriteSpecifiersWithElementName(const AtomicString& nam
espacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bo
ol tagIsForNamespaceRule) | 530 void CSSSelectorParser::rewriteSpecifiersWithElementName(const AtomicString& nam
espacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bo
ol tagIsForNamespaceRule) |
531 { | 531 { |
532 AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleShe
et ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace; | 532 AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleShe
et ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace; |
533 QualifiedName tag(namespacePrefix, elementName, determinedNamespace); | 533 QualifiedName tag(namespacePrefix, elementName, determinedNamespace); |
534 | 534 |
535 if (specifiers->crossesTreeScopes()) | 535 if (specifiers->crossesTreeScopes()) |
536 return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, eleme
ntName, specifiers, tagIsForNamespaceRule); | 536 return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, speci
fiers, tagIsForNamespaceRule); |
537 | 537 |
538 if (specifiers->isContentPseudoElement()) | 538 if (specifiers->isContentPseudoElement()) |
539 return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, elem
entName, specifiers, tagIsForNamespaceRule); | 539 return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, spec
ifiers, tagIsForNamespaceRule); |
540 | 540 |
541 // *:host never matches, so we can't discard the * otherwise we can't tell t
he | 541 // *:host never matches, so we can't discard the * otherwise we can't tell t
he |
542 // difference between *:host and just :host. | 542 // difference between *:host and just :host. |
543 if (tag == anyQName() && !specifiers->hasHostPseudoSelector()) | 543 if (tag == anyQName() && !specifiers->hasHostPseudoSelector()) |
544 return; | 544 return; |
545 if (specifiers->pseudoType() != CSSSelector::PseudoCue) | 545 if (specifiers->pseudoType() != CSSSelector::PseudoCue) |
546 specifiers->prependTagSelector(tag, tagIsForNamespaceRule); | 546 specifiers->prependTagSelector(tag, tagIsForNamespaceRule); |
547 } | 547 } |
548 | 548 |
549 void CSSSelectorParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(c
onst QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* spe
cifiers, bool tagIsForNamespaceRule) | 549 void CSSSelectorParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(c
onst QualifiedName& tag, CSSParserSelector* specifiers, bool tagIsForNamespaceRu
le) |
550 { | 550 { |
551 CSSParserSelector* lastShadowPseudo = specifiers; | 551 CSSParserSelector* lastShadowPseudo = specifiers; |
552 CSSParserSelector* history = specifiers; | 552 CSSParserSelector* history = specifiers; |
553 while (history->tagHistory()) { | 553 while (history->tagHistory()) { |
554 history = history->tagHistory(); | 554 history = history->tagHistory(); |
555 if (history->crossesTreeScopes() || history->hasShadowPseudo()) | 555 if (history->crossesTreeScopes() || history->hasShadowPseudo()) |
556 lastShadowPseudo = history; | 556 lastShadowPseudo = history; |
557 } | 557 } |
558 | 558 |
559 if (lastShadowPseudo->tagHistory()) { | 559 if (lastShadowPseudo->tagHistory()) { |
560 if (tag != anyQName()) | 560 if (tag != anyQName()) |
561 lastShadowPseudo->tagHistory()->prependTagSelector(tag, tagIsForName
spaceRule); | 561 lastShadowPseudo->tagHistory()->prependTagSelector(tag, tagIsForName
spaceRule); |
562 return; | 562 return; |
563 } | 563 } |
564 | 564 |
565 // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo c
ombinator has to be used. | 565 // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo c
ombinator has to be used. |
566 // We therefore create a new Selector with that combinator here in any case,
even if matching any (host) element in any namespace (i.e. '*'). | 566 // We therefore create a new Selector with that combinator here in any case,
even if matching any (host) element in any namespace (i.e. '*'). |
567 OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelect
or(tag)); | 567 OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelect
or(tag)); |
568 lastShadowPseudo->setTagHistory(elementNameSelector.release()); | 568 lastShadowPseudo->setTagHistory(elementNameSelector.release()); |
569 lastShadowPseudo->setRelation(CSSSelector::ShadowPseudo); | 569 lastShadowPseudo->setRelation(CSSSelector::ShadowPseudo); |
570 } | 570 } |
571 | 571 |
572 void CSSSelectorParser::rewriteSpecifiersWithElementNameForContentPseudoElement(
const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* sp
ecifiers, bool tagIsForNamespaceRule) | 572 void CSSSelectorParser::rewriteSpecifiersWithElementNameForContentPseudoElement(
const QualifiedName& tag, CSSParserSelector* specifiers, bool tagIsForNamespaceR
ule) |
573 { | 573 { |
574 CSSParserSelector* last = specifiers; | 574 CSSParserSelector* last = specifiers; |
575 CSSParserSelector* history = specifiers; | 575 CSSParserSelector* history = specifiers; |
576 while (history->tagHistory()) { | 576 while (history->tagHistory()) { |
577 history = history->tagHistory(); | 577 history = history->tagHistory(); |
578 if (history->isContentPseudoElement() || history->relationIsAffectedByPs
eudoContent()) | 578 if (history->isContentPseudoElement() || history->relationIsAffectedByPs
eudoContent()) |
579 last = history; | 579 last = history; |
580 } | 580 } |
581 | 581 |
582 if (last->tagHistory()) { | 582 if (last->tagHistory()) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 context.useCounter()->count(feature); | 655 context.useCounter()->count(feature); |
656 if (current->relation() == CSSSelector::ShadowDeep) | 656 if (current->relation() == CSSSelector::ShadowDeep) |
657 context.useCounter()->count(UseCounter::CSSDeepCombinator); | 657 context.useCounter()->count(UseCounter::CSSDeepCombinator); |
658 if (current->selectorList()) | 658 if (current->selectorList()) |
659 recordSelectorStats(context, *current->selectorList()); | 659 recordSelectorStats(context, *current->selectorList()); |
660 } | 660 } |
661 } | 661 } |
662 } | 662 } |
663 | 663 |
664 } // namespace blink | 664 } // namespace blink |
OLD | NEW |