4 * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2012 Intel Corporation. All rights reserved.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "CSSPropertyNames.h"
29 #include "HTMLNames.h"
30 #include "core/css/CSSKeyframeRule.h"
31 #include "core/css/CSSKeyframesRule.h"
32 #include "core/css/parser/BisonCSSParser.h"
33 #include "core/css/CSSParserMode.h"
34 #include "core/css/CSSPrimitiveValue.h"
35 #include "core/css/CSSSelector.h"
36 #include "core/css/CSSSelectorList.h"
37 #include "core/css/MediaList.h"
38 #include "core/css/MediaQueryExp.h"
39 #include "core/css/StyleRule.h"
40 #include "core/css/StyleSheetContents.h"
41 #include "core/dom/Document.h"
42 #include "wtf/FastMalloc.h"
46 using namespace WebCore;
47 using namespace HTMLNames;
49 #define YYMALLOC fastMalloc
50 #define YYFREE fastFree
52 #define YYENABLE_NLS 0
53 #define YYLTYPE_IS_TRIVIAL 1
54 #define YYMAXDEPTH 10000
58 #define YYPRINT(File,Type,Value) if (isCSSTokenAString(Type)) YYFPRINTF(File, "%s", String((Value).string).utf8().data())
65 %parse-param { BisonCSSParser* parser }
66 %lex-param { BisonCSSParser* parser }
73 CSSParserString string;
76 // The content of the three below HeapVectors are guaranteed to be kept alive by
77 // the corresponding m_parsedRules, m_floatingMediaQueryExpList, and m_parsedKeyFrames
78 // lists in BisonCSSParser.h.
79 WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >* ruleList;
80 WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* mediaQueryExpList;
81 WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* keyframeRuleList;
82 CSSParserSelector* selector;
83 Vector<OwnPtr<CSSParserSelector> >* selectorList;
84 CSSSelector::MarginBoxType marginBox;
85 CSSSelector::Relation relation;
86 MediaQuerySet* mediaList;
87 MediaQuery* mediaQuery;
88 MediaQuery::Restrictor mediaQueryRestrictor;
89 MediaQueryExp* mediaQueryExp;
91 CSSParserValueList* valueList;
92 StyleKeyframe* keyframe;
95 CSSParserLocation location;
100 static inline int cssyyerror(void*, const char*)
106 static inline bool isCSSTokenAString(int yytype)
120 case HOSTCONTEXTFUNCTION:
131 inline static CSSParserValue makeOperatorValue(int value)
134 v.id = CSSValueInvalid;
135 v.unit = CSSParserValue::Operator;
140 inline static CSSParserValue makeIdentValue(CSSParserString string)
143 v.id = cssValueKeywordID(string);
144 v.unit = CSSPrimitiveValue::CSS_IDENT;
153 %nonassoc LOWEST_PREC
155 %left UNIMPORTANT_TOK
157 %token WHITESPACE SGML_CD
166 %token <string> STRING
167 %right <string> IDENT
170 %nonassoc <string> HEX
171 %nonassoc <string> IDSEL
175 %nonassoc <string> '*'
186 %token VIEWPORT_RULE_SYM
187 %token INTERNAL_DECLS_SYM
188 %token INTERNAL_MEDIALIST_SYM
189 %token INTERNAL_RULE_SYM
190 %token INTERNAL_SELECTOR_SYM
191 %token INTERNAL_VALUE_SYM
192 %token INTERNAL_KEYFRAME_RULE_SYM
193 %token INTERNAL_KEYFRAME_KEY_LIST_SYM
194 %token INTERNAL_SUPPORTS_CONDITION_SYM
196 %token WEBKIT_KEYFRAMES_SYM
197 %token <marginBox> TOPLEFTCORNER_SYM
198 %token <marginBox> TOPLEFT_SYM
199 %token <marginBox> TOPCENTER_SYM
200 %token <marginBox> TOPRIGHT_SYM
201 %token <marginBox> TOPRIGHTCORNER_SYM
202 %token <marginBox> BOTTOMLEFTCORNER_SYM
203 %token <marginBox> BOTTOMLEFT_SYM
204 %token <marginBox> BOTTOMCENTER_SYM
205 %token <marginBox> BOTTOMRIGHT_SYM
206 %token <marginBox> BOTTOMRIGHTCORNER_SYM
207 %token <marginBox> LEFTTOP_SYM
208 %token <marginBox> LEFTMIDDLE_SYM
209 %token <marginBox> LEFTBOTTOM_SYM
210 %token <marginBox> RIGHTTOP_SYM
211 %token <marginBox> RIGHTMIDDLE_SYM
212 %token <marginBox> RIGHTBOTTOM_SYM
239 %token <number> GRADS
240 %token <number> TURNS
241 %token <number> MSECS
243 %token <number> HERTZ
244 %token <number> KHERTZ
245 %token <string> DIMEN
246 %token <string> INVALIDDIMEN
247 %token <number> PERCENTAGE
248 %token <number> FLOATTOKEN
249 %token <number> INTEGER
260 %token <string> FUNCTION
261 %token <string> ANYFUNCTION
262 %token <string> CUEFUNCTION
263 %token <string> NOTFUNCTION
264 %token <string> DISTRIBUTEDFUNCTION
265 %token <string> CALCFUNCTION
266 %token <string> HOSTFUNCTION
267 %token <string> HOSTCONTEXTFUNCTION
269 %token <string> UNICODERANGE
271 %type <relation> combinator
276 %type <rule> namespace
278 %type <rule> margin_box
279 %type <rule> font_face
280 %type <rule> keyframes
282 %type <rule> valid_rule
283 %type <ruleList> block_rule_body
284 %type <ruleList> block_rule_list
285 %type <rule> block_rule
286 %type <rule> block_valid_rule
287 %type <rule> supports
288 %type <rule> viewport
289 %type <boolean> keyframes_rule_start
291 %type <string> maybe_ns_prefix
293 %type <string> namespace_selector
295 %type <string> string_or_uri
296 %type <string> ident_or_string
297 %type <string> medium
298 %type <marginBox> margin_sym
300 %type <mediaList> media_list
301 %type <mediaList> maybe_media_list
302 %type <mediaList> mq_list
303 %type <mediaQuery> media_query
304 %type <mediaQuery> valid_media_query
305 %type <mediaQueryRestrictor> maybe_media_restrictor
306 %type <valueList> maybe_media_value
307 %type <mediaQueryExp> media_query_exp
308 %type <mediaQueryExpList> media_query_exp_list
309 %type <mediaQueryExpList> maybe_and_media_query_exp_list
311 %type <boolean> supports_condition
312 %type <boolean> supports_condition_in_parens
313 %type <boolean> supports_negation
314 %type <boolean> supports_conjunction
315 %type <boolean> supports_disjunction
316 %type <boolean> supports_declaration_condition
318 %type <string> keyframe_name
319 %type <keyframe> keyframe_rule
320 %type <keyframeRuleList> keyframes_rule
321 %type <keyframeRuleList> keyframe_rule_list
322 %type <valueList> key_list
327 %type <selector> specifier
328 %type <selector> specifier_list
329 %type <selector> simple_selector
330 %type <selector> selector
331 %type <selectorList> selector_list
332 %type <selectorList> simple_selector_list
333 %type <selector> class
334 %type <selector> attrib
335 %type <selector> pseudo
336 %type <selector> pseudo_page
337 %type <selector> page_selector
339 %type <boolean> declaration_list
340 %type <boolean> decl_list
341 %type <boolean> declaration
342 %type <boolean> declarations_and_margins
346 %type <integer> match
347 %type <integer> unary_operator
348 %type <integer> maybe_unary_operator
349 %type <character> operator
351 %type <valueList> expr
353 %type <value> unary_term
354 %type <value> function
355 %type <value> calc_func_term
356 %type <character> calc_func_operator
357 %type <valueList> calc_func_expr
358 %type <valueList> calc_func_paren_expr
359 %type <value> calc_function
361 %type <string> element_name
362 %type <string> attr_name
364 %type <location> error_location
366 %type <valueList> ident_list
367 %type <value> track_names_list
372 maybe_charset maybe_sgml rule_list
378 | internal_keyframe_rule
379 | internal_keyframe_key_list
380 | internal_supports_condition
384 INTERNAL_RULE_SYM maybe_space valid_rule maybe_space TOKEN_EOF {
389 internal_keyframe_rule:
390 INTERNAL_KEYFRAME_RULE_SYM maybe_space keyframe_rule maybe_space TOKEN_EOF {
391 parser->m_keyframe = $3;
395 internal_keyframe_key_list:
396 INTERNAL_KEYFRAME_KEY_LIST_SYM maybe_space key_list TOKEN_EOF {
397 parser->m_valueList = parser->sinkFloatingValueList($3);
402 INTERNAL_DECLS_SYM maybe_space_before_declaration declaration_list TOKEN_EOF {
408 INTERNAL_VALUE_SYM maybe_space expr TOKEN_EOF {
409 parser->m_valueList = parser->sinkFloatingValueList($3);
410 int oldParsedProperties = parser->m_parsedProperties.size();
411 if (!parser->parseValue(parser->m_id, parser->m_important))
412 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
413 parser->m_valueList = nullptr;
418 INTERNAL_MEDIALIST_SYM maybe_space location_label maybe_media_list TOKEN_EOF {
419 parser->m_mediaList = $4;
424 INTERNAL_SELECTOR_SYM maybe_space selector_list TOKEN_EOF {
425 if (parser->m_selectorListForParseSelector)
426 parser->m_selectorListForParseSelector->adoptSelectorVector(*$3);
430 internal_supports_condition:
431 INTERNAL_SUPPORTS_CONDITION_SYM maybe_space supports_condition TOKEN_EOF {
432 parser->m_supportsCondition = $3;
442 /* empty */ %prec UNIMPORTANT_TOK
449 | maybe_sgml WHITESPACE
454 | %prec LOWEST_PREC TOKEN_EOF
459 | %prec LOWEST_PREC TOKEN_EOF
462 closing_square_bracket:
464 | %prec LOWEST_PREC TOKEN_EOF
474 | CHARSET_SYM maybe_space STRING maybe_space semi_or_eof {
475 if (parser->m_styleSheet)
476 parser->m_styleSheet->parserSetEncodingFromCharsetRule($3);
477 parser->startEndUnknownRule();
479 | CHARSET_SYM at_rule_recovery
484 | rule_list rule maybe_sgml {
485 if ($2 && parser->m_styleSheet)
486 parser->m_styleSheet->parserAppendRule($2);
509 before_rule valid_rule {
511 parser->m_hadSyntacticallyValidCSSRule = true;
512 parser->endRule(!!$$);
514 | before_rule invalid_rule {
516 parser->endRule(false);
522 | block_rule_list block_rule_recovery
526 /* empty */ { $$ = 0; }
527 | block_rule_list block_rule maybe_sgml {
528 $$ = parser->appendRule($1, $2);
533 before_rule invalid_rule_header {
534 parser->endRule(false);
550 before_rule block_valid_rule {
552 parser->endRule(!!$$);
554 | before_rule invalid_rule {
556 parser->endRule(false);
562 parser->startRuleHeader(CSSRuleSourceData::IMPORT_RULE);
567 before_import_rule IMPORT_SYM maybe_space {
568 parser->endRuleHeader();
569 parser->startRuleBody();
574 import_rule_start string_or_uri maybe_space location_label maybe_media_list semi_or_eof {
575 $$ = parser->createImportRule($2, $5);
577 | import_rule_start string_or_uri maybe_space location_label maybe_media_list invalid_block {
583 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space semi_or_eof {
584 parser->addNamespace($3, $4);
590 /* empty */ { $$.clear(); }
603 | ':' maybe_space expr {
609 '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
610 parser->tokenToLowerCase($3);
611 $$ = parser->createFloatingMediaQueryExp($3, $5);
615 | '(' error error_recovery closing_parenthesis {
620 media_query_exp_list:
622 $$ = parser->createFloatingMediaQueryExpList();
623 $$->append(parser->sinkFloatingMediaQueryExp($1));
625 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
627 $$->append(parser->sinkFloatingMediaQueryExp($5));
631 maybe_and_media_query_exp_list:
633 $$ = parser->createFloatingMediaQueryExpList();
635 | maybe_space MEDIA_AND maybe_space media_query_exp_list maybe_space {
640 maybe_media_restrictor:
642 $$ = MediaQuery::None;
644 | MEDIA_ONLY maybe_space {
645 $$ = MediaQuery::Only;
647 | MEDIA_NOT maybe_space {
648 $$ = MediaQuery::Not;
653 media_query_exp_list maybe_space {
654 $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
656 | maybe_media_restrictor medium maybe_and_media_query_exp_list {
657 parser->tokenToLowerCase($2);
658 $$ = parser->createFloatingMediaQuery($1, $2, parser->sinkFloatingMediaQueryExpList($3));
664 | valid_media_query error error_location rule_error_recovery {
665 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
666 $$ = parser->createFloatingNotAllQuery();
668 | error error_location rule_error_recovery {
669 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
670 $$ = parser->createFloatingNotAllQuery();
676 $$ = parser->createMediaQuerySet();
683 $$ = parser->createMediaQuerySet();
684 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
686 | mq_list media_query {
688 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
692 $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));
697 media_query ',' maybe_space location_label {
698 $$ = parser->createMediaQuerySet();
699 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
701 | mq_list media_query ',' maybe_space location_label {
703 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
709 parser->startRuleBody();
715 parser->startRuleHeader(CSSRuleSourceData::MEDIA_RULE);
719 at_rule_header_end_maybe_space:
721 parser->endRuleHeader();
726 before_media_rule MEDIA_SYM maybe_space;
729 media_rule_start maybe_media_list at_rule_header_end '{' at_rule_body_start maybe_space block_rule_body closing_brace {
730 $$ = parser->createMediaRule($2, $7);
739 before_supports_rule SUPPORTS_SYM maybe_space supports_condition at_supports_rule_header_end '{' at_rule_body_start maybe_space block_rule_body closing_brace {
740 $$ = parser->createSupportsRule($4, $9);
744 before_supports_rule:
746 parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);
747 parser->markSupportsRuleHeaderStart();
751 at_supports_rule_header_end:
753 parser->endRuleHeader();
754 parser->markSupportsRuleHeaderEnd();
759 supports_condition_in_parens
761 | supports_conjunction
762 | supports_disjunction
766 SUPPORTS_NOT maybe_space supports_condition_in_parens {
771 supports_conjunction:
772 supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
775 | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
780 supports_disjunction:
781 supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
784 | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
789 supports_condition_in_parens:
790 '(' maybe_space supports_condition closing_parenthesis maybe_space {
793 | supports_declaration_condition
794 | '(' error error_location error_recovery closing_parenthesis maybe_space {
795 parser->reportError($3, InvalidSupportsConditionCSSError);
800 supports_declaration_condition:
801 '(' maybe_space IDENT maybe_space ':' maybe_space expr prio closing_parenthesis maybe_space {
803 CSSPropertyID id = cssPropertyID($3);
804 if (id != CSSPropertyInvalid) {
805 parser->m_valueList = parser->sinkFloatingValueList($7);
806 int oldParsedProperties = parser->m_parsedProperties.size();
807 $$ = parser->parseValue(id, $8);
808 // We just need to know if the declaration is supported as it is written. Rollback any additions.
810 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
812 parser->m_valueList = nullptr;
813 parser->endProperty($8, false);
815 | '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
817 parser->endProperty(false, false, GeneralCSSError);
821 before_keyframes_rule:
823 parser->startRuleHeader(CSSRuleSourceData::KEYFRAMES_RULE);
827 keyframes_rule_start:
828 before_keyframes_rule KEYFRAMES_SYM maybe_space {
831 | before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space {
837 keyframes_rule_start keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space location_label keyframes_rule closing_brace {
838 $$ = parser->createKeyframesRule($2, parser->sinkFloatingKeyframeVector($8), $1 /* isPrefixed */);
849 | keyframe_rule_list keyframes_error_recovery {
850 parser->clearProperties();
855 $$ = parser->createFloatingKeyframeVector();
856 parser->resumeErrorLogging();
858 | keyframe_rule_list keyframe_rule maybe_space location_label {
862 | keyframe_rule_list keyframes_error_recovery invalid_block maybe_space location_label {
863 parser->clearProperties();
864 parser->resumeErrorLogging();
869 key_list '{' maybe_space declaration_list closing_brace {
870 $$ = parser->createKeyframe($1);
876 $$ = parser->createFloatingValueList();
877 $$->addValue(parser->sinkFloatingValue($1));
879 | key_list ',' maybe_space key maybe_space {
881 $$->addValue(parser->sinkFloatingValue($4));
886 maybe_unary_operator PERCENTAGE {
887 $$.setFromNumber($1 * $2);
890 if ($1.equalIgnoringCase("from"))
892 else if ($1.equalIgnoringCase("to"))
893 $$.setFromNumber(100);
900 keyframes_error_recovery:
901 error rule_error_recovery {
902 parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
908 parser->startRuleHeader(CSSRuleSourceData::PAGE_RULE);
913 before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end
914 '{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
916 $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
918 // Clear properties in the invalid @page rule.
919 parser->clearProperties();
920 // Also clear margin at-rules here once we fully implement margin at-rules parsing.
928 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
931 | IDENT pseudo_page maybe_space {
933 $$->prependTagSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
936 | pseudo_page maybe_space {
941 $$ = parser->createFloatingSelector();
946 declarations_and_margins:
948 | declarations_and_margins margin_box maybe_space declaration_list
953 parser->startDeclarationsForMarginBox();
954 } maybe_space '{' maybe_space declaration_list closing_brace {
955 $$ = parser->createMarginAtRule($1);
961 $$ = CSSSelector::TopLeftCornerMarginBox;
964 $$ = CSSSelector::TopLeftMarginBox;
967 $$ = CSSSelector::TopCenterMarginBox;
970 $$ = CSSSelector::TopRightMarginBox;
972 | TOPRIGHTCORNER_SYM {
973 $$ = CSSSelector::TopRightCornerMarginBox;
975 | BOTTOMLEFTCORNER_SYM {
976 $$ = CSSSelector::BottomLeftCornerMarginBox;
979 $$ = CSSSelector::BottomLeftMarginBox;
982 $$ = CSSSelector::BottomCenterMarginBox;
985 $$ = CSSSelector::BottomRightMarginBox;
987 | BOTTOMRIGHTCORNER_SYM {
988 $$ = CSSSelector::BottomRightCornerMarginBox;
991 $$ = CSSSelector::LeftTopMarginBox;
994 $$ = CSSSelector::LeftMiddleMarginBox;
997 $$ = CSSSelector::LeftBottomMarginBox;
1000 $$ = CSSSelector::RightTopMarginBox;
1003 $$ = CSSSelector::RightMiddleMarginBox;
1006 $$ = CSSSelector::RightBottomMarginBox;
1010 before_font_face_rule:
1012 parser->startRuleHeader(CSSRuleSourceData::FONT_FACE_RULE);
1017 before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
1018 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1019 $$ = parser->createFontFaceRule();
1023 before_viewport_rule:
1025 parser->markViewportRuleBodyStart();
1026 parser->startRuleHeader(CSSRuleSourceData::VIEWPORT_RULE);
1031 before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
1032 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1033 $$ = parser->createViewportRule();
1034 parser->markViewportRuleBodyEnd();
1039 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
1040 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
1041 | '>' maybe_space { $$ = CSSSelector::Child; }
1042 | '/' IDENT '/' maybe_space {
1043 if ($2.equalIgnoringCase("deep"))
1044 $$ = CSSSelector::ShadowDeep;
1050 maybe_unary_operator:
1052 | /* empty */ { $$ = 1; }
1060 maybe_space_before_declaration:
1062 parser->startProperty();
1066 before_selector_list:
1068 parser->startRuleHeader(CSSRuleSourceData::STYLE_RULE);
1069 parser->startSelector();
1075 parser->endRuleHeader();
1081 parser->endSelector();
1086 before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1087 $$ = parser->createStyleRule($2);
1091 before_selector_group_item:
1093 parser->startSelector();
1097 selector %prec UNIMPORTANT_TOK {
1098 $$ = parser->reusableSelectorVector();
1100 $$->append(parser->sinkFloatingSelector($1));
1102 | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
1104 $$->append(parser->sinkFloatingSelector($6));
1110 | selector WHITESPACE
1111 | selector WHITESPACE simple_selector
1114 CSSParserSelector* end = $$;
1115 while (end->tagHistory())
1116 end = end->tagHistory();
1117 end->setRelation(CSSSelector::Descendant);
1118 if ($1->isContentPseudoElement())
1119 end->setRelationIsAffectedByPseudoContent();
1120 end->setTagHistory(parser->sinkFloatingSelector($1));
1122 | selector combinator simple_selector {
1124 CSSParserSelector* end = $$;
1125 while (end->tagHistory())
1126 end = end->tagHistory();
1127 end->setRelation($2);
1128 if ($1->isContentPseudoElement())
1129 end->setRelationIsAffectedByPseudoContent();
1130 end->setTagHistory(parser->sinkFloatingSelector($1));
1135 /* empty */ '|' { $$.clear(); }
1136 | '*' '|' { static const LChar star = '*'; $$.init(&star, 1); }
1142 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
1144 | element_name specifier_list {
1145 $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $2);
1150 $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($1);
1154 | namespace_selector element_name {
1155 $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
1159 | namespace_selector element_name specifier_list {
1160 $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);
1164 | namespace_selector specifier_list {
1165 $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);
1171 simple_selector_list:
1172 simple_selector %prec UNIMPORTANT_TOK {
1173 $$ = parser->createFloatingSelectorVector();
1174 $$->append(parser->sinkFloatingSelector($1));
1176 | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
1178 $$->append(parser->sinkFloatingSelector($5));
1184 if (parser->m_context.isHTMLDocument())
1185 parser->tokenToLowerCase($1);
1189 static const LChar star = '*';
1196 | specifier_list specifier {
1197 $$ = parser->rewriteSpecifiers($1, $2);
1203 $$ = parser->createFloatingSelector();
1204 $$->setMatch(CSSSelector::Id);
1205 if (isQuirksModeBehavior(parser->m_context.mode()))
1206 parser->tokenToLowerCase($1);
1210 if ($1[0] >= '0' && $1[0] <= '9') {
1213 $$ = parser->createFloatingSelector();
1214 $$->setMatch(CSSSelector::Id);
1215 if (isQuirksModeBehavior(parser->m_context.mode()))
1216 parser->tokenToLowerCase($1);
1227 $$ = parser->createFloatingSelector();
1228 $$->setMatch(CSSSelector::Class);
1229 if (isQuirksModeBehavior(parser->m_context.mode()))
1230 parser->tokenToLowerCase($2);
1237 if (parser->m_context.isHTMLDocument())
1238 parser->tokenToLowerCase($1);
1244 '[' maybe_space attr_name closing_square_bracket {
1245 $$ = parser->createFloatingSelector();
1246 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1247 $$->setMatch(CSSSelector::Set);
1249 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space closing_square_bracket {
1250 $$ = parser->createFloatingSelector();
1251 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1252 $$->setMatch((CSSSelector::Match)$4);
1255 | '[' maybe_space namespace_selector attr_name closing_square_bracket {
1256 $$ = parser->createFloatingSelector();
1257 $$->setAttribute(parser->determineNameInNamespace($3, $4));
1258 $$->setMatch(CSSSelector::Set);
1260 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space closing_square_bracket {
1261 $$ = parser->createFloatingSelector();
1262 $$->setAttribute(parser->determineNameInNamespace($3, $4));
1263 $$->setMatch((CSSSelector::Match)$5);
1266 | '[' selector_recovery closing_square_bracket {
1273 $$ = CSSSelector::Exact;
1276 $$ = CSSSelector::List;
1279 $$ = CSSSelector::Hyphen;
1282 $$ = CSSSelector::Begin;
1285 $$ = CSSSelector::End;
1288 $$ = CSSSelector::Contain;
1299 if ($2.isFunction())
1301 $$ = parser->createFloatingSelector();
1302 $$->setMatch(CSSSelector::PagePseudoClass);
1303 parser->tokenToLowerCase($2);
1305 CSSSelector::PseudoType type = $$->pseudoType();
1306 if (type == CSSSelector::PseudoUnknown)
1311 ':' error_location IDENT {
1312 if ($3.isFunction())
1314 $$ = parser->createFloatingSelector();
1315 $$->setMatch(CSSSelector::PseudoClass);
1316 parser->tokenToLowerCase($3);
1318 CSSSelector::PseudoType type = $$->pseudoType();
1319 if (type == CSSSelector::PseudoUnknown) {
1320 parser->reportError($2, InvalidSelectorPseudoCSSError);
1324 | ':' ':' error_location IDENT {
1325 if ($4.isFunction())
1327 $$ = parser->createFloatingSelector();
1328 $$->setMatch(CSSSelector::PseudoElement);
1329 parser->tokenToLowerCase($4);
1331 // FIXME: This call is needed to force selector to compute the pseudoType early enough.
1332 CSSSelector::PseudoType type = $$->pseudoType();
1333 if (type == CSSSelector::PseudoUnknown) {
1334 parser->reportError($3, InvalidSelectorPseudoCSSError);
1338 // used by ::cue(:past/:future)
1339 | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1340 $$ = parser->createFloatingSelector();
1341 $$->setMatch(CSSSelector::PseudoElement);
1342 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
1344 CSSSelector::PseudoType type = $$->pseudoType();
1345 if (type != CSSSelector::PseudoCue)
1348 | ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
1351 // use by :-webkit-any.
1352 // FIXME: should we support generic selectors here or just simple_selectors?
1353 // Use simple_selector_list for now to match -moz-any.
1354 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
1355 // related discussion with respect to :not.
1356 | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1357 $$ = parser->createFloatingSelector();
1358 $$->setMatch(CSSSelector::PseudoClass);
1359 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1360 parser->tokenToLowerCase($2);
1362 CSSSelector::PseudoType type = $$->pseudoType();
1363 if (type != CSSSelector::PseudoAny)
1366 | ':' ANYFUNCTION selector_recovery closing_parenthesis {
1369 // used by :nth-*(ax+b)
1370 | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
1371 $$ = parser->createFloatingSelector();
1372 $$->setMatch(CSSSelector::PseudoClass);
1373 $$->setArgument($4);
1375 CSSSelector::PseudoType type = $$->pseudoType();
1376 if (type == CSSSelector::PseudoUnknown)
1380 | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
1381 $$ = parser->createFloatingSelector();
1382 $$->setMatch(CSSSelector::PseudoClass);
1383 $$->setArgument(AtomicString::number($4 * $5));
1385 CSSSelector::PseudoType type = $$->pseudoType();
1386 if (type == CSSSelector::PseudoUnknown)
1389 // used by :nth-*(odd/even) and :lang
1390 | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
1391 $$ = parser->createFloatingSelector();
1392 $$->setMatch(CSSSelector::PseudoClass);
1393 $$->setArgument($4);
1394 parser->tokenToLowerCase($2);
1396 CSSSelector::PseudoType type = $$->pseudoType();
1397 if (type == CSSSelector::PseudoUnknown)
1399 else if (type == CSSSelector::PseudoNthChild ||
1400 type == CSSSelector::PseudoNthOfType ||
1401 type == CSSSelector::PseudoNthLastChild ||
1402 type == CSSSelector::PseudoNthLastOfType) {
1403 if (!isValidNthToken($4))
1407 | ':' FUNCTION selector_recovery closing_parenthesis {
1411 | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
1412 if (!$4->isSimple())
1415 $$ = parser->createFloatingSelector();
1416 $$->setMatch(CSSSelector::PseudoClass);
1418 Vector<OwnPtr<CSSParserSelector> > selectorVector;
1419 selectorVector.append(parser->sinkFloatingSelector($4));
1420 $$->adoptSelectorVector(selectorVector);
1422 parser->tokenToLowerCase($2);
1426 | ':' NOTFUNCTION selector_recovery closing_parenthesis {
1429 | ':' HOSTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1430 $$ = parser->createFloatingSelector();
1431 $$->setMatch(CSSSelector::PseudoClass);
1432 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1433 parser->tokenToLowerCase($2);
1435 CSSSelector::PseudoType type = $$->pseudoType();
1436 if (type != CSSSelector::PseudoHost)
1439 | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
1442 // used by :host-context()
1443 | ':' HOSTCONTEXTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1444 $$ = parser->createFloatingSelector();
1445 $$->setMatch(CSSSelector::PseudoClass);
1446 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1447 parser->tokenToLowerCase($2);
1449 CSSSelector::PseudoType type = $$->pseudoType();
1450 if (type != CSSSelector::PseudoHostContext)
1453 | ':' HOSTCONTEXTFUNCTION selector_recovery closing_parenthesis {
1459 error error_location error_recovery;
1462 /* empty */ { $$ = false; }
1464 | decl_list declaration {
1471 declaration ';' maybe_space {
1472 parser->startProperty();
1475 | decl_list declaration ';' maybe_space {
1476 parser->startProperty();
1482 property ':' maybe_space error_location expr prio {
1484 bool isPropertyParsed = false;
1485 if ($1 != CSSPropertyInvalid) {
1486 parser->m_valueList = parser->sinkFloatingValueList($5);
1487 int oldParsedProperties = parser->m_parsedProperties.size();
1488 $$ = parser->parseValue($1, $6);
1490 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
1491 parser->reportError($4, InvalidPropertyValueCSSError);
1493 isPropertyParsed = true;
1494 parser->m_valueList = nullptr;
1496 parser->endProperty($6, isPropertyParsed);
1499 property ':' maybe_space error_location expr prio error error_recovery {
1500 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1501 parser->reportError($4, InvalidPropertyValueCSSError);
1502 parser->endProperty(false, false);
1506 property ':' maybe_space error_location error error_recovery {
1507 parser->reportError($4, InvalidPropertyValueCSSError);
1508 parser->endProperty(false, false);
1512 property error error_location error_recovery {
1513 parser->reportError($3, PropertyDeclarationCSSError);
1514 parser->endProperty(false, false, GeneralCSSError);
1518 error error_location error_recovery {
1519 parser->reportError($2, PropertyDeclarationCSSError);
1525 error_location IDENT maybe_space {
1526 $$ = cssPropertyID($2);
1527 parser->setCurrentProperty($$);
1528 if ($$ == CSSPropertyInvalid)
1529 parser->reportError($1, InvalidPropertyCSSError);
1534 IMPORTANT_SYM maybe_space { $$ = true; }
1535 | /* empty */ { $$ = false; }
1540 $$ = parser->createFloatingValueList();
1541 $$->addValue(makeIdentValue($1));
1543 | ident_list IDENT maybe_space {
1545 $$->addValue(makeIdentValue($2));
1550 '(' maybe_space closing_parenthesis {
1551 $$.setFromValueList(parser->sinkFloatingValueList(parser->createFloatingValueList()));
1553 | '(' maybe_space ident_list closing_parenthesis {
1554 $$.setFromValueList(parser->sinkFloatingValueList($3));
1556 | '(' maybe_space expr_recovery closing_parenthesis {
1563 $$ = parser->createFloatingValueList();
1564 $$->addValue(parser->sinkFloatingValue($1));
1566 | expr operator term {
1568 $$->addValue(makeOperatorValue($2));
1569 $$->addValue(parser->sinkFloatingValue($3));
1573 $$->addValue(parser->sinkFloatingValue($2));
1578 error error_location error_recovery {
1579 parser->reportError($2, PropertyDeclarationCSSError);
1593 unary_term maybe_space
1594 | unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
1595 | STRING maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1596 | IDENT maybe_space { $$ = makeIdentValue($1); }
1597 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1598 | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1599 | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1600 | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1601 | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1602 | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1603 | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1604 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1605 | function maybe_space
1606 | calc_function maybe_space
1607 | '%' maybe_space { /* Handle width: %; */
1608 $$.id = CSSValueInvalid; $$.unit = 0;
1610 | track_names_list maybe_space
1614 INTEGER { $$.setFromNumber($1); $$.isInt = true; }
1615 | FLOATTOKEN { $$.setFromNumber($1); }
1616 | PERCENTAGE { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PERCENTAGE); }
1617 | PXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PX); }
1618 | CMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CM); }
1619 | MMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MM); }
1620 | INS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_IN); }
1621 | PTS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PT); }
1622 | PCS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PC); }
1623 | DEGS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DEG); }
1624 | RADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_RAD); }
1625 | GRADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_GRAD); }
1626 | TURNS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_TURN); }
1627 | MSECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MS); }
1628 | SECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_S); }
1629 | HERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_HZ); }
1630 | KHERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_KHZ); }
1631 | EMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EMS); }
1632 | QEMS { $$.setFromNumber($1, CSSParserValue::Q_EMS); }
1633 | EXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EXS); }
1635 $$.setFromNumber($1, CSSPrimitiveValue::CSS_REMS);
1636 if (parser->m_styleSheet)
1637 parser->m_styleSheet->parserSetUsesRemUnits(true);
1639 | CHS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CHS); }
1640 | VW { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VW); }
1641 | VH { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VH); }
1642 | VMIN { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMIN); }
1643 | VMAX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMAX); }
1644 | DPPX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPPX); }
1645 | DPI { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPI); }
1646 | DPCM { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPCM); }
1647 | FR { $$.setFromNumber($1, CSSPrimitiveValue::CSS_FR); }
1651 FUNCTION maybe_space expr closing_parenthesis {
1652 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1654 FUNCTION maybe_space closing_parenthesis {
1655 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList(parser->createFloatingValueList())));
1657 FUNCTION maybe_space expr_recovery closing_parenthesis {
1664 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1674 | calc_maybe_space '*' maybe_space {
1677 | calc_maybe_space '/' maybe_space {
1687 calc_func_paren_expr:
1688 '(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1690 $$->insertValueAt(0, makeOperatorValue('('));
1691 $$->addValue(makeOperatorValue(')'));
1693 | '(' maybe_space expr_recovery closing_parenthesis {
1700 $$ = parser->createFloatingValueList();
1701 $$->addValue(parser->sinkFloatingValue($1));
1703 | calc_func_expr calc_func_operator calc_func_term {
1705 $$->addValue(makeOperatorValue($2));
1706 $$->addValue(parser->sinkFloatingValue($3));
1708 | calc_func_expr calc_func_operator calc_func_paren_expr {
1710 $$->addValue(makeOperatorValue($2));
1711 $$->stealValues(*($3));
1713 | calc_func_paren_expr
1717 CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1718 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1720 | CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
1732 at_rule_header_recovery at_invalid_rule_header_end at_rule_end
1735 at_rule_header_recovery:
1736 error error_location rule_error_recovery {
1737 parser->reportError($2, InvalidRuleCSSError);
1742 at_invalid_rule_header_end semi_or_eof
1743 | at_invalid_rule_header_end invalid_block
1746 regular_invalid_at_rule_header:
1747 keyframes_rule_start at_rule_header_recovery
1748 | before_page_rule PAGE_SYM at_rule_header_recovery
1749 | before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
1750 | before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
1751 parser->reportError($4, InvalidSupportsConditionCSSError);
1752 parser->popSupportsRuleData();
1754 | before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
1755 parser->markViewportRuleBodyEnd();
1757 | import_rule_start at_rule_header_recovery
1758 | NAMESPACE_SYM at_rule_header_recovery
1759 | error_location invalid_at at_rule_header_recovery {
1760 parser->resumeErrorLogging();
1761 parser->reportError($1, InvalidRuleCSSError);
1766 error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
1767 parser->reportError($2, InvalidRuleCSSError);
1769 | regular_invalid_at_rule_header at_invalid_rule_header_end ';'
1770 | regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
1771 | media_rule_start maybe_media_list ';'
1774 invalid_rule_header:
1775 error error_location rule_error_recovery at_invalid_rule_header_end {
1776 parser->reportError($2, InvalidRuleCSSError);
1778 | regular_invalid_at_rule_header at_invalid_rule_header_end
1779 | media_rule_start maybe_media_list
1782 at_invalid_rule_header_end:
1784 parser->endInvalidRuleHeader();
1789 '{' error_recovery closing_brace {
1790 parser->invalidBlockHit();
1794 invalid_square_brackets_block:
1795 '[' error_recovery closing_square_bracket
1798 invalid_parentheses_block:
1799 opening_parenthesis error_recovery closing_parenthesis;
1801 opening_parenthesis:
1802 '(' | FUNCTION | CALCFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
1806 $$ = parser->currentLocation();
1811 parser->setLocationLabel(parser->currentLocation());
1817 | error_recovery error
1818 | error_recovery invalid_block
1819 | error_recovery invalid_square_brackets_block
1820 | error_recovery invalid_parentheses_block
1823 rule_error_recovery:
1825 | rule_error_recovery error
1826 | rule_error_recovery invalid_square_brackets_block
1827 | rule_error_recovery invalid_parentheses_block