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 "CSSPrimitiveValue.h"
30 #include "CSSPropertyNames.h"
31 #include "CSSRuleList.h"
32 #include "CSSSelector.h"
33 #include "CSSStyleSheet.h"
35 #include "HTMLNames.h"
36 #include "MediaList.h"
37 #include "WebKitCSSKeyframeRule.h"
38 #include "WebKitCSSKeyframesRule.h"
39 #include <wtf/FastMalloc.h>
43 using namespace WebCore;
44 using namespace HTMLNames;
46 #define YYMALLOC fastMalloc
47 #define YYFREE fastFree
49 #define YYENABLE_NLS 0
50 #define YYLTYPE_IS_TRIVIAL 1
51 #define YYMAXDEPTH 10000
54 // FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
55 #define YYPARSE_PARAM parser
56 #define YYLEX_PARAM parser
67 CSSParserString string;
70 CSSRuleList* ruleList;
71 CSSSelector* selector;
72 Vector<CSSSelector*>* selectorList;
73 CSSSelector::Relation relation;
75 MediaQuery* mediaQuery;
76 MediaQuery::Restrictor mediaQueryRestrictor;
77 MediaQueryExp* mediaQueryExp;
79 CSSParserValueList* valueList;
80 Vector<MediaQueryExp*>* mediaQueryExpList;
81 WebKitCSSKeyframeRule* keyframeRule;
82 WebKitCSSKeyframesRule* keyframesRule;
88 static inline int cssyyerror(const char*)
93 static int cssyylex(YYSTYPE* yylval, void* parser)
95 return static_cast<CSSParser*>(parser)->lex(yylval);
102 %nonassoc LOWEST_PREC
104 %left UNIMPORTANT_TOK
106 %token WHITESPACE SGML_CD
115 %token <string> STRING
116 %right <string> IDENT
119 %nonassoc <string> HEX
120 %nonassoc <string> IDSEL
124 %nonassoc <string> '*'
134 %token WEBKIT_RULE_SYM
135 %token WEBKIT_DECLS_SYM
136 %token WEBKIT_KEYFRAME_RULE_SYM
137 %token WEBKIT_KEYFRAMES_SYM
138 %token WEBKIT_VALUE_SYM
139 %token WEBKIT_MEDIAQUERY_SYM
140 %token WEBKIT_SELECTOR_SYM
141 %token WEBKIT_VARIABLES_SYM
142 %token WEBKIT_DEFINE_SYM
144 %token WEBKIT_VARIABLES_DECLS_SYM
164 %token <number> GRADS
165 %token <number> TURNS
166 %token <number> MSECS
169 %token <number> KHERZ
170 %token <string> DIMEN
171 %token <number> PERCENTAGE
172 %token <number> FLOATTOKEN
173 %token <number> INTEGER
176 %token <string> FUNCTION
177 %token <string> NOTFUNCTION
179 %token <string> UNICODERANGE
181 %token <string> VARCALL
183 %type <relation> combinator
187 %type <rule> valid_rule_or_import
191 %type <rule> font_face
192 %type <rule> keyframes
193 %type <rule> invalid_rule
194 %type <rule> save_block
195 %type <rule> invalid_at
196 %type <rule> invalid_at_list
197 %type <rule> invalid_import
198 %type <rule> invalid_media
200 %type <rule> valid_rule
201 %type <ruleList> block_rule_list
202 %type <rule> block_rule
203 %type <rule> block_valid_rule
204 %type <rule> variables_rule
205 %type <mediaList> variables_media_list
207 %type <string> maybe_ns_prefix
209 %type <string> namespace_selector
211 %type <string> string_or_uri
212 %type <string> ident_or_string
213 %type <string> medium
214 %type <string> hexcolor
216 %type <string> media_feature
217 %type <mediaList> media_list
218 %type <mediaList> maybe_media_list
219 %type <mediaQuery> media_query
220 %type <mediaQueryRestrictor> maybe_media_restrictor
221 %type <valueList> maybe_media_value
222 %type <mediaQueryExp> media_query_exp
223 %type <mediaQueryExpList> media_query_exp_list
224 %type <mediaQueryExpList> maybe_and_media_query_exp_list
226 %type <string> keyframe_name
227 %type <keyframeRule> keyframe_rule
228 %type <keyframesRule> keyframes_rule
229 %type <valueList> key_list
232 %type <integer> property
234 %type <selector> specifier
235 %type <selector> specifier_list
236 %type <selector> simple_selector
237 %type <selector> selector
238 %type <selectorList> selector_list
239 %type <selector> selector_with_trailing_whitespace
240 %type <selector> class
241 %type <selector> attrib
242 %type <selector> pseudo
244 %type <boolean> declaration_list
245 %type <boolean> decl_list
246 %type <boolean> declaration
250 %type <integer> match
251 %type <integer> unary_operator
252 %type <character> operator
254 %type <valueList> expr
256 %type <value> unary_term
257 %type <value> function
259 %type <string> element_name
260 %type <string> attr_name
262 %type <string> variable_name
263 %type <boolean> variables_declaration_list
264 %type <boolean> variables_decl_list
265 %type <boolean> variables_declaration
266 %type <value> variable_reference
271 maybe_charset maybe_sgml import_list variables_list namespace_list rule_list
272 | webkit_rule maybe_space
273 | webkit_decls maybe_space
274 | webkit_value maybe_space
275 | webkit_mediaquery maybe_space
276 | webkit_selector maybe_space
277 | webkit_variables_decls maybe_space
278 | webkit_keyframe_rule maybe_space
281 valid_rule_or_import:
287 WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
288 static_cast<CSSParser*>(parser)->m_rule = $4;
292 webkit_keyframe_rule:
293 WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' {
294 static_cast<CSSParser*>(parser)->m_keyframe = $4;
299 WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
304 webkit_variables_decls:
305 WEBKIT_VARIABLES_DECLS_SYM '{' maybe_space variables_declaration_list '}' {
311 WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
312 CSSParser* p = static_cast<CSSParser*>(parser);
314 p->m_valueList = p->sinkFloatingValueList($4);
315 int oldParsedProperties = p->m_numParsedProperties;
316 if (!p->parseValue(p->m_id, p->m_important))
317 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
318 delete p->m_valueList;
325 WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
326 CSSParser* p = static_cast<CSSParser*>(parser);
327 p->m_mediaQuery = p->sinkFloatingMediaQuery($4);
332 WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' {
334 CSSParser* p = static_cast<CSSParser*>(parser);
335 if (p->m_selectorListForParseSelector)
336 p->m_selectorListForParseSelector->adoptSelectorVector(*$4);
342 /* empty */ %prec UNIMPORTANT_TOK
343 | maybe_space WHITESPACE
349 | maybe_sgml WHITESPACE
360 | %prec LOWEST_PREC TOKEN_EOF
364 CHARSET_SYM maybe_space STRING maybe_space ';' {
365 CSSParser* p = static_cast<CSSParser*>(parser);
366 $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
367 if ($$ && p->m_styleSheet)
368 p->m_styleSheet->append($$);
370 | CHARSET_SYM error invalid_block {
372 | CHARSET_SYM error ';' {
378 | import_list import maybe_sgml {
379 CSSParser* p = static_cast<CSSParser*>(parser);
380 if ($2 && p->m_styleSheet)
381 p->m_styleSheet->append($2);
389 | variables_list variables_rule maybe_sgml {
390 CSSParser* p = static_cast<CSSParser*>(parser);
391 if ($2 && p->m_styleSheet)
392 p->m_styleSheet->append($2);
398 | namespace_list namespace maybe_sgml
403 | rule_list rule maybe_sgml {
404 CSSParser* p = static_cast<CSSParser*>(parser);
405 if ($2 && p->m_styleSheet)
406 p->m_styleSheet->append($2);
426 /* empty */ { $$ = 0; }
427 | block_rule_list block_rule maybe_sgml {
431 $$ = static_cast<CSSParser*>(parser)->createRuleList();
454 IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
455 $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
457 | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list invalid_block {
460 | IMPORT_SYM error ';' {
463 | IMPORT_SYM error invalid_block {
469 WEBKIT_VARIABLES_SYM maybe_space maybe_media_list '{' maybe_space variables_declaration_list '}' {
470 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, true);
473 WEBKIT_DEFINE_SYM maybe_space variables_media_list '{' maybe_space variables_declaration_list '}' {
474 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, false);
478 variables_media_list:
480 $$ = static_cast<CSSParser*>(parser)->createMediaList();
483 VARIABLES_FOR WHITESPACE media_list {
488 variables_declaration_list:
489 variables_declaration {
492 | variables_decl_list variables_declaration {
497 | variables_decl_list {
500 | error invalid_block_list error {
506 | variables_decl_list error {
512 variables_declaration ';' maybe_space {
515 | variables_declaration invalid_block_list ';' maybe_space {
518 | error ';' maybe_space {
521 | error invalid_block_list error ';' maybe_space {
524 | variables_decl_list variables_declaration ';' maybe_space {
529 | variables_decl_list error ';' maybe_space {
532 | variables_decl_list error invalid_block_list error ';' maybe_space {
537 variables_declaration:
538 variable_name ':' maybe_space expr {
539 $$ = static_cast<CSSParser*>(parser)->addVariable($1, $4);
542 variable_name maybe_space '{' maybe_space declaration_list '}' maybe_space {
543 $$ = static_cast<CSSParser*>(parser)->addVariableDeclarationBlock($1);
546 variable_name error {
550 variable_name ':' maybe_space error expr {
554 variable_name ':' maybe_space {
555 /* @variables { varname: } Just reduce away this variable with no value. */
559 variable_name ':' maybe_space error {
560 /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */
572 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
573 CSSParser* p = static_cast<CSSParser*>(parser);
575 p->m_styleSheet->addNamespace(p, $3, $4);
577 | NAMESPACE_SYM error invalid_block
578 | NAMESPACE_SYM error ';'
582 /* empty */ { $$.characters = 0; }
583 | IDENT WHITESPACE { $$ = $1; }
601 | ':' maybe_space expr maybe_space {
607 '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
609 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5);
613 media_query_exp_list:
615 CSSParser* p = static_cast<CSSParser*>(parser);
616 $$ = p->createFloatingMediaQueryExpList();
617 $$->append(p->sinkFloatingMediaQueryExp($1));
619 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
621 $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
625 maybe_and_media_query_exp_list:
627 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
629 | MEDIA_AND maybe_space media_query_exp_list {
634 maybe_media_restrictor:
636 $$ = MediaQuery::None;
639 $$ = MediaQuery::Only;
642 $$ = MediaQuery::Not;
647 media_query_exp_list {
648 CSSParser* p = static_cast<CSSParser*>(parser);
649 $$ = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList($1));
652 maybe_media_restrictor maybe_space medium maybe_and_media_query_exp_list {
653 CSSParser* p = static_cast<CSSParser*>(parser);
655 $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
661 $$ = static_cast<CSSParser*>(parser)->createMediaList();
668 CSSParser* p = static_cast<CSSParser*>(parser);
669 $$ = p->createMediaList();
670 $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
672 | media_list ',' maybe_space media_query {
675 $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
683 MEDIA_SYM maybe_space media_list '{' maybe_space block_rule_list save_block {
684 $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
686 | MEDIA_SYM maybe_space '{' maybe_space block_rule_list save_block {
687 $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
698 WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name maybe_space '{' maybe_space keyframes_rule '}' {
700 $7->setNameInternal($3);
710 /* empty */ { $$ = static_cast<CSSParser*>(parser)->createKeyframesRule(); }
711 | keyframes_rule keyframe_rule maybe_space {
719 key_list maybe_space '{' maybe_space declaration_list '}' {
720 $$ = static_cast<CSSParser*>(parser)->createKeyframeRule($1);
726 CSSParser* p = static_cast<CSSParser*>(parser);
727 $$ = p->createFloatingValueList();
728 $$->addValue(p->sinkFloatingValue($1));
730 | key_list maybe_space ',' maybe_space key {
731 CSSParser* p = static_cast<CSSParser*>(parser);
734 $$->addValue(p->sinkFloatingValue($5));
739 PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
741 $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
742 CSSParserString& str = $1;
743 if (equalIgnoringCase("from", str.characters, str.length))
745 else if (equalIgnoringCase("to", str.characters, str.length))
754 PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
755 '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
764 PAGE_SYM error invalid_block {
767 | PAGE_SYM error ';' {
773 FONT_FACE_SYM maybe_space
774 '{' maybe_space declaration_list '}' maybe_space {
775 $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
777 | FONT_FACE_SYM error invalid_block {
780 | FONT_FACE_SYM error ';' {
786 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
787 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
788 | '>' maybe_space { $$ = CSSSelector::Child; }
797 selector_list '{' maybe_space declaration_list closing_brace {
798 $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
803 selector %prec UNIMPORTANT_TOK {
805 CSSParser* p = static_cast<CSSParser*>(parser);
806 $$ = p->reusableSelectorVector();
807 deleteAllValues(*$$);
809 $$->append(p->sinkFloatingSelector($1));
812 | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
814 CSSParser* p = static_cast<CSSParser*>(parser);
816 $$->append(p->sinkFloatingSelector($4));
820 | selector_list error {
825 selector_with_trailing_whitespace:
826 selector WHITESPACE {
835 | selector_with_trailing_whitespace
839 | selector_with_trailing_whitespace simple_selector
845 CSSParser* p = static_cast<CSSParser*>(parser);
846 CSSSelector* end = $$;
847 while (end->tagHistory())
848 end = end->tagHistory();
849 end->m_relation = CSSSelector::Descendant;
850 end->setTagHistory(p->sinkFloatingSelector($1));
851 if (Document* doc = p->document())
852 doc->setUsesDescendantRules(true);
855 | selector combinator simple_selector {
860 CSSParser* p = static_cast<CSSParser*>(parser);
861 CSSSelector* end = $$;
862 while (end->tagHistory())
863 end = end->tagHistory();
864 end->m_relation = $2;
865 end->setTagHistory(p->sinkFloatingSelector($1));
866 if ($2 == CSSSelector::Child) {
867 if (Document* doc = p->document())
868 doc->setUsesDescendantRules(true);
869 } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
870 if (Document* doc = p->document())
871 doc->setUsesSiblingRules(true);
881 /* empty */ '|' { $$.characters = 0; $$.length = 0; }
882 | '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
883 | IDENT '|' { $$ = $1; }
888 CSSParser* p = static_cast<CSSParser*>(parser);
889 $$ = p->createFloatingSelector();
890 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
892 | element_name specifier_list {
895 CSSParser* p = static_cast<CSSParser*>(parser);
896 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
901 CSSParser* p = static_cast<CSSParser*>(parser);
902 if ($$ && p->m_defaultNamespace != starAtom)
903 $$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace);
905 | namespace_selector element_name {
906 AtomicString namespacePrefix = $1;
907 CSSParser* p = static_cast<CSSParser*>(parser);
908 $$ = p->createFloatingSelector();
910 $$->m_tag = QualifiedName(namespacePrefix, $2,
911 p->m_styleSheet->determineNamespace(namespacePrefix));
912 else // FIXME: Shouldn't this case be an error?
913 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
915 | namespace_selector element_name specifier_list {
918 AtomicString namespacePrefix = $1;
919 CSSParser* p = static_cast<CSSParser*>(parser);
921 $$->m_tag = QualifiedName(namespacePrefix, $2,
922 p->m_styleSheet->determineNamespace(namespacePrefix));
923 else // FIXME: Shouldn't this case be an error?
924 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
927 | namespace_selector specifier_list {
930 AtomicString namespacePrefix = $1;
931 CSSParser* p = static_cast<CSSParser*>(parser);
933 $$->m_tag = QualifiedName(namespacePrefix, starAtom,
934 p->m_styleSheet->determineNamespace(namespacePrefix));
941 CSSParserString& str = $1;
942 CSSParser* p = static_cast<CSSParser*>(parser);
943 Document* doc = p->document();
944 if (doc && doc->isHTMLDocument())
949 static UChar star = '*';
950 $$.characters = ☆
959 | specifier_list specifier {
964 CSSParser* p = static_cast<CSSParser*>(parser);
965 CSSSelector* end = $1;
966 while (end->tagHistory())
967 end = end->tagHistory();
968 end->m_relation = CSSSelector::SubSelector;
969 end->setTagHistory(p->sinkFloatingSelector($2));
972 | specifier_list error {
979 CSSParser* p = static_cast<CSSParser*>(parser);
980 $$ = p->createFloatingSelector();
981 $$->m_match = CSSSelector::Id;
987 if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
990 CSSParser* p = static_cast<CSSParser*>(parser);
991 $$ = p->createFloatingSelector();
992 $$->m_match = CSSSelector::Id;
1005 CSSParser* p = static_cast<CSSParser*>(parser);
1006 $$ = p->createFloatingSelector();
1007 $$->m_match = CSSSelector::Class;
1016 CSSParserString& str = $1;
1017 CSSParser* p = static_cast<CSSParser*>(parser);
1018 Document* doc = p->document();
1019 if (doc && doc->isHTMLDocument())
1026 '[' maybe_space attr_name ']' {
1027 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1028 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1029 $$->m_match = CSSSelector::Set;
1031 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
1032 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1033 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1034 $$->m_match = (CSSSelector::Match)$4;
1037 | '[' maybe_space namespace_selector attr_name ']' {
1038 AtomicString namespacePrefix = $3;
1039 CSSParser* p = static_cast<CSSParser*>(parser);
1040 $$ = p->createFloatingSelector();
1041 $$->setAttribute(QualifiedName(namespacePrefix, $4,
1042 p->m_styleSheet->determineNamespace(namespacePrefix)));
1043 $$->m_match = CSSSelector::Set;
1045 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
1046 AtomicString namespacePrefix = $3;
1047 CSSParser* p = static_cast<CSSParser*>(parser);
1048 $$ = p->createFloatingSelector();
1049 $$->setAttribute(QualifiedName(namespacePrefix, $4,
1050 p->m_styleSheet->determineNamespace(namespacePrefix)));
1051 $$->m_match = (CSSSelector::Match)$5;
1058 $$ = CSSSelector::Exact;
1061 $$ = CSSSelector::List;
1064 $$ = CSSSelector::Hyphen;
1067 $$ = CSSSelector::Begin;
1070 $$ = CSSSelector::End;
1073 $$ = CSSSelector::Contain;
1084 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1085 $$->m_match = CSSSelector::PseudoClass;
1088 CSSSelector::PseudoType type = $$->pseudoType();
1089 if (type == CSSSelector::PseudoUnknown)
1091 else if (type == CSSSelector::PseudoEmpty ||
1092 type == CSSSelector::PseudoFirstChild ||
1093 type == CSSSelector::PseudoFirstOfType ||
1094 type == CSSSelector::PseudoLastChild ||
1095 type == CSSSelector::PseudoLastOfType ||
1096 type == CSSSelector::PseudoOnlyChild ||
1097 type == CSSSelector::PseudoOnlyOfType) {
1098 CSSParser* p = static_cast<CSSParser*>(parser);
1099 Document* doc = p->document();
1101 doc->setUsesSiblingRules(true);
1102 } else if (type == CSSSelector::PseudoFirstLine) {
1103 CSSParser* p = static_cast<CSSParser*>(parser);
1104 if (Document* doc = p->document())
1105 doc->setUsesFirstLineRules(true);
1106 } else if (type == CSSSelector::PseudoBefore ||
1107 type == CSSSelector::PseudoAfter) {
1108 CSSParser* p = static_cast<CSSParser*>(parser);
1109 if (Document* doc = p->document())
1110 doc->setUsesBeforeAfterRules(true);
1114 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1115 $$->m_match = CSSSelector::PseudoElement;
1118 CSSSelector::PseudoType type = $$->pseudoType();
1119 if (type == CSSSelector::PseudoUnknown)
1121 else if (type == CSSSelector::PseudoFirstLine) {
1122 CSSParser* p = static_cast<CSSParser*>(parser);
1123 if (Document* doc = p->document())
1124 doc->setUsesFirstLineRules(true);
1125 } else if (type == CSSSelector::PseudoBefore ||
1126 type == CSSSelector::PseudoAfter) {
1127 CSSParser* p = static_cast<CSSParser*>(parser);
1128 if (Document* doc = p->document())
1129 doc->setUsesBeforeAfterRules(true);
1132 // used by :nth-*(ax+b)
1133 | ':' FUNCTION NTH ')' {
1134 CSSParser *p = static_cast<CSSParser*>(parser);
1135 $$ = p->createFloatingSelector();
1136 $$->m_match = CSSSelector::PseudoClass;
1137 $$->setArgument($3);
1139 CSSSelector::PseudoType type = $$->pseudoType();
1140 if (type == CSSSelector::PseudoUnknown)
1142 else if (type == CSSSelector::PseudoNthChild ||
1143 type == CSSSelector::PseudoNthOfType ||
1144 type == CSSSelector::PseudoNthLastChild ||
1145 type == CSSSelector::PseudoNthLastOfType) {
1147 p->document()->setUsesSiblingRules(true);
1151 | ':' FUNCTION INTEGER ')' {
1152 CSSParser *p = static_cast<CSSParser*>(parser);
1153 $$ = p->createFloatingSelector();
1154 $$->m_match = CSSSelector::PseudoClass;
1155 $$->setArgument(String::number($3));
1157 CSSSelector::PseudoType type = $$->pseudoType();
1158 if (type == CSSSelector::PseudoUnknown)
1160 else if (type == CSSSelector::PseudoNthChild ||
1161 type == CSSSelector::PseudoNthOfType ||
1162 type == CSSSelector::PseudoNthLastChild ||
1163 type == CSSSelector::PseudoNthLastOfType) {
1165 p->document()->setUsesSiblingRules(true);
1168 // used by :nth-*(odd/even) and :lang
1169 | ':' FUNCTION IDENT ')' {
1170 CSSParser *p = static_cast<CSSParser*>(parser);
1171 $$ = p->createFloatingSelector();
1172 $$->m_match = CSSSelector::PseudoClass;
1173 $$->setArgument($3);
1176 CSSSelector::PseudoType type = $$->pseudoType();
1177 if (type == CSSSelector::PseudoUnknown)
1179 else if (type == CSSSelector::PseudoNthChild ||
1180 type == CSSSelector::PseudoNthOfType ||
1181 type == CSSSelector::PseudoNthLastChild ||
1182 type == CSSSelector::PseudoNthLastOfType) {
1184 p->document()->setUsesSiblingRules(true);
1188 | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
1189 if (!$4 || $4->simpleSelector() || $4->tagHistory())
1192 CSSParser* p = static_cast<CSSParser*>(parser);
1193 $$ = p->createFloatingSelector();
1194 $$->m_match = CSSSelector::PseudoClass;
1195 $$->setSimpleSelector(p->sinkFloatingSelector($4));
1206 | decl_list declaration {
1214 | error invalid_block_list error {
1223 | decl_list invalid_block_list {
1229 declaration ';' maybe_space {
1232 | declaration invalid_block_list ';' maybe_space {
1235 | error ';' maybe_space {
1238 | error invalid_block_list error ';' maybe_space {
1241 | decl_list declaration ';' maybe_space {
1246 | decl_list error ';' maybe_space {
1249 | decl_list error invalid_block_list error ';' maybe_space {
1255 property ':' maybe_space expr prio {
1257 CSSParser* p = static_cast<CSSParser*>(parser);
1259 p->m_valueList = p->sinkFloatingValueList($4);
1260 int oldParsedProperties = p->m_numParsedProperties;
1261 $$ = p->parseValue($1, $5);
1263 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1264 delete p->m_valueList;
1269 variable_reference maybe_space {
1270 CSSParser* p = static_cast<CSSParser*>(parser);
1271 p->m_valueList = new CSSParserValueList;
1272 p->m_valueList->addValue(p->sinkFloatingValue($1));
1273 int oldParsedProperties = p->m_numParsedProperties;
1274 $$ = p->parseValue(CSSPropertyWebkitVariableDeclarationBlock, false);
1276 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1277 delete p->m_valueList;
1285 property ':' maybe_space error expr prio {
1286 /* The default movable type template has letter-spacing: .none; Handle this by looking for
1287 error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
1288 up and deleting the shifted expr. */
1292 property ':' maybe_space expr prio error {
1293 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1297 IMPORTANT_SYM maybe_space {
1298 /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
1302 property ':' maybe_space {
1303 /* div { font-family: } Just reduce away this property with no value. */
1307 property ':' maybe_space error {
1308 /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
1312 property invalid_block {
1313 /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */
1320 $$ = cssPropertyID($1);
1325 IMPORTANT_SYM maybe_space { $$ = true; }
1326 | /* empty */ { $$ = false; }
1331 CSSParser* p = static_cast<CSSParser*>(parser);
1332 $$ = p->createFloatingValueList();
1333 $$->addValue(p->sinkFloatingValue($1));
1335 | expr operator term {
1336 CSSParser* p = static_cast<CSSParser*>(parser);
1342 v.unit = CSSParserValue::Operator;
1346 $$->addValue(p->sinkFloatingValue($3));
1367 unary_term { $$ = $1; }
1368 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1369 | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1370 | IDENT maybe_space {
1371 $$.id = cssValueKeywordID($1);
1372 $$.unit = CSSPrimitiveValue::CSS_IDENT;
1375 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1376 | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1377 | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1378 | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1379 | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1380 | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1381 | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1382 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1386 | variable_reference maybe_space {
1389 | '%' maybe_space { /* Handle width: %; */
1390 $$.id = 0; $$.unit = 0;
1395 INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1396 | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1397 | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1398 | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1399 | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
1400 | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
1401 | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
1402 | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
1403 | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
1404 | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
1405 | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
1406 | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
1407 | TURNS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_TURN; }
1408 | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
1409 | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
1410 | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
1411 | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
1412 | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
1413 | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSParserValue::Q_EMS; }
1414 | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
1415 | REMS maybe_space {
1418 $$.unit = CSSPrimitiveValue::CSS_REMS;
1419 CSSParser* p = static_cast<CSSParser*>(parser);
1420 if (Document* doc = p->document())
1421 doc->setUsesRemUnits(true);
1429 $$.unit = CSSPrimitiveValue::CSS_PARSER_VARIABLE_FUNCTION_SYNTAX;
1434 FUNCTION maybe_space expr ')' maybe_space {
1435 CSSParser* p = static_cast<CSSParser*>(parser);
1436 CSSParserFunction* f = p->createFloatingFunction();
1438 f->args = p->sinkFloatingValueList($3);
1440 $$.unit = CSSParserValue::Function;
1443 FUNCTION maybe_space error {
1444 CSSParser* p = static_cast<CSSParser*>(parser);
1445 CSSParserFunction* f = p->createFloatingFunction();
1449 $$.unit = CSSParserValue::Function;
1454 * There is a constraint on the color that it must
1455 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
1456 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
1459 HEX maybe_space { $$ = $1; }
1460 | IDSEL maybe_space { $$ = $1; }
1464 /* error handling rules */
1470 | error closing_brace {
1476 ATKEYWORD error invalid_block {
1479 | ATKEYWORD error ';' {
1485 invalid_at maybe_sgml
1486 | invalid_at_list invalid_at maybe_sgml
1502 error invalid_block {
1507 Seems like the two rules below are trying too much and violating
1508 http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
1520 '{' error invalid_block_list error closing_brace
1521 | '{' error closing_brace
1526 | invalid_block_list error invalid_block