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 "CSSStyleSheet.h"
34 #include "HTMLNames.h"
35 #include "MediaList.h"
36 #include "WebKitCSSKeyframeRule.h"
37 #include "WebKitCSSKeyframesRule.h"
41 using namespace WebCore;
42 using namespace HTMLNames;
44 #define YYENABLE_NLS 0
45 #define YYLTYPE_IS_TRIVIAL 1
46 #define YYMAXDEPTH 10000
49 // FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
50 #define YYPARSE_PARAM parser
51 #define YYLEX_PARAM parser
62 CSSParserString string;
65 CSSRuleList* ruleList;
66 CSSSelector* selector;
67 Vector<CSSSelector*>* selectorList;
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);
101 %token WHITESPACE SGML_CD
110 %token <string> STRING
111 %right <string> IDENT
114 %nonassoc <string> HEX
115 %nonassoc <string> IDSEL
119 %nonassoc <string> '*'
129 %token WEBKIT_RULE_SYM
130 %token WEBKIT_DECLS_SYM
131 %token WEBKIT_KEYFRAME_RULE_SYM
132 %token WEBKIT_KEYFRAMES_SYM
133 %token WEBKIT_VALUE_SYM
134 %token WEBKIT_MEDIAQUERY_SYM
135 %token WEBKIT_SELECTOR_SYM
136 %token WEBKIT_VARIABLES_SYM
137 %token WEBKIT_DEFINE_SYM
139 %token WEBKIT_VARIABLES_DECLS_SYM
158 %token <number> GRADS
159 %token <number> TURNS
160 %token <number> MSECS
163 %token <number> KHERZ
164 %token <string> DIMEN
165 %token <number> PERCENTAGE
166 %token <number> FLOATTOKEN
167 %token <number> INTEGER
170 %token <string> FUNCTION
171 %token <string> NOTFUNCTION
173 %token <string> UNICODERANGE
175 %token <string> VARCALL
177 %type <relation> combinator
181 %type <rule> valid_rule_or_import
185 %type <rule> font_face
186 %type <rule> keyframes
187 %type <rule> invalid_rule
188 %type <rule> save_block
189 %type <rule> invalid_at
190 %type <rule> invalid_at_list
191 %type <rule> invalid_import
192 %type <rule> invalid_media
194 %type <rule> valid_rule
195 %type <ruleList> block_rule_list
196 %type <rule> block_rule
197 %type <rule> block_valid_rule
198 %type <rule> variables_rule
199 %type <mediaList> variables_media_list
201 %type <string> maybe_ns_prefix
203 %type <string> namespace_selector
205 %type <string> string_or_uri
206 %type <string> ident_or_string
207 %type <string> medium
208 %type <string> hexcolor
210 %type <string> media_feature
211 %type <mediaList> media_list
212 %type <mediaList> maybe_media_list
213 %type <mediaQuery> media_query
214 %type <mediaQueryRestrictor> maybe_media_restrictor
215 %type <valueList> maybe_media_value
216 %type <mediaQueryExp> media_query_exp
217 %type <mediaQueryExpList> media_query_exp_list
218 %type <mediaQueryExpList> maybe_and_media_query_exp_list
220 %type <string> keyframe_name
221 %type <keyframeRule> keyframe_rule
222 %type <keyframesRule> keyframes_rule
223 %type <valueList> key_list
226 %type <integer> property
228 %type <selector> specifier
229 %type <selector> specifier_list
230 %type <selector> simple_selector
231 %type <selector> selector
232 %type <selectorList> selector_list
233 %type <selector> selector_with_trailing_whitespace
234 %type <selector> class
235 %type <selector> attrib
236 %type <selector> pseudo
238 %type <boolean> declaration_list
239 %type <boolean> decl_list
240 %type <boolean> declaration
244 %type <integer> match
245 %type <integer> unary_operator
246 %type <character> operator
248 %type <valueList> expr
250 %type <value> unary_term
251 %type <value> function
253 %type <string> element_name
254 %type <string> attr_name
256 %type <string> variable_name
257 %type <boolean> variables_declaration_list
258 %type <boolean> variables_decl_list
259 %type <boolean> variables_declaration
260 %type <value> variable_reference
265 maybe_charset maybe_sgml import_list variables_list namespace_list rule_list
266 | webkit_rule maybe_space
267 | webkit_decls maybe_space
268 | webkit_value maybe_space
269 | webkit_mediaquery maybe_space
270 | webkit_selector maybe_space
271 | webkit_variables_decls maybe_space
272 | webkit_keyframe_rule maybe_space
275 valid_rule_or_import:
281 WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
282 static_cast<CSSParser*>(parser)->m_rule = $4;
286 webkit_keyframe_rule:
287 WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' {
288 static_cast<CSSParser*>(parser)->m_keyframe = $4;
293 WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
298 webkit_variables_decls:
299 WEBKIT_VARIABLES_DECLS_SYM '{' maybe_space variables_declaration_list '}' {
305 WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
306 CSSParser* p = static_cast<CSSParser*>(parser);
308 p->m_valueList = p->sinkFloatingValueList($4);
309 int oldParsedProperties = p->m_numParsedProperties;
310 if (!p->parseValue(p->m_id, p->m_important))
311 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
312 delete p->m_valueList;
319 WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
320 CSSParser* p = static_cast<CSSParser*>(parser);
321 p->m_mediaQuery = p->sinkFloatingMediaQuery($4);
326 WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' {
328 CSSParser* p = static_cast<CSSParser*>(parser);
329 if (p->m_selectorListForParseSelector)
330 p->m_selectorListForParseSelector->adoptSelectorVector(*$4);
336 /* empty */ %prec UNIMPORTANT_TOK
337 | maybe_space WHITESPACE
343 | maybe_sgml WHITESPACE
354 | %prec LOWEST_PREC TOKEN_EOF
358 CHARSET_SYM maybe_space STRING maybe_space ';' {
359 CSSParser* p = static_cast<CSSParser*>(parser);
360 $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
361 if ($$ && p->m_styleSheet)
362 p->m_styleSheet->append($$);
364 | CHARSET_SYM error invalid_block {
366 | CHARSET_SYM error ';' {
372 | import_list import maybe_sgml {
373 CSSParser* p = static_cast<CSSParser*>(parser);
374 if ($2 && p->m_styleSheet)
375 p->m_styleSheet->append($2);
383 | variables_list variables_rule maybe_sgml {
384 CSSParser* p = static_cast<CSSParser*>(parser);
385 if ($2 && p->m_styleSheet)
386 p->m_styleSheet->append($2);
392 | namespace_list namespace maybe_sgml
397 | rule_list rule maybe_sgml {
398 CSSParser* p = static_cast<CSSParser*>(parser);
399 if ($2 && p->m_styleSheet)
400 p->m_styleSheet->append($2);
420 /* empty */ { $$ = 0; }
421 | block_rule_list block_rule maybe_sgml {
425 $$ = static_cast<CSSParser*>(parser)->createRuleList();
448 IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
449 $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
451 | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list invalid_block {
454 | IMPORT_SYM error ';' {
457 | IMPORT_SYM error invalid_block {
463 WEBKIT_VARIABLES_SYM maybe_space maybe_media_list '{' maybe_space variables_declaration_list '}' {
464 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, true);
467 WEBKIT_DEFINE_SYM maybe_space variables_media_list '{' maybe_space variables_declaration_list '}' {
468 $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, false);
472 variables_media_list:
474 $$ = static_cast<CSSParser*>(parser)->createMediaList();
477 VARIABLES_FOR WHITESPACE media_list {
482 variables_declaration_list:
483 variables_declaration {
486 | variables_decl_list variables_declaration {
491 | variables_decl_list {
494 | error invalid_block_list error {
500 | variables_decl_list error {
506 variables_declaration ';' maybe_space {
509 | variables_declaration invalid_block_list ';' maybe_space {
512 | error ';' maybe_space {
515 | error invalid_block_list error ';' maybe_space {
518 | variables_decl_list variables_declaration ';' maybe_space {
523 | variables_decl_list error ';' maybe_space {
526 | variables_decl_list error invalid_block_list error ';' maybe_space {
531 variables_declaration:
532 variable_name ':' maybe_space expr {
533 $$ = static_cast<CSSParser*>(parser)->addVariable($1, $4);
536 variable_name maybe_space '{' maybe_space declaration_list '}' maybe_space {
537 $$ = static_cast<CSSParser*>(parser)->addVariableDeclarationBlock($1);
540 variable_name error {
544 variable_name ':' maybe_space error expr {
548 variable_name ':' maybe_space {
549 /* @variables { varname: } Just reduce away this variable with no value. */
553 variable_name ':' maybe_space error {
554 /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */
566 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
567 CSSParser* p = static_cast<CSSParser*>(parser);
569 p->m_styleSheet->addNamespace(p, $3, $4);
571 | NAMESPACE_SYM error invalid_block
572 | NAMESPACE_SYM error ';'
576 /* empty */ { $$.characters = 0; }
577 | IDENT WHITESPACE { $$ = $1; }
595 | ':' maybe_space expr maybe_space {
601 '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
603 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5);
607 media_query_exp_list:
609 CSSParser* p = static_cast<CSSParser*>(parser);
610 $$ = p->createFloatingMediaQueryExpList();
611 $$->append(p->sinkFloatingMediaQueryExp($1));
613 | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
615 $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
619 maybe_and_media_query_exp_list:
621 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
623 | MEDIA_AND maybe_space media_query_exp_list {
628 maybe_media_restrictor:
630 $$ = MediaQuery::None;
633 $$ = MediaQuery::Only;
636 $$ = MediaQuery::Not;
641 media_query_exp_list {
642 CSSParser* p = static_cast<CSSParser*>(parser);
643 $$ = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList($1));
646 maybe_media_restrictor maybe_space medium maybe_and_media_query_exp_list {
647 CSSParser* p = static_cast<CSSParser*>(parser);
649 $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
655 $$ = static_cast<CSSParser*>(parser)->createMediaList();
662 CSSParser* p = static_cast<CSSParser*>(parser);
663 $$ = p->createMediaList();
664 $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
666 | media_list ',' maybe_space media_query {
669 $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
677 MEDIA_SYM maybe_space media_list '{' maybe_space block_rule_list save_block {
678 $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
680 | MEDIA_SYM maybe_space '{' maybe_space block_rule_list save_block {
681 $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
692 WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name maybe_space '{' maybe_space keyframes_rule '}' {
694 $7->setNameInternal($3);
704 /* empty */ { $$ = static_cast<CSSParser*>(parser)->createKeyframesRule(); }
705 | keyframes_rule keyframe_rule maybe_space {
713 key_list maybe_space '{' maybe_space declaration_list '}' {
714 $$ = static_cast<CSSParser*>(parser)->createKeyframeRule($1);
720 CSSParser* p = static_cast<CSSParser*>(parser);
721 $$ = p->createFloatingValueList();
722 $$->addValue(p->sinkFloatingValue($1));
724 | key_list maybe_space ',' maybe_space key {
725 CSSParser* p = static_cast<CSSParser*>(parser);
728 $$->addValue(p->sinkFloatingValue($5));
733 PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
735 $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
736 CSSParserString& str = $1;
737 if (equalIgnoringCase(static_cast<const String&>(str), "from"))
739 else if (equalIgnoringCase(static_cast<const String&>(str), "to"))
748 PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
749 '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
758 PAGE_SYM error invalid_block {
761 | PAGE_SYM error ';' {
767 FONT_FACE_SYM maybe_space
768 '{' maybe_space declaration_list '}' maybe_space {
769 $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
771 | FONT_FACE_SYM error invalid_block {
774 | FONT_FACE_SYM error ';' {
780 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
781 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
782 | '>' maybe_space { $$ = CSSSelector::Child; }
791 selector_list '{' maybe_space declaration_list closing_brace {
792 $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
797 selector %prec UNIMPORTANT_TOK {
799 CSSParser* p = static_cast<CSSParser*>(parser);
800 $$ = p->reusableSelectorVector();
801 deleteAllValues(*$$);
803 $$->append(p->sinkFloatingSelector($1));
806 | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
808 CSSParser* p = static_cast<CSSParser*>(parser);
810 $$->append(p->sinkFloatingSelector($4));
814 | selector_list error {
819 selector_with_trailing_whitespace:
820 selector WHITESPACE {
829 | selector_with_trailing_whitespace
833 | selector_with_trailing_whitespace simple_selector
839 CSSParser* p = static_cast<CSSParser*>(parser);
840 CSSSelector* end = $$;
841 while (end->tagHistory())
842 end = end->tagHistory();
843 end->m_relation = CSSSelector::Descendant;
844 end->setTagHistory(p->sinkFloatingSelector($1));
845 if (Document* doc = p->document())
846 doc->setUsesDescendantRules(true);
849 | selector combinator simple_selector {
854 CSSParser* p = static_cast<CSSParser*>(parser);
855 CSSSelector* end = $$;
856 while (end->tagHistory())
857 end = end->tagHistory();
858 end->m_relation = $2;
859 end->setTagHistory(p->sinkFloatingSelector($1));
860 if ($2 == CSSSelector::Child) {
861 if (Document* doc = p->document())
862 doc->setUsesDescendantRules(true);
863 } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
864 if (Document* doc = p->document())
865 doc->setUsesSiblingRules(true);
875 /* empty */ '|' { $$.characters = 0; $$.length = 0; }
876 | '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
877 | IDENT '|' { $$ = $1; }
882 CSSParser* p = static_cast<CSSParser*>(parser);
883 $$ = p->createFloatingSelector();
884 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
886 | element_name specifier_list {
889 CSSParser* p = static_cast<CSSParser*>(parser);
890 $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
895 CSSParser* p = static_cast<CSSParser*>(parser);
896 if ($$ && p->m_defaultNamespace != starAtom)
897 $$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace);
899 | namespace_selector element_name {
900 AtomicString namespacePrefix = $1;
901 CSSParser* p = static_cast<CSSParser*>(parser);
902 $$ = p->createFloatingSelector();
904 $$->m_tag = QualifiedName(namespacePrefix, $2,
905 p->m_styleSheet->determineNamespace(namespacePrefix));
906 else // FIXME: Shouldn't this case be an error?
907 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
909 | namespace_selector element_name specifier_list {
912 AtomicString namespacePrefix = $1;
913 CSSParser* p = static_cast<CSSParser*>(parser);
915 $$->m_tag = QualifiedName(namespacePrefix, $2,
916 p->m_styleSheet->determineNamespace(namespacePrefix));
917 else // FIXME: Shouldn't this case be an error?
918 $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
921 | namespace_selector specifier_list {
924 AtomicString namespacePrefix = $1;
925 CSSParser* p = static_cast<CSSParser*>(parser);
927 $$->m_tag = QualifiedName(namespacePrefix, starAtom,
928 p->m_styleSheet->determineNamespace(namespacePrefix));
935 CSSParserString& str = $1;
936 CSSParser* p = static_cast<CSSParser*>(parser);
937 Document* doc = p->document();
938 if (doc && doc->isHTMLDocument())
943 static UChar star = '*';
944 $$.characters = ☆
953 | specifier_list specifier {
958 CSSParser* p = static_cast<CSSParser*>(parser);
959 CSSSelector* end = $1;
960 while (end->tagHistory())
961 end = end->tagHistory();
962 end->m_relation = CSSSelector::SubSelector;
963 end->setTagHistory(p->sinkFloatingSelector($2));
966 | specifier_list error {
973 CSSParser* p = static_cast<CSSParser*>(parser);
974 $$ = p->createFloatingSelector();
975 $$->m_match = CSSSelector::Id;
981 if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
984 CSSParser* p = static_cast<CSSParser*>(parser);
985 $$ = p->createFloatingSelector();
986 $$->m_match = CSSSelector::Id;
999 CSSParser* p = static_cast<CSSParser*>(parser);
1000 $$ = p->createFloatingSelector();
1001 $$->m_match = CSSSelector::Class;
1010 CSSParserString& str = $1;
1011 CSSParser* p = static_cast<CSSParser*>(parser);
1012 Document* doc = p->document();
1013 if (doc && doc->isHTMLDocument())
1020 '[' maybe_space attr_name ']' {
1021 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1022 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1023 $$->m_match = CSSSelector::Set;
1025 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
1026 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1027 $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
1028 $$->m_match = (CSSSelector::Match)$4;
1031 | '[' maybe_space namespace_selector attr_name ']' {
1032 AtomicString namespacePrefix = $3;
1033 CSSParser* p = static_cast<CSSParser*>(parser);
1034 $$ = p->createFloatingSelector();
1035 $$->setAttribute(QualifiedName(namespacePrefix, $4,
1036 p->m_styleSheet->determineNamespace(namespacePrefix)));
1037 $$->m_match = CSSSelector::Set;
1039 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
1040 AtomicString namespacePrefix = $3;
1041 CSSParser* p = static_cast<CSSParser*>(parser);
1042 $$ = p->createFloatingSelector();
1043 $$->setAttribute(QualifiedName(namespacePrefix, $4,
1044 p->m_styleSheet->determineNamespace(namespacePrefix)));
1045 $$->m_match = (CSSSelector::Match)$5;
1052 $$ = CSSSelector::Exact;
1055 $$ = CSSSelector::List;
1058 $$ = CSSSelector::Hyphen;
1061 $$ = CSSSelector::Begin;
1064 $$ = CSSSelector::End;
1067 $$ = CSSSelector::Contain;
1078 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1079 $$->m_match = CSSSelector::PseudoClass;
1082 CSSSelector::PseudoType type = $$->pseudoType();
1083 if (type == CSSSelector::PseudoUnknown)
1085 else if (type == CSSSelector::PseudoEmpty ||
1086 type == CSSSelector::PseudoFirstChild ||
1087 type == CSSSelector::PseudoFirstOfType ||
1088 type == CSSSelector::PseudoLastChild ||
1089 type == CSSSelector::PseudoLastOfType ||
1090 type == CSSSelector::PseudoOnlyChild ||
1091 type == CSSSelector::PseudoOnlyOfType) {
1092 CSSParser* p = static_cast<CSSParser*>(parser);
1093 Document* doc = p->document();
1095 doc->setUsesSiblingRules(true);
1096 } else if (type == CSSSelector::PseudoFirstLine) {
1097 CSSParser* p = static_cast<CSSParser*>(parser);
1098 if (Document* doc = p->document())
1099 doc->setUsesFirstLineRules(true);
1100 } else if (type == CSSSelector::PseudoBefore ||
1101 type == CSSSelector::PseudoAfter) {
1102 CSSParser* p = static_cast<CSSParser*>(parser);
1103 if (Document* doc = p->document())
1104 doc->setUsesBeforeAfterRules(true);
1108 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
1109 $$->m_match = CSSSelector::PseudoElement;
1112 CSSSelector::PseudoType type = $$->pseudoType();
1113 if (type == CSSSelector::PseudoUnknown)
1115 else if (type == CSSSelector::PseudoFirstLine) {
1116 CSSParser* p = static_cast<CSSParser*>(parser);
1117 if (Document* doc = p->document())
1118 doc->setUsesFirstLineRules(true);
1119 } else if (type == CSSSelector::PseudoBefore ||
1120 type == CSSSelector::PseudoAfter) {
1121 CSSParser* p = static_cast<CSSParser*>(parser);
1122 if (Document* doc = p->document())
1123 doc->setUsesBeforeAfterRules(true);
1126 // used by :nth-*(ax+b)
1127 | ':' FUNCTION NTH ')' {
1128 CSSParser *p = static_cast<CSSParser*>(parser);
1129 $$ = p->createFloatingSelector();
1130 $$->m_match = CSSSelector::PseudoClass;
1131 $$->setArgument($3);
1133 CSSSelector::PseudoType type = $$->pseudoType();
1134 if (type == CSSSelector::PseudoUnknown)
1136 else if (type == CSSSelector::PseudoNthChild ||
1137 type == CSSSelector::PseudoNthOfType ||
1138 type == CSSSelector::PseudoNthLastChild ||
1139 type == CSSSelector::PseudoNthLastOfType) {
1141 p->document()->setUsesSiblingRules(true);
1145 | ':' FUNCTION INTEGER ')' {
1146 CSSParser *p = static_cast<CSSParser*>(parser);
1147 $$ = p->createFloatingSelector();
1148 $$->m_match = CSSSelector::PseudoClass;
1149 $$->setArgument(String::number($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);
1162 // used by :nth-*(odd/even) and :lang
1163 | ':' FUNCTION IDENT ')' {
1164 CSSParser *p = static_cast<CSSParser*>(parser);
1165 $$ = p->createFloatingSelector();
1166 $$->m_match = CSSSelector::PseudoClass;
1167 $$->setArgument($3);
1170 CSSSelector::PseudoType type = $$->pseudoType();
1171 if (type == CSSSelector::PseudoUnknown)
1173 else if (type == CSSSelector::PseudoNthChild ||
1174 type == CSSSelector::PseudoNthOfType ||
1175 type == CSSSelector::PseudoNthLastChild ||
1176 type == CSSSelector::PseudoNthLastOfType) {
1178 p->document()->setUsesSiblingRules(true);
1182 | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
1183 if (!$4 || $4->simpleSelector() || $4->tagHistory())
1186 CSSParser* p = static_cast<CSSParser*>(parser);
1187 $$ = p->createFloatingSelector();
1188 $$->m_match = CSSSelector::PseudoClass;
1189 $$->setSimpleSelector(p->sinkFloatingSelector($4));
1200 | decl_list declaration {
1208 | error invalid_block_list error {
1217 | decl_list invalid_block_list {
1223 declaration ';' maybe_space {
1226 | declaration invalid_block_list ';' maybe_space {
1229 | error ';' maybe_space {
1232 | error invalid_block_list error ';' maybe_space {
1235 | decl_list declaration ';' maybe_space {
1240 | decl_list error ';' maybe_space {
1243 | decl_list error invalid_block_list error ';' maybe_space {
1249 property ':' maybe_space expr prio {
1251 CSSParser* p = static_cast<CSSParser*>(parser);
1253 p->m_valueList = p->sinkFloatingValueList($4);
1254 int oldParsedProperties = p->m_numParsedProperties;
1255 $$ = p->parseValue($1, $5);
1257 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1258 delete p->m_valueList;
1263 variable_reference maybe_space {
1264 CSSParser* p = static_cast<CSSParser*>(parser);
1265 p->m_valueList = new CSSParserValueList;
1266 p->m_valueList->addValue(p->sinkFloatingValue($1));
1267 int oldParsedProperties = p->m_numParsedProperties;
1268 $$ = p->parseValue(CSSPropertyWebkitVariableDeclarationBlock, false);
1270 p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
1271 delete p->m_valueList;
1279 property ':' maybe_space error expr prio {
1280 /* The default movable type template has letter-spacing: .none; Handle this by looking for
1281 error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
1282 up and deleting the shifted expr. */
1286 property ':' maybe_space expr prio error {
1287 /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1291 IMPORTANT_SYM maybe_space {
1292 /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
1296 property ':' maybe_space {
1297 /* div { font-family: } Just reduce away this property with no value. */
1301 property ':' maybe_space error {
1302 /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
1306 property invalid_block {
1307 /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */
1314 $$ = cssPropertyID($1);
1319 IMPORTANT_SYM maybe_space { $$ = true; }
1320 | /* empty */ { $$ = false; }
1325 CSSParser* p = static_cast<CSSParser*>(parser);
1326 $$ = p->createFloatingValueList();
1327 $$->addValue(p->sinkFloatingValue($1));
1329 | expr operator term {
1330 CSSParser* p = static_cast<CSSParser*>(parser);
1336 v.unit = CSSParserValue::Operator;
1340 $$->addValue(p->sinkFloatingValue($3));
1361 unary_term { $$ = $1; }
1362 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1363 | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1364 | IDENT maybe_space {
1365 $$.id = cssValueKeywordID($1);
1366 $$.unit = CSSPrimitiveValue::CSS_IDENT;
1369 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1370 | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1371 | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1372 | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1373 | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1374 | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1375 | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1376 /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1380 | variable_reference maybe_space {
1383 | '%' maybe_space { $$.id = 0; $$.fValue = 0; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; } /* Handle width: %; ANDROID: Fix an uninitialized Value object causing the device to crash */
1387 INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1388 | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1389 | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1390 | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1391 | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
1392 | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
1393 | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
1394 | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
1395 | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
1396 | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
1397 | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
1398 | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
1399 | TURNS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_TURN; }
1400 | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
1401 | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
1402 | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
1403 | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
1404 | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
1405 | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSParserValue::Q_EMS; }
1406 | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
1413 $$.unit = CSSPrimitiveValue::CSS_PARSER_VARIABLE_FUNCTION_SYNTAX;
1418 FUNCTION maybe_space expr ')' maybe_space {
1419 CSSParser* p = static_cast<CSSParser*>(parser);
1420 CSSParserFunction* f = p->createFloatingFunction();
1422 f->args = p->sinkFloatingValueList($3);
1424 $$.unit = CSSParserValue::Function;
1427 FUNCTION maybe_space error {
1428 CSSParser* p = static_cast<CSSParser*>(parser);
1429 CSSParserFunction* f = p->createFloatingFunction();
1433 $$.unit = CSSParserValue::Function;
1438 * There is a constraint on the color that it must
1439 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
1440 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
1443 HEX maybe_space { $$ = $1; }
1444 | IDSEL maybe_space { $$ = $1; }
1448 /* error handling rules */
1454 | error closing_brace {
1460 ATKEYWORD error invalid_block {
1463 | ATKEYWORD error ';' {
1469 invalid_at maybe_sgml
1470 | invalid_at_list invalid_at maybe_sgml
1486 error invalid_block {
1491 Seems like the two rules below are trying too much and violating
1492 http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
1504 '{' error invalid_block_list error closing_brace
1505 | '{' error closing_brace
1510 | invalid_block_list error invalid_block