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

Side by Side Diff: Source/core/css/CSSParser.cpp

Issue 13646013: Enable support for CSS Conditional Rules (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSRule.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. 9 * Copyright (C) 2012 Intel Corporation. All rights reserved.
10 * 10 *
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 && a.isCSSGridLayoutEnabled == b.isCSSGridLayoutEnabled 283 && a.isCSSGridLayoutEnabled == b.isCSSGridLayoutEnabled
284 && a.isCSSVariablesEnabled == b.isCSSVariablesEnabled 284 && a.isCSSVariablesEnabled == b.isCSSVariablesEnabled
285 && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks; 285 && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks;
286 } 286 }
287 287
288 CSSParser::CSSParser(const CSSParserContext& context) 288 CSSParser::CSSParser(const CSSParserContext& context)
289 : m_context(context) 289 : m_context(context)
290 , m_important(false) 290 , m_important(false)
291 , m_id(CSSPropertyInvalid) 291 , m_id(CSSPropertyInvalid)
292 , m_styleSheet(0) 292 , m_styleSheet(0)
293 #if ENABLE(CSS3_CONDITIONAL_RULES)
294 , m_supportsCondition(false) 293 , m_supportsCondition(false)
295 #endif
296 , m_selectorListForParseSelector(0) 294 , m_selectorListForParseSelector(0)
297 , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES) 295 , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
298 , m_inParseShorthand(0) 296 , m_inParseShorthand(0)
299 , m_currentShorthand(CSSPropertyInvalid) 297 , m_currentShorthand(CSSPropertyInvalid)
300 , m_implicitShorthand(false) 298 , m_implicitShorthand(false)
301 , m_hasFontFaceOnlyValues(false) 299 , m_hasFontFaceOnlyValues(false)
302 , m_hadSyntacticallyValidCSSRule(false) 300 , m_hadSyntacticallyValidCSSRule(false)
303 , m_logErrors(false) 301 , m_logErrors(false)
304 , m_inFilterRule(false) 302 , m_inFilterRule(false)
305 , m_defaultNamespace(starAtom) 303 , m_defaultNamespace(starAtom)
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 459 }
462 460
463 PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet , const String& string) 461 PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet , const String& string)
464 { 462 {
465 setStyleSheet(sheet); 463 setStyleSheet(sheet);
466 setupParser("@-webkit-keyframe-rule{ ", string, "} "); 464 setupParser("@-webkit-keyframe-rule{ ", string, "} ");
467 cssyyparse(this); 465 cssyyparse(this);
468 return m_keyframe.release(); 466 return m_keyframe.release();
469 } 467 }
470 468
471 #if ENABLE(CSS3_CONDITIONAL_RULES)
472 bool CSSParser::parseSupportsCondition(const String& string) 469 bool CSSParser::parseSupportsCondition(const String& string)
473 { 470 {
474 m_supportsCondition = false; 471 m_supportsCondition = false;
475 setupParser("@-webkit-supports-condition{ ", string, "} "); 472 setupParser("@-webkit-supports-condition{ ", string, "} ");
476 cssyyparse(this); 473 cssyyparse(this);
477 return m_supportsCondition; 474 return m_supportsCondition;
478 } 475 }
479 #endif
480 476
481 static inline bool isColorPropertyID(CSSPropertyID propertyId) 477 static inline bool isColorPropertyID(CSSPropertyID propertyId)
482 { 478 {
483 switch (propertyId) { 479 switch (propertyId) {
484 case CSSPropertyColor: 480 case CSSPropertyColor:
485 case CSSPropertyBackgroundColor: 481 case CSSPropertyBackgroundColor:
486 case CSSPropertyBorderBottomColor: 482 case CSSPropertyBorderBottomColor:
487 case CSSPropertyBorderLeftColor: 483 case CSSPropertyBorderLeftColor:
488 case CSSPropertyBorderRightColor: 484 case CSSPropertyBorderRightColor:
489 case CSSPropertyBorderTopColor: 485 case CSSPropertyBorderTopColor:
(...skipping 9694 matching lines...) Expand 10 before | Expand all | Expand 10 after
10184 m_token = RIGHTTOP_SYM; 10180 m_token = RIGHTTOP_SYM;
10185 } else if (length == 13) { 10181 } else if (length == 13) {
10186 // Checking the last character first could further reduce the possib ile cases. 10182 // Checking the last character first could further reduce the possib ile cases.
10187 if (isASCIIAlphaCaselessEqual(name[12], 'e') && isEqualToCSSIdentifi er(name + 2, "ight-middl")) 10183 if (isASCIIAlphaCaselessEqual(name[12], 'e') && isEqualToCSSIdentifi er(name + 2, "ight-middl"))
10188 m_token = RIGHTMIDDLE_SYM; 10184 m_token = RIGHTMIDDLE_SYM;
10189 else if (isASCIIAlphaCaselessEqual(name[12], 'm') && isEqualToCSSIde ntifier(name + 2, "ight-botto")) 10185 else if (isASCIIAlphaCaselessEqual(name[12], 'm') && isEqualToCSSIde ntifier(name + 2, "ight-botto"))
10190 m_token = RIGHTBOTTOM_SYM; 10186 m_token = RIGHTBOTTOM_SYM;
10191 } 10187 }
10192 return; 10188 return;
10193 10189
10194 #if ENABLE(CSS3_CONDITIONAL_RULES)
10195 case 's': 10190 case 's':
10196 if (length == 9 && isEqualToCSSIdentifier(name + 2, "upports")) { 10191 if (length == 9 && isEqualToCSSIdentifier(name + 2, "upports")) {
10197 m_parsingMode = SupportsMode; 10192 m_parsingMode = SupportsMode;
10198 m_token = SUPPORTS_SYM; 10193 m_token = SUPPORTS_SYM;
10199 } 10194 }
10200 return; 10195 return;
10201 #endif
10202 10196
10203 case 't': 10197 case 't':
10204 if (hasEscape) 10198 if (hasEscape)
10205 return; 10199 return;
10206 10200
10207 switch (length) { 10201 switch (length) {
10208 case 9: 10202 case 9:
10209 if (isEqualToCSSIdentifier(name + 2, "op-left")) 10203 if (isEqualToCSSIdentifier(name + 2, "op-left"))
10210 m_token = TOPLEFT_SYM; 10204 m_token = TOPLEFT_SYM;
10211 return; 10205 return;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
10292 m_token = WEBKIT_MEDIAQUERY_SYM; 10286 m_token = WEBKIT_MEDIAQUERY_SYM;
10293 } 10287 }
10294 return; 10288 return;
10295 10289
10296 case 22: 10290 case 22:
10297 if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-keyframe- rule")) 10291 if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-keyframe- rule"))
10298 m_token = WEBKIT_KEYFRAME_RULE_SYM; 10292 m_token = WEBKIT_KEYFRAME_RULE_SYM;
10299 return; 10293 return;
10300 10294
10301 case 27: 10295 case 27:
10302 #if ENABLE(CSS3_CONDITIONAL_RULES)
10303 if (isEqualToCSSIdentifier(name + 2, "webkit-supports-condition")) { 10296 if (isEqualToCSSIdentifier(name + 2, "webkit-supports-condition")) {
10304 m_parsingMode = SupportsMode; 10297 m_parsingMode = SupportsMode;
10305 m_token = WEBKIT_SUPPORTS_CONDITION_SYM; 10298 m_token = WEBKIT_SUPPORTS_CONDITION_SYM;
10306 } 10299 }
10307 #endif
10308 return; 10300 return;
10309 } 10301 }
10310 } 10302 }
10311 } 10303 }
10312 10304
10313 #if ENABLE(CSS3_CONDITIONAL_RULES)
10314 template <typename CharacterType> 10305 template <typename CharacterType>
10315 inline void CSSParser::detectSupportsToken(int length) 10306 inline void CSSParser::detectSupportsToken(int length)
10316 { 10307 {
10317 ASSERT(m_parsingMode == SupportsMode); 10308 ASSERT(m_parsingMode == SupportsMode);
10318 CharacterType* name = tokenStart<CharacterType>(); 10309 CharacterType* name = tokenStart<CharacterType>();
10319 10310
10320 if (length == 2) { 10311 if (length == 2) {
10321 if (isASCIIAlphaCaselessEqual(name[0], 'o') && isASCIIAlphaCaselessEqual (name[1], 'r')) 10312 if (isASCIIAlphaCaselessEqual(name[0], 'o') && isASCIIAlphaCaselessEqual (name[1], 'r'))
10322 m_token = SUPPORTS_OR; 10313 m_token = SUPPORTS_OR;
10323 } else if (length == 3) { 10314 } else if (length == 3) {
10324 if (isASCIIAlphaCaselessEqual(name[0], 'a') && isASCIIAlphaCaselessEqual (name[1], 'n') && isASCIIAlphaCaselessEqual(name[2], 'd')) 10315 if (isASCIIAlphaCaselessEqual(name[0], 'a') && isASCIIAlphaCaselessEqual (name[1], 'n') && isASCIIAlphaCaselessEqual(name[2], 'd'))
10325 m_token = SUPPORTS_AND; 10316 m_token = SUPPORTS_AND;
10326 else if (isASCIIAlphaCaselessEqual(name[0], 'n') && isASCIIAlphaCaseless Equal(name[1], 'o') && isASCIIAlphaCaselessEqual(name[2], 't')) 10317 else if (isASCIIAlphaCaselessEqual(name[0], 'n') && isASCIIAlphaCaseless Equal(name[1], 'o') && isASCIIAlphaCaselessEqual(name[2], 't'))
10327 m_token = SUPPORTS_NOT; 10318 m_token = SUPPORTS_NOT;
10328 } 10319 }
10329 } 10320 }
10330 #endif
10331 10321
10332 template <typename SrcCharacterType> 10322 template <typename SrcCharacterType>
10333 int CSSParser::realLex(void* yylvalWithoutType) 10323 int CSSParser::realLex(void* yylvalWithoutType)
10334 { 10324 {
10335 YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType); 10325 YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType);
10336 // Write pointer for the next character. 10326 // Write pointer for the next character.
10337 SrcCharacterType* result; 10327 SrcCharacterType* result;
10338 CSSParserString resultString; 10328 CSSParserString resultString;
10339 bool hasEscape; 10329 bool hasEscape;
10340 10330
(...skipping 20 matching lines...) Expand all
10361 break; 10351 break;
10362 } 10352 }
10363 // Fall through to CharacterIdentifierStart. 10353 // Fall through to CharacterIdentifierStart.
10364 10354
10365 case CharacterIdentifierStart: 10355 case CharacterIdentifierStart:
10366 --currentCharacter<SrcCharacterType>(); 10356 --currentCharacter<SrcCharacterType>();
10367 parseIdentifier(result, yylval->string, hasEscape); 10357 parseIdentifier(result, yylval->string, hasEscape);
10368 m_token = IDENT; 10358 m_token = IDENT;
10369 10359
10370 if (UNLIKELY(*currentCharacter<SrcCharacterType>() == '(')) { 10360 if (UNLIKELY(*currentCharacter<SrcCharacterType>() == '(')) {
10371 #if ENABLE(CSS3_CONDITIONAL_RULES)
10372 if (m_parsingMode == SupportsMode && !hasEscape) { 10361 if (m_parsingMode == SupportsMode && !hasEscape) {
10373 detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCha racterType>()); 10362 detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCha racterType>());
10374 if (m_token != IDENT) 10363 if (m_token != IDENT)
10375 break; 10364 break;
10376 } 10365 }
10377 #endif 10366
10378 m_token = FUNCTION; 10367 m_token = FUNCTION;
10379 bool shouldSkipParenthesis = true; 10368 bool shouldSkipParenthesis = true;
10380 if (!hasEscape) { 10369 if (!hasEscape) {
10381 bool detected = detectFunctionTypeToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>()); 10370 bool detected = detectFunctionTypeToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
10382 if (!detected && m_parsingMode == MediaQueryMode) { 10371 if (!detected && m_parsingMode == MediaQueryMode) {
10383 // ... and(max-width: 480px) ... looks like a function, but in fact it is not, 10372 // ... and(max-width: 480px) ... looks like a function, but in fact it is not,
10384 // so run more detection code in the MediaQueryMode. 10373 // so run more detection code in the MediaQueryMode.
10385 detectMediaQueryToken<SrcCharacterType>(result - tokenStart< SrcCharacterType>()); 10374 detectMediaQueryToken<SrcCharacterType>(result - tokenStart< SrcCharacterType>());
10386 shouldSkipParenthesis = false; 10375 shouldSkipParenthesis = false;
10387 } 10376 }
10388 } 10377 }
10389 10378
10390 if (LIKELY(shouldSkipParenthesis)) { 10379 if (LIKELY(shouldSkipParenthesis)) {
10391 ++currentCharacter<SrcCharacterType>(); 10380 ++currentCharacter<SrcCharacterType>();
10392 ++result; 10381 ++result;
10393 ++yylval->string.m_length; 10382 ++yylval->string.m_length;
10394 } 10383 }
10395 10384
10396 if (token() == URI) { 10385 if (token() == URI) {
10397 m_token = FUNCTION; 10386 m_token = FUNCTION;
10398 // Check whether it is really an URI. 10387 // Check whether it is really an URI.
10399 if (yylval->string.is8Bit()) 10388 if (yylval->string.is8Bit())
10400 parseURI<LChar>(yylval->string); 10389 parseURI<LChar>(yylval->string);
10401 else 10390 else
10402 parseURI<UChar>(yylval->string); 10391 parseURI<UChar>(yylval->string);
10403 } 10392 }
10404 } else if (UNLIKELY(m_parsingMode != NormalMode) && !hasEscape) { 10393 } else if (UNLIKELY(m_parsingMode != NormalMode) && !hasEscape) {
10405 if (m_parsingMode == MediaQueryMode) 10394 if (m_parsingMode == MediaQueryMode)
10406 detectMediaQueryToken<SrcCharacterType>(result - tokenStart<SrcC haracterType>()); 10395 detectMediaQueryToken<SrcCharacterType>(result - tokenStart<SrcC haracterType>());
10407 #if ENABLE(CSS3_CONDITIONAL_RULES)
10408 else if (m_parsingMode == SupportsMode) 10396 else if (m_parsingMode == SupportsMode)
10409 detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCha racterType>()); 10397 detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCha racterType>());
10410 #endif
10411 else if (m_parsingMode == NthChildMode && isASCIIAlphaCaselessEqual( tokenStart<SrcCharacterType>()[0], 'n')) { 10398 else if (m_parsingMode == NthChildMode && isASCIIAlphaCaselessEqual( tokenStart<SrcCharacterType>()[0], 'n')) {
10412 if (result - tokenStart<SrcCharacterType>() == 1) { 10399 if (result - tokenStart<SrcCharacterType>() == 1) {
10413 // String "n" is IDENT but "n+1" is NTH. 10400 // String "n" is IDENT but "n+1" is NTH.
10414 if (parseNthChildExtra<SrcCharacterType>()) { 10401 if (parseNthChildExtra<SrcCharacterType>()) {
10415 m_token = NTH; 10402 m_token = NTH;
10416 yylval->string.m_length = currentCharacter<SrcCharacterT ype>() - tokenStart<SrcCharacterType>(); 10403 yylval->string.m_length = currentCharacter<SrcCharacterT ype>() - tokenStart<SrcCharacterType>();
10417 } 10404 }
10418 } else if (result - tokenStart<SrcCharacterType>() >= 2 && token Start<SrcCharacterType>()[1] == '-') { 10405 } else if (result - tokenStart<SrcCharacterType>() >= 2 && token Start<SrcCharacterType>()[1] == '-') {
10419 // String "n-" is IDENT but "n-1" is NTH. 10406 // String "n-" is IDENT but "n-1" is NTH.
10420 // Set currentCharacter to '-' to continue parsing. 10407 // Set currentCharacter to '-' to continue parsing.
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
10902 else { 10889 else {
10903 RuleList emptyRules; 10890 RuleList emptyRules;
10904 rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), e mptyRules); 10891 rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), e mptyRules);
10905 } 10892 }
10906 StyleRuleMedia* result = rule.get(); 10893 StyleRuleMedia* result = rule.get();
10907 m_parsedRules.append(rule.release()); 10894 m_parsedRules.append(rule.release());
10908 endRuleBody(); 10895 endRuleBody();
10909 return result; 10896 return result;
10910 } 10897 }
10911 10898
10912 #if ENABLE(CSS3_CONDITIONAL_RULES)
10913 StyleRuleBase* CSSParser::createSupportsRule(bool conditionIsSupported, RuleList * rules) 10899 StyleRuleBase* CSSParser::createSupportsRule(bool conditionIsSupported, RuleList * rules)
10914 { 10900 {
10915 m_allowImportRules = m_allowNamespaceDeclarations = false; 10901 m_allowImportRules = m_allowNamespaceDeclarations = false;
10916 10902
10917 RefPtr<CSSRuleSourceData> data = popSupportsRuleData(); 10903 RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
10918 RefPtr<StyleRuleSupports> rule; 10904 RefPtr<StyleRuleSupports> rule;
10919 String conditionText; 10905 String conditionText;
10920 unsigned conditionOffset = data->ruleHeaderRange.start + 9; 10906 unsigned conditionOffset = data->ruleHeaderRange.start + 9;
10921 unsigned conditionLength = data->ruleHeaderRange.length() - 9; 10907 unsigned conditionLength = data->ruleHeaderRange.length() - 9;
10922 10908
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
10960 } 10946 }
10961 10947
10962 PassRefPtr<CSSRuleSourceData> CSSParser::popSupportsRuleData() 10948 PassRefPtr<CSSRuleSourceData> CSSParser::popSupportsRuleData()
10963 { 10949 {
10964 ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty()); 10950 ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
10965 RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last(); 10951 RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
10966 m_supportsRuleDataStack->removeLast(); 10952 m_supportsRuleDataStack->removeLast();
10967 return data.release(); 10953 return data.release();
10968 } 10954 }
10969 10955
10970 #endif
10971
10972 CSSParser::RuleList* CSSParser::createRuleList() 10956 CSSParser::RuleList* CSSParser::createRuleList()
10973 { 10957 {
10974 OwnPtr<RuleList> list = adoptPtr(new RuleList); 10958 OwnPtr<RuleList> list = adoptPtr(new RuleList);
10975 RuleList* listPtr = list.get(); 10959 RuleList* listPtr = list.get();
10976 10960
10977 m_parsedRuleLists.append(list.release()); 10961 m_parsedRuleLists.append(list.release());
10978 return listPtr; 10962 return listPtr;
10979 } 10963 }
10980 10964
10981 void CSSParser::syntaxError(const Location& location, SyntaxErrorType error) 10965 void CSSParser::syntaxError(const Location& location, SyntaxErrorType error)
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
11728 { 11712 {
11729 // The tokenizer checks for the construct of an+b. 11713 // The tokenizer checks for the construct of an+b.
11730 // However, since the {ident} rule precedes the {nth} rule, some of those 11714 // However, since the {ident} rule precedes the {nth} rule, some of those
11731 // tokens are identified as string literal. Furthermore we need to accept 11715 // tokens are identified as string literal. Furthermore we need to accept
11732 // "odd" and "even" which does not match to an+b. 11716 // "odd" and "even" which does not match to an+b.
11733 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even") 11717 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
11734 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n"); 11718 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
11735 } 11719 }
11736 11720
11737 } 11721 }
OLDNEW
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSRule.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698