1 %{
2
3 /*
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.
9 *
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.
14 *
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.
19 *
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
23 *
24 */
25
26 #include "config.h"
27
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 "wtf/FastMalloc.h"
43 #include <stdlib.h>
44 #include <string.h>
45
46 using namespace blink;
47 using namespace HTMLNames;
48
49 #define YYMALLOC fastMalloc
50 #define YYFREE fastFree
51
52 #define YYENABLE_NLS 0
53 #define YYLTYPE_IS_TRIVIAL 1
54 #define YYMAXDEPTH 10000
55 #define YYDEBUG 0
56
57 #if YYDEBUG > 0
58 #define YYPRINT(File,Type,Value) if (isCSSTokenAString(Type)) YYFPRINTF(File, "%s", String((Value).string).utf8().data())
59 #endif
60
61 %}
62
63 %pure-parser
64
65 %parse-param { BisonCSSParser* parser }
66 %lex-param { BisonCSSParser* parser }
67
68 %union {
69 bool boolean;
70 char character;
71 int integer;
72 double number;
73 CSSParserString string;
74
75 StyleRuleBase* rule;
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 CSSSelector::AttributeMatchType attributeMatchType;
87 MediaQuerySet* mediaList;
88 MediaQuery* mediaQuery;
89 MediaQuery::Restrictor mediaQueryRestrictor;
90 MediaQueryExp* mediaQueryExp;
91 CSSParserValue value;
92 CSSParserValueList* valueList;
93 StyleKeyframe* keyframe;
94 float val;
95 CSSPropertyID id;
96 CSSParserLocation location;
97 }
98
99 %{
100
cssyyerror(void *,const char *)101 static inline int cssyyerror(void*, const char*)
102 {
103 return 1;
104 }
105
106 #if YYDEBUG > 0
isCSSTokenAString(int yytype)107 static inline bool isCSSTokenAString(int yytype)
108 {
109 switch (yytype) {
110 case IDENT:
111 case STRING:
112 case NTH:
113 case HEX:
114 case IDSEL:
115 case DIMEN:
116 case INVALIDDIMEN:
117 case URI:
118 case FUNCTION:
119 case ANYFUNCTION:
120 case HOSTFUNCTION:
121 case HOSTCONTEXTFUNCTION:
122 case NOTFUNCTION:
123 case CALCFUNCTION:
124 case UNICODERANGE:
125 return true;
126 default:
127 return false;
128 }
129 }
130 #endif
131
makeOperatorValue(int value)132 inline static CSSParserValue makeOperatorValue(int value)
133 {
134 CSSParserValue v;
135 v.id = CSSValueInvalid;
136 v.isInt = false;
137 v.unit = CSSParserValue::Operator;
138 v.iValue = value;
139 return v;
140 }
141
makeIdentValue(CSSParserString string)142 inline static CSSParserValue makeIdentValue(CSSParserString string)
143 {
144 CSSParserValue v;
145 v.id = cssValueKeywordID(string);
146 v.isInt = false;
147 v.unit = CSSPrimitiveValue::CSS_IDENT;
148 v.string = string;
149 return v;
150 }
151
152 %}
153
154 %expect 0
155
156 %nonassoc LOWEST_PREC
157
158 %left UNIMPORTANT_TOK
159
160 %token WHITESPACE SGML_CD
161 %token TOKEN_EOF 0
162
163 %token INCLUDES
164 %token DASHMATCH
165 %token BEGINSWITH
166 %token ENDSWITH
167 %token CONTAINS
168
169 %token <string> STRING
170 %right <string> IDENT
171 %token <string> NTH
172
173 %nonassoc <string> HEX
174 %nonassoc <string> IDSEL
175 %nonassoc ':'
176 %nonassoc '.'
177 %nonassoc '['
178 %nonassoc <string> '*'
179 %nonassoc error
180 %left '|'
181
182 %token IMPORT_SYM
183 %token PAGE_SYM
184 %token MEDIA_SYM
185 %token SUPPORTS_SYM
186 %token FONT_FACE_SYM
187 %token CHARSET_SYM
188 %token NAMESPACE_SYM
189 %token VIEWPORT_RULE_SYM
190 %token INTERNAL_DECLS_SYM
191 %token INTERNAL_RULE_SYM
192 %token INTERNAL_SELECTOR_SYM
193 %token INTERNAL_VALUE_SYM
194 %token INTERNAL_KEYFRAME_RULE_SYM
195 %token INTERNAL_KEYFRAME_KEY_LIST_SYM
196 %token INTERNAL_SUPPORTS_CONDITION_SYM
197 %token KEYFRAMES_SYM
198 %token WEBKIT_KEYFRAMES_SYM
199 %token <marginBox> TOPLEFTCORNER_SYM
200 %token <marginBox> TOPLEFT_SYM
201 %token <marginBox> TOPCENTER_SYM
202 %token <marginBox> TOPRIGHT_SYM
203 %token <marginBox> TOPRIGHTCORNER_SYM
204 %token <marginBox> BOTTOMLEFTCORNER_SYM
205 %token <marginBox> BOTTOMLEFT_SYM
206 %token <marginBox> BOTTOMCENTER_SYM
207 %token <marginBox> BOTTOMRIGHT_SYM
208 %token <marginBox> BOTTOMRIGHTCORNER_SYM
209 %token <marginBox> LEFTTOP_SYM
210 %token <marginBox> LEFTMIDDLE_SYM
211 %token <marginBox> LEFTBOTTOM_SYM
212 %token <marginBox> RIGHTTOP_SYM
213 %token <marginBox> RIGHTMIDDLE_SYM
214 %token <marginBox> RIGHTBOTTOM_SYM
215
216 %token ATKEYWORD
217
218 %token IMPORTANT_SYM
219 %token MEDIA_ONLY
220 %token MEDIA_NOT
221 %token MEDIA_AND
222 %token MEDIA_OR
223
224 %token SUPPORTS_NOT
225 %token SUPPORTS_AND
226 %token SUPPORTS_OR
227
228 %token <number> REMS
229 %token <number> CHS
230 %token <number> QEMS
231 %token <number> EMS
232 %token <number> EXS
233 %token <number> PXS
234 %token <number> CMS
235 %token <number> MMS
236 %token <number> INS
237 %token <number> PTS
238 %token <number> PCS
239 %token <number> DEGS
240 %token <number> RADS
241 %token <number> GRADS
242 %token <number> TURNS
243 %token <number> MSECS
244 %token <number> SECS
245 %token <number> HERTZ
246 %token <number> KHERTZ
247 %token <string> DIMEN
248 %token <string> INVALIDDIMEN
249 %token <number> PERCENTAGE
250 %token <number> FLOATTOKEN
251 %token <number> INTEGER
252 %token <number> VW
253 %token <number> VH
254 %token <number> VMIN
255 %token <number> VMAX
256 %token <number> DPPX
257 %token <number> DPI
258 %token <number> DPCM
259 %token <number> FR
260
261 %token <string> URI
262 %token <string> FUNCTION
263 %token <string> ANYFUNCTION
264 %token <string> CUEFUNCTION
265 %token <string> NOTFUNCTION
266 %token <string> DISTRIBUTEDFUNCTION
267 %token <string> CALCFUNCTION
268 %token <string> HOSTFUNCTION
269 %token <string> HOSTCONTEXTFUNCTION
270
271 %token <string> UNICODERANGE
272
273 %type <relation> combinator
274
275 %type <rule> ruleset
276 %type <rule> media
277 %type <rule> import
278 %type <rule> namespace
279 %type <rule> page
280 %type <rule> margin_box
281 %type <rule> font_face
282 %type <rule> keyframes
283 %type <rule> rule
284 %type <rule> valid_rule
285 %type <ruleList> block_rule_body
286 %type <ruleList> block_rule_list
287 %type <rule> block_rule
288 %type <rule> block_valid_rule
289 %type <rule> supports
290 %type <rule> viewport
291 %type <boolean> keyframes_rule_start
292
293 %type <string> maybe_ns_prefix
294
295 %type <string> namespace_selector
296
297 %type <string> string_or_uri
298 %type <string> ident_or_string
299 %type <string> medium
300 %type <marginBox> margin_sym
301
302 %type <mediaList> media_list
303 %type <mediaList> maybe_media_list
304 %type <mediaList> mq_list
305 %type <mediaQuery> media_query
306 %type <mediaQuery> valid_media_query
307 %type <mediaQueryRestrictor> maybe_media_restrictor
308 %type <valueList> maybe_media_value
309 %type <mediaQueryExp> media_query_exp
310 %type <mediaQueryExpList> media_query_exp_list
311 %type <mediaQueryExpList> maybe_and_media_query_exp_list
312
313 %type <boolean> supports_condition
314 %type <boolean> supports_condition_in_parens
315 %type <boolean> supports_negation
316 %type <boolean> supports_conjunction
317 %type <boolean> supports_disjunction
318 %type <boolean> supports_declaration_condition
319
320 %type <string> keyframe_name
321 %type <keyframe> keyframe_rule
322 %type <keyframeRuleList> keyframes_rule
323 %type <keyframeRuleList> keyframe_rule_list
324 %type <valueList> key_list
325 %type <value> key
326
327 %type <id> property
328
329 %type <selector> specifier
330 %type <selector> specifier_list
331 %type <selector> simple_selector
332 %type <selector> 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
340
341 %type <boolean> declaration_list
342 %type <boolean> decl_list
343 %type <boolean> declaration
344 %type <boolean> declarations_and_margins
345
346 %type <boolean> prio
347
348 %type <integer> match
349 %type <integer> unary_operator
350 %type <integer> maybe_unary_operator
351 %type <character> operator
352
353 %type <valueList> expr
354 %type <value> term
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_paren_expr
361 %type <value> calc_function
362
363 %type <string> element_name
364 %type <string> attr_name
365
366 %type <attributeMatchType> attr_match_type
367 %type <attributeMatchType> maybe_attr_match_type
368
369 %type <location> error_location
370
371 %type <valueList> ident_list
372 %type <value> track_names_list
373
374 %%
375
376 stylesheet:
377 maybe_charset maybe_sgml rule_list
378 | internal_decls
379 | internal_rule
380 | internal_selector
381 | internal_value
382 | internal_keyframe_rule
383 | internal_keyframe_key_list
384 | internal_supports_condition
385 ;
386
387 internal_rule:
388 INTERNAL_RULE_SYM maybe_space valid_rule maybe_space TOKEN_EOF {
389 parser->m_rule = $3;
390 }
391 ;
392
393 internal_keyframe_rule:
394 INTERNAL_KEYFRAME_RULE_SYM maybe_space keyframe_rule maybe_space TOKEN_EOF {
395 parser->m_keyframe = $3;
396 }
397 ;
398
399 internal_keyframe_key_list:
400 INTERNAL_KEYFRAME_KEY_LIST_SYM maybe_space key_list TOKEN_EOF {
401 parser->m_valueList = parser->sinkFloatingValueList($3);
402 }
403 ;
404
405 internal_decls:
406 INTERNAL_DECLS_SYM maybe_space_before_declaration declaration_list TOKEN_EOF {
407 /* can be empty */
408 }
409 ;
410
411 internal_value:
412 INTERNAL_VALUE_SYM maybe_space expr TOKEN_EOF {
413 parser->m_valueList = parser->sinkFloatingValueList($3);
414 int oldParsedProperties = parser->m_parsedProperties.size();
415 if (!parser->parseValue(parser->m_id, parser->m_important))
416 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
417 parser->m_valueList = nullptr;
418 }
419 ;
420
421 internal_selector:
422 INTERNAL_SELECTOR_SYM maybe_space selector_list TOKEN_EOF {
423 if (parser->m_selectorListForParseSelector)
424 parser->m_selectorListForParseSelector->adoptSelectorVector(*$3);
425 }
426 ;
427
428 internal_supports_condition:
429 INTERNAL_SUPPORTS_CONDITION_SYM maybe_space supports_condition TOKEN_EOF {
430 parser->m_supportsCondition = $3;
431 }
432 ;
433
434 space:
435 WHITESPACE
436 | space WHITESPACE
437 ;
438
439 maybe_space:
440 /* empty */ %prec UNIMPORTANT_TOK
441 | space
442 ;
443
444 maybe_sgml:
445 /* empty */
446 | maybe_sgml SGML_CD
447 | maybe_sgml WHITESPACE
448 ;
449
450 closing_brace:
451 '}'
452 | %prec LOWEST_PREC TOKEN_EOF
453 ;
454
455 closing_parenthesis:
456 ')'
457 | %prec LOWEST_PREC TOKEN_EOF
458 ;
459
460 closing_square_bracket:
461 ']'
462 | %prec LOWEST_PREC TOKEN_EOF
463 ;
464
465 semi_or_eof:
466 ';'
467 | TOKEN_EOF
468 ;
469
470 before_charset_rule:
471 /* empty */ {
472 parser->startRule();
473 parser->startRuleHeader(CSSRuleSourceData::CHARSET_RULE);
474 }
475
476 maybe_charset:
477 /* empty */
478 | before_charset_rule CHARSET_SYM maybe_space STRING maybe_space semi_or_eof {
479 if (parser->m_styleSheet)
480 parser->m_styleSheet->parserSetEncodingFromCharsetRule($4);
481 parser->endRuleHeader();
482 parser->startRuleBody();
483 parser->endRule(true);
484 }
485 | before_charset_rule CHARSET_SYM at_rule_recovery {
486 parser->endRule(false);
487 }
488 ;
489
490 rule_list:
491 /* empty */
492 | rule_list rule maybe_sgml {
493 if ($2 && parser->m_styleSheet)
494 parser->m_styleSheet->parserAppendRule($2);
495 }
496 ;
497
498 valid_rule:
499 ruleset
500 | media
501 | page
502 | font_face
503 | keyframes
504 | namespace
505 | import
506 | supports
507 | viewport
508 ;
509
510 before_rule:
511 /* empty */ {
512 parser->startRule();
513 }
514 ;
515
516 rule:
517 before_rule valid_rule {
518 $$ = $2;
519 parser->m_hadSyntacticallyValidCSSRule = true;
520 parser->endRule(!!$$);
521 }
522 | before_rule invalid_rule {
523 $$ = 0;
524 parser->endRule(false);
525 }
526 ;
527
528 block_rule_body:
529 block_rule_list
530 | block_rule_list block_rule_recovery
531 ;
532
533 block_rule_list:
534 /* empty */ { $$ = 0; }
535 | block_rule_list block_rule maybe_sgml {
536 $$ = parser->appendRule($1, $2);
537 }
538 ;
539
540 block_rule_recovery:
541 before_rule invalid_rule_header {
542 parser->endRule(false);
543 }
544 ;
545
546 block_valid_rule:
547 ruleset
548 | page
549 | font_face
550 | media
551 | keyframes
552 | supports
553 | viewport
554 | namespace
555 ;
556
557 block_rule:
558 before_rule block_valid_rule {
559 $$ = $2;
560 parser->endRule(!!$$);
561 }
562 | before_rule invalid_rule {
563 $$ = 0;
564 parser->endRule(false);
565 }
566 ;
567
568 before_import_rule:
569 /* empty */ {
570 parser->startRuleHeader(CSSRuleSourceData::IMPORT_RULE);
571 }
572 ;
573
574 import_rule_start:
575 before_import_rule IMPORT_SYM maybe_space {
576 parser->endRuleHeader();
577 parser->startRuleBody();
578 }
579 ;
580
581 import:
582 import_rule_start string_or_uri maybe_space location_label maybe_media_list semi_or_eof {
583 $$ = parser->createImportRule($2, $5);
584 }
585 | import_rule_start string_or_uri maybe_space location_label maybe_media_list invalid_block {
586 $$ = 0;
587 }
588 ;
589
590 namespace:
591 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space semi_or_eof {
592 parser->addNamespace($3, $4);
593 $$ = 0;
594 }
595 ;
596
597 maybe_ns_prefix:
598 /* empty */ { $$.clear(); }
599 | IDENT maybe_space
600 ;
601
602 string_or_uri:
603 STRING
604 | URI
605 ;
606
607 maybe_media_value:
608 /*empty*/ {
609 $$ = 0;
610 }
611 | ':' maybe_space expr {
612 $$ = $3;
613 }
614 ;
615
616 media_query_exp:
617 '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
618 parser->tokenToLowerCase($3);
619 $$ = parser->createFloatingMediaQueryExp($3, $5);
620 if (!$$)
621 YYERROR;
622 }
623 | '(' error error_recovery closing_parenthesis {
624 YYERROR;
625 }
626 ;
627
628 media_query_exp_list:
629 media_query_exp {
630 $$ = parser->createFloatingMediaQueryExpList();
631 $$->append(parser->sinkFloatingMediaQueryExp($1));
632 }
633 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
634 $$ = $1;
635 $$->append(parser->sinkFloatingMediaQueryExp($5));
636 }
637 ;
638
639 maybe_and_media_query_exp_list:
640 maybe_space {
641 $$ = parser->createFloatingMediaQueryExpList();
642 }
643 | maybe_space MEDIA_AND maybe_space media_query_exp_list maybe_space {
644 $$ = $4;
645 }
646 ;
647
648 maybe_media_restrictor:
649 /*empty*/ {
650 $$ = MediaQuery::None;
651 }
652 | MEDIA_ONLY maybe_space {
653 $$ = MediaQuery::Only;
654 }
655 | MEDIA_NOT maybe_space {
656 $$ = MediaQuery::Not;
657 }
658 ;
659
660 valid_media_query:
661 media_query_exp_list maybe_space {
662 $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
663 }
664 | maybe_media_restrictor medium maybe_and_media_query_exp_list {
665 parser->tokenToLowerCase($2);
666 $$ = parser->createFloatingMediaQuery($1, $2, parser->sinkFloatingMediaQueryExpList($3));
667 }
668 ;
669
670 media_query:
671 valid_media_query
672 | valid_media_query error error_location rule_error_recovery {
673 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
674 $$ = parser->createFloatingNotAllQuery();
675 }
676 | error error_location rule_error_recovery {
677 parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
678 $$ = parser->createFloatingNotAllQuery();
679 }
680 ;
681
682 maybe_media_list:
683 /* empty */ {
684 $$ = parser->createMediaQuerySet();
685 }
686 | media_list
687 ;
688
689 media_list:
690 media_query {
691 $$ = parser->createMediaQuerySet();
692 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
693 }
694 | mq_list media_query {
695 $$ = $1;
696 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
697 }
698 | mq_list {
699 $$ = $1;
700 $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));
701 }
702 ;
703
704 mq_list:
705 media_query ',' maybe_space location_label {
706 $$ = parser->createMediaQuerySet();
707 $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
708 }
709 | mq_list media_query ',' maybe_space location_label {
710 $$ = $1;
711 $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
712 }
713 ;
714
715 at_rule_body_start:
716 /* empty */ {
717 parser->startRuleBody();
718 }
719 ;
720
721 before_media_rule:
722 /* empty */ {
723 parser->startRuleHeader(CSSRuleSourceData::MEDIA_RULE);
724 }
725 ;
726
727 at_rule_header_end_maybe_space:
728 maybe_space {
729 parser->endRuleHeader();
730 }
731 ;
732
733 media_rule_start:
734 before_media_rule MEDIA_SYM maybe_space;
735
736 media:
737 media_rule_start maybe_media_list '{' at_rule_header_end at_rule_body_start maybe_space block_rule_body closing_brace {
738 $$ = parser->createMediaRule($2, $7);
739 }
740 ;
741
742 medium:
743 IDENT
744 ;
745
746 supports:
747 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 {
748 $$ = parser->createSupportsRule($4, $9);
749 }
750 ;
751
752 before_supports_rule:
753 /* empty */ {
754 parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);
755 parser->markSupportsRuleHeaderStart();
756 }
757 ;
758
759 at_supports_rule_header_end:
760 /* empty */ {
761 parser->endRuleHeader();
762 parser->markSupportsRuleHeaderEnd();
763 }
764 ;
765
766 supports_condition:
767 supports_condition_in_parens
768 | supports_negation
769 | supports_conjunction
770 | supports_disjunction
771 ;
772
773 supports_negation:
774 SUPPORTS_NOT maybe_space supports_condition_in_parens {
775 $$ = !$3;
776 }
777 ;
778
779 supports_conjunction:
780 supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
781 $$ = $1 && $4;
782 }
783 | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
784 $$ = $1 && $4;
785 }
786 ;
787
788 supports_disjunction:
789 supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
790 $$ = $1 || $4;
791 }
792 | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
793 $$ = $1 || $4;
794 }
795 ;
796
797 supports_condition_in_parens:
798 '(' maybe_space supports_condition closing_parenthesis maybe_space {
799 $$ = $3;
800 }
801 | supports_declaration_condition
802 | '(' error error_location error_recovery closing_parenthesis maybe_space {
803 parser->reportError($3, InvalidSupportsConditionCSSError);
804 $$ = false;
805 }
806 ;
807
808 supports_declaration_condition:
809 '(' maybe_space IDENT maybe_space ':' maybe_space expr prio closing_parenthesis maybe_space {
810 $$ = false;
811 CSSPropertyID id = cssPropertyID($3);
812 if (id != CSSPropertyInvalid) {
813 parser->m_valueList = parser->sinkFloatingValueList($7);
814 int oldParsedProperties = parser->m_parsedProperties.size();
815 $$ = parser->parseValue(id, $8);
816 // We just need to know if the declaration is supported as it is written. Rollback any additions.
817 if ($$)
818 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
819 }
820 parser->m_valueList = nullptr;
821 parser->endProperty($8, false);
822 }
823 | '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
824 $$ = false;
825 parser->endProperty(false, false, GeneralCSSError);
826 }
827 ;
828
829 before_keyframes_rule:
830 /* empty */ {
831 parser->startRuleHeader(CSSRuleSourceData::KEYFRAMES_RULE);
832 }
833 ;
834
835 keyframes_rule_start:
836 before_keyframes_rule KEYFRAMES_SYM maybe_space {
837 $$ = false;
838 }
839 | before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space {
840 $$ = true;
841 }
842 ;
843
844 keyframes:
845 keyframes_rule_start keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space location_label keyframes_rule closing_brace {
846 $$ = parser->createKeyframesRule($2, parser->sinkFloatingKeyframeVector($8), $1 /* isPrefixed */);
847 }
848 ;
849
850 keyframe_name:
851 IDENT
852 | STRING
853 ;
854
855 keyframes_rule:
856 keyframe_rule_list
857 | keyframe_rule_list keyframes_error_recovery {
858 parser->clearProperties();
859 };
860
861 keyframe_rule_list:
862 /* empty */ {
863 $$ = parser->createFloatingKeyframeVector();
864 parser->resumeErrorLogging();
865 }
866 | keyframe_rule_list keyframe_rule maybe_space location_label {
867 $$ = $1;
868 $$->append($2);
869 }
870 | keyframe_rule_list keyframes_error_recovery invalid_block maybe_space location_label {
871 parser->clearProperties();
872 parser->resumeErrorLogging();
873 }
874 ;
875
876 keyframe_rule:
877 key_list '{' maybe_space declaration_list closing_brace {
878 $$ = parser->createKeyframe($1);
879 }
880 ;
881
882 key_list:
883 key maybe_space {
884 $$ = parser->createFloatingValueList();
885 $$->addValue(parser->sinkFloatingValue($1));
886 }
887 | key_list ',' maybe_space key maybe_space {
888 $$ = $1;
889 $$->addValue(parser->sinkFloatingValue($4));
890 }
891 ;
892
893 key:
894 maybe_unary_operator PERCENTAGE {
895 $$.setFromNumber($1 * $2);
896 }
897 | IDENT {
898 if ($1.equalIgnoringCase("from"))
899 $$.setFromNumber(0);
900 else if ($1.equalIgnoringCase("to"))
901 $$.setFromNumber(100);
902 else {
903 YYERROR;
904 }
905 }
906 ;
907
908 keyframes_error_recovery:
909 error rule_error_recovery {
910 parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
911 }
912 ;
913
914 before_page_rule:
915 /* empty */ {
916 parser->startRuleHeader(CSSRuleSourceData::PAGE_RULE);
917 }
918 ;
919
920 page:
921 before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end
922 '{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
923 if ($4)
924 $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
925 else {
926 // Clear properties in the invalid @page rule.
927 parser->clearProperties();
928 // Also clear margin at-rules here once we fully implement margin at-rules parsing.
929 $$ = 0;
930 }
931 }
932 ;
933
934 page_selector:
935 IDENT maybe_space {
936 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
937 $$->setForPage();
938 }
939 | IDENT pseudo_page maybe_space {
940 $$ = $2;
941 $$->prependTagSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
942 $$->setForPage();
943 }
944 | pseudo_page maybe_space {
945 $$ = $1;
946 $$->setForPage();
947 }
948 | /* empty */ {
949 $$ = parser->createFloatingSelector();
950 $$->setForPage();
951 }
952 ;
953
954 declarations_and_margins:
955 declaration_list
956 | declarations_and_margins margin_box maybe_space declaration_list
957 ;
958
959 margin_box:
960 margin_sym {
961 parser->startDeclarationsForMarginBox();
962 } maybe_space '{' maybe_space declaration_list closing_brace {
963 $$ = parser->createMarginAtRule($1);
964 }
965 ;
966
967 margin_sym :
968 TOPLEFTCORNER_SYM {
969 $$ = CSSSelector::TopLeftCornerMarginBox;
970 }
971 | TOPLEFT_SYM {
972 $$ = CSSSelector::TopLeftMarginBox;
973 }
974 | TOPCENTER_SYM {
975 $$ = CSSSelector::TopCenterMarginBox;
976 }
977 | TOPRIGHT_SYM {
978 $$ = CSSSelector::TopRightMarginBox;
979 }
980 | TOPRIGHTCORNER_SYM {
981 $$ = CSSSelector::TopRightCornerMarginBox;
982 }
983 | BOTTOMLEFTCORNER_SYM {
984 $$ = CSSSelector::BottomLeftCornerMarginBox;
985 }
986 | BOTTOMLEFT_SYM {
987 $$ = CSSSelector::BottomLeftMarginBox;
988 }
989 | BOTTOMCENTER_SYM {
990 $$ = CSSSelector::BottomCenterMarginBox;
991 }
992 | BOTTOMRIGHT_SYM {
993 $$ = CSSSelector::BottomRightMarginBox;
994 }
995 | BOTTOMRIGHTCORNER_SYM {
996 $$ = CSSSelector::BottomRightCornerMarginBox;
997 }
998 | LEFTTOP_SYM {
999 $$ = CSSSelector::LeftTopMarginBox;
1000 }
1001 | LEFTMIDDLE_SYM {
1002 $$ = CSSSelector::LeftMiddleMarginBox;
1003 }
1004 | LEFTBOTTOM_SYM {
1005 $$ = CSSSelector::LeftBottomMarginBox;
1006 }
1007 | RIGHTTOP_SYM {
1008 $$ = CSSSelector::RightTopMarginBox;
1009 }
1010 | RIGHTMIDDLE_SYM {
1011 $$ = CSSSelector::RightMiddleMarginBox;
1012 }
1013 | RIGHTBOTTOM_SYM {
1014 $$ = CSSSelector::RightBottomMarginBox;
1015 }
1016 ;
1017
1018 before_font_face_rule:
1019 /* empty */ {
1020 parser->startRuleHeader(CSSRuleSourceData::FONT_FACE_RULE);
1021 }
1022 ;
1023
1024 font_face:
1025 before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
1026 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1027 $$ = parser->createFontFaceRule();
1028 }
1029 ;
1030
1031 before_viewport_rule:
1032 /* empty */ {
1033 parser->markViewportRuleBodyStart();
1034 parser->startRuleHeader(CSSRuleSourceData::VIEWPORT_RULE);
1035 }
1036 ;
1037
1038 viewport:
1039 before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
1040 '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1041 $$ = parser->createViewportRule();
1042 parser->markViewportRuleBodyEnd();
1043 }
1044 ;
1045
1046 combinator:
1047 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
1048 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
1049 | '>' maybe_space { $$ = CSSSelector::Child; }
1050 | '/' IDENT '/' maybe_space {
1051 if ($2.equalIgnoringCase("deep"))
1052 $$ = CSSSelector::ShadowDeep;
1053 else
1054 YYERROR;
1055 }
1056 ;
1057
1058 maybe_unary_operator:
1059 unary_operator
1060 | /* empty */ { $$ = 1; }
1061 ;
1062
1063 unary_operator:
1064 '-' { $$ = -1; }
1065 | '+' { $$ = 1; }
1066 ;
1067
1068 maybe_space_before_declaration:
1069 maybe_space {
1070 parser->startProperty();
1071 }
1072 ;
1073
1074 before_selector_list:
1075 /* empty */ {
1076 parser->startRuleHeader(CSSRuleSourceData::STYLE_RULE);
1077 parser->startSelector();
1078 }
1079 ;
1080
1081 at_rule_header_end:
1082 /* empty */ {
1083 parser->endRuleHeader();
1084 }
1085 ;
1086
1087 at_selector_end:
1088 /* empty */ {
1089 parser->endSelector();
1090 }
1091 ;
1092
1093 ruleset:
1094 before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1095 $$ = parser->createStyleRule($2);
1096 }
1097 ;
1098
1099 before_selector_group_item:
1100 /* empty */ {
1101 parser->startSelector();
1102 }
1103
1104 selector_list:
1105 selector %prec UNIMPORTANT_TOK {
1106 $$ = parser->reusableSelectorVector();
1107 $$->shrink(0);
1108 $$->append(parser->sinkFloatingSelector($1));
1109 }
1110 | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
1111 $$ = $1;
1112 $$->append(parser->sinkFloatingSelector($6));
1113 }
1114 ;
1115
1116 selector:
1117 simple_selector
1118 | selector WHITESPACE
1119 | selector WHITESPACE simple_selector
1120 {
1121 $$ = $3;
1122 CSSParserSelector* end = $$;
1123 while (end->tagHistory())
1124 end = end->tagHistory();
1125 end->setRelation(CSSSelector::Descendant);
1126 if ($1->isContentPseudoElement())
1127 end->setRelationIsAffectedByPseudoContent();
1128 end->setTagHistory(parser->sinkFloatingSelector($1));
1129 }
1130 | selector combinator simple_selector {
1131 $$ = $3;
1132 CSSParserSelector* end = $$;
1133 while (end->tagHistory())
1134 end = end->tagHistory();
1135 end->setRelation($2);
1136 if ($1->isContentPseudoElement())
1137 end->setRelationIsAffectedByPseudoContent();
1138 end->setTagHistory(parser->sinkFloatingSelector($1));
1139 }
1140 ;
1141
1142 namespace_selector:
1143 /* empty */ '|' { $$.clear(); }
1144 | '*' '|' { static const LChar star = '*'; $$.init(&star, 1); }
1145 | IDENT '|'
1146 ;
1147
1148 simple_selector:
1149 element_name {
1150 $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
1151 }
1152 | element_name specifier_list {
1153 $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $2);
1154 if (!$$)
1155 YYERROR;
1156 }
1157 | specifier_list {
1158 $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($1);
1159 if (!$$)
1160 YYERROR;
1161 }
1162 | namespace_selector element_name {
1163 $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
1164 if (!$$)
1165 YYERROR;
1166 }
1167 | namespace_selector element_name specifier_list {
1168 $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);
1169 if (!$$)
1170 YYERROR;
1171 }
1172 | namespace_selector specifier_list {
1173 $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);
1174 if (!$$)
1175 YYERROR;
1176 }
1177 ;
1178
1179 simple_selector_list:
1180 simple_selector %prec UNIMPORTANT_TOK {
1181 $$ = parser->createFloatingSelectorVector();
1182 $$->append(parser->sinkFloatingSelector($1));
1183 }
1184 | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
1185 $$ = $1;
1186 $$->append(parser->sinkFloatingSelector($5));
1187 }
1188 ;
1189
1190 element_name:
1191 IDENT {
1192 if (parser->m_context.isHTMLDocument())
1193 parser->tokenToLowerCase($1);
1194 $$ = $1;
1195 }
1196 | '*' {
1197 static const LChar star = '*';
1198 $$.init(&star, 1);
1199 }
1200 ;
1201
1202 specifier_list:
1203 specifier
1204 | specifier_list specifier {
1205 $$ = parser->rewriteSpecifiers($1, $2);
1206 }
1207 ;
1208
1209 specifier:
1210 IDSEL {
1211 $$ = parser->createFloatingSelector();
1212 $$->setMatch(CSSSelector::Id);
1213 if (isQuirksModeBehavior(parser->m_context.mode()))
1214 parser->tokenToLowerCase($1);
1215 $$->setValue($1);
1216 }
1217 | HEX {
1218 if ($1[0] >= '0' && $1[0] <= '9') {
1219 YYERROR;
1220 } else {
1221 $$ = parser->createFloatingSelector();
1222 $$->setMatch(CSSSelector::Id);
1223 if (isQuirksModeBehavior(parser->m_context.mode()))
1224 parser->tokenToLowerCase($1);
1225 $$->setValue($1);
1226 }
1227 }
1228 | class
1229 | attrib
1230 | pseudo
1231 ;
1232
1233 class:
1234 '.' IDENT {
1235 $$ = parser->createFloatingSelector();
1236 $$->setMatch(CSSSelector::Class);
1237 if (isQuirksModeBehavior(parser->m_context.mode()))
1238 parser->tokenToLowerCase($2);
1239 $$->setValue($2);
1240 }
1241 ;
1242
1243 attr_name:
1244 IDENT maybe_space {
1245 if (parser->m_context.isHTMLDocument())
1246 parser->tokenToLowerCase($1);
1247 $$ = $1;
1248 }
1249 ;
1250
1251 attr_match_type:
1252 IDENT maybe_space {
1253 CSSSelector::AttributeMatchType attrMatchType = CSSSelector::CaseSensitive;
1254 if (!parser->parseAttributeMatchType(attrMatchType, $1))
1255 YYERROR;
1256 $$ = attrMatchType;
1257 }
1258 ;
1259
1260 maybe_attr_match_type:
1261 attr_match_type
1262 | /* empty */ { $$ = CSSSelector::CaseSensitive; }
1263 ;
1264
1265 attrib:
1266 '[' maybe_space attr_name closing_square_bracket {
1267 $$ = parser->createFloatingSelector();
1268 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), CSSSelector::CaseSensitive);
1269 $$->setMatch(CSSSelector::Set);
1270 }
1271 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1272 $$ = parser->createFloatingSelector();
1273 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), $8);
1274 $$->setMatch((CSSSelector::Match)$4);
1275 $$->setValue($6);
1276 }
1277 | '[' maybe_space namespace_selector attr_name closing_square_bracket {
1278 $$ = parser->createFloatingSelector();
1279 $$->setAttribute(parser->determineNameInNamespace($3, $4), CSSSelector::CaseSensitive);
1280 $$->setMatch(CSSSelector::Set);
1281 }
1282 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1283 $$ = parser->createFloatingSelector();
1284 $$->setAttribute(parser->determineNameInNamespace($3, $4), $9);
1285 $$->setMatch((CSSSelector::Match)$5);
1286 $$->setValue($7);
1287 }
1288 | '[' selector_recovery closing_square_bracket {
1289 YYERROR;
1290 }
1291 ;
1292
1293 match:
1294 '=' {
1295 $$ = CSSSelector::Exact;
1296 }
1297 | INCLUDES {
1298 $$ = CSSSelector::List;
1299 }
1300 | DASHMATCH {
1301 $$ = CSSSelector::Hyphen;
1302 }
1303 | BEGINSWITH {
1304 $$ = CSSSelector::Begin;
1305 }
1306 | ENDSWITH {
1307 $$ = CSSSelector::End;
1308 }
1309 | CONTAINS {
1310 $$ = CSSSelector::Contain;
1311 }
1312 ;
1313
1314 ident_or_string:
1315 IDENT
1316 | STRING
1317 ;
1318
1319 pseudo_page:
1320 ':' IDENT {
1321 if ($2.isFunction())
1322 YYERROR;
1323 $$ = parser->createFloatingSelector();
1324 $$->setMatch(CSSSelector::PagePseudoClass);
1325 parser->tokenToLowerCase($2);
1326 $$->setValue($2);
1327 CSSSelector::PseudoType type = $$->pseudoType();
1328 if (type == CSSSelector::PseudoUnknown)
1329 YYERROR;
1330 }
1331
1332 pseudo:
1333 ':' error_location IDENT {
1334 if ($3.isFunction())
1335 YYERROR;
1336 $$ = parser->createFloatingSelector();
1337 $$->setMatch(CSSSelector::PseudoClass);
1338 parser->tokenToLowerCase($3);
1339 $$->setValue($3);
1340 CSSSelector::PseudoType type = $$->pseudoType();
1341 if (type == CSSSelector::PseudoUnknown) {
1342 parser->reportError($2, InvalidSelectorPseudoCSSError);
1343 YYERROR;
1344 }
1345 }
1346 | ':' ':' error_location IDENT {
1347 if ($4.isFunction())
1348 YYERROR;
1349 $$ = parser->createFloatingSelector();
1350 $$->setMatch(CSSSelector::PseudoElement);
1351 parser->tokenToLowerCase($4);
1352 $$->setValue($4);
1353 // FIXME: This call is needed to force selector to compute the pseudoType early enough.
1354 CSSSelector::PseudoType type = $$->pseudoType();
1355 if (type == CSSSelector::PseudoUnknown) {
1356 parser->reportError($3, InvalidSelectorPseudoCSSError);
1357 YYERROR;
1358 }
1359 }
1360 // used by ::cue(:past/:future)
1361 | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1362 $$ = parser->createFloatingSelector();
1363 $$->setMatch(CSSSelector::PseudoElement);
1364 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
1365 $$->setValue($3);
1366 CSSSelector::PseudoType type = $$->pseudoType();
1367 if (type != CSSSelector::PseudoCue)
1368 YYERROR;
1369 }
1370 | ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
1371 YYERROR;
1372 }
1373 // use by :-webkit-any.
1374 // FIXME: should we support generic selectors here or just simple_selectors?
1375 // Use simple_selector_list for now to match -moz-any.
1376 // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
1377 // related discussion with respect to :not.
1378 | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1379 $$ = parser->createFloatingSelector();
1380 $$->setMatch(CSSSelector::PseudoClass);
1381 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1382 parser->tokenToLowerCase($2);
1383 $$->setValue($2);
1384 CSSSelector::PseudoType type = $$->pseudoType();
1385 if (type != CSSSelector::PseudoAny)
1386 YYERROR;
1387 }
1388 | ':' ANYFUNCTION selector_recovery closing_parenthesis {
1389 YYERROR;
1390 }
1391 // used by :nth-*(ax+b)
1392 | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
1393 $$ = parser->createFloatingSelector();
1394 $$->setMatch(CSSSelector::PseudoClass);
1395 $$->setArgument($4);
1396 $$->setValue($2);
1397 CSSSelector::PseudoType type = $$->pseudoType();
1398 if (type == CSSSelector::PseudoUnknown)
1399 YYERROR;
1400 }
1401 // used by :nth-*
1402 | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
1403 $$ = parser->createFloatingSelector();
1404 $$->setMatch(CSSSelector::PseudoClass);
1405 $$->setArgument(AtomicString::number($4 * $5));
1406 $$->setValue($2);
1407 CSSSelector::PseudoType type = $$->pseudoType();
1408 if (type == CSSSelector::PseudoUnknown)
1409 YYERROR;
1410 }
1411 // used by :nth-*(odd/even) and :lang
1412 | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
1413 $$ = parser->createFloatingSelector();
1414 $$->setMatch(CSSSelector::PseudoClass);
1415 $$->setArgument($4);
1416 parser->tokenToLowerCase($2);
1417 $$->setValue($2);
1418 CSSSelector::PseudoType type = $$->pseudoType();
1419 if (type == CSSSelector::PseudoUnknown)
1420 YYERROR;
1421 else if (type == CSSSelector::PseudoNthChild ||
1422 type == CSSSelector::PseudoNthOfType ||
1423 type == CSSSelector::PseudoNthLastChild ||
1424 type == CSSSelector::PseudoNthLastOfType) {
1425 if (!isValidNthToken($4))
1426 YYERROR;
1427 }
1428 }
1429 | ':' FUNCTION selector_recovery closing_parenthesis {
1430 YYERROR;
1431 }
1432 // used by :not
1433 | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
1434 if (!$4->isSimple())
1435 YYERROR;
1436 else {
1437 $$ = parser->createFloatingSelector();
1438 $$->setMatch(CSSSelector::PseudoClass);
1439
1440 Vector<OwnPtr<CSSParserSelector> > selectorVector;
1441 selectorVector.append(parser->sinkFloatingSelector($4));
1442 $$->adoptSelectorVector(selectorVector);
1443
1444 parser->tokenToLowerCase($2);
1445 $$->setValue($2);
1446 }
1447 }
1448 | ':' NOTFUNCTION selector_recovery closing_parenthesis {
1449 YYERROR;
1450 }
1451 | ':' HOSTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1452 $$ = parser->createFloatingSelector();
1453 $$->setMatch(CSSSelector::PseudoClass);
1454 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1455 parser->tokenToLowerCase($2);
1456 $$->setValue($2);
1457 CSSSelector::PseudoType type = $$->pseudoType();
1458 if (type != CSSSelector::PseudoHost)
1459 YYERROR;
1460 }
1461 | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
1462 YYERROR;
1463 }
1464 // used by :host-context()
1465 | ':' HOSTCONTEXTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1466 $$ = parser->createFloatingSelector();
1467 $$->setMatch(CSSSelector::PseudoClass);
1468 $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1469 parser->tokenToLowerCase($2);
1470 $$->setValue($2);
1471 CSSSelector::PseudoType type = $$->pseudoType();
1472 if (type != CSSSelector::PseudoHostContext)
1473 YYERROR;
1474 }
1475 | ':' HOSTCONTEXTFUNCTION selector_recovery closing_parenthesis {
1476 YYERROR;
1477 }
1478 ;
1479
1480 selector_recovery:
1481 error error_location error_recovery;
1482
1483 declaration_list:
1484 /* empty */ { $$ = false; }
1485 | declaration
1486 | decl_list declaration {
1487 $$ = $1 || $2;
1488 }
1489 | decl_list
1490 ;
1491
1492 decl_list:
1493 declaration ';' maybe_space {
1494 parser->startProperty();
1495 $$ = $1;
1496 }
1497 | decl_list declaration ';' maybe_space {
1498 parser->startProperty();
1499 $$ = $1 || $2;
1500 }
1501 ;
1502
1503 declaration:
1504 property ':' maybe_space error_location expr prio {
1505 $$ = false;
1506 bool isPropertyParsed = false;
1507 if ($1 != CSSPropertyInvalid) {
1508 parser->m_valueList = parser->sinkFloatingValueList($5);
1509 int oldParsedProperties = parser->m_parsedProperties.size();
1510 $$ = parser->parseValue($1, $6);
1511 if (!$$) {
1512 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
1513 parser->reportError($4, InvalidPropertyValueCSSError);
1514 } else
1515 isPropertyParsed = true;
1516 parser->m_valueList = nullptr;
1517 }
1518 parser->endProperty($6, isPropertyParsed);
1519 }
1520 |
1521 property ':' maybe_space error_location expr prio error error_recovery {
1522 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1523 parser->reportError($4, InvalidPropertyValueCSSError);
1524 parser->endProperty(false, false);
1525 $$ = false;
1526 }
1527 |
1528 property ':' maybe_space error_location error error_recovery {
1529 parser->reportError($4, InvalidPropertyValueCSSError);
1530 parser->endProperty(false, false);
1531 $$ = false;
1532 }
1533 |
1534 property error error_location error_recovery {
1535 parser->reportError($3, PropertyDeclarationCSSError);
1536 parser->endProperty(false, false, GeneralCSSError);
1537 $$ = false;
1538 }
1539 |
1540 error error_location error_recovery {
1541 parser->reportError($2, PropertyDeclarationCSSError);
1542 $$ = false;
1543 }
1544 ;
1545
1546 property:
1547 error_location IDENT maybe_space {
1548 $$ = cssPropertyID($2);
1549 parser->setCurrentProperty($$);
1550 if ($$ == CSSPropertyInvalid)
1551 parser->reportError($1, InvalidPropertyCSSError);
1552 }
1553 ;
1554
1555 prio:
1556 IMPORTANT_SYM maybe_space { $$ = true; }
1557 | /* empty */ { $$ = false; }
1558 ;
1559
1560 ident_list:
1561 IDENT maybe_space {
1562 $$ = parser->createFloatingValueList();
1563 $$->addValue(makeIdentValue($1));
1564 }
1565 | ident_list IDENT maybe_space {
1566 $$ = $1;
1567 $$->addValue(makeIdentValue($2));
1568 }
1569 ;
1570
1571 track_names_list:
1572 '(' maybe_space closing_parenthesis {
1573 $$.setFromValueList(parser->sinkFloatingValueList(parser->createFloatingValueList()));
1574 }
1575 | '(' maybe_space ident_list closing_parenthesis {
1576 $$.setFromValueList(parser->sinkFloatingValueList($3));
1577 }
1578 | '(' maybe_space expr_recovery closing_parenthesis {
1579 YYERROR;
1580 }
1581 ;
1582
1583 expr:
1584 term {
1585 $$ = parser->createFloatingValueList();
1586 $$->addValue(parser->sinkFloatingValue($1));
1587 }
1588 | expr operator term {
1589 $$ = $1;
1590 $$->addValue(makeOperatorValue($2));
1591 $$->addValue(parser->sinkFloatingValue($3));
1592 }
1593 | expr term {
1594 $$ = $1;
1595 $$->addValue(parser->sinkFloatingValue($2));
1596 }
1597 ;
1598
1599 expr_recovery:
1600 error error_location error_recovery {
1601 parser->reportError($2, PropertyDeclarationCSSError);
1602 }
1603 ;
1604
1605 operator:
1606 '/' maybe_space {
1607 $$ = '/';
1608 }
1609 | ',' maybe_space {
1610 $$ = ',';
1611 }
1612 ;
1613
1614 term:
1615 unary_term maybe_space
1616 | unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
1617 | STRING maybe_space { $$.id = CSSValueInvalid; $$.isInt = false; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1618 | IDENT maybe_space { $$ = makeIdentValue($1); }
1619 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1620 | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1621 | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1622 | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_URI; }
1623 | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1624 | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1625 | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1626 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1627 | function maybe_space
1628 | calc_function maybe_space
1629 | '%' maybe_space { /* Handle width: %; */
1630 $$.id = CSSValueInvalid; $$.isInt = false; $$.unit = 0;
1631 }
1632 | track_names_list maybe_space
1633 ;
1634
1635 unary_term:
1636 INTEGER { $$.setFromNumber($1); $$.isInt = true; }
1637 | FLOATTOKEN { $$.setFromNumber($1); }
1638 | PERCENTAGE { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PERCENTAGE); }
1639 | PXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PX); }
1640 | CMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CM); }
1641 | MMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MM); }
1642 | INS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_IN); }
1643 | PTS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PT); }
1644 | PCS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PC); }
1645 | DEGS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DEG); }
1646 | RADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_RAD); }
1647 | GRADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_GRAD); }
1648 | TURNS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_TURN); }
1649 | MSECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MS); }
1650 | SECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_S); }
1651 | HERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_HZ); }
1652 | KHERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_KHZ); }
1653 | EMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EMS); }
1654 | QEMS { $$.setFromNumber($1, CSSParserValue::Q_EMS); }
1655 | EXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EXS); }
1656 | REMS {
1657 $$.setFromNumber($1, CSSPrimitiveValue::CSS_REMS);
1658 if (parser->m_styleSheet)
1659 parser->m_styleSheet->parserSetUsesRemUnits(true);
1660 }
1661 | CHS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CHS); }
1662 | VW { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VW); }
1663 | VH { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VH); }
1664 | VMIN { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMIN); }
1665 | VMAX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMAX); }
1666 | DPPX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPPX); }
1667 | DPI { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPI); }
1668 | DPCM { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPCM); }
1669 | FR { $$.setFromNumber($1, CSSPrimitiveValue::CSS_FR); }
1670 ;
1671
1672 function:
1673 FUNCTION maybe_space expr closing_parenthesis {
1674 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1675 } |
1676 FUNCTION maybe_space closing_parenthesis {
1677 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList(parser->createFloatingValueList())));
1678 } |
1679 FUNCTION maybe_space expr_recovery closing_parenthesis {
1680 YYERROR;
1681 }
1682 ;
1683
1684 calc_func_term:
1685 unary_term
1686 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1687 ;
1688
1689 calc_func_operator:
1690 space '+' space {
1691 $$ = '+';
1692 }
1693 | space '-' space {
1694 $$ = '-';
1695 }
1696 | calc_maybe_space '*' maybe_space {
1697 $$ = '*';
1698 }
1699 | calc_maybe_space '/' maybe_space {
1700 $$ = '/';
1701 }
1702 ;
1703
1704 calc_maybe_space:
1705 /* empty */
1706 | WHITESPACE
1707 ;
1708
1709 calc_func_paren_expr:
1710 '(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1711 $$ = $3;
1712 $$->insertValueAt(0, makeOperatorValue('('));
1713 $$->addValue(makeOperatorValue(')'));
1714 }
1715 | '(' maybe_space expr_recovery closing_parenthesis {
1716 YYERROR;
1717 }
1718 ;
1719
1720 calc_func_expr:
1721 calc_func_term {
1722 $$ = parser->createFloatingValueList();
1723 $$->addValue(parser->sinkFloatingValue($1));
1724 }
1725 | calc_func_expr calc_func_operator calc_func_term {
1726 $$ = $1;
1727 $$->addValue(makeOperatorValue($2));
1728 $$->addValue(parser->sinkFloatingValue($3));
1729 }
1730 | calc_func_expr calc_func_operator calc_func_paren_expr {
1731 $$ = $1;
1732 $$->addValue(makeOperatorValue($2));
1733 $$->stealValues(*($3));
1734 }
1735 | calc_func_paren_expr
1736 ;
1737
1738 calc_function:
1739 CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1740 $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1741 }
1742 | CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
1743 YYERROR;
1744 }
1745 ;
1746
1747
1748 invalid_at:
1749 ATKEYWORD
1750 | margin_sym
1751 ;
1752
1753 at_rule_recovery:
1754 at_rule_header_recovery at_invalid_rule_header_end at_rule_end
1755 ;
1756
1757 at_rule_header_recovery:
1758 error error_location rule_error_recovery {
1759 parser->reportError($2, InvalidRuleCSSError);
1760 }
1761 ;
1762
1763 at_rule_end:
1764 at_invalid_rule_header_end semi_or_eof
1765 | at_invalid_rule_header_end invalid_block
1766 ;
1767
1768 regular_invalid_at_rule_header:
1769 keyframes_rule_start at_rule_header_recovery
1770 | before_page_rule PAGE_SYM at_rule_header_recovery
1771 | before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
1772 | before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
1773 parser->reportError($4, InvalidSupportsConditionCSSError);
1774 parser->popSupportsRuleData();
1775 }
1776 | before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
1777 parser->markViewportRuleBodyEnd();
1778 }
1779 | import_rule_start at_rule_header_recovery
1780 | NAMESPACE_SYM at_rule_header_recovery
1781 | error_location invalid_at at_rule_header_recovery {
1782 parser->resumeErrorLogging();
1783 parser->reportError($1, InvalidRuleCSSError);
1784 }
1785 ;
1786
1787 invalid_rule:
1788 error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
1789 parser->reportError($2, InvalidRuleCSSError);
1790 }
1791 | regular_invalid_at_rule_header at_invalid_rule_header_end ';'
1792 | regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
1793 | media_rule_start maybe_media_list ';'
1794 ;
1795
1796 invalid_rule_header:
1797 error error_location rule_error_recovery at_invalid_rule_header_end {
1798 parser->reportError($2, InvalidRuleCSSError);
1799 }
1800 | regular_invalid_at_rule_header at_invalid_rule_header_end
1801 | media_rule_start maybe_media_list
1802 ;
1803
1804 at_invalid_rule_header_end:
1805 /* empty */ {
1806 parser->endInvalidRuleHeader();
1807 }
1808 ;
1809
1810 invalid_block:
1811 '{' error_recovery closing_brace {
1812 parser->invalidBlockHit();
1813 }
1814 ;
1815
1816 invalid_square_brackets_block:
1817 '[' error_recovery closing_square_bracket
1818 ;
1819
1820 invalid_parentheses_block:
1821 opening_parenthesis error_recovery closing_parenthesis;
1822
1823 opening_parenthesis:
1824 '(' | FUNCTION | CALCFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
1825 ;
1826
1827 error_location: {
1828 $$ = parser->currentLocation();
1829 }
1830 ;
1831
1832 location_label: {
1833 parser->setLocationLabel(parser->currentLocation());
1834 }
1835 ;
1836
1837 error_recovery:
1838 /* empty */
1839 | error_recovery error
1840 | error_recovery invalid_block
1841 | error_recovery invalid_square_brackets_block
1842 | error_recovery invalid_parentheses_block
1843 ;
1844
1845 rule_error_recovery:
1846 /* empty */
1847 | rule_error_recovery error
1848 | rule_error_recovery invalid_square_brackets_block
1849 | rule_error_recovery invalid_parentheses_block
1850 ;
1851
1852 %%
1853