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 "core/css/parser/CSSSelectorParser.h" | 5 #include "core/css/parser/CSSSelectorParser.h" |
6 | 6 |
7 #include "core/css/CSSSelectorList.h" | 7 #include "core/css/CSSSelectorList.h" |
8 #include "core/css/StyleSheetContents.h" | 8 #include "core/css/StyleSheetContents.h" |
9 #include "core/css/parser/CSSParserContext.h" | 9 #include "core/css/parser/CSSParserContext.h" |
| 10 #include "core/frame/Deprecation.h" |
10 #include "core/frame/UseCounter.h" | 11 #include "core/frame/UseCounter.h" |
11 #include "platform/RuntimeEnabledFeatures.h" | 12 #include "platform/RuntimeEnabledFeatures.h" |
12 #include "wtf/PtrUtil.h" | 13 #include "wtf/PtrUtil.h" |
13 #include <memory> | 14 #include <memory> |
14 | 15 |
15 namespace blink { | 16 namespace blink { |
16 | 17 |
17 static void recordSelectorStats(const CSSParserContext* context, | 18 // static |
18 const CSSSelectorList& selectorList) { | |
19 if (!context->isUseCounterRecordingEnabled()) | |
20 return; | |
21 | |
22 for (const CSSSelector* selector = selectorList.first(); selector; | |
23 selector = CSSSelectorList::next(*selector)) { | |
24 for (const CSSSelector* current = selector; current; | |
25 current = current->tagHistory()) { | |
26 UseCounter::Feature feature = UseCounter::NumberOfFeatures; | |
27 switch (current->getPseudoType()) { | |
28 case CSSSelector::PseudoAny: | |
29 feature = UseCounter::CSSSelectorPseudoAny; | |
30 break; | |
31 case CSSSelector::PseudoUnresolved: | |
32 feature = UseCounter::CSSSelectorPseudoUnresolved; | |
33 break; | |
34 case CSSSelector::PseudoDefined: | |
35 feature = UseCounter::CSSSelectorPseudoDefined; | |
36 break; | |
37 case CSSSelector::PseudoSlotted: | |
38 feature = UseCounter::CSSSelectorPseudoSlotted; | |
39 break; | |
40 case CSSSelector::PseudoContent: | |
41 feature = UseCounter::CSSSelectorPseudoContent; | |
42 break; | |
43 case CSSSelector::PseudoHost: | |
44 feature = UseCounter::CSSSelectorPseudoHost; | |
45 break; | |
46 case CSSSelector::PseudoHostContext: | |
47 feature = UseCounter::CSSSelectorPseudoHostContext; | |
48 break; | |
49 case CSSSelector::PseudoFullScreenAncestor: | |
50 feature = UseCounter::CSSSelectorPseudoFullScreenAncestor; | |
51 break; | |
52 case CSSSelector::PseudoFullScreen: | |
53 feature = UseCounter::CSSSelectorPseudoFullScreen; | |
54 break; | |
55 case CSSSelector::PseudoListBox: | |
56 if (context->mode() != UASheetMode) | |
57 feature = UseCounter::CSSSelectorInternalPseudoListBox; | |
58 break; | |
59 case CSSSelector::PseudoWebKitCustomElement: | |
60 if (context->mode() != UASheetMode) { | |
61 if (current->value() == "-internal-media-controls-cast-button") | |
62 feature = UseCounter::CSSSelectorInternalMediaControlsCastButton; | |
63 else if (current->value() == | |
64 "-internal-media-controls-overlay-cast-button") | |
65 feature = | |
66 UseCounter::CSSSelectorInternalMediaControlsOverlayCastButton; | |
67 } | |
68 break; | |
69 case CSSSelector::PseudoSpatialNavigationFocus: | |
70 if (context->mode() != UASheetMode) | |
71 feature = | |
72 UseCounter::CSSSelectorInternalPseudoSpatialNavigationFocus; | |
73 break; | |
74 case CSSSelector::PseudoReadOnly: | |
75 if (context->mode() != UASheetMode) | |
76 feature = UseCounter::CSSSelectorPseudoReadOnly; | |
77 break; | |
78 case CSSSelector::PseudoReadWrite: | |
79 if (context->mode() != UASheetMode) | |
80 feature = UseCounter::CSSSelectorPseudoReadWrite; | |
81 break; | |
82 default: | |
83 break; | |
84 } | |
85 if (feature != UseCounter::NumberOfFeatures) | |
86 context->useCounter()->count(feature); | |
87 if (current->relation() == CSSSelector::IndirectAdjacent) | |
88 context->useCounter()->count(UseCounter::CSSSelectorIndirectAdjacent); | |
89 if (current->selectorList()) | |
90 recordSelectorStats(context, *current->selectorList()); | |
91 } | |
92 } | |
93 } | |
94 | |
95 CSSSelectorList CSSSelectorParser::parseSelector( | 19 CSSSelectorList CSSSelectorParser::parseSelector( |
96 CSSParserTokenRange range, | 20 CSSParserTokenRange range, |
97 const CSSParserContext* context, | 21 const CSSParserContext* context, |
98 StyleSheetContents* styleSheet) { | 22 StyleSheetContents* styleSheet) { |
99 CSSSelectorParser parser(context, styleSheet); | 23 CSSSelectorParser parser(context, styleSheet); |
100 range.consumeWhitespace(); | 24 range.consumeWhitespace(); |
101 CSSSelectorList result = parser.consumeComplexSelectorList(range); | 25 CSSSelectorList result = parser.consumeComplexSelectorList(range); |
102 if (!range.atEnd()) | 26 if (!range.atEnd()) |
103 return CSSSelectorList(); | 27 return CSSSelectorList(); |
104 | 28 |
105 recordSelectorStats(context, result); | 29 parser.recordUsageAndDeprecations(result); |
106 return result; | 30 return result; |
107 } | 31 } |
108 | 32 |
109 CSSSelectorParser::CSSSelectorParser(const CSSParserContext* context, | 33 CSSSelectorParser::CSSSelectorParser(const CSSParserContext* context, |
110 StyleSheetContents* styleSheet) | 34 StyleSheetContents* styleSheet) |
111 : m_context(context), m_styleSheet(styleSheet) {} | 35 : m_context(context), m_styleSheet(styleSheet) {} |
112 | 36 |
113 CSSSelectorList CSSSelectorParser::consumeComplexSelectorList( | 37 CSSSelectorList CSSSelectorParser::consumeComplexSelectorList( |
114 CSSParserTokenRange& range) { | 38 CSSParserTokenRange& range) { |
115 Vector<std::unique_ptr<CSSParserSelector>> selectorList; | 39 Vector<std::unique_ptr<CSSParserSelector>> selectorList; |
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 std::unique_ptr<CSSParserSelector> secondCompound = | 797 std::unique_ptr<CSSParserSelector> secondCompound = |
874 splitAfter->releaseTagHistory(); | 798 splitAfter->releaseTagHistory(); |
875 secondCompound->appendTagHistory( | 799 secondCompound->appendTagHistory( |
876 secondCompound->pseudoType() == CSSSelector::PseudoSlotted | 800 secondCompound->pseudoType() == CSSSelector::PseudoSlotted |
877 ? CSSSelector::ShadowSlot | 801 ? CSSSelector::ShadowSlot |
878 : CSSSelector::ShadowPseudo, | 802 : CSSSelector::ShadowPseudo, |
879 std::move(compoundSelector)); | 803 std::move(compoundSelector)); |
880 return secondCompound; | 804 return secondCompound; |
881 } | 805 } |
882 | 806 |
| 807 void CSSSelectorParser::recordUsageAndDeprecations( |
| 808 const CSSSelectorList& selectorList) { |
| 809 if (!m_context->useCounter()) |
| 810 return; |
| 811 |
| 812 for (const CSSSelector* selector = selectorList.first(); selector; |
| 813 selector = CSSSelectorList::next(*selector)) { |
| 814 for (const CSSSelector* current = selector; current; |
| 815 current = current->tagHistory()) { |
| 816 UseCounter::Feature feature = UseCounter::NumberOfFeatures; |
| 817 switch (current->getPseudoType()) { |
| 818 case CSSSelector::PseudoAny: |
| 819 feature = UseCounter::CSSSelectorPseudoAny; |
| 820 break; |
| 821 case CSSSelector::PseudoUnresolved: |
| 822 feature = UseCounter::CSSSelectorPseudoUnresolved; |
| 823 break; |
| 824 case CSSSelector::PseudoDefined: |
| 825 feature = UseCounter::CSSSelectorPseudoDefined; |
| 826 break; |
| 827 case CSSSelector::PseudoSlotted: |
| 828 feature = UseCounter::CSSSelectorPseudoSlotted; |
| 829 break; |
| 830 case CSSSelector::PseudoContent: |
| 831 feature = UseCounter::CSSSelectorPseudoContent; |
| 832 break; |
| 833 case CSSSelector::PseudoHost: |
| 834 feature = UseCounter::CSSSelectorPseudoHost; |
| 835 break; |
| 836 case CSSSelector::PseudoHostContext: |
| 837 feature = UseCounter::CSSSelectorPseudoHostContext; |
| 838 break; |
| 839 case CSSSelector::PseudoFullScreenAncestor: |
| 840 feature = UseCounter::CSSSelectorPseudoFullScreenAncestor; |
| 841 break; |
| 842 case CSSSelector::PseudoFullScreen: |
| 843 feature = UseCounter::CSSSelectorPseudoFullScreen; |
| 844 break; |
| 845 case CSSSelector::PseudoListBox: |
| 846 if (m_context->mode() != UASheetMode) |
| 847 feature = UseCounter::CSSSelectorInternalPseudoListBox; |
| 848 break; |
| 849 case CSSSelector::PseudoWebKitCustomElement: |
| 850 if (m_context->mode() != UASheetMode) { |
| 851 if (current->value() == "-internal-media-controls-cast-button") { |
| 852 feature = UseCounter::CSSSelectorInternalMediaControlsCastButton; |
| 853 } else if (current->value() == |
| 854 "-internal-media-controls-overlay-cast-button") { |
| 855 feature = |
| 856 UseCounter::CSSSelectorInternalMediaControlsOverlayCastButton; |
| 857 } else if (current->value() == |
| 858 "-internal-media-controls-text-track-list") { |
| 859 feature = |
| 860 UseCounter::CSSSelectorInternalMediaControlsTextTrackList; |
| 861 } else if (current->value() == |
| 862 "-internal-media-controls-text-track-list-item") { |
| 863 feature = |
| 864 UseCounter::CSSSelectorInternalMediaControlsTextTrackListItem; |
| 865 } else if (current->value() == |
| 866 "-internal-media-controls-text-track-list-item-input") { |
| 867 feature = UseCounter:: |
| 868 CSSSelectorInternalMediaControlsTextTrackListItemInput; |
| 869 } else if (current->value() == |
| 870 "-internal-media-controls-text-track-list-kind-" |
| 871 "captions") { |
| 872 feature = UseCounter:: |
| 873 CSSSelectorInternalMediaControlsTextTrackListKindCaptions; |
| 874 } else if (current->value() == |
| 875 "-internal-media-controls-text-track-list-kind-" |
| 876 "subtitles") { |
| 877 feature = UseCounter:: |
| 878 CSSSelectorInternalMediaControlsTextTrackListKindSubtitles; |
| 879 } |
| 880 } |
| 881 break; |
| 882 case CSSSelector::PseudoSpatialNavigationFocus: |
| 883 if (m_context->mode() != UASheetMode) { |
| 884 feature = |
| 885 UseCounter::CSSSelectorInternalPseudoSpatialNavigationFocus; |
| 886 } |
| 887 break; |
| 888 case CSSSelector::PseudoReadOnly: |
| 889 if (m_context->mode() != UASheetMode) |
| 890 feature = UseCounter::CSSSelectorPseudoReadOnly; |
| 891 break; |
| 892 case CSSSelector::PseudoReadWrite: |
| 893 if (m_context->mode() != UASheetMode) |
| 894 feature = UseCounter::CSSSelectorPseudoReadWrite; |
| 895 break; |
| 896 default: |
| 897 break; |
| 898 } |
| 899 if (feature != UseCounter::NumberOfFeatures) { |
| 900 if (!Deprecation::deprecationMessage(feature).isEmpty() && |
| 901 m_styleSheet->anyOwnerDocument()) { |
| 902 Deprecation::countDeprecation(*m_styleSheet->anyOwnerDocument(), |
| 903 feature); |
| 904 } else { |
| 905 m_context->useCounter()->count(feature); |
| 906 } |
| 907 } |
| 908 if (current->relation() == CSSSelector::IndirectAdjacent) |
| 909 m_context->useCounter()->count(UseCounter::CSSSelectorIndirectAdjacent); |
| 910 if (current->selectorList()) |
| 911 recordUsageAndDeprecations(*current->selectorList()); |
| 912 } |
| 913 } |
| 914 } |
| 915 |
883 } // namespace blink | 916 } // namespace blink |
OLD | NEW |