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 Vector<RefPtr<StyleRuleBase> >* ruleList;
77 CSSParserSelector* selector;
78 Vector<OwnPtr<CSSParserSelector> >* selectorList;
79 CSSSelector::MarginBoxType marginBox;
80 CSSSelector::Relation relation;
81 MediaQuerySet* mediaList;
82 MediaQuery* mediaQuery;
83 MediaQuery::Restrictor mediaQueryRestrictor;
84 MediaQueryExp* mediaQueryExp;
86 CSSParserValueList* valueList;
87 Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList;
88 StyleKeyframe* keyframe;
89 Vector<RefPtr<StyleKeyframe> >* keyframeRuleList;
92 CSSParserLocation location;
97 static inline int cssyyerror(void*, const char*)
103 static inline bool isCSSTokenAString(int yytype)
117 case ANCESTORFUNCTION:
130 inline static CSSParserValue makeOperatorValue(int value)
133 v.id = CSSValueInvalid;
134 v.unit = CSSParserValue::Operator;
139 inline static CSSParserValue makeIdentValue(CSSParserString string)
142 v.id = cssValueKeywordID(string);
143 v.unit = CSSPrimitiveValue::CSS_IDENT;
152 %nonassoc LOWEST_PREC
154 %left UNIMPORTANT_TOK
156 %token WHITESPACE SGML_CD
165 %token <string> STRING
166 %right <string> IDENT
169 %nonassoc <string> HEX
170 %nonassoc <string> IDSEL
174 %nonassoc <string> '*'
185 %token VIEWPORT_RULE_SYM
186 %token INTERNAL_DECLS_SYM
187 %token INTERNAL_MEDIALIST_SYM
188 %token INTERNAL_RULE_SYM
189 %token INTERNAL_SELECTOR_SYM
190 %token INTERNAL_VALUE_SYM
191 %token INTERNAL_KEYFRAME_RULE_SYM
192 %token INTERNAL_KEYFRAME_KEY_LIST_SYM
193 %token INTERNAL_SUPPORTS_CONDITION_SYM
195 %token WEBKIT_KEYFRAMES_SYM
196 %token <marginBox> TOPLEFTCORNER_SYM
197 %token <marginBox> TOPLEFT_SYM
198 %token <marginBox> TOPCENTER_SYM
199 %token <marginBox> TOPRIGHT_SYM
200 %token <marginBox> TOPRIGHTCORNER_SYM
201 %token <marginBox> BOTTOMLEFTCORNER_SYM
202 %token <marginBox> BOTTOMLEFT_SYM
203 %token <marginBox> BOTTOMCENTER_SYM
204 %token <marginBox> BOTTOMRIGHT_SYM
205 %token <marginBox> BOTTOMRIGHTCORNER_SYM
206 %token <marginBox> LEFTTOP_SYM
207 %token <marginBox> LEFTMIDDLE_SYM
208 %token <marginBox> LEFTBOTTOM_SYM
209 %token <marginBox> RIGHTTOP_SYM
210 %token <marginBox> RIGHTMIDDLE_SYM
211 %token <marginBox> RIGHTBOTTOM_SYM
238 %token <number> GRADS
239 %token <number> TURNS
240 %token <number> MSECS
242 %token <number> HERTZ
243 %token <number> KHERTZ
244 %token <string> DIMEN
245 %token <string> INVALIDDIMEN
246 %token <number> PERCENTAGE
247 %token <number> FLOATTOKEN
248 %token <number> INTEGER
259 %token <string> FUNCTION
260 %token <string> ANYFUNCTION
261 %token <string> CUEFUNCTION
262 %token <string> NOTFUNCTION
263 %token <string> DISTRIBUTEDFUNCTION
264 %token <string> CALCFUNCTION
265 %token <string> MINFUNCTION
266 %token <string> MAXFUNCTION
267 %token <string> HOSTFUNCTION
268 %token <string> ANCESTORFUNCTION
270 %token <string> UNICODERANGE
272 %type <relation> combinator
277 %type <rule> namespace
279 %type <rule> margin_box
280 %type <rule> font_face
281 %type <rule> keyframes
283 %type <rule> valid_rule
284 %type <ruleList> block_rule_body
285 %type <ruleList> block_rule_list
286 %type <rule> block_rule
287 %type <rule> block_valid_rule
288 %type <rule> supports
289 %type <rule> viewport
290 %type <boolean> keyframes_rule_start
292 %type <string> maybe_ns_prefix
294 %type <string> namespace_selector
296 %type <string> string_or_uri
297 %type <string> ident_or_string
298 %type <string> medium
299 %type <marginBox> margin_sym
301 %type <mediaList> media_list
302 %type <mediaList> maybe_media_list
303 %type <mediaList> mq_list
304 %type <mediaQuery> media_query
305 %type <mediaQuery> valid_media_query
306 %type <mediaQueryRestrictor> maybe_media_restrictor
307 %type <valueList> maybe_media_value
308 %type <mediaQueryExp> media_query_exp
309 %type <mediaQueryExpList> media_query_exp_list
310 %type <mediaQueryExpList> maybe_and_media_query_exp_list
312 %type <boolean> supports_condition
313 %type <boolean> supports_condition_in_parens
314 %type <boolean> supports_negation
315 %type <boolean> supports_conjunction
316 %type <boolean> supports_disjunction
317 %type <boolean> supports_declaration_condition
319 %type <string> keyframe_name
320 %type <keyframe> keyframe_rule
321 %type <keyframeRuleList> keyframes_rule
322 %type <keyframeRuleList> keyframe_rule_list
323 %type <valueList> key_list
328 %type <selector> specifier
329 %type <selector> specifier_list
330 %type <selector> simple_selector
331 %type <selector> selector
332 %type <selector> relative_selector
333 %type <selectorList> selector_list
334 %type <selectorList> simple_selector_list
335 %type <selector> class
336 %type <selector> attrib
337 %type <selector> pseudo
338 %type <selector> pseudo_page
339 %type <selector> page_selector
341 %type <boolean> declaration_list
342 %type <boolean> decl_list
343 %type <boolean> declaration
344 %type <boolean> declarations_and_margins
348 %type <integer> match
349 %type <integer> unary_operator
350 %type <integer> maybe_unary_operator
351 %type <character> operator
353 %type <valueList> expr
355 %type <value> unary_term
356 %type <value> function
357 %type <value> calc_func_term
358 %type <character> calc_func_operator
359 %type <valueList> calc_func_expr
360 %type <valueList> calc_func_expr_list
361 %type <valueList> calc_func_paren_expr
362 %type <value> calc_function
363 %type <string> min_or_max
364 %type <value> min_or_max_function
366 %type <string> element_name
367 %type <string> attr_name
369 %type <location> error_location
371 %type <valueList> ident_list
372 %type <value> track_names_list
377 maybe_charset maybe_sgml rule_list
383 | internal_keyframe_rule
384 | internal_keyframe_key_list
385 | internal_supports_condition
389 INTERNAL_RULE_SYM maybe_space valid_rule maybe_space TOKEN_EOF {
394 internal_keyframe_rule:
395 INTERNAL_KEYFRAME_RULE_SYM maybe_space keyframe_rule maybe_space TOKEN_EOF {
396 parser->m_keyframe = $3;
400 internal_keyframe_key_list:
401 INTERNAL_KEYFRAME_KEY_LIST_SYM maybe_space key_list TOKEN_EOF {
402 parser->m_valueList = parser->sinkFloatingValueList($3);
407 INTERNAL_DECLS_SYM maybe_space_before_declaration declaration_list TOKEN_EOF {
413 INTERNAL_VALUE_SYM maybe_space expr TOKEN_EOF {
414 parser->m_valueList = parser->sinkFloatingValueList($3);
415 int oldParsedProperties = parser->m_parsedProperties.size();
416 if (!parser->parseValue(parser->m_id, parser->m_important))
417 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
418 parser->m_valueList = nullptr;
423 INTERNAL_MEDIALIST_SYM maybe_space location_label maybe_media_list TOKEN_EOF {
424 parser->m_mediaList = $4;
429 INTERNAL_SELECTOR_SYM maybe_space selector_list TOKEN_EOF {
430 if (parser->m_selectorListForParseSelector)
431 parser->m_selectorListForParseSelector->adoptSelectorVector(*$3);
435 internal_supports_condition:
436 INTERNAL_SUPPORTS_CONDITION_SYM maybe_space supports_condition TOKEN_EOF {
437 parser->m_supportsCondition = $3;
447 /* empty */ %prec UNIMPORTANT_TOK
454 | maybe_sgml WHITESPACE
459 | %prec LOWEST_PREC TOKEN_EOF
464 | %prec LOWEST_PREC TOKEN_EOF
467 closing_square_bracket:
469 | %prec LOWEST_PREC TOKEN_EOF
479 | CHARSET_SYM maybe_space STRING maybe_space semi_or_eof {
480 if (parser->m_styleSheet)
481 parser->m_styleSheet->parserSetEncodingFromCharsetRule($3);
482 parser->startEndUnknownRule();
484 | CHARSET_SYM at_rule_recovery
489 | rule_list rule maybe_sgml {
490 if ($2 && parser->m_styleSheet)
491 parser->m_styleSheet->parserAppendRule($2);
514 before_rule valid_rule {
516 parser->m_hadSyntacticallyValidCSSRule = true;
517 parser->endRule(!!$$);
519 | before_rule invalid_rule {
521 parser->endRule(false);
527 | block_rule_list block_rule_recovery
531 /* empty */ { $$ = 0; }
532 | block_rule_list block_rule maybe_sgml {
533 $$ = parser->appendRule($1, $2);
538 before_rule invalid_rule_header {
539 parser->endRule(false);
555 before_rule block_valid_rule {
557 parser->endRule(!!$$);
559 | before_rule invalid_rule {
561 parser->endRule(false);
567 parser->startRuleHeader(CSSRuleSourceData::IMPORT_RULE);
572 before_import_rule IMPORT_SYM maybe_space {
573 parser->endRuleHeader();
574 parser->startRuleBody();
579 import_rule_start string_or_uri maybe_space location_label maybe_media_list semi_or_eof {
580 $$ = parser->createImportRule($2, $5);
582 | import_rule_start string_or_uri maybe_space location_label maybe_media_list invalid_block {
588 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space semi_or_eof {
589 parser->addNamespace($3, $4);
595 /* empty */ { $$.clear(); }
608 | ':' maybe_space expr {
614 '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
615 parser->tokenToLowerCase($3);
616 $$ = parser->createFloatingMediaQueryExp($3, $5);
620 | '(' error error_recovery closing_parenthesis {
625 media_query_exp_list:
627 $$ = parser->createFloatingMediaQueryExpList();
628 $$->append(parser->sinkFloatingMediaQueryExp($1));
630 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
632 $$->append(parser->sinkFloatingMediaQueryExp($5));
636 maybe_and_media_query_exp_list:
638 $$ = parser->createFloatingMediaQueryExpList();
640 | maybe_space MEDIA_AND maybe_space media_query_exp_list maybe_space {
645 maybe_media_restrictor:
647 $$ = MediaQuery::None;
649 | MEDIA_ONLY maybe_space {
650 $$ = MediaQuery::Only;
652 | MEDIA_NOT maybe_space {
653 $$ = MediaQuery::Not;
658 media_query_exp_list maybe_space {
659 $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
661 | maybe_media_restrictor medium maybe_and_media_query_exp_list {
662 parser->tokenToLowerCase($2);
663 $$ = parser->createFloatingMediaQuery($1, $2, parser->sinkFloatingMediaQueryExpList($3));
669 | valid_media_query error error_location rule_error_recovery {
670 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
671 $$ = parser->createFloatingNotAllQuery();
673 | error error_location rule_error_recovery {
674 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
675 $$ = parser->createFloatingNotAllQuery();
681 $$ = parser->createMediaQuerySet();
688 $$ = parser->createMediaQuerySet();
689 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
691 | mq_list media_query {
693 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
697 $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));
702 media_query ',' maybe_space location_label {
703 $$ = parser->createMediaQuerySet();
704 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
706 | mq_list media_query ',' maybe_space location_label {
708 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
714 parser->startRuleBody();
720 parser->startRuleHeader(CSSRuleSourceData::MEDIA_RULE);
724 at_rule_header_end_maybe_space:
726 parser->endRuleHeader();
731 before_media_rule MEDIA_SYM maybe_space;
734 media_rule_start maybe_media_list at_rule_header_end '{' at_rule_body_start maybe_space block_rule_body closing_brace {
735 $$ = parser->createMediaRule($2, $7);
744 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 {
745 $$ = parser->createSupportsRule($4, $9);
749 before_supports_rule:
751 parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);
752 parser->markSupportsRuleHeaderStart();
756 at_supports_rule_header_end:
758 parser->endRuleHeader();
759 parser->markSupportsRuleHeaderEnd();
764 supports_condition_in_parens
766 | supports_conjunction
767 | supports_disjunction
771 SUPPORTS_NOT maybe_space supports_condition_in_parens {
776 supports_conjunction:
777 supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
780 | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
785 supports_disjunction:
786 supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
789 | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
794 supports_condition_in_parens:
795 '(' maybe_space supports_condition closing_parenthesis maybe_space {
798 | supports_declaration_condition
799 | '(' error error_location error_recovery closing_parenthesis maybe_space {
800 parser->reportError($3, InvalidSupportsConditionCSSError);
805 supports_declaration_condition:
806 '(' maybe_space IDENT maybe_space ':' maybe_space expr prio closing_parenthesis maybe_space {
808 CSSPropertyID id = cssPropertyID($3);
809 if (id != CSSPropertyInvalid) {
810 parser->m_valueList = parser->sinkFloatingValueList($7);
811 int oldParsedProperties = parser->m_parsedProperties.size();
812 $$ = parser->parseValue(id, $8);
813 // We just need to know if the declaration is supported as it is written. Rollback any additions.
815 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
817 parser->m_valueList = nullptr;
818 parser->endProperty($8, false);
820 | '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
822 parser->endProperty(false, false, GeneralCSSError);
826 before_keyframes_rule:
828 parser->startRuleHeader(CSSRuleSourceData::KEYFRAMES_RULE);
832 keyframes_rule_start:
833 before_keyframes_rule KEYFRAMES_SYM maybe_space {
836 | before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space {
842 keyframes_rule_start keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space location_label keyframes_rule closing_brace {
843 $$ = parser->createKeyframesRule($2, parser->sinkFloatingKeyframeVector($8), $1 /* isPrefixed */);
854 | keyframe_rule_list keyframes_error_recovery {
855 parser->clearProperties();
860 $$ = parser->createFloatingKeyframeVector();
861 parser->resumeErrorLogging();
863 | keyframe_rule_list keyframe_rule maybe_space location_label {
867 | keyframe_rule_list keyframes_error_recovery invalid_block maybe_space location_label {
868 parser->clearProperties();
869 parser->resumeErrorLogging();
874 key_list '{' maybe_space declaration_list closing_brace {
875 $$ = parser->createKeyframe($1);
881 $$ = parser->createFloatingValueList();
882 $$->addValue(parser->sinkFloatingValue($1));
884 | key_list ',' maybe_space key maybe_space {
886 $$->addValue(parser->sinkFloatingValue($4));
891 maybe_unary_operator PERCENTAGE {
892 $$.setFromNumber($1 * $2);
895 if ($1.equalIgnoringCase("from"))
897 else if ($1.equalIgnoringCase("to"))
898 $$.setFromNumber(100);
905 keyframes_error_recovery:
906 error rule_error_recovery {
907 parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
913 parser->startRuleHeader(CSSRuleSourceData::PAGE_RULE);
918 before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end
919 '{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
921 $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
923 // Clear properties in the invalid @page rule.
924 parser->clearProperties();
925 // Also clear margin at-rules here once we fully implement margin at-rules parsing.
933 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
936 | IDENT pseudo_page maybe_space {
938 $$->prependTagSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
941 | pseudo_page maybe_space {
946 $$ = parser->createFloatingSelector();
951 declarations_and_margins:
953 | declarations_and_margins margin_box maybe_space declaration_list
958 parser->startDeclarationsForMarginBox();
959 } maybe_space '{' maybe_space declaration_list closing_brace {
960 $$ = parser->createMarginAtRule($1);
966 $$ = CSSSelector::TopLeftCornerMarginBox;
969 $$ = CSSSelector::TopLeftMarginBox;
972 $$ = CSSSelector::TopCenterMarginBox;
975 $$ = CSSSelector::TopRightMarginBox;
977 | TOPRIGHTCORNER_SYM {
978 $$ = CSSSelector::TopRightCornerMarginBox;
980 | BOTTOMLEFTCORNER_SYM {
981 $$ = CSSSelector::BottomLeftCornerMarginBox;
984 $$ = CSSSelector::BottomLeftMarginBox;
987 $$ = CSSSelector::BottomCenterMarginBox;
990 $$ = CSSSelector::BottomRightMarginBox;
992 | BOTTOMRIGHTCORNER_SYM {
993 $$ = CSSSelector::BottomRightCornerMarginBox;
996 $$ = CSSSelector::LeftTopMarginBox;
999 $$ = CSSSelector::LeftMiddleMarginBox;
1002 $$ = CSSSelector::LeftBottomMarginBox;
1005 $$ = CSSSelector::RightTopMarginBox;
1008 $$ = CSSSelector::RightMiddleMarginBox;
1011 $$ = CSSSelector::RightBottomMarginBox;
1015 before_font_face_rule:
1017 parser->startRuleHeader(CSSRuleSourceData::FONT_FACE_RULE);
1022 before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
1023 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1024 $$ = parser->createFontFaceRule();
1028 before_viewport_rule:
1030 parser->markViewportRuleBodyStart();
1031 parser->startRuleHeader(CSSRuleSourceData::VIEWPORT_RULE);
1036 before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
1037 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1038 $$ = parser->createViewportRule();
1039 parser->markViewportRuleBodyEnd();
1044 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
1045 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
1046 | '>' maybe_space { $$ = CSSSelector::Child; }
1048 if (!RuntimeEnabledFeatures::shadowDOMEnabled())
1050 $$ = CSSSelector::ChildTree;
1052 | '^' '^' maybe_space {
1053 if (!RuntimeEnabledFeatures::shadowDOMEnabled())
1055 $$ = CSSSelector::DescendantTree;
1059 maybe_unary_operator:
1061 | /* empty */ { $$ = 1; }
1069 maybe_space_before_declaration:
1071 parser->startProperty();
1075 before_selector_list:
1077 parser->startRuleHeader(CSSRuleSourceData::STYLE_RULE);
1078 parser->startSelector();
1084 parser->endRuleHeader();
1090 parser->endSelector();
1095 before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1096 $$ = parser->createStyleRule($2);
1100 before_selector_group_item:
1102 parser->startSelector();
1106 selector %prec UNIMPORTANT_TOK {
1107 $$ = parser->reusableSelectorVector();
1109 $$->append(parser->sinkFloatingSelector($1));
1111 | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
1113 $$->append(parser->sinkFloatingSelector($6));
1118 combinator selector {
1120 CSSParserSelector* end = $$;
1121 while (end->tagHistory())
1122 end = end->tagHistory();
1123 end->setRelation($1);
1130 | selector WHITESPACE
1131 | selector WHITESPACE simple_selector
1134 CSSParserSelector* end = $$;
1135 while (end->tagHistory())
1136 end = end->tagHistory();
1137 end->setRelation(CSSSelector::Descendant);
1138 if ($1->isContentPseudoElement())
1139 end->setRelationIsAffectedByPseudoContent();
1140 end->setTagHistory(parser->sinkFloatingSelector($1));
1142 | selector combinator simple_selector {
1144 CSSParserSelector* end = $$;
1145 while (end->tagHistory())
1146 end = end->tagHistory();
1147 end->setRelation($2);
1148 if ($1->isContentPseudoElement())
1149 end->setRelationIsAffectedByPseudoContent();
1150 end->setTagHistory(parser->sinkFloatingSelector($1));
1155 /* empty */ '|' { $$.clear(); }
1156 | '*' '|' { static const LChar star = '*'; $$.init(&star, 1); }
1162 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
1164 | element_name specifier_list {
1165 $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $2);
1170 $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($1);
1174 | namespace_selector element_name {
1175 $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
1179 | namespace_selector element_name specifier_list {
1180 $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);
1184 | namespace_selector specifier_list {
1185 $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);
1191 simple_selector_list:
1192 simple_selector %prec UNIMPORTANT_TOK {
1193 $$ = parser->createFloatingSelectorVector();
1194 $$->append(parser->sinkFloatingSelector($1));
1196 | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
1198 $$->append(parser->sinkFloatingSelector($5));
1204 if (parser->m_context.isHTMLDocument())
1205 parser->tokenToLowerCase($1);
1209 static const LChar star = '*';
1216 | specifier_list specifier {
1217 $$ = parser->rewriteSpecifiers($1, $2);
1223 $$ = parser->createFloatingSelector();
1224 $$->setMatch(CSSSelector::Id);
1225 if (isQuirksModeBehavior(parser->m_context.mode()))
1226 parser->tokenToLowerCase($1);
1230 if ($1[0] >= '0' && $1[0] <= '9') {
1233 $$ = parser->createFloatingSelector();
1234 $$->setMatch(CSSSelector::Id);
1235 if (isQuirksModeBehavior(parser->m_context.mode()))
1236 parser->tokenToLowerCase($1);
1247 $$ = parser->createFloatingSelector();
1248 $$->setMatch(CSSSelector::Class);
1249 if (isQuirksModeBehavior(parser->m_context.mode()))
1250 parser->tokenToLowerCase($2);
1257 if (parser->m_context.isHTMLDocument())
1258 parser->tokenToLowerCase($1);
1264 '[' maybe_space attr_name closing_square_bracket {
1265 $$ = parser->createFloatingSelector();
1266 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1267 $$->setMatch(CSSSelector::Set);
1269 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space closing_square_bracket {
1270 $$ = parser->createFloatingSelector();
1271 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1272 $$->setMatch((CSSSelector::Match)$4);
1275 | '[' maybe_space namespace_selector attr_name closing_square_bracket {
1276 $$ = parser->createFloatingSelector();
1277 $$->setAttribute(parser->determineNameInNamespace($3, $4));
1278 $$->setMatch(CSSSelector::Set);
1280 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space closing_square_bracket {
1281 $$ = parser->createFloatingSelector();
1282 $$->setAttribute(parser->determineNameInNamespace($3, $4));
1283 $$->setMatch((CSSSelector::Match)$5);
1286 | '[' selector_recovery closing_square_bracket {
1293 $$ = CSSSelector::Exact;
1296 $$ = CSSSelector::List;
1299 $$ = CSSSelector::Hyphen;
1302 $$ = CSSSelector::Begin;
1305 $$ = CSSSelector::End;
1308 $$ = CSSSelector::Contain;
1319 if ($2.isFunction())
1321 $$ = parser->createFloatingSelector();
1322 $$->setMatch(CSSSelector::PagePseudoClass);
1323 parser->tokenToLowerCase($2);
1325 CSSSelector::PseudoType type = $$->pseudoType();
1326 if (type == CSSSelector::PseudoUnknown)
1331 ':' error_location IDENT {
1332 if ($3.isFunction())
1334 $$ = parser->createFloatingSelector();
1335 $$->setMatch(CSSSelector::PseudoClass);
1336 parser->tokenToLowerCase($3);
1338 CSSSelector::PseudoType type = $$->pseudoType();
1339 if (type == CSSSelector::PseudoUnknown) {
1340 parser->reportError($2, InvalidSelectorPseudoCSSError);
1344 | ':' ':' error_location IDENT {
1345 if ($4.isFunction())
1347 $$ = parser->createFloatingSelector();
1348 $$->setMatch(CSSSelector::PseudoElement);
1349 parser->tokenToLowerCase($4);
1351 // FIXME: This call is needed to force selector to compute the pseudoType early enough.
1352 CSSSelector::PseudoType type = $$->pseudoType();
1353 if (type == CSSSelector::PseudoUnknown) {
1354 parser->reportError($3, InvalidSelectorPseudoCSSError);
1358 // used by ::cue(:past/:future)
1359 | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1360 $$ = parser->createFloatingSelector();
1361 $$->setMatch(CSSSelector::PseudoElement);
1362 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
1364 CSSSelector::PseudoType type = $$->pseudoType();
1365 if (type != CSSSelector::PseudoCue)
1368 | ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
1371 | ':' ':' DISTRIBUTEDFUNCTION maybe_space relative_selector closing_parenthesis {
1372 $$ = parser->createFloatingSelector();
1373 $$->setMatch(CSSSelector::PseudoElement);
1374 $$->setFunctionArgumentSelector($5);
1375 parser->tokenToLowerCase($3);
1378 | ':' ':' DISTRIBUTEDFUNCTION selector_recovery closing_parenthesis {
1381 // use by :-webkit-any.
1382 // FIXME: should we support generic selectors here or just simple_selectors?
1383 // Use simple_selector_list for now to match -moz-any.
1384 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
1385 // related discussion with respect to :not.
1386 | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1387 $$ = parser->createFloatingSelector();
1388 $$->setMatch(CSSSelector::PseudoClass);
1389 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1390 parser->tokenToLowerCase($2);
1392 CSSSelector::PseudoType type = $$->pseudoType();
1393 if (type != CSSSelector::PseudoAny)
1396 | ':' ANYFUNCTION selector_recovery closing_parenthesis {
1399 // used by :nth-*(ax+b)
1400 | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
1401 $$ = parser->createFloatingSelector();
1402 $$->setMatch(CSSSelector::PseudoClass);
1403 $$->setArgument($4);
1405 CSSSelector::PseudoType type = $$->pseudoType();
1406 if (type == CSSSelector::PseudoUnknown)
1410 | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
1411 $$ = parser->createFloatingSelector();
1412 $$->setMatch(CSSSelector::PseudoClass);
1413 $$->setArgument(AtomicString::number($4 * $5));
1415 CSSSelector::PseudoType type = $$->pseudoType();
1416 if (type == CSSSelector::PseudoUnknown)
1419 // used by :nth-*(odd/even) and :lang
1420 | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
1421 $$ = parser->createFloatingSelector();
1422 $$->setMatch(CSSSelector::PseudoClass);
1423 $$->setArgument($4);
1424 parser->tokenToLowerCase($2);
1426 CSSSelector::PseudoType type = $$->pseudoType();
1427 if (type == CSSSelector::PseudoUnknown)
1429 else if (type == CSSSelector::PseudoNthChild ||
1430 type == CSSSelector::PseudoNthOfType ||
1431 type == CSSSelector::PseudoNthLastChild ||
1432 type == CSSSelector::PseudoNthLastOfType) {
1433 if (!isValidNthToken($4))
1437 | ':' FUNCTION selector_recovery closing_parenthesis {
1441 | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
1442 if (!$4->isSimple())
1445 $$ = parser->createFloatingSelector();
1446 $$->setMatch(CSSSelector::PseudoClass);
1448 Vector<OwnPtr<CSSParserSelector> > selectorVector;
1449 selectorVector.append(parser->sinkFloatingSelector($4));
1450 $$->adoptSelectorVector(selectorVector);
1452 parser->tokenToLowerCase($2);
1456 | ':' NOTFUNCTION selector_recovery closing_parenthesis {
1459 | ':' HOSTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1460 $$ = parser->createFloatingSelector();
1461 $$->setMatch(CSSSelector::PseudoClass);
1462 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1463 parser->tokenToLowerCase($2);
1465 CSSSelector::PseudoType type = $$->pseudoType();
1466 if (type != CSSSelector::PseudoHost)
1470 | ':' HOSTFUNCTION maybe_space closing_parenthesis {
1471 $$ = parser->createFloatingSelector();
1472 $$->setMatch(CSSSelector::PseudoClass);
1473 parser->tokenToLowerCase($2);
1474 $$->setValue($2.atomicSubstring(0, $2.length() - 1));
1475 CSSSelector::PseudoType type = $$->pseudoType();
1476 if (type != CSSSelector::PseudoHost)
1479 | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
1482 | ':' ANCESTORFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1483 $$ = parser->createFloatingSelector();
1484 $$->setMatch(CSSSelector::PseudoClass);
1485 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1486 parser->tokenToLowerCase($2);
1488 CSSSelector::PseudoType type = $$->pseudoType();
1489 if (type != CSSSelector::PseudoAncestor)
1492 // used by :ancestor()
1493 | ':' ANCESTORFUNCTION maybe_space closing_parenthesis {
1494 $$ = parser->createFloatingSelector();
1495 $$->setMatch(CSSSelector::PseudoClass);
1496 parser->tokenToLowerCase($2);
1497 $$->setValue($2.atomicSubstring(0, $2.length() - 1));
1498 CSSSelector::PseudoType type = $$->pseudoType();
1499 if (type != CSSSelector::PseudoAncestor)
1502 | ':' ANCESTORFUNCTION selector_recovery closing_parenthesis {
1508 error error_location error_recovery;
1511 /* empty */ { $$ = false; }
1513 | decl_list declaration {
1520 declaration ';' maybe_space {
1521 parser->startProperty();
1524 | decl_list declaration ';' maybe_space {
1525 parser->startProperty();
1531 property ':' maybe_space error_location expr prio {
1533 bool isPropertyParsed = false;
1534 if ($1 != CSSPropertyInvalid) {
1535 parser->m_valueList = parser->sinkFloatingValueList($5);
1536 int oldParsedProperties = parser->m_parsedProperties.size();
1537 $$ = parser->parseValue($1, $6);
1539 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
1540 parser->reportError($4, InvalidPropertyValueCSSError);
1542 isPropertyParsed = true;
1543 parser->m_valueList = nullptr;
1545 parser->endProperty($6, isPropertyParsed);
1548 property ':' maybe_space error_location expr prio error error_recovery {
1549 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1550 parser->reportError($4, InvalidPropertyValueCSSError);
1551 parser->endProperty(false, false);
1555 property ':' maybe_space error_location error error_recovery {
1556 parser->reportError($4, InvalidPropertyValueCSSError);
1557 parser->endProperty(false, false);
1561 property error error_location error_recovery {
1562 parser->reportError($3, PropertyDeclarationCSSError);
1563 parser->endProperty(false, false, GeneralCSSError);
1567 error error_location error_recovery {
1568 parser->reportError($2, PropertyDeclarationCSSError);
1574 error_location IDENT maybe_space {
1575 $$ = cssPropertyID($2);
1576 parser->setCurrentProperty($$);
1577 if ($$ == CSSPropertyInvalid)
1578 parser->reportError($1, InvalidPropertyCSSError);
1583 IMPORTANT_SYM maybe_space { $$ = true; }
1584 | /* empty */ { $$ = false; }
1589 $$ = parser->createFloatingValueList();
1590 $$->addValue(makeIdentValue($1));
1592 | ident_list IDENT maybe_space {
1594 $$->addValue(makeIdentValue($2));
1599 '(' maybe_space closing_parenthesis {
1600 $$.setFromValueList(parser->sinkFloatingValueList(parser->createFloatingValueList()));
1602 | '(' maybe_space ident_list closing_parenthesis {
1603 $$.setFromValueList(parser->sinkFloatingValueList($3));
1605 | '(' maybe_space expr_recovery closing_parenthesis {
1612 $$ = parser->createFloatingValueList();
1613 $$->addValue(parser->sinkFloatingValue($1));
1615 | expr operator term {
1617 $$->addValue(makeOperatorValue($2));
1618 $$->addValue(parser->sinkFloatingValue($3));
1622 $$->addValue(parser->sinkFloatingValue($2));
1627 error error_location error_recovery {
1628 parser->reportError($2, PropertyDeclarationCSSError);
1642 unary_term maybe_space
1643 | unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
1644 | STRING maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1645 | IDENT maybe_space { $$ = makeIdentValue($1); }
1646 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1647 | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1648 | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1649 | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1650 | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1651 | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1652 | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1653 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1654 | function maybe_space
1655 | calc_function maybe_space
1656 | min_or_max_function maybe_space
1657 | '%' maybe_space { /* Handle width: %; */
1658 $$.id = CSSValueInvalid; $$.unit = 0;
1660 | track_names_list maybe_space
1664 INTEGER { $$.setFromNumber($1); $$.isInt = true; }
1665 | FLOATTOKEN { $$.setFromNumber($1); }
1666 | PERCENTAGE { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PERCENTAGE); }
1667 | PXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PX); }
1668 | CMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CM); }
1669 | MMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MM); }
1670 | INS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_IN); }
1671 | PTS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PT); }
1672 | PCS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PC); }
1673 | DEGS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DEG); }
1674 | RADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_RAD); }
1675 | GRADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_GRAD); }
1676 | TURNS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_TURN); }
1677 | MSECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MS); }
1678 | SECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_S); }
1679 | HERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_HZ); }
1680 | KHERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_KHZ); }
1681 | EMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EMS); }
1682 | QEMS { $$.setFromNumber($1, CSSParserValue::Q_EMS); }
1683 | EXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EXS); }
1685 $$.setFromNumber($1, CSSPrimitiveValue::CSS_REMS);
1686 if (parser->m_styleSheet)
1687 parser->m_styleSheet->parserSetUsesRemUnits(true);
1689 | CHS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CHS); }
1690 | VW { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VW); }
1691 | VH { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VH); }
1692 | VMIN { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMIN); }
1693 | VMAX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMAX); }
1694 | DPPX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPPX); }
1695 | DPI { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPI); }
1696 | DPCM { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPCM); }
1697 | FR { $$.setFromNumber($1, CSSPrimitiveValue::CSS_FR); }
1701 FUNCTION maybe_space expr closing_parenthesis {
1702 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1704 FUNCTION maybe_space closing_parenthesis {
1705 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList(parser->createFloatingValueList())));
1707 FUNCTION maybe_space expr_recovery closing_parenthesis {
1714 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1724 | calc_maybe_space '*' maybe_space {
1727 | calc_maybe_space '/' maybe_space {
1737 calc_func_paren_expr:
1738 '(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1740 $$->insertValueAt(0, makeOperatorValue('('));
1741 $$->addValue(makeOperatorValue(')'));
1743 | '(' maybe_space expr_recovery closing_parenthesis {
1750 $$ = parser->createFloatingValueList();
1751 $$->addValue(parser->sinkFloatingValue($1));
1753 | calc_func_expr calc_func_operator calc_func_term {
1755 $$->addValue(makeOperatorValue($2));
1756 $$->addValue(parser->sinkFloatingValue($3));
1758 | calc_func_expr calc_func_operator calc_func_paren_expr {
1760 $$->addValue(makeOperatorValue($2));
1761 $$->stealValues(*($3));
1763 | calc_func_paren_expr
1766 calc_func_expr_list:
1767 calc_func_expr calc_maybe_space
1768 | calc_func_expr_list ',' maybe_space calc_func_expr calc_maybe_space {
1770 $$->addValue(makeOperatorValue(','));
1771 $$->stealValues(*($4));
1776 CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1777 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1779 | CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
1790 min_or_max_function:
1791 min_or_max maybe_space calc_func_expr_list closing_parenthesis {
1792 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1794 | min_or_max maybe_space expr_recovery closing_parenthesis {
1805 at_rule_header_recovery at_invalid_rule_header_end at_rule_end
1808 at_rule_header_recovery:
1809 error error_location rule_error_recovery {
1810 parser->reportError($2, InvalidRuleCSSError);
1815 at_invalid_rule_header_end semi_or_eof
1816 | at_invalid_rule_header_end invalid_block
1819 regular_invalid_at_rule_header:
1820 keyframes_rule_start at_rule_header_recovery
1821 | before_page_rule PAGE_SYM at_rule_header_recovery
1822 | before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
1823 | before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
1824 parser->reportError($4, InvalidSupportsConditionCSSError);
1825 parser->popSupportsRuleData();
1827 | before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
1828 parser->markViewportRuleBodyEnd();
1830 | import_rule_start at_rule_header_recovery
1831 | NAMESPACE_SYM at_rule_header_recovery
1832 | error_location invalid_at at_rule_header_recovery {
1833 parser->resumeErrorLogging();
1834 parser->reportError($1, InvalidRuleCSSError);
1839 error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
1840 parser->reportError($2, InvalidRuleCSSError);
1842 | regular_invalid_at_rule_header at_invalid_rule_header_end ';'
1843 | regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
1844 | media_rule_start maybe_media_list ';'
1847 invalid_rule_header:
1848 error error_location rule_error_recovery at_invalid_rule_header_end {
1849 parser->reportError($2, InvalidRuleCSSError);
1851 | regular_invalid_at_rule_header at_invalid_rule_header_end
1852 | media_rule_start maybe_media_list
1855 at_invalid_rule_header_end:
1857 parser->endInvalidRuleHeader();
1862 '{' error_recovery closing_brace {
1863 parser->invalidBlockHit();
1867 invalid_square_brackets_block:
1868 '[' error_recovery closing_square_bracket
1871 invalid_parentheses_block:
1872 opening_parenthesis error_recovery closing_parenthesis;
1874 opening_parenthesis:
1875 '(' | FUNCTION | CALCFUNCTION | MINFUNCTION | MAXFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
1879 $$ = parser->currentLocation();
1884 parser->setLocationLabel(parser->currentLocation());
1890 | error_recovery error
1891 | error_recovery invalid_block
1892 | error_recovery invalid_square_brackets_block
1893 | error_recovery invalid_parentheses_block
1896 rule_error_recovery:
1898 | rule_error_recovery error
1899 | rule_error_recovery invalid_square_brackets_block
1900 | rule_error_recovery invalid_parentheses_block