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 << 1, | |
Timothy Loh
2016/01/19 04:59:27
Shouldn't we start counting from 1 << 0?
rune
2016/01/19 08:41:51
Done.
| |
137 HasContentPseudoElement = 1 << 2 | |
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 |