4 * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "CSSMediaRule.h"
28 #include "CSSParser.h"
29 #include "CSSPropertyNames.h"
30 #include "CSSRuleList.h"
31 #include "CSSSelector.h"
32 #include "CSSNthSelector.h"
33 #include "CSSStyleSheet.h"
35 #include "HTMLNames.h"
36 #include "MediaList.h"
37 #include "WebKitCSSKeyframeRule.h"
38 #include "WebKitCSSKeyframesRule.h"
42 using namespace WebCore;
43 using namespace HTMLNames;
45 #define YYENABLE_NLS 0
46 #define YYLTYPE_IS_TRIVIAL 1
47 #define YYMAXDEPTH 10000
50 // FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
51 #define YYPARSE_PARAM parser
52 #define YYLEX_PARAM parser
63 CSSParserString string;
66 CSSRuleList* ruleList;
67 CSSSelector* selector;
68 CSSSelector::Relation relation;
70 MediaQuery* mediaQuery;
71 MediaQuery::Restrictor mediaQueryRestrictor;
72 MediaQueryExp* mediaQueryExp;
74 CSSParserValueList* valueList;
75 Vector<MediaQueryExp*>* mediaQueryExpList;
76 WebKitCSSKeyframeRule* keyframeRule;
77 WebKitCSSKeyframesRule* keyframesRule;
83 static inline int cssyyerror(const char*)
88 static int cssyylex(YYSTYPE* yylval, void* parser)
90 return static_cast<CSSParser*>(parser)->lex(yylval);
99 %token WHITESPACE SGML_CD
108 %token <string> STRING
109 %right <string> IDENT
112 %nonassoc <string> HEX
113 %nonassoc <string> IDSEL
117 %nonassoc <string> '*'
127 %token WEBKIT_RULE_SYM
128 %token WEBKIT_DECLS_SYM
129 %token WEBKIT_KEYFRAME_RULE_SYM
130 %token WEBKIT_KEYFRAMES_SYM
131 %token WEBKIT_VALUE_SYM
132 %token WEBKIT_MEDIAQUERY_SYM
133 %token WEBKIT_SELECTOR_SYM
134 %token WEBKIT_VARIABLES_SYM
135 %token WEBKIT_DEFINE_SYM
137 %token WEBKIT_VARIABLES_DECLS_SYM
156 %token <number> GRADS
157 %token <number> MSECS
160 %token <number> KHERZ
161 %token <string> DIMEN
162 %token <number> PERCENTAGE
163 %token <number> FLOATTOKEN
164 %token <number> INTEGER
167 %token <string> FUNCTION
168 %token <string> NOTFUNCTION
170 %token <string> UNICODERANGE
172 %token <string> VARCALL
174 %type <relation> combinator
178 %type <rule> valid_rule_or_import
182 %type <rule> font_face
183 %type <rule> keyframes
184 %type <rule> invalid_rule
185 %type <rule> save_block
186 %type <rule> invalid_at
187 %type <rule> invalid_at_list
188 %type <rule> invalid_import
189 %type <rule> invalid_media
191 %type <rule> valid_rule
192 %type <ruleList> block_rule_list
193 %type <rule> block_rule
194 %type <rule> block_valid_rule
195 %type <rule> variables_rule
196 %type <mediaList> variables_media_list
198 %type <string> maybe_ns_prefix
200 %type <string> namespace_selector
202 %type <string> string_or_uri
203 %type <string> ident_or_string
204 %type <string> medium
205 %type <string> hexcolor
207 %type <string> media_feature
208 %type <mediaList> media_list
209 %type <mediaList> maybe_media_list
210 %type <mediaQuery> media_query
211 %type <mediaQueryRestrictor> maybe_media_restrictor
212 %type <valueList> maybe_media_value
213 %type <mediaQueryExp> media_query_exp
214 %type <mediaQueryExpList> media_query_exp_list
215 %type <mediaQueryExpList> maybe_and_media_query_exp_list
217 %type <string> keyframe_name
218 %type <keyframeRule> keyframe_rule
219 %type <keyframesRule> keyframes_rule
220 %type <valueList> key_list
223 %type <integer> property
225 %type <selector> specifier
226 %type <selector> specifier_list
227 %type <selector> simple_selector
228 %type <selector> selector
229 %type <selector> selector_list
230 %type <selector> selector_with_trailing_whitespace
231 %type <selector> class
232 %type <selector> attrib
233 %type <selector> pseudo
235 %type <boolean> declaration_list
236 %type <boolean> decl_list
237 %type <boolean> declaration
241 %type <integer> match
242 %type <integer> unary_operator
243 %type <character> operator
245 %type <valueList> expr
247 %type <value> unary_term
248 %type <value> function
250 %type <string> element_name
251 %type <string> attr_name
253 %type <string> variable_name
254 %type <boolean> variables_declaration_list
255 %type <boolean> variables_decl_list
256 %type <boolean> variables_declaration
257 %type <value> variable_reference
262 maybe_charset maybe_sgml import_list variables_list namespace_list rule_list
263 | webkit_rule maybe_space
264 | webkit_decls maybe_space
265 | webkit_value maybe_space
266 | webkit_mediaquery maybe_space
267 | webkit_selector maybe_space
268 | webkit_variables_decls maybe_space
269 | webkit_keyframe_rule maybe_space
272 valid_rule_or_import:
278 WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
279 static_cast<CSSParser*>(parser)->m_rule = $4;
283 webkit_keyframe_rule:
284 WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' {
285 static_cast<CSSParser*>(parser)->m_keyframe = $4;
290 WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
295 webkit_variables_decls:
296 WEBKIT_VARIABLES_DECLS_SYM '{' maybe_space variables_declaration_list '}' {
302 WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
303 CSSParser* p = static_cast<CSSParser*>(parser);
305 p->m_valueList = p->sinkFloatingValueList($4);
306 int oldParsedProperties = p->m_numParsedProperties;
307 if (!p->parseValue(p->m_id, p->m_important))
308 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
309 delete p->m_valueList;
316 WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
317 CSSParser* p = static_cast<CSSParser*>(parser);
318 p->m_mediaQuery = p->sinkFloatingMediaQuery($4);
323 WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' {
324 CSSParser* p = static_cast<CSSParser*>(parser);
325 p->m_floatingSelector = p->sinkFloatingSelector($4);
330 /* empty */ %prec UNIMPORTANT_TOK
331 | maybe_space WHITESPACE
337 | maybe_sgml WHITESPACE
348 | %prec maybe_sgml TOKEN_EOF
352 CHARSET_SYM maybe_space STRING maybe_space ';' {
353 CSSParser* p = static_cast<CSSParser*>(parser);
354 $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
355 if ($$ && p->m_styleSheet)
356 p->m_styleSheet->append($$);
358 | CHARSET_SYM error invalid_block {
360 | CHARSET_SYM error ';' {
366 | import_list import maybe_sgml {
367 CSSParser* p = static_cast<CSSParser*>(parser);
368 if ($2 && p->m_styleSheet)
369 p->m_styleSheet->append($2);
377 | variables_list variables_rule maybe_sgml {
378 CSSParser* p = static_cast<CSSParser*>(parser);
379 if ($2 && p->m_styleSheet)
380 p->m_styleSheet->append($2);
386 | namespace_list namespace maybe_sgml
391 | rule_list rule maybe_sgml {
392 CSSParser* p = static_cast<CSSParser*>(parser);
393 if ($2 && p->m_styleSheet)
394 p->m_styleSheet->append($2);
414 /* empty */ { $$ = 0; }
415 | block_rule_list block_rule maybe_sgml {
419 $$ = static_cast<CSSParser*>(parser)->createRuleList();
442 IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
443 $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
445 | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list invalid_block {
448 | IMPORT_SYM error ';' {
451 | IMPORT_SYM error invalid_block {
457 WEBKIT_VARIABLES_SYM maybe_space maybe_media_list '{' maybe_space variables_declaration_list '}' {
458 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, true);
461 WEBKIT_DEFINE_SYM maybe_space variables_media_list '{' maybe_space variables_declaration_list '}' {
462 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, false);
466 variables_media_list:
468 $$ = static_cast<CSSParser*>(parser)->createMediaList();
471 VARIABLES_FOR WHITESPACE media_list {
476 variables_declaration_list:
477 variables_declaration {
480 | variables_decl_list variables_declaration {
485 | variables_decl_list {
488 | error invalid_block_list error {
494 | variables_decl_list error {
500 variables_declaration ';' maybe_space {
503 | variables_declaration invalid_block_list ';' maybe_space {
506 | error ';' maybe_space {
509 | error invalid_block_list error ';' maybe_space {
512 | variables_decl_list variables_declaration ';' maybe_space {
517 | variables_decl_list error ';' maybe_space {
520 | variables_decl_list error invalid_block_list error ';' maybe_space {
525 variables_declaration:
526 variable_name ':' maybe_space expr {
527 $$ = static_cast<CSSParser*>(parser)->addVariable($1, $4);
530 variable_name maybe_space '{' maybe_space declaration_list '}' maybe_space {
531 $$ = static_cast<CSSParser*>(parser)->addVariableDeclarationBlock($1);
534 variable_name error {
538 variable_name ':' maybe_space error expr {
542 variable_name ':' maybe_space {
543 /* @variables { varname: } Just reduce away this variable with no value. */
547 variable_name ':' maybe_space error {
548 /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */
560 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
561 CSSParser* p = static_cast<CSSParser*>(parser);
563 p->m_styleSheet->addNamespace(p, $3, $4);
565 | NAMESPACE_SYM error invalid_block
566 | NAMESPACE_SYM error ';'
570 /* empty */ { $$.characters = 0; }
571 | IDENT WHITESPACE { $$ = $1; }
589 | ':' maybe_space expr maybe_space {
595 '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
597 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5);
601 media_query_exp_list:
603 CSSParser* p = static_cast<CSSParser*>(parser);
604 $$ = p->createFloatingMediaQueryExpList();
605 $$->append(p->sinkFloatingMediaQueryExp($1));
607 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
609 $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
613 maybe_and_media_query_exp_list:
615 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
617 | MEDIA_AND maybe_space media_query_exp_list {
622 maybe_media_restrictor:
624 $$ = MediaQuery::None;
627 $$ = MediaQuery::Only;
630 $$ = MediaQuery::Not;
635 media_query_exp_list {
636 CSSParser* p = static_cast<CSSParser*>(parser);
637 $$ = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList($1));
640 maybe_media_restrictor maybe_space medium maybe_and_media_query_exp_list {
641 CSSParser* p = static_cast<CSSParser*>(parser);
643 $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
649 $$ = static_cast<CSSParser*>(parser)->createMediaList();
656 CSSParser* p = static_cast<CSSParser*>(parser);
657 $$ = p->createMediaList();
658 $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
660 | media_list ',' maybe_space media_query {
663 $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
671 MEDIA_SYM maybe_space media_list '{' maybe_space block_rule_list save_block {
672 $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
674 | MEDIA_SYM maybe_space '{' maybe_space block_rule_list save_block {
675 $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
686 WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name maybe_space '{' maybe_space keyframes_rule '}' {
688 $7->setNameInternal($3);
698 /* empty */ { $$ = static_cast<CSSParser*>(parser)->createKeyframesRule(); }
699 | keyframes_rule keyframe_rule maybe_space {
707 key_list maybe_space '{' maybe_space declaration_list '}' {
708 $$ = static_cast<CSSParser*>(parser)->createKeyframeRule($1);
714 CSSParser* p = static_cast<CSSParser*>(parser);
715 $$ = p->createFloatingValueList();
716 $$->addValue(p->sinkFloatingValue($1));
718 | key_list maybe_space ',' maybe_space key {
719 CSSParser* p = static_cast<CSSParser*>(parser);
722 $$->addValue(p->sinkFloatingValue($5));
727 PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
729 $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
730 CSSParserString& str = $1;
731 if (equalIgnoringCase(static_cast<const String&>(str), "from"))
733 else if (equalIgnoringCase(static_cast<const String&>(str), "to"))
742 PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
743 '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
752 PAGE_SYM error invalid_block {
755 | PAGE_SYM error ';' {
761 FONT_FACE_SYM maybe_space
762 '{' maybe_space declaration_list '}' maybe_space {
763 $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
765 | FONT_FACE_SYM error invalid_block {
768 | FONT_FACE_SYM error ';' {
774 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
775 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
776 | '>' maybe_space { $$ = CSSSelector::Child; }
785 selector_list '{' maybe_space declaration_list closing_brace {
786 $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
791 selector %prec UNIMPORTANT_TOK {
794 | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
796 CSSParser* p = static_cast<CSSParser*>(parser);
798 $$->append(p->sinkFloatingSelector($4));
802 | selector_list error {
807 selector_with_trailing_whitespace:
808 selector WHITESPACE {
817 | selector_with_trailing_whitespace
821 | selector_with_trailing_whitespace simple_selector
827 CSSParser* p = static_cast<CSSParser*>(parser);
828 CSSSelector* end = $$;
829 while (end->m_tagHistory)
830 end = end->m_tagHistory;
831 end->m_relation = CSSSelector::Descendant;
832 end->m_tagHistory = p->sinkFloatingSelector($1);
833 if (Document* doc = p->document())
834 doc->setUsesDescendantRules(true);
837 | selector combinator simple_selector {
842 CSSParser* p = static_cast<CSSParser*>(parser);
843 CSSSelector* end = $$;
844 while (end->m_tagHistory)
845 end = end->m_tagHistory;
846 end->m_relation = $2;
847 end->m_tagHistory = p->sinkFloatingSelector($1);
848 if ($2 == CSSSelector::Child) {
849 if (Document* doc = p->document())
850 doc->setUsesDescendantRules(true);
851 } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
852 if (Document* doc = p->document())
853 doc->setUsesSiblingRules(true);
863 /* empty */ '|' { $$.characters = 0; $$.length = 0; }
864 | '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
865 | IDENT '|' { $$ = $1; }
870 CSSParser* p = static_cast<CSSParser*>(parser);
871 $$ = p->createFloatingSelector();
872 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
874 | element_name specifier_list {
877 CSSParser* p = static_cast<CSSParser*>(parser);
878 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
883 CSSParser* p = static_cast<CSSParser*>(parser);
884 if ($$ && p->m_defaultNamespace != starAtom)
885 $$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace);
887 | namespace_selector element_name {
888 AtomicString namespacePrefix = $1;
889 CSSParser* p = static_cast<CSSParser*>(parser);
890 $$ = p->createFloatingSelector();
892 $$->m_tag = QualifiedName(namespacePrefix, $2,
893 p->m_styleSheet->determineNamespace(namespacePrefix));
894 else // FIXME: Shouldn't this case be an error?
895 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
897 | namespace_selector element_name specifier_list {
900 AtomicString namespacePrefix = $1;
901 CSSParser* p = static_cast<CSSParser*>(parser);
903 $$->m_tag = QualifiedName(namespacePrefix, $2,
904 p->m_styleSheet->determineNamespace(namespacePrefix));
905 else // FIXME: Shouldn't this case be an error?
906 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
909 | namespace_selector specifier_list {
912 AtomicString namespacePrefix = $1;
913 CSSParser* p = static_cast<CSSParser*>(parser);
915 $$->m_tag = QualifiedName(namespacePrefix, starAtom,
916 p->m_styleSheet->determineNamespace(namespacePrefix));
923 CSSParserString& str = $1;
924 CSSParser* p = static_cast<CSSParser*>(parser);
925 Document* doc = p->document();
926 if (doc && doc->isHTMLDocument())
931 static UChar star = '*';
932 $$.characters = ☆
941 | specifier_list specifier {
946 CSSParser* p = static_cast<CSSParser*>(parser);
947 CSSSelector* end = $1;
948 while (end->m_tagHistory)
949 end = end->m_tagHistory;
950 end->m_relation = CSSSelector::SubSelector;
951 end->m_tagHistory = p->sinkFloatingSelector($2);
954 | specifier_list error {
961 CSSParser* p = static_cast<CSSParser*>(parser);
962 $$ = p->createFloatingSelector();
963 $$->m_match = CSSSelector::Id;
970 if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
973 CSSParser* p = static_cast<CSSParser*>(parser);
974 $$ = p->createFloatingSelector();
975 $$->m_match = CSSSelector::Id;
989 CSSParser* p = static_cast<CSSParser*>(parser);
990 $$ = p->createFloatingSelector();
991 $$->m_match = CSSSelector::Class;
994 $$->m_attr = classAttr;
1001 CSSParserString& str = $1;
1002 CSSParser* p = static_cast<CSSParser*>(parser);
1003 Document* doc = p->document();
1004 if (doc && doc->isHTMLDocument())
1011 '[' maybe_space attr_name ']' {
1012 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1013 $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
1014 $$->m_match = CSSSelector::Set;
1016 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
1017 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1018 $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
1019 $$->m_match = (CSSSelector::Match)$4;
1022 | '[' maybe_space namespace_selector attr_name ']' {
1023 AtomicString namespacePrefix = $3;
1024 CSSParser* p = static_cast<CSSParser*>(parser);
1025 $$ = p->createFloatingSelector();
1026 $$->m_attr = QualifiedName(namespacePrefix, $4,
1027 p->m_styleSheet->determineNamespace(namespacePrefix));
1028 $$->m_match = CSSSelector::Set;
1030 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
1031 AtomicString namespacePrefix = $3;
1032 CSSParser* p = static_cast<CSSParser*>(parser);
1033 $$ = p->createFloatingSelector();
1034 $$->m_attr = QualifiedName(namespacePrefix, $4,
1035 p->m_styleSheet->determineNamespace(namespacePrefix));
1036 $$->m_match = (CSSSelector::Match)$5;
1043 $$ = CSSSelector::Exact;
1046 $$ = CSSSelector::List;
1049 $$ = CSSSelector::Hyphen;
1052 $$ = CSSSelector::Begin;
1055 $$ = CSSSelector::End;
1058 $$ = CSSSelector::Contain;
1069 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1070 $$->m_match = CSSSelector::PseudoClass;
1073 CSSSelector::PseudoType type = $$->pseudoType();
1074 if (type == CSSSelector::PseudoUnknown)
1076 else if (type == CSSSelector::PseudoEmpty ||
1077 type == CSSSelector::PseudoFirstChild ||
1078 type == CSSSelector::PseudoFirstOfType ||
1079 type == CSSSelector::PseudoLastChild ||
1080 type == CSSSelector::PseudoLastOfType ||
1081 type == CSSSelector::PseudoOnlyChild ||
1082 type == CSSSelector::PseudoOnlyOfType) {
1083 CSSParser* p = static_cast<CSSParser*>(parser);
1084 Document* doc = p->document();
1086 doc->setUsesSiblingRules(true);
1087 } else if (type == CSSSelector::PseudoFirstLine) {
1088 CSSParser* p = static_cast<CSSParser*>(parser);
1089 if (Document* doc = p->document())
1090 doc->setUsesFirstLineRules(true);
1094 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1095 $$->m_match = CSSSelector::PseudoElement;
1098 CSSSelector::PseudoType type = $$->pseudoType();
1099 if (type == CSSSelector::PseudoUnknown)
1101 else if (type == CSSSelector::PseudoFirstLine) {
1102 CSSParser* p = static_cast<CSSParser*>(parser);
1103 if (Document* doc = p->document())
1104 doc->setUsesFirstLineRules(true);
1107 // used by :nth-*(ax+b)
1108 | ':' FUNCTION NTH ')' {
1109 CSSParser *p = static_cast<CSSParser*>(parser);
1110 $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
1111 $$->m_match = CSSSelector::PseudoClass;
1112 $$->m_argument = $3;
1114 CSSSelector::PseudoType type = $$->pseudoType();
1115 if (type == CSSSelector::PseudoUnknown)
1117 else if (type == CSSSelector::PseudoNthChild ||
1118 type == CSSSelector::PseudoNthOfType ||
1119 type == CSSSelector::PseudoNthLastChild ||
1120 type == CSSSelector::PseudoNthLastOfType) {
1122 p->document()->setUsesSiblingRules(true);
1126 | ':' FUNCTION INTEGER ')' {
1127 CSSParser *p = static_cast<CSSParser*>(parser);
1128 $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
1129 $$->m_match = CSSSelector::PseudoClass;
1130 $$->m_argument = String::number($3);
1132 CSSSelector::PseudoType type = $$->pseudoType();
1133 if (type == CSSSelector::PseudoUnknown)
1135 else if (type == CSSSelector::PseudoNthChild ||
1136 type == CSSSelector::PseudoNthOfType ||
1137 type == CSSSelector::PseudoNthLastChild ||
1138 type == CSSSelector::PseudoNthLastOfType) {
1140 p->document()->setUsesSiblingRules(true);
1143 // used by :nth-*(odd/even) and :lang
1144 | ':' FUNCTION IDENT ')' {
1145 CSSParser *p = static_cast<CSSParser*>(parser);
1146 $$ = static_cast<CSSSelector*>(p->createFloatingNthSelector());
1147 $$->m_match = CSSSelector::PseudoClass;
1148 $$->m_argument = $3;
1151 CSSSelector::PseudoType type = $$->pseudoType();
1152 if (type == CSSSelector::PseudoUnknown)
1154 else if (type == CSSSelector::PseudoNthChild ||
1155 type == CSSSelector::PseudoNthOfType ||
1156 type == CSSSelector::PseudoNthLastChild ||
1157 type == CSSSelector::PseudoNthLastOfType) {
1159 p->document()->setUsesSiblingRules(true);
1163 | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
1167 CSSParser* p = static_cast<CSSParser*>(parser);
1168 $$ = p->createFloatingSelector();
1169 $$->m_match = CSSSelector::PseudoClass;
1170 $$->m_simpleSelector = p->sinkFloatingSelector($4);
1181 | decl_list declaration {
1189 | error invalid_block_list error {
1198 | decl_list invalid_block_list {
1204 declaration ';' maybe_space {
1207 | declaration invalid_block_list ';' maybe_space {
1210 | error ';' maybe_space {
1213 | error invalid_block_list error ';' maybe_space {
1216 | decl_list declaration ';' maybe_space {
1221 | decl_list error ';' maybe_space {
1224 | decl_list error invalid_block_list error ';' maybe_space {
1230 property ':' maybe_space expr prio {
1232 CSSParser* p = static_cast<CSSParser*>(parser);
1234 p->m_valueList = p->sinkFloatingValueList($4);
1235 int oldParsedProperties = p->m_numParsedProperties;
1236 $$ = p->parseValue($1, $5);
1238 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1239 delete p->m_valueList;
1244 variable_reference maybe_space {
1245 CSSParser* p = static_cast<CSSParser*>(parser);
1246 p->m_valueList = new CSSParserValueList;
1247 p->m_valueList->addValue(p->sinkFloatingValue($1));
1248 int oldParsedProperties = p->m_numParsedProperties;
1249 $$ = p->parseValue(CSSPropertyWebkitVariableDeclarationBlock, false);
1251 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1252 delete p->m_valueList;
1260 property ':' maybe_space error expr prio {
1261 /* The default movable type template has letter-spacing: .none; Handle this by looking for
1262 error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
1263 up and deleting the shifted expr. */
1267 property ':' maybe_space expr prio error {
1268 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1272 IMPORTANT_SYM maybe_space {
1273 /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
1277 property ':' maybe_space {
1278 /* div { font-family: } Just reduce away this property with no value. */
1282 property ':' maybe_space error {
1283 /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
1287 property invalid_block {
1288 /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */
1295 $$ = cssPropertyID($1);
1300 IMPORTANT_SYM maybe_space { $$ = true; }
1301 | /* empty */ { $$ = false; }
1306 CSSParser* p = static_cast<CSSParser*>(parser);
1307 $$ = p->createFloatingValueList();
1308 $$->addValue(p->sinkFloatingValue($1));
1310 | expr operator term {
1311 CSSParser* p = static_cast<CSSParser*>(parser);
1317 v.unit = CSSParserValue::Operator;
1321 $$->addValue(p->sinkFloatingValue($3));
1342 unary_term { $$ = $1; }
1343 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1344 | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1345 | IDENT maybe_space {
1346 $$.id = cssValueKeywordID($1);
1347 $$.unit = CSSPrimitiveValue::CSS_IDENT;
1350 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1351 | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1352 | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1353 | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1354 | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
1355 | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1356 | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1357 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1361 | variable_reference maybe_space {
1364 | '%' maybe_space { $$.id = 0; $$.fValue = 0; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; } /* Handle width: %; ANDROID: Fix an uninitialized Value object causing the device to crash */
1368 INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1369 | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1370 | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1371 | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1372 | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
1373 | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
1374 | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
1375 | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
1376 | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
1377 | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
1378 | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
1379 | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
1380 | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
1381 | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
1382 | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
1383 | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
1384 | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
1385 | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSParserValue::Q_EMS; }
1386 | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
1393 $$.unit = CSSPrimitiveValue::CSS_PARSER_VARIABLE_FUNCTION_SYNTAX;
1398 FUNCTION maybe_space expr ')' maybe_space {
1399 CSSParser* p = static_cast<CSSParser*>(parser);
1400 CSSParserFunction* f = p->createFloatingFunction();
1402 f->args = p->sinkFloatingValueList($3);
1404 $$.unit = CSSParserValue::Function;
1407 FUNCTION maybe_space error {
1408 CSSParser* p = static_cast<CSSParser*>(parser);
1409 CSSParserFunction* f = p->createFloatingFunction();
1413 $$.unit = CSSParserValue::Function;
1418 * There is a constraint on the color that it must
1419 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
1420 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
1423 HEX maybe_space { $$ = $1; }
1424 | IDSEL maybe_space { $$ = $1; }
1428 /* error handling rules */
1434 | error closing_brace {
1440 ATKEYWORD error invalid_block {
1443 | ATKEYWORD error ';' {
1449 invalid_at maybe_sgml
1450 | invalid_at_list invalid_at maybe_sgml
1466 error invalid_block {
1471 Seems like the two rules below are trying too much and violating
1472 http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
1484 '{' error invalid_block_list error closing_brace
1485 | '{' error closing_brace
1490 | invalid_block_list error invalid_block