| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 end->setRelationIsAffectedByPseudoContent(); | 156 end->setRelationIsAffectedByPseudoContent(); |
| 157 previousCompoundHasContentPseudo = compoundHasContentPseudo; | 157 previousCompoundHasContentPseudo = compoundHasContentPseudo; |
| 158 end->setTagHistory(selector.release()); | 158 end->setTagHistory(selector.release()); |
| 159 | 159 |
| 160 selector = nextSelector.release(); | 160 selector = nextSelector.release(); |
| 161 } | 161 } |
| 162 | 162 |
| 163 return selector.release(); | 163 return selector.release(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 namespace { |
| 167 |
| 168 bool isScrollbarPseudoClass(CSSSelector::PseudoType pseudo) |
| 169 { |
| 170 switch (pseudo) { |
| 171 case CSSSelector::PseudoEnabled: |
| 172 case CSSSelector::PseudoDisabled: |
| 173 case CSSSelector::PseudoHover: |
| 174 case CSSSelector::PseudoActive: |
| 175 case CSSSelector::PseudoHorizontal: |
| 176 case CSSSelector::PseudoVertical: |
| 177 case CSSSelector::PseudoDecrement: |
| 178 case CSSSelector::PseudoIncrement: |
| 179 case CSSSelector::PseudoStart: |
| 180 case CSSSelector::PseudoEnd: |
| 181 case CSSSelector::PseudoDoubleButton: |
| 182 case CSSSelector::PseudoSingleButton: |
| 183 case CSSSelector::PseudoNoButton: |
| 184 case CSSSelector::PseudoCornerPresent: |
| 185 case CSSSelector::PseudoWindowInactive: |
| 186 return true; |
| 187 default: |
| 188 return false; |
| 189 } |
| 190 } |
| 191 |
| 192 bool isUserActionPseudoClass(CSSSelector::PseudoType pseudo) |
| 193 { |
| 194 switch (pseudo) { |
| 195 case CSSSelector::PseudoHover: |
| 196 case CSSSelector::PseudoFocus: |
| 197 case CSSSelector::PseudoActive: |
| 198 return true; |
| 199 default: |
| 200 return false; |
| 201 } |
| 202 } |
| 203 |
| 204 bool isPseudoClassValidAfterPseudoElement(CSSSelector::PseudoType pseudoClass, C
SSSelector::PseudoType compoundPseudoElement) |
| 205 { |
| 206 switch (compoundPseudoElement) { |
| 207 case CSSSelector::PseudoResizer: |
| 208 case CSSSelector::PseudoScrollbar: |
| 209 case CSSSelector::PseudoScrollbarCorner: |
| 210 case CSSSelector::PseudoScrollbarButton: |
| 211 case CSSSelector::PseudoScrollbarThumb: |
| 212 case CSSSelector::PseudoScrollbarTrack: |
| 213 case CSSSelector::PseudoScrollbarTrackPiece: |
| 214 return isScrollbarPseudoClass(pseudoClass); |
| 215 case CSSSelector::PseudoSelection: |
| 216 return pseudoClass == CSSSelector::PseudoWindowInactive; |
| 217 case CSSSelector::PseudoWebKitCustomElement: |
| 218 return isUserActionPseudoClass(pseudoClass); |
| 219 default: |
| 220 return false; |
| 221 } |
| 222 } |
| 223 |
| 224 bool isSimpleSelectorValidAfterPseudoElement(const CSSParserSelector& simpleSele
ctor, CSSSelector::PseudoType compoundPseudoElement) |
| 225 { |
| 226 if (compoundPseudoElement == CSSSelector::PseudoUnknown) |
| 227 return true; |
| 228 if (simpleSelector.match() != CSSSelector::PseudoClass) |
| 229 return false; |
| 230 CSSSelector::PseudoType pseudo = simpleSelector.pseudoType(); |
| 231 if (pseudo == CSSSelector::PseudoNot) { |
| 232 ASSERT(simpleSelector.selectorList()); |
| 233 ASSERT(simpleSelector.selectorList()->first()); |
| 234 ASSERT(!simpleSelector.selectorList()->first()->tagHistory()); |
| 235 pseudo = simpleSelector.selectorList()->first()->pseudoType(); |
| 236 } |
| 237 return isPseudoClassValidAfterPseudoElement(pseudo, compoundPseudoElement); |
| 238 } |
| 239 |
| 240 } // namespace |
| 241 |
| 166 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSPars
erTokenRange& range) | 242 PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeCompoundSelector(CSSPars
erTokenRange& range) |
| 167 { | 243 { |
| 168 OwnPtr<CSSParserSelector> compoundSelector; | 244 OwnPtr<CSSParserSelector> compoundSelector; |
| 169 | 245 |
| 170 AtomicString namespacePrefix; | 246 AtomicString namespacePrefix; |
| 171 AtomicString elementName; | 247 AtomicString elementName; |
| 248 CSSSelector::PseudoType compoundPseudoElement = CSSSelector::PseudoUnknown; |
| 172 if (!consumeName(range, elementName, namespacePrefix)) { | 249 if (!consumeName(range, elementName, namespacePrefix)) { |
| 173 compoundSelector = consumeSimpleSelector(range); | 250 compoundSelector = consumeSimpleSelector(range); |
| 174 if (!compoundSelector) | 251 if (!compoundSelector) |
| 175 return nullptr; | 252 return nullptr; |
| 253 if (compoundSelector->match() == CSSSelector::PseudoElement) |
| 254 compoundPseudoElement = compoundSelector->pseudoType(); |
| 176 } | 255 } |
| 177 if (m_context.isHTMLDocument()) | 256 if (m_context.isHTMLDocument()) |
| 178 elementName = elementName.lower(); | 257 elementName = elementName.lower(); |
| 179 | 258 |
| 180 while (OwnPtr<CSSParserSelector> simpleSelector = consumeSimpleSelector(rang
e)) { | 259 while (OwnPtr<CSSParserSelector> simpleSelector = consumeSimpleSelector(rang
e)) { |
| 260 // TODO(rune@opera.com): crbug.com/578131 |
| 261 // The UASheetMode check is a work-around to allow this selector in medi
aControls(New).css: |
| 262 // video::-webkit-media-text-track-region-container.scrolling |
| 263 if (m_context.mode() != UASheetMode && !isSimpleSelectorValidAfterPseudo
Element(*simpleSelector.get(), compoundPseudoElement)) |
| 264 return nullptr; |
| 265 if (simpleSelector->match() == CSSSelector::PseudoElement) |
| 266 compoundPseudoElement = simpleSelector->pseudoType(); |
| 267 |
| 181 if (compoundSelector) | 268 if (compoundSelector) |
| 182 compoundSelector = addSimpleSelectorToCompound(compoundSelector.rele
ase(), simpleSelector.release()); | 269 compoundSelector = addSimpleSelectorToCompound(compoundSelector.rele
ase(), simpleSelector.release()); |
| 183 else | 270 else |
| 184 compoundSelector = simpleSelector.release(); | 271 compoundSelector = simpleSelector.release(); |
| 185 } | 272 } |
| 186 | 273 |
| 187 if (!compoundSelector) { | 274 if (!compoundSelector) { |
| 188 AtomicString namespaceURI = determineNamespace(namespacePrefix); | 275 AtomicString namespaceURI = determineNamespace(namespacePrefix); |
| 189 if (namespaceURI.isNull()) | 276 if (namespaceURI.isNull()) |
| 190 return nullptr; | 277 return nullptr; |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 | 715 |
| 629 if (!splitAfter || !splitAfter->tagHistory()) | 716 if (!splitAfter || !splitAfter->tagHistory()) |
| 630 return compoundSelector; | 717 return compoundSelector; |
| 631 | 718 |
| 632 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); | 719 OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); |
| 633 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector
); | 720 secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector
); |
| 634 return secondCompound.release(); | 721 return secondCompound.release(); |
| 635 } | 722 } |
| 636 | 723 |
| 637 } // namespace blink | 724 } // namespace blink |
| OLD | NEW |