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

Side by Side Diff: Source/core/css/parser/CSSSelectorParser.cpp

Issue 1305973007: Clean up empty namespace handling and fix empty namespaces in compound selectors (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@defaultns
Patch Set: Created 5 years, 3 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 | « Source/core/css/parser/CSSSelectorParser.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 // 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 135
136 return selector.release(); 136 return selector.release();
137 } 137 }
138 138
139 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSPars erTokenRange& range) 139 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSPars erTokenRange& range)
140 { 140 {
141 OwnPtr<CSSParserSelector> compoundSelector; 141 OwnPtr<CSSParserSelector> compoundSelector;
142 142
143 AtomicString namespacePrefix; 143 AtomicString namespacePrefix;
144 AtomicString elementName; 144 AtomicString elementName;
145 bool hasNamespace; 145 if (!consumeName(range, elementName, namespacePrefix)) {
146 if (!consumeName(range, elementName, namespacePrefix, hasNamespace)) {
147 compoundSelector = consumeSimpleSelector(range); 146 compoundSelector = consumeSimpleSelector(range);
148 if (!compoundSelector) 147 if (!compoundSelector)
149 return nullptr; 148 return nullptr;
150 } 149 }
151 if (m_context.isHTMLDocument()) 150 if (m_context.isHTMLDocument())
152 elementName = elementName.lower(); 151 elementName = elementName.lower();
153 152
154 while (OwnPtr<CSSParserSelector> simpleSelector = consumeSimpleSelector(rang e)) { 153 while (OwnPtr<CSSParserSelector> simpleSelector = consumeSimpleSelector(rang e)) {
155 if (compoundSelector) 154 if (compoundSelector)
156 compoundSelector = addSimpleSelectorToCompound(compoundSelector.rele ase(), simpleSelector.release()); 155 compoundSelector = addSimpleSelectorToCompound(compoundSelector.rele ase(), simpleSelector.release());
157 else 156 else
158 compoundSelector = simpleSelector.release(); 157 compoundSelector = simpleSelector.release();
159 } 158 }
160 159
161 if (!compoundSelector) { 160 if (!compoundSelector)
162 if (hasNamespace) 161 return CSSParserSelector::create(determineNameInNamespace(namespacePrefi x, elementName));
163 return CSSParserSelector::create(determineNameInNamespace(namespaceP refix, elementName));
164 return CSSParserSelector::create(QualifiedName(nullAtom, elementName, de faultNamespace()));
165 }
166 prependTypeSelectorIfNeeded(namespacePrefix, elementName, compoundSelector.g et()); 162 prependTypeSelectorIfNeeded(namespacePrefix, elementName, compoundSelector.g et());
167 return compoundSelector.release(); 163 return compoundSelector.release();
168 } 164 }
169 165
170 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeSimpleSelector(CSSParser TokenRange& range) 166 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeSimpleSelector(CSSParser TokenRange& range)
171 { 167 {
172 const CSSParserToken& token = range.peek(); 168 const CSSParserToken& token = range.peek();
173 OwnPtr<CSSParserSelector> selector; 169 OwnPtr<CSSParserSelector> selector;
174 if (token.type() == HashToken) 170 if (token.type() == HashToken)
175 selector = consumeId(range); 171 selector = consumeId(range);
176 else if (token.type() == DelimiterToken && token.delimiter() == '.') 172 else if (token.type() == DelimiterToken && token.delimiter() == '.')
177 selector = consumeClass(range); 173 selector = consumeClass(range);
178 else if (token.type() == LeftBracketToken) 174 else if (token.type() == LeftBracketToken)
179 selector = consumeAttribute(range); 175 selector = consumeAttribute(range);
180 else if (token.type() == ColonToken) 176 else if (token.type() == ColonToken)
181 selector = consumePseudo(range); 177 selector = consumePseudo(range);
182 else 178 else
183 return nullptr; 179 return nullptr;
184 if (!selector) 180 if (!selector)
185 m_failedParsing = true; 181 m_failedParsing = true;
186 return selector.release(); 182 return selector.release();
187 } 183 }
188 184
189 bool CSSSelectorParser::consumeName(CSSParserTokenRange& range, AtomicString& na me, AtomicString& namespacePrefix, bool& hasNamespace) 185 bool CSSSelectorParser::consumeName(CSSParserTokenRange& range, AtomicString& na me, AtomicString& namespacePrefix)
190 { 186 {
191 name = nullAtom; 187 name = nullAtom;
192 namespacePrefix = nullAtom; 188 namespacePrefix = nullAtom;
193 hasNamespace = false;
194 189
195 const CSSParserToken& firstToken = range.peek(); 190 const CSSParserToken& firstToken = range.peek();
196 if (firstToken.type() == IdentToken) { 191 if (firstToken.type() == IdentToken) {
197 name = firstToken.value(); 192 name = firstToken.value();
198 range.consume(); 193 range.consume();
199 } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '*') { 194 } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '*') {
200 name = starAtom; 195 name = starAtom;
201 range.consume(); 196 range.consume();
202 } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '|') { 197 } else if (firstToken.type() == DelimiterToken && firstToken.delimiter() == '|') {
203 // No namespace 198 // This is an empty namespace, which'll get assigned this value below
199 name = emptyAtom;
204 } else { 200 } else {
205 return false; 201 return false;
206 } 202 }
207 203
208 if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '|' ) 204 if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '|' )
209 return true; 205 return true;
210 range.consume(); 206 range.consume();
211 207
212 hasNamespace = true;
213 namespacePrefix = name; 208 namespacePrefix = name;
214 const CSSParserToken& nameToken = range.consume(); 209 const CSSParserToken& nameToken = range.consume();
215 if (nameToken.type() == IdentToken) { 210 if (nameToken.type() == IdentToken) {
216 name = nameToken.value(); 211 name = nameToken.value();
217 } else if (nameToken.type() == DelimiterToken && nameToken.delimiter() == '* ') { 212 } else if (nameToken.type() == DelimiterToken && nameToken.delimiter() == '* ') {
218 name = starAtom; 213 name = starAtom;
219 } else { 214 } else {
220 name = nullAtom; 215 name = nullAtom;
221 namespacePrefix = nullAtom; 216 namespacePrefix = nullAtom;
222 return false; 217 return false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 } 253 }
259 254
260 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeAttribute(CSSParserToken Range& range) 255 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeAttribute(CSSParserToken Range& range)
261 { 256 {
262 ASSERT(range.peek().type() == LeftBracketToken); 257 ASSERT(range.peek().type() == LeftBracketToken);
263 CSSParserTokenRange block = range.consumeBlock(); 258 CSSParserTokenRange block = range.consumeBlock();
264 block.consumeWhitespace(); 259 block.consumeWhitespace();
265 260
266 AtomicString namespacePrefix; 261 AtomicString namespacePrefix;
267 AtomicString attributeName; 262 AtomicString attributeName;
268 bool hasNamespace; 263 if (!consumeName(block, attributeName, namespacePrefix))
269 if (!consumeName(block, attributeName, namespacePrefix, hasNamespace))
270 return nullptr; 264 return nullptr;
271 block.consumeWhitespace(); 265 block.consumeWhitespace();
272 266
273 if (m_context.isHTMLDocument()) 267 if (m_context.isHTMLDocument())
274 attributeName = attributeName.lower(); 268 attributeName = attributeName.lower();
275 269
276 QualifiedName qualifiedName = hasNamespace 270 QualifiedName qualifiedName = namespacePrefix.isNull()
277 ? determineNameInNamespace(namespacePrefix, attributeName) 271 ? QualifiedName(nullAtom, attributeName, nullAtom)
278 : QualifiedName(nullAtom, attributeName, nullAtom); 272 : determineNameInNamespace(namespacePrefix, attributeName);
279 273
280 OwnPtr<CSSParserSelector> selector = CSSParserSelector::create(); 274 OwnPtr<CSSParserSelector> selector = CSSParserSelector::create();
281 275
282 if (block.atEnd()) { 276 if (block.atEnd()) {
283 selector->setAttribute(qualifiedName, CSSSelector::CaseSensitive); 277 selector->setAttribute(qualifiedName, CSSSelector::CaseSensitive);
284 selector->setMatch(CSSSelector::AttributeSet); 278 selector->setMatch(CSSSelector::AttributeSet);
285 return selector.release(); 279 return selector.release();
286 } 280 }
287 281
288 selector->setMatch(consumeAttributeMatch(block)); 282 selector->setMatch(consumeAttributeMatch(block));
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 return QualifiedName(prefix, localName, defaultNamespace()); 542 return QualifiedName(prefix, localName, defaultNamespace());
549 return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(pre fix)); 543 return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(pre fix));
550 } 544 }
551 545
552 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector) 546 void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespac ePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector)
553 { 547 {
554 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->crossesTreeScopes()) 548 if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelec tor->crossesTreeScopes())
555 return; 549 return;
556 550
557 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName; 551 AtomicString determinedElementName = elementName.isNull() ? starAtom : eleme ntName;
558 AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleShe et ? m_styleSheet->determineNamespace(namespacePrefix) : defaultNamespace(); 552 QualifiedName tag = determineNameInNamespace(namespacePrefix, determinedElem entName);
559 QualifiedName tag(namespacePrefix, determinedElementName, determinedNamespac e);
560 553
561 if (compoundSelector->crossesTreeScopes()) 554 if (compoundSelector->crossesTreeScopes())
562 return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, compo undSelector, elementName.isNull()); 555 return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, compo undSelector, elementName.isNull());
563 556
564 if (compoundSelector->pseudoType() == CSSSelector::PseudoContent) 557 if (compoundSelector->pseudoType() == CSSSelector::PseudoContent)
565 return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, comp oundSelector, elementName.isNull()); 558 return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, comp oundSelector, elementName.isNull());
566 559
567 // *:host never matches, so we can't discard the * otherwise we can't tell t he 560 // *:host never matches, so we can't discard the * otherwise we can't tell t he
568 // difference between *:host and just :host. 561 // difference between *:host and just :host.
569 if (tag == anyQName() && !compoundSelector->hasHostPseudoSelector()) 562 if (tag == anyQName() && !compoundSelector->hasHostPseudoSelector())
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 compoundSelector->insertTagHistory(CSSSelector::SubSelector, simpleSelec tor, relation); 653 compoundSelector->insertTagHistory(CSSSelector::SubSelector, simpleSelec tor, relation);
661 return compoundSelector; 654 return compoundSelector;
662 } 655 }
663 656
664 // All other simple selectors are added to the end of the compound. 657 // All other simple selectors are added to the end of the compound.
665 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ; 658 compoundSelector->appendTagHistory(CSSSelector::SubSelector, simpleSelector) ;
666 return compoundSelector; 659 return compoundSelector;
667 } 660 }
668 661
669 } // namespace blink 662 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/css/parser/CSSSelectorParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698