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/frame/UseCounter.h" | 9 #include "core/frame/UseCounter.h" |
10 #include "platform/RuntimeEnabledFeatures.h" | 10 #include "platform/RuntimeEnabledFeatures.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 return CSSSelectorList(); | 123 return CSSSelectorList(); |
124 selectorList.append(selector.release()); | 124 selectorList.append(selector.release()); |
125 } | 125 } |
126 | 126 |
127 if (m_failedParsing) | 127 if (m_failedParsing) |
128 return CSSSelectorList(); | 128 return CSSSelectorList(); |
129 | 129 |
130 return CSSSelectorList::adoptSelectorVector(selectorList); | 130 return CSSSelectorList::adoptSelectorVector(selectorList); |
131 } | 131 } |
132 | 132 |
| 133 namespace { |
| 134 |
| 135 enum CompoundSelectorFlags { |
| 136 HasPseudoElementForRightmostCompound = 1 << 0, |
| 137 HasContentPseudoElement = 1 << 1 |
| 138 }; |
| 139 |
| 140 unsigned extractCompoundFlags(const CSSParserSelector& simpleSelector, CSSParser
Mode parserMode) |
| 141 { |
| 142 if (simpleSelector.match() != CSSSelector::PseudoElement) |
| 143 return 0; |
| 144 if (simpleSelector.pseudoType() == CSSSelector::PseudoContent) |
| 145 return HasContentPseudoElement; |
| 146 if (simpleSelector.pseudoType() == CSSSelector::PseudoShadow) |
| 147 return 0; |
| 148 // TODO(rune@opera.com): crbug.com/578131 |
| 149 // The UASheetMode check is a work-around to allow this selector in mediaCon
trols(New).css: |
| 150 // input[type="range" i]::-webkit-media-slider-container > div { |
| 151 if (parserMode == UASheetMode && simpleSelector.pseudoType() == CSSSelector:
:PseudoWebKitCustomElement) |
| 152 return 0; |
| 153 return HasPseudoElementForRightmostCompound; |
| 154 } |
| 155 |
| 156 } // namespace |
| 157 |
133 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector(CSSParse
rTokenRange& range) | 158 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeComplexSelector(CSSParse
rTokenRange& range) |
134 { | 159 { |
135 OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(range); | 160 OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(range); |
136 if (!selector) | 161 if (!selector) |
137 return nullptr; | 162 return nullptr; |
138 | 163 |
139 bool previousCompoundHasContentPseudo = false; | |
140 | 164 |
141 for (CSSParserSelector* simple = selector.get(); simple && !previousCompound
HasContentPseudo; simple = simple->tagHistory()) | 165 unsigned previousCompoundFlags = 0; |
142 previousCompoundHasContentPseudo = simple->pseudoType() == CSSSelector::
PseudoContent; | 166 |
| 167 for (CSSParserSelector* simple = selector.get(); simple && !previousCompound
Flags; simple = simple->tagHistory()) |
| 168 previousCompoundFlags |= extractCompoundFlags(*simple, m_context.mode())
; |
143 | 169 |
144 while (CSSSelector::Relation combinator = consumeCombinator(range)) { | 170 while (CSSSelector::Relation combinator = consumeCombinator(range)) { |
145 OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector(range); | 171 OwnPtr<CSSParserSelector> nextSelector = consumeCompoundSelector(range); |
146 if (!nextSelector) | 172 if (!nextSelector) |
147 return combinator == CSSSelector::Descendant ? selector.release() :
nullptr; | 173 return combinator == CSSSelector::Descendant ? selector.release() :
nullptr; |
| 174 if (previousCompoundFlags & HasPseudoElementForRightmostCompound) |
| 175 return nullptr; |
148 CSSParserSelector* end = nextSelector.get(); | 176 CSSParserSelector* end = nextSelector.get(); |
149 bool compoundHasContentPseudo = end->pseudoType() == CSSSelector::Pseudo
Content; | 177 unsigned compoundFlags = extractCompoundFlags(*end, m_context.mode()); |
150 while (end->tagHistory()) { | 178 while (end->tagHistory()) { |
151 end = end->tagHistory(); | 179 end = end->tagHistory(); |
152 compoundHasContentPseudo |= end->pseudoType() == CSSSelector::Pseudo
Content; | 180 compoundFlags |= extractCompoundFlags(*end, m_context.mode()); |
153 } | 181 } |
154 end->setRelation(combinator); | 182 end->setRelation(combinator); |
155 if (previousCompoundHasContentPseudo) | 183 if (previousCompoundFlags & HasContentPseudoElement) |
156 end->setRelationIsAffectedByPseudoContent(); | 184 end->setRelationIsAffectedByPseudoContent(); |
157 previousCompoundHasContentPseudo = compoundHasContentPseudo; | 185 previousCompoundFlags = compoundFlags; |
158 end->setTagHistory(selector.release()); | 186 end->setTagHistory(selector.release()); |
159 | 187 |
160 selector = nextSelector.release(); | 188 selector = nextSelector.release(); |
161 } | 189 } |
162 | 190 |
163 return selector.release(); | 191 return selector.release(); |
164 } | 192 } |
165 | 193 |
166 namespace { | 194 namespace { |
167 | 195 |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 | 743 |
716 if (!splitAfter || !splitAfter->tagHistory()) | 744 if (!splitAfter || !splitAfter->tagHistory()) |
717 return compoundSelector; | 745 return compoundSelector; |
718 | 746 |
719 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); | 747 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); |
720 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector
); | 748 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector
); |
721 return secondCompound.release(); | 749 return secondCompound.release(); |
722 } | 750 } |
723 | 751 |
724 } // namespace blink | 752 } // namespace blink |
OLD | NEW |