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/parser/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 "core/frame/UseCounter.h"
43 #include "wtf/FastMalloc.h"
47 using namespace blink;
48 using namespace HTMLNames;
50 #define YYMALLOC fastMalloc
51 #define YYFREE fastFree
53 #define YYENABLE_NLS 0
54 #define YYLTYPE_IS_TRIVIAL 1
55 #define YYMAXDEPTH 10000
59 #define YYPRINT(File,Type,Value) if (isCSSTokenAString(Type)) YYFPRINTF(File, "%s", String((Value).string).utf8().data())
66 %parse-param { BisonCSSParser* parser }
67 %lex-param { BisonCSSParser* parser }
74 CSSParserString string;
77 // The content of the three below HeapVectors are guaranteed to be kept alive by
78 // the corresponding m_parsedRules, m_floatingMediaQueryExpList, and m_parsedKeyFrames
79 // lists in BisonCSSParser.h.
80 WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >* ruleList;
81 WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* mediaQueryExpList;
82 WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* keyframeRuleList;
83 CSSParserSelector* selector;
84 Vector<OwnPtr<CSSParserSelector> >* selectorList;
85 CSSSelector::MarginBoxType marginBox;
86 CSSSelector::Relation relation;
87 CSSSelector::AttributeMatchType attributeMatchType;
88 MediaQuerySet* mediaList;
89 MediaQuery* mediaQuery;
90 MediaQuery::Restrictor mediaQueryRestrictor;
91 MediaQueryExp* mediaQueryExp;
93 CSSParserValueList* valueList;
94 StyleKeyframe* keyframe;
97 CSSParserLocation location;
102 static inline int cssyyerror(void*, const char*)
108 static inline bool isCSSTokenAString(int yytype)
122 case HOSTCONTEXTFUNCTION:
133 inline static CSSParserValue makeOperatorValue(int value)
136 v.id = CSSValueInvalid;
138 v.unit = CSSParserValue::Operator;
143 inline static CSSParserValue makeIdentValue(CSSParserString string)
146 v.id = cssValueKeywordID(string);
148 v.unit = CSSPrimitiveValue::CSS_IDENT;
157 %nonassoc LOWEST_PREC
159 %left UNIMPORTANT_TOK
161 %token WHITESPACE SGML_CD
170 %token <string> STRING
171 %right <string> IDENT
174 %nonassoc <string> HEX
175 %nonassoc <string> IDSEL
179 %nonassoc <string> '*'
190 %token VIEWPORT_RULE_SYM
191 %token INTERNAL_DECLS_SYM
192 %token INTERNAL_RULE_SYM
193 %token INTERNAL_SELECTOR_SYM
194 %token INTERNAL_VALUE_SYM
195 %token INTERNAL_KEYFRAME_RULE_SYM
196 %token INTERNAL_KEYFRAME_KEY_LIST_SYM
197 %token INTERNAL_SUPPORTS_CONDITION_SYM
199 %token WEBKIT_KEYFRAMES_SYM
200 %token <marginBox> TOPLEFTCORNER_SYM
201 %token <marginBox> TOPLEFT_SYM
202 %token <marginBox> TOPCENTER_SYM
203 %token <marginBox> TOPRIGHT_SYM
204 %token <marginBox> TOPRIGHTCORNER_SYM
205 %token <marginBox> BOTTOMLEFTCORNER_SYM
206 %token <marginBox> BOTTOMLEFT_SYM
207 %token <marginBox> BOTTOMCENTER_SYM
208 %token <marginBox> BOTTOMRIGHT_SYM
209 %token <marginBox> BOTTOMRIGHTCORNER_SYM
210 %token <marginBox> LEFTTOP_SYM
211 %token <marginBox> LEFTMIDDLE_SYM
212 %token <marginBox> LEFTBOTTOM_SYM
213 %token <marginBox> RIGHTTOP_SYM
214 %token <marginBox> RIGHTMIDDLE_SYM
215 %token <marginBox> RIGHTBOTTOM_SYM
242 %token <number> GRADS
243 %token <number> TURNS
244 %token <number> MSECS
246 %token <number> HERTZ
247 %token <number> KHERTZ
248 %token <string> DIMEN
249 %token <string> INVALIDDIMEN
250 %token <number> PERCENTAGE
251 %token <number> FLOATTOKEN
252 %token <number> INTEGER
263 %token <string> FUNCTION
264 %token <string> ANYFUNCTION
265 %token <string> CUEFUNCTION
266 %token <string> NOTFUNCTION
267 %token <string> DISTRIBUTEDFUNCTION
268 %token <string> CALCFUNCTION
269 %token <string> HOSTFUNCTION
270 %token <string> HOSTCONTEXTFUNCTION
272 %token <string> UNICODERANGE
274 %type <relation> combinator
279 %type <rule> namespace
281 %type <rule> margin_box
282 %type <rule> font_face
283 %type <rule> keyframes
285 %type <rule> valid_rule
286 %type <ruleList> block_rule_body
287 %type <ruleList> block_rule_list
288 %type <rule> block_rule
289 %type <rule> block_valid_rule
290 %type <rule> supports
291 %type <rule> viewport
292 %type <boolean> keyframes_rule_start
294 %type <string> maybe_ns_prefix
296 %type <string> namespace_selector
298 %type <string> string_or_uri
299 %type <string> ident_or_string
300 %type <string> medium
301 %type <marginBox> margin_sym
303 %type <mediaList> media_list
304 %type <mediaList> maybe_media_list
305 %type <mediaList> mq_list
306 %type <mediaQuery> media_query
307 %type <mediaQuery> valid_media_query
308 %type <mediaQueryRestrictor> maybe_media_restrictor
309 %type <valueList> maybe_media_value
310 %type <mediaQueryExp> media_query_exp
311 %type <mediaQueryExpList> media_query_exp_list
312 %type <mediaQueryExpList> maybe_and_media_query_exp_list
314 %type <boolean> supports_condition
315 %type <boolean> supports_condition_in_parens
316 %type <boolean> supports_negation
317 %type <boolean> supports_conjunction
318 %type <boolean> supports_disjunction
319 %type <boolean> supports_declaration_condition
321 %type <string> keyframe_name
322 %type <keyframe> keyframe_rule
323 %type <keyframeRuleList> keyframes_rule
324 %type <keyframeRuleList> keyframe_rule_list
325 %type <valueList> key_list
330 %type <selector> specifier
331 %type <selector> specifier_list
332 %type <selector> simple_selector
333 %type <selector> selector
334 %type <selectorList> selector_list
335 %type <selectorList> simple_selector_list
336 %type <selector> class
337 %type <selector> attrib
338 %type <selector> pseudo
339 %type <selector> pseudo_page
340 %type <selector> page_selector
342 %type <boolean> declaration_list
343 %type <boolean> decl_list
344 %type <boolean> declaration
345 %type <boolean> declarations_and_margins
349 %type <integer> match
350 %type <integer> unary_operator
351 %type <integer> maybe_unary_operator
352 %type <character> operator
354 %type <valueList> expr
356 %type <value> unary_term
357 %type <value> function
358 %type <value> calc_func_term
359 %type <character> calc_func_operator
360 %type <valueList> calc_func_expr
361 %type <valueList> calc_func_paren_expr
362 %type <value> calc_function
364 %type <string> element_name
365 %type <string> attr_name
367 %type <attributeMatchType> attr_match_type
368 %type <attributeMatchType> maybe_attr_match_type
370 %type <location> error_location
372 %type <valueList> ident_list
373 %type <value> track_names_list
378 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 parser->parseValue(parser->m_id, parser->m_important);
416 parser->m_valueList = nullptr;
421 INTERNAL_SELECTOR_SYM maybe_space selector_list TOKEN_EOF {
422 if (parser->m_selectorListForParseSelector)
423 parser->m_selectorListForParseSelector->adoptSelectorVector(*$3);
427 internal_supports_condition:
428 INTERNAL_SUPPORTS_CONDITION_SYM maybe_space supports_condition TOKEN_EOF {
429 parser->m_supportsCondition = $3;
439 /* empty */ %prec UNIMPORTANT_TOK
446 | maybe_sgml WHITESPACE
451 | %prec LOWEST_PREC TOKEN_EOF
456 | %prec LOWEST_PREC TOKEN_EOF
459 closing_square_bracket:
461 | %prec LOWEST_PREC TOKEN_EOF
472 parser->startRuleHeader(CSSRuleSourceData::CHARSET_RULE);
477 | before_charset_rule CHARSET_SYM maybe_space STRING maybe_space semi_or_eof {
478 if (parser->m_styleSheet)
479 parser->m_styleSheet->parserSetEncodingFromCharsetRule($4);
480 parser->endRuleHeader();
481 parser->startRuleBody();
482 parser->endRule(true);
484 | before_charset_rule CHARSET_SYM at_rule_recovery {
485 parser->endRule(false);
491 | rule_list rule maybe_sgml {
492 if ($2 && parser->m_styleSheet)
493 parser->m_styleSheet->parserAppendRule($2);
516 before_rule valid_rule {
518 parser->m_hadSyntacticallyValidCSSRule = true;
519 parser->endRule(!!$$);
521 | before_rule invalid_rule {
523 parser->endRule(false);
529 | block_rule_list block_rule_recovery
533 /* empty */ { $$ = 0; }
534 | block_rule_list block_rule maybe_sgml {
535 $$ = parser->appendRule($1, $2);
540 before_rule invalid_rule_header {
541 parser->endRule(false);
557 before_rule block_valid_rule {
559 parser->endRule(!!$$);
561 | before_rule invalid_rule {
563 parser->endRule(false);
569 parser->startRuleHeader(CSSRuleSourceData::IMPORT_RULE);
574 before_import_rule IMPORT_SYM maybe_space {
575 parser->endRuleHeader();
576 parser->startRuleBody();
581 import_rule_start string_or_uri maybe_space location_label maybe_media_list semi_or_eof {
582 $$ = parser->createImportRule($2, $5);
584 | import_rule_start string_or_uri maybe_space location_label maybe_media_list invalid_block {
590 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space semi_or_eof {
591 parser->addNamespace($3, $4);
597 /* empty */ { $$.clear(); }
606 before_media_value_expr:
608 parser->startMediaValue();
616 | ':' maybe_space before_media_value_expr expr {
618 parser->endMediaValue();
623 '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
624 parser->tokenToLowerCase($3);
625 $$ = parser->createFloatingMediaQueryExp($3, $5);
629 | '(' error error_recovery closing_parenthesis {
634 media_query_exp_list:
636 $$ = parser->createFloatingMediaQueryExpList();
637 $$->append(parser->sinkFloatingMediaQueryExp($1));
639 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
641 $$->append(parser->sinkFloatingMediaQueryExp($5));
645 maybe_and_media_query_exp_list:
647 $$ = parser->createFloatingMediaQueryExpList();
649 | maybe_space MEDIA_AND maybe_space media_query_exp_list maybe_space {
654 maybe_media_restrictor:
656 $$ = MediaQuery::None;
658 | MEDIA_ONLY maybe_space {
659 $$ = MediaQuery::Only;
661 | MEDIA_NOT maybe_space {
662 $$ = MediaQuery::Not;
668 parser->startMediaQuery();
673 before_media_query media_query_exp_list maybe_space {
674 $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($2));
676 | before_media_query maybe_media_restrictor medium maybe_and_media_query_exp_list {
677 parser->tokenToLowerCase($3);
678 $$ = parser->createFloatingMediaQuery($2, $3, parser->sinkFloatingMediaQueryExpList($4));
684 | valid_media_query error error_location rule_error_recovery {
685 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
686 $$ = parser->createFloatingNotAllQuery();
688 | error error_location rule_error_recovery {
689 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
690 $$ = parser->createFloatingNotAllQuery();
696 $$ = parser->createMediaQuerySet();
703 $$ = parser->createMediaQuerySet();
704 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
706 | mq_list media_query {
708 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
712 $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));
717 media_query ',' maybe_space location_label {
718 $$ = parser->createMediaQuerySet();
719 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
721 | mq_list media_query ',' maybe_space location_label {
723 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
729 parser->startRuleBody();
735 parser->startRuleHeader(CSSRuleSourceData::MEDIA_RULE);
739 at_rule_header_end_maybe_space:
741 parser->endRuleHeader();
746 before_media_rule MEDIA_SYM maybe_space;
749 media_rule_start maybe_media_list '{' at_rule_header_end at_rule_body_start maybe_space block_rule_body closing_brace {
750 $$ = parser->createMediaRule($2, $7);
759 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 {
760 $$ = parser->createSupportsRule($4, $9);
764 before_supports_rule:
766 parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);
767 parser->markSupportsRuleHeaderStart();
771 at_supports_rule_header_end:
773 parser->endRuleHeader();
774 parser->markSupportsRuleHeaderEnd();
779 supports_condition_in_parens
781 | supports_conjunction
782 | supports_disjunction
786 SUPPORTS_NOT maybe_space supports_condition_in_parens {
791 supports_conjunction:
792 supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
795 | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
800 supports_disjunction:
801 supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
804 | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
809 supports_condition_in_parens:
810 '(' maybe_space supports_condition closing_parenthesis maybe_space {
813 | supports_declaration_condition
814 | '(' error error_location error_recovery closing_parenthesis maybe_space {
815 parser->reportError($3, InvalidSupportsConditionCSSError);
820 supports_declaration_condition:
821 '(' maybe_space IDENT maybe_space ':' maybe_space expr prio closing_parenthesis maybe_space {
823 CSSPropertyID id = cssPropertyID($3);
824 if (id != CSSPropertyInvalid) {
825 parser->m_valueList = parser->sinkFloatingValueList($7);
826 int oldParsedProperties = parser->m_parsedProperties.size();
827 $$ = parser->parseValue(id, $8);
828 // We just need to know if the declaration is supported as it is written. Rollback any additions.
830 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
832 parser->m_valueList = nullptr;
833 parser->endProperty($8, false);
835 | '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
837 parser->endProperty(false, false, GeneralCSSError);
841 before_keyframes_rule:
843 parser->startRuleHeader(CSSRuleSourceData::KEYFRAMES_RULE);
847 keyframes_rule_start:
848 before_keyframes_rule KEYFRAMES_SYM maybe_space {
851 | before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space {
857 keyframes_rule_start keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space location_label keyframes_rule closing_brace {
858 $$ = parser->createKeyframesRule($2, parser->sinkFloatingKeyframeVector($8), $1 /* isPrefixed */);
865 if (parser->m_context.useCounter())
866 parser->m_context.useCounter()->count(UseCounter::QuotedKeyframesRule);
872 | keyframe_rule_list keyframes_error_recovery {
873 parser->clearProperties();
878 $$ = parser->createFloatingKeyframeVector();
879 parser->resumeErrorLogging();
881 | keyframe_rule_list keyframe_rule maybe_space location_label {
885 | keyframe_rule_list keyframes_error_recovery invalid_block maybe_space location_label {
886 parser->clearProperties();
887 parser->resumeErrorLogging();
892 key_list '{' maybe_space declaration_list closing_brace {
893 $$ = parser->createKeyframe($1);
899 $$ = parser->createFloatingValueList();
900 $$->addValue(parser->sinkFloatingValue($1));
902 | key_list ',' maybe_space key maybe_space {
904 $$->addValue(parser->sinkFloatingValue($4));
909 maybe_unary_operator PERCENTAGE {
910 $$.setFromNumber($1 * $2);
913 if ($1.equalIgnoringCase("from"))
915 else if ($1.equalIgnoringCase("to"))
916 $$.setFromNumber(100);
923 keyframes_error_recovery:
924 error rule_error_recovery {
925 parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
931 parser->startRuleHeader(CSSRuleSourceData::PAGE_RULE);
936 before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end
937 '{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
939 $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
941 // Clear properties in the invalid @page rule.
942 parser->clearProperties();
943 // Also clear margin at-rules here once we fully implement margin at-rules parsing.
951 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
954 | IDENT pseudo_page maybe_space {
956 $$->prependTagSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
959 | pseudo_page maybe_space {
964 $$ = parser->createFloatingSelector();
969 declarations_and_margins:
971 | declarations_and_margins margin_box maybe_space declaration_list
976 parser->startDeclarationsForMarginBox();
977 } maybe_space '{' maybe_space declaration_list closing_brace {
978 $$ = parser->createMarginAtRule($1);
984 $$ = CSSSelector::TopLeftCornerMarginBox;
987 $$ = CSSSelector::TopLeftMarginBox;
990 $$ = CSSSelector::TopCenterMarginBox;
993 $$ = CSSSelector::TopRightMarginBox;
995 | TOPRIGHTCORNER_SYM {
996 $$ = CSSSelector::TopRightCornerMarginBox;
998 | BOTTOMLEFTCORNER_SYM {
999 $$ = CSSSelector::BottomLeftCornerMarginBox;
1002 $$ = CSSSelector::BottomLeftMarginBox;
1004 | BOTTOMCENTER_SYM {
1005 $$ = CSSSelector::BottomCenterMarginBox;
1008 $$ = CSSSelector::BottomRightMarginBox;
1010 | BOTTOMRIGHTCORNER_SYM {
1011 $$ = CSSSelector::BottomRightCornerMarginBox;
1014 $$ = CSSSelector::LeftTopMarginBox;
1017 $$ = CSSSelector::LeftMiddleMarginBox;
1020 $$ = CSSSelector::LeftBottomMarginBox;
1023 $$ = CSSSelector::RightTopMarginBox;
1026 $$ = CSSSelector::RightMiddleMarginBox;
1029 $$ = CSSSelector::RightBottomMarginBox;
1033 before_font_face_rule:
1035 parser->startRuleHeader(CSSRuleSourceData::FONT_FACE_RULE);
1040 before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
1041 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1042 $$ = parser->createFontFaceRule();
1046 before_viewport_rule:
1048 parser->markViewportRuleBodyStart();
1049 parser->startRuleHeader(CSSRuleSourceData::VIEWPORT_RULE);
1054 before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
1055 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1056 $$ = parser->createViewportRule();
1057 parser->markViewportRuleBodyEnd();
1062 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
1063 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
1064 | '>' maybe_space { $$ = CSSSelector::Child; }
1065 | '/' IDENT '/' maybe_space {
1066 if ($2.equalIgnoringCase("deep"))
1067 $$ = CSSSelector::ShadowDeep;
1073 maybe_unary_operator:
1075 | /* empty */ { $$ = 1; }
1083 maybe_space_before_declaration:
1085 parser->startProperty();
1089 before_selector_list:
1091 parser->startRuleHeader(CSSRuleSourceData::STYLE_RULE);
1092 parser->startSelector();
1098 parser->endRuleHeader();
1104 parser->endSelector();
1109 before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1110 $$ = parser->createStyleRule($2);
1114 before_selector_group_item:
1116 parser->startSelector();
1120 selector %prec UNIMPORTANT_TOK {
1121 $$ = parser->reusableSelectorVector();
1123 $$->append(parser->sinkFloatingSelector($1));
1125 | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
1127 $$->append(parser->sinkFloatingSelector($6));
1133 | selector WHITESPACE
1134 | selector WHITESPACE simple_selector
1137 CSSParserSelector* end = $$;
1138 while (end->tagHistory())
1139 end = end->tagHistory();
1140 end->setRelation(CSSSelector::Descendant);
1141 if ($1->isContentPseudoElement())
1142 end->setRelationIsAffectedByPseudoContent();
1143 end->setTagHistory(parser->sinkFloatingSelector($1));
1145 | selector combinator simple_selector {
1147 CSSParserSelector* end = $$;
1148 while (end->tagHistory())
1149 end = end->tagHistory();
1150 end->setRelation($2);
1151 if ($1->isContentPseudoElement())
1152 end->setRelationIsAffectedByPseudoContent();
1153 end->setTagHistory(parser->sinkFloatingSelector($1));
1158 /* empty */ '|' { $$.clear(); }
1159 | '*' '|' { static const LChar star = '*'; $$.init(&star, 1); }
1165 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
1167 | element_name specifier_list {
1168 $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $2);
1173 $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($1);
1177 | namespace_selector element_name {
1178 $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
1182 | namespace_selector element_name specifier_list {
1183 $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);
1187 | namespace_selector specifier_list {
1188 $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);
1194 simple_selector_list:
1195 simple_selector %prec UNIMPORTANT_TOK {
1196 $$ = parser->createFloatingSelectorVector();
1197 $$->append(parser->sinkFloatingSelector($1));
1199 | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
1201 $$->append(parser->sinkFloatingSelector($5));
1207 if (parser->m_context.isHTMLDocument())
1208 parser->tokenToLowerCase($1);
1212 static const LChar star = '*';
1219 | specifier_list specifier {
1220 $$ = parser->rewriteSpecifiers($1, $2);
1226 $$ = parser->createFloatingSelector();
1227 $$->setMatch(CSSSelector::Id);
1228 if (isQuirksModeBehavior(parser->m_context.mode()))
1229 parser->tokenToLowerCase($1);
1233 if ($1[0] >= '0' && $1[0] <= '9') {
1236 $$ = parser->createFloatingSelector();
1237 $$->setMatch(CSSSelector::Id);
1238 if (isQuirksModeBehavior(parser->m_context.mode()))
1239 parser->tokenToLowerCase($1);
1250 $$ = parser->createFloatingSelector();
1251 $$->setMatch(CSSSelector::Class);
1252 if (isQuirksModeBehavior(parser->m_context.mode()))
1253 parser->tokenToLowerCase($2);
1260 if (parser->m_context.isHTMLDocument())
1261 parser->tokenToLowerCase($1);
1268 CSSSelector::AttributeMatchType attrMatchType = CSSSelector::CaseSensitive;
1269 if (!parser->parseAttributeMatchType(attrMatchType, $1))
1275 maybe_attr_match_type:
1277 | /* empty */ { $$ = CSSSelector::CaseSensitive; }
1281 '[' maybe_space attr_name closing_square_bracket {
1282 $$ = parser->createFloatingSelector();
1283 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), CSSSelector::CaseSensitive);
1284 $$->setMatch(CSSSelector::AttributeSet);
1286 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1287 $$ = parser->createFloatingSelector();
1288 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), $8);
1289 $$->setMatch((CSSSelector::Match)$4);
1292 | '[' maybe_space namespace_selector attr_name closing_square_bracket {
1293 $$ = parser->createFloatingSelector();
1294 $$->setAttribute(parser->determineNameInNamespace($3, $4), CSSSelector::CaseSensitive);
1295 $$->setMatch(CSSSelector::AttributeSet);
1297 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1298 $$ = parser->createFloatingSelector();
1299 $$->setAttribute(parser->determineNameInNamespace($3, $4), $9);
1300 $$->setMatch((CSSSelector::Match)$5);
1303 | '[' selector_recovery closing_square_bracket {
1310 $$ = CSSSelector::AttributeExact;
1313 $$ = CSSSelector::AttributeList;
1316 $$ = CSSSelector::AttributeHyphen;
1319 $$ = CSSSelector::AttributeBegin;
1322 $$ = CSSSelector::AttributeEnd;
1325 $$ = CSSSelector::AttributeContain;
1336 if ($2.isFunction())
1338 $$ = parser->createFloatingSelector();
1339 $$->setMatch(CSSSelector::PagePseudoClass);
1340 parser->tokenToLowerCase($2);
1342 CSSSelector::PseudoType type = $$->pseudoType();
1343 if (type == CSSSelector::PseudoUnknown)
1348 ':' error_location IDENT {
1349 if ($3.isFunction())
1351 $$ = parser->createFloatingSelector();
1352 $$->setMatch(CSSSelector::PseudoClass);
1353 parser->tokenToLowerCase($3);
1355 CSSSelector::PseudoType type = $$->pseudoType();
1356 if (type == CSSSelector::PseudoUnknown) {
1357 parser->reportError($2, InvalidSelectorPseudoCSSError);
1361 | ':' ':' error_location IDENT {
1362 if ($4.isFunction())
1364 $$ = parser->createFloatingSelector();
1365 $$->setMatch(CSSSelector::PseudoElement);
1366 parser->tokenToLowerCase($4);
1368 // FIXME: This call is needed to force selector to compute the pseudoType early enough.
1369 CSSSelector::PseudoType type = $$->pseudoType();
1370 if (type == CSSSelector::PseudoUnknown) {
1371 parser->reportError($3, InvalidSelectorPseudoCSSError);
1375 // used by ::cue(:past/:future)
1376 | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1377 $$ = parser->createFloatingSelector();
1378 $$->setMatch(CSSSelector::PseudoElement);
1379 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
1381 CSSSelector::PseudoType type = $$->pseudoType();
1382 if (type != CSSSelector::PseudoCue)
1385 | ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
1388 // use by :-webkit-any.
1389 // FIXME: should we support generic selectors here or just simple_selectors?
1390 // Use simple_selector_list for now to match -moz-any.
1391 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
1392 // related discussion with respect to :not.
1393 | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1394 $$ = parser->createFloatingSelector();
1395 $$->setMatch(CSSSelector::PseudoClass);
1396 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1397 parser->tokenToLowerCase($2);
1399 CSSSelector::PseudoType type = $$->pseudoType();
1400 if (type != CSSSelector::PseudoAny)
1403 | ':' ANYFUNCTION selector_recovery closing_parenthesis {
1406 // used by :nth-*(ax+b)
1407 | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
1408 $$ = parser->createFloatingSelector();
1409 $$->setMatch(CSSSelector::PseudoClass);
1410 $$->setArgument($4);
1412 CSSSelector::PseudoType type = $$->pseudoType();
1413 if (type == CSSSelector::PseudoUnknown)
1417 | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
1418 $$ = parser->createFloatingSelector();
1419 $$->setMatch(CSSSelector::PseudoClass);
1420 $$->setArgument(AtomicString::number($4 * $5));
1422 CSSSelector::PseudoType type = $$->pseudoType();
1423 if (type == CSSSelector::PseudoUnknown)
1426 // used by :nth-*(odd/even) and :lang
1427 | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
1428 $$ = parser->createFloatingSelector();
1429 $$->setMatch(CSSSelector::PseudoClass);
1430 $$->setArgument($4);
1431 parser->tokenToLowerCase($2);
1433 CSSSelector::PseudoType type = $$->pseudoType();
1434 if (type == CSSSelector::PseudoUnknown)
1436 else if (type == CSSSelector::PseudoNthChild ||
1437 type == CSSSelector::PseudoNthOfType ||
1438 type == CSSSelector::PseudoNthLastChild ||
1439 type == CSSSelector::PseudoNthLastOfType) {
1440 if (!isValidNthToken($4))
1444 | ':' FUNCTION selector_recovery closing_parenthesis {
1448 | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
1449 if (!$4->isSimple())
1452 $$ = parser->createFloatingSelector();
1453 $$->setMatch(CSSSelector::PseudoClass);
1455 Vector<OwnPtr<CSSParserSelector> > selectorVector;
1456 selectorVector.append(parser->sinkFloatingSelector($4));
1457 $$->adoptSelectorVector(selectorVector);
1459 parser->tokenToLowerCase($2);
1463 | ':' NOTFUNCTION selector_recovery closing_parenthesis {
1466 | ':' HOSTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1467 $$ = parser->createFloatingSelector();
1468 $$->setMatch(CSSSelector::PseudoClass);
1469 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1470 parser->tokenToLowerCase($2);
1472 CSSSelector::PseudoType type = $$->pseudoType();
1473 if (type != CSSSelector::PseudoHost)
1476 | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
1479 // used by :host-context()
1480 | ':' HOSTCONTEXTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1481 $$ = parser->createFloatingSelector();
1482 $$->setMatch(CSSSelector::PseudoClass);
1483 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1484 parser->tokenToLowerCase($2);
1486 CSSSelector::PseudoType type = $$->pseudoType();
1487 if (type != CSSSelector::PseudoHostContext)
1490 | ':' HOSTCONTEXTFUNCTION selector_recovery closing_parenthesis {
1496 error error_location error_recovery;
1499 /* empty */ { $$ = false; }
1501 | decl_list declaration {
1508 declaration ';' maybe_space {
1509 parser->startProperty();
1512 | decl_list declaration ';' maybe_space {
1513 parser->startProperty();
1519 property ':' maybe_space error_location expr prio {
1521 bool isPropertyParsed = false;
1522 if ($1 != CSSPropertyInvalid) {
1523 parser->m_valueList = parser->sinkFloatingValueList($5);
1524 $$ = parser->parseValue($1, $6);
1526 parser->reportError($4, InvalidPropertyValueCSSError);
1528 isPropertyParsed = true;
1529 parser->m_valueList = nullptr;
1531 parser->endProperty($6, isPropertyParsed);
1534 property ':' maybe_space error_location expr prio error error_recovery {
1535 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1536 parser->reportError($4, InvalidPropertyValueCSSError);
1537 parser->endProperty(false, false);
1541 property ':' maybe_space error_location error error_recovery {
1542 parser->reportError($4, InvalidPropertyValueCSSError);
1543 parser->endProperty(false, false);
1547 property error error_location error_recovery {
1548 parser->reportError($3, PropertyDeclarationCSSError);
1549 parser->endProperty(false, false, GeneralCSSError);
1553 error error_location error_recovery {
1554 parser->reportError($2, PropertyDeclarationCSSError);
1560 error_location IDENT maybe_space {
1561 $$ = cssPropertyID($2);
1562 parser->setCurrentProperty($$);
1563 if ($$ == CSSPropertyInvalid)
1564 parser->reportError($1, InvalidPropertyCSSError);
1569 IMPORTANT_SYM maybe_space { $$ = true; }
1570 | /* empty */ { $$ = false; }
1575 $$ = parser->createFloatingValueList();
1576 $$->addValue(makeIdentValue($1));
1578 | ident_list IDENT maybe_space {
1580 $$->addValue(makeIdentValue($2));
1585 '(' maybe_space closing_parenthesis {
1586 $$.setFromValueList(parser->sinkFloatingValueList(parser->createFloatingValueList()));
1588 | '(' maybe_space ident_list closing_parenthesis {
1589 $$.setFromValueList(parser->sinkFloatingValueList($3));
1591 | '(' maybe_space expr_recovery closing_parenthesis {
1598 $$ = parser->createFloatingValueList();
1599 $$->addValue(parser->sinkFloatingValue($1));
1601 | expr operator term {
1603 $$->addValue(makeOperatorValue($2));
1604 $$->addValue(parser->sinkFloatingValue($3));
1608 $$->addValue(parser->sinkFloatingValue($2));
1613 error error_location error_recovery {
1614 parser->reportError($2, PropertyDeclarationCSSError);
1628 unary_term maybe_space
1629 | unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
1630 | STRING maybe_space { $$.id = CSSValueInvalid; $$.isInt = false; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1631 | IDENT maybe_space { $$ = makeIdentValue($1); }
1632 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1633 | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1634 | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1635 | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_URI; }
1636 | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1637 | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1638 | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1639 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1640 | function maybe_space
1641 | calc_function maybe_space
1642 | '%' maybe_space { /* Handle width: %; */
1643 $$.id = CSSValueInvalid; $$.isInt = false; $$.unit = 0;
1645 | track_names_list maybe_space
1649 INTEGER { $$.setFromNumber($1); $$.isInt = true; }
1650 | FLOATTOKEN { $$.setFromNumber($1); }
1651 | PERCENTAGE { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PERCENTAGE); }
1652 | PXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PX); }
1653 | CMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CM); }
1654 | MMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MM); }
1655 | INS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_IN); }
1656 | PTS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PT); }
1657 | PCS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PC); }
1658 | DEGS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DEG); }
1659 | RADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_RAD); }
1660 | GRADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_GRAD); }
1661 | TURNS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_TURN); }
1662 | MSECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MS); }
1663 | SECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_S); }
1664 | HERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_HZ); }
1665 | KHERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_KHZ); }
1666 | EMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EMS); }
1667 | QEMS { $$.setFromNumber($1, CSSParserValue::Q_EMS); }
1668 | EXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EXS); }
1670 $$.setFromNumber($1, CSSPrimitiveValue::CSS_REMS);
1671 if (parser->m_styleSheet)
1672 parser->m_styleSheet->parserSetUsesRemUnits(true);
1674 | CHS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CHS); }
1675 | VW { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VW); }
1676 | VH { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VH); }
1677 | VMIN { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMIN); }
1678 | VMAX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMAX); }
1679 | DPPX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPPX); }
1680 | DPI { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPI); }
1681 | DPCM { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPCM); }
1682 | FR { $$.setFromNumber($1, CSSPrimitiveValue::CSS_FR); }
1686 FUNCTION maybe_space expr closing_parenthesis {
1687 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1689 FUNCTION maybe_space closing_parenthesis {
1690 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList(parser->createFloatingValueList())));
1692 FUNCTION maybe_space expr_recovery closing_parenthesis {
1699 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1709 | calc_maybe_space '*' maybe_space {
1712 | calc_maybe_space '/' maybe_space {
1722 calc_func_paren_expr:
1723 '(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1725 $$->insertValueAt(0, makeOperatorValue('('));
1726 $$->addValue(makeOperatorValue(')'));
1728 | '(' maybe_space expr_recovery closing_parenthesis {
1735 $$ = parser->createFloatingValueList();
1736 $$->addValue(parser->sinkFloatingValue($1));
1738 | calc_func_expr calc_func_operator calc_func_term {
1740 $$->addValue(makeOperatorValue($2));
1741 $$->addValue(parser->sinkFloatingValue($3));
1743 | calc_func_expr calc_func_operator calc_func_paren_expr {
1745 $$->addValue(makeOperatorValue($2));
1746 $$->stealValues(*($3));
1748 | calc_func_paren_expr
1752 CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1753 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1755 | CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
1767 at_rule_header_recovery at_invalid_rule_header_end at_rule_end
1770 at_rule_header_recovery:
1771 error error_location rule_error_recovery {
1772 parser->reportError($2, InvalidRuleCSSError);
1777 at_invalid_rule_header_end semi_or_eof
1778 | at_invalid_rule_header_end invalid_block
1781 regular_invalid_at_rule_header:
1782 keyframes_rule_start at_rule_header_recovery
1783 | before_page_rule PAGE_SYM at_rule_header_recovery
1784 | before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
1785 | before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
1786 parser->reportError($4, InvalidSupportsConditionCSSError);
1787 parser->popSupportsRuleData();
1789 | before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
1790 parser->markViewportRuleBodyEnd();
1792 | import_rule_start at_rule_header_recovery
1793 | NAMESPACE_SYM at_rule_header_recovery
1794 | error_location invalid_at at_rule_header_recovery {
1795 parser->resumeErrorLogging();
1796 parser->reportError($1, InvalidRuleCSSError);
1801 error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
1802 parser->reportError($2, InvalidRuleCSSError);
1804 | regular_invalid_at_rule_header at_invalid_rule_header_end ';'
1805 | regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
1806 | media_rule_start maybe_media_list ';'
1809 invalid_rule_header:
1810 error error_location rule_error_recovery at_invalid_rule_header_end {
1811 parser->reportError($2, InvalidRuleCSSError);
1813 | regular_invalid_at_rule_header at_invalid_rule_header_end
1814 | media_rule_start maybe_media_list
1817 at_invalid_rule_header_end:
1819 parser->endInvalidRuleHeader();
1824 '{' error_recovery closing_brace {
1825 parser->invalidBlockHit();
1829 invalid_square_brackets_block:
1830 '[' error_recovery closing_square_bracket
1833 invalid_parentheses_block:
1834 opening_parenthesis error_recovery closing_parenthesis;
1836 opening_parenthesis:
1837 '(' | FUNCTION | CALCFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
1841 $$ = parser->currentLocation();
1846 parser->setLocationLabel(parser->currentLocation());
1852 | error_recovery error
1853 | error_recovery invalid_block
1854 | error_recovery invalid_square_brackets_block
1855 | error_recovery invalid_parentheses_block
1858 rule_error_recovery:
1860 | rule_error_recovery error
1861 | rule_error_recovery invalid_square_brackets_block
1862 | rule_error_recovery invalid_parentheses_block