4 * This file is part of the KDE libraries
5 * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
6 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
7 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "CSSMediaRule.h"
28 #include "CSSPrimitiveValue.h"
30 #include "CSSRuleList.h"
31 #include "CSSSelector.h"
32 #include "CSSStyleSheet.h"
34 #include "HTMLNames.h"
35 #include "MediaList.h"
36 #include "MediaQuery.h"
37 #include "MediaQueryExp.h"
38 #include "PlatformString.h"
39 #include "cssparser.h"
45 #include "ksvgcssproperties.h"
46 #include "ksvgcssvalues.h"
49 using namespace WebCore;
50 using namespace HTMLNames;
52 // The following file defines the function
53 // const struct props *findProp(const char *word, int len)
55 // with 'props->id' a CSS property in the range from CSS_PROP_MIN to
56 // (and including) CSS_PROP_TOTAL-1
58 #include "CSSPropertyNames.c"
59 #include "CSSValueKeywords.c"
63 int getPropertyID(const char* tagStr, int len)
65 DeprecatedString prop;
67 if (len && tagStr[0] == '-') {
68 prop = DeprecatedString(tagStr, len);
69 if (prop.startsWith("-apple-")) {
70 prop = "-webkit-" + prop.mid(7);
71 tagStr = prop.ascii();
73 } else if (prop.startsWith("-khtml-")) {
74 prop = "-webkit-" + prop.mid(7);
76 tagStr = prop.ascii();
79 // Honor the use of old-style opacity (for Safari 1.1).
80 if (prop == "-webkit-opacity") {
81 const char * const opacity = "opacity";
83 len = strlen(opacity);
87 const struct props* propsPtr = findProp(tagStr, len);
96 static inline int getValueID(const char* tagStr, int len)
98 DeprecatedString prop;
99 if (len && tagStr[0] == '-') {
100 prop = DeprecatedString(tagStr, len);
101 if (prop.startsWith("-apple-")) {
102 prop = "-webkit-" + prop.mid(7);
103 tagStr = prop.ascii();
105 } else if (prop.startsWith("-khtml-")) {
106 prop = "-webkit-" + prop.mid(7);
108 tagStr = prop.ascii();
112 const struct css_value *val = findValue(tagStr, len);
119 #define YYENABLE_NLS 0
120 #define YYLTYPE_IS_TRIVIAL 1
121 #define YYMAXDEPTH 10000
123 #define YYPARSE_PARAM parser
131 CSSSelector* selector;
133 MediaList *mediaList;
134 CSSMediaRule* mediaRule;
135 CSSRuleList* ruleList;
140 CSSSelector::Relation relation;
145 ValueList* valueList;
147 MediaQuery* mediaQuery;
148 MediaQueryExp* mediaQueryExp;
149 Vector<MediaQueryExp*>* mediaQueryExpList;
150 MediaQuery::Restrictor mediaQueryRestrictor;
155 static inline int cssyyerror(const char *) { return 1; }
156 static int cssyylex(YYSTYPE *yylval) { return CSSParser::current()->lex(yylval); }
162 %left UNIMPORTANT_TOK
164 %token WHITESPACE SGML_CD
172 %token <string> STRING
174 %right <string> IDENT
176 %nonassoc <string> HASH
180 %nonassoc <string> '*'
190 %token WEBKIT_RULE_SYM
191 %token WEBKIT_DECLS_SYM
192 %token WEBKIT_VALUE_SYM
193 %token WEBKIT_MEDIAQUERY_SYM
216 %token <string> DIMEN
217 %token <val> PERCENTAGE
222 %token <string> FUNCTION
223 %token <string> NOTFUNCTION
225 %token <string> UNICODERANGE
227 %type <relation> combinator
231 %type <rule> ruleset_or_import
235 %type <rule> font_face
236 %type <rule> invalid_rule
237 %type <rule> invalid_at
238 %type <rule> invalid_import
241 %type <string> maybe_ns_prefix
243 %type <string> namespace_selector
245 %type <string> string_or_uri
246 %type <string> ident_or_string
247 %type <string> medium
248 %type <string> hexcolor
250 %type <string> media_feature
251 %type <mediaList> media_list
252 %type <mediaList> maybe_media_list
253 %type <mediaQuery> media_query
254 %type <mediaQueryRestrictor> maybe_media_restrictor
255 %type <valueList> maybe_media_value
256 %type <mediaQueryExp> media_query_exp
257 %type <mediaQueryExpList> media_query_exp_list
258 %type <mediaQueryExpList> maybe_media_query_exp_list
260 %type <ruleList> ruleset_list
262 %type <prop_id> property
264 %type <selector> specifier
265 %type <selector> specifier_list
266 %type <selector> simple_selector
267 %type <selector> selector
268 %type <selector> selector_list
269 %type <selector> class
270 %type <selector> attrib
271 %type <selector> pseudo
273 %type <ok> declaration_list
275 %type <ok> declaration
280 %type <i> unary_operator
283 %type <valueList> expr
285 %type <value> unary_term
286 %type <value> function
288 %type <string> element_name
289 %type <string> attr_name
294 maybe_charset maybe_sgml import_list namespace_list rule_list
295 | webkit_rule maybe_space
296 | webkit_decls maybe_space
297 | webkit_value maybe_space
298 | webkit_mediaquery maybe_space
307 WEBKIT_RULE_SYM '{' maybe_space ruleset_or_import maybe_space '}' {
308 static_cast<CSSParser*>(parser)->rule = $4;
313 WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
319 WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
320 CSSParser *p = static_cast<CSSParser *>(parser);
322 p->valueList = p->sinkFloatingValueList($4);
323 int oldParsedProperties = p->numParsedProperties;
324 if (!p->parseValue(p->id, p->important))
325 p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
333 WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
334 CSSParser* p = static_cast<CSSParser*>(parser);
335 p->mediaQuery = p->sinkFloatingMediaQuery($4);
340 /* empty */ %prec UNIMPORTANT_TOK
341 | maybe_space WHITESPACE
347 | maybe_sgml WHITESPACE
357 CHARSET_SYM maybe_space STRING maybe_space ';' {
358 CSSParser* p = static_cast<CSSParser*>(parser);
359 $$ = static_cast<CSSParser *>(parser)->createCharsetRule($3);
360 if ($$ && p->styleElement && p->styleElement->isCSSStyleSheet())
361 p->styleElement->append($$);
363 | CHARSET_SYM error invalid_block {
365 | CHARSET_SYM error ';' {
371 | import_list import maybe_sgml {
372 CSSParser* p = static_cast<CSSParser*>(parser);
373 if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
374 p->styleElement->append($2);
380 | namespace_list namespace maybe_sgml
385 | rule_list rule maybe_sgml {
386 CSSParser* p = static_cast<CSSParser*>(parser);
387 if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
388 p->styleElement->append($2);
403 IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
404 $$ = static_cast<CSSParser *>(parser)->createImportRule($3, $5);
406 | IMPORT_SYM error invalid_block {
409 | IMPORT_SYM error ';' {
415 NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
416 CSSParser *p = static_cast<CSSParser *>(parser);
417 if (p->styleElement && p->styleElement->isCSSStyleSheet())
418 static_cast<CSSStyleSheet*>(p->styleElement)->addNamespace(p, atomicString($3), atomicString($4));
420 | NAMESPACE_SYM error invalid_block
421 | NAMESPACE_SYM error ';'
425 /* empty */ { $$.characters = 0; }
426 | IDENT WHITESPACE { $$ = $1; }
444 | ':' maybe_space expr maybe_space {
450 MEDIA_AND maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
452 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp(atomicString($5), $7);
456 media_query_exp_list:
458 CSSParser* p = static_cast<CSSParser*>(parser);
459 $$ = p->createFloatingMediaQueryExpList();
460 $$->append(p->sinkFloatingMediaQueryExp($1));
462 | media_query_exp_list media_query_exp {
464 $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
468 maybe_media_query_exp_list:
470 $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
472 | media_query_exp_list
475 maybe_media_restrictor:
477 $$ = MediaQuery::None;
480 $$ = MediaQuery::Only;
483 $$ = MediaQuery::Not;
488 maybe_media_restrictor maybe_space medium maybe_media_query_exp_list {
489 CSSParser* p = static_cast<CSSParser*>(parser);
491 $$ = p->createFloatingMediaQuery($1, domString($3), p->sinkFloatingMediaQueryExpList($4));
497 $$ = static_cast<CSSParser*>(parser)->createMediaList();
504 CSSParser* p = static_cast<CSSParser*>(parser);
505 $$ = p->createMediaList();
506 $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
508 | media_list ',' maybe_space media_query {
511 $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
519 MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' {
520 $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
522 | MEDIA_SYM maybe_space '{' maybe_space ruleset_list '}' {
523 $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
528 /* empty */ { $$ = 0; }
529 | ruleset_list ruleset maybe_space {
533 $$ = static_cast<CSSParser*>(parser)->createRuleList();
547 PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
548 '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
556 : FONT_FACE_SYM maybe_space
557 '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
562 PAGE_SYM error invalid_block {
565 | PAGE_SYM error ';' {
571 FONT_FACE_SYM error invalid_block {
574 | FONT_FACE_SYM error ';' {
580 '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
581 | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
582 | '>' maybe_space { $$ = CSSSelector::Child; }
583 | /* empty */ { $$ = CSSSelector::Descendant; }
592 selector_list '{' maybe_space declaration_list '}' {
593 $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
598 selector %prec UNIMPORTANT_TOK {
601 | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
603 CSSParser* p = static_cast<CSSParser*>(parser);
605 $$->append(p->sinkFloatingSelector($4));
610 | selector_list error {
619 | selector combinator simple_selector {
625 CSSParser* p = static_cast<CSSParser*>(parser);
626 CSSSelector* end = $$;
627 while (end->tagHistory)
628 end = end->tagHistory;
629 end->m_relation = $2;
630 end->tagHistory = p->sinkFloatingSelector($1);
631 if ($2 == CSSSelector::Descendant || $2 == CSSSelector::Child) {
632 if (Document* doc = p->document())
633 doc->setUsesDescendantRules(true);
634 } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
635 if (Document* doc = p->document())
636 doc->setUsesSiblingRules(true);
646 /* empty */ '|' { $$.characters = 0; $$.length = 0; }
647 | '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
648 | IDENT '|' { $$ = $1; }
652 element_name maybe_space {
653 CSSParser *p = static_cast<CSSParser *>(parser);
654 $$ = p->createFloatingSelector();
655 $$->tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
657 | element_name specifier_list maybe_space {
660 CSSParser *p = static_cast<CSSParser *>(parser);
661 $$->tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
664 | specifier_list maybe_space {
666 CSSParser *p = static_cast<CSSParser *>(parser);
667 if ($$ && p->defaultNamespace != starAtom)
668 $$->tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
670 | namespace_selector element_name maybe_space {
671 AtomicString namespacePrefix = atomicString($1);
672 CSSParser *p = static_cast<CSSParser *>(parser);
673 $$ = p->createFloatingSelector();
674 if (p->styleElement && p->styleElement->isCSSStyleSheet())
675 $$->tag = QualifiedName(namespacePrefix,
677 static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
678 else // FIXME: Shouldn't this case be an error?
679 $$->tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
681 | namespace_selector element_name specifier_list maybe_space {
684 AtomicString namespacePrefix = atomicString($1);
685 CSSParser *p = static_cast<CSSParser *>(parser);
686 if (p->styleElement && p->styleElement->isCSSStyleSheet())
687 $$->tag = QualifiedName(namespacePrefix,
689 static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
690 else // FIXME: Shouldn't this case be an error?
691 $$->tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
694 | namespace_selector specifier_list maybe_space {
697 AtomicString namespacePrefix = atomicString($1);
698 CSSParser *p = static_cast<CSSParser *>(parser);
699 if (p->styleElement && p->styleElement->isCSSStyleSheet())
700 $$->tag = QualifiedName(namespacePrefix,
702 static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
709 ParseString& str = $1;
710 CSSParser *p = static_cast<CSSParser *>(parser);
711 Document *doc = p->document();
712 if (doc && doc->isHTMLDocument())
717 static UChar star = '*';
718 $$.characters = ☆
727 | specifier_list specifier {
730 CSSParser* p = static_cast<CSSParser*>(parser);
731 CSSSelector* end = $1;
732 while (end->tagHistory)
733 end = end->tagHistory;
734 end->m_relation = CSSSelector::SubSelector;
735 end->tagHistory = p->sinkFloatingSelector($2);
738 | specifier_list error {
745 CSSParser *p = static_cast<CSSParser *>(parser);
746 $$ = p->createFloatingSelector();
747 $$->match = CSSSelector::Id;
751 $$->value = atomicString($1);
760 CSSParser *p = static_cast<CSSParser *>(parser);
761 $$ = p->createFloatingSelector();
762 $$->match = CSSSelector::Class;
765 $$->attr = classAttr;
766 $$->value = atomicString($2);
772 ParseString& str = $1;
773 CSSParser *p = static_cast<CSSParser *>(parser);
774 Document *doc = p->document();
775 if (doc && doc->isHTMLDocument())
782 '[' maybe_space attr_name ']' {
783 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
784 $$->attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
785 $$->match = CSSSelector::Set;
787 | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
788 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
789 $$->attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
790 $$->match = (CSSSelector::Match)$4;
791 $$->value = atomicString($6);
793 | '[' maybe_space namespace_selector attr_name ']' {
794 AtomicString namespacePrefix = atomicString($3);
795 CSSParser *p = static_cast<CSSParser *>(parser);
796 $$ = p->createFloatingSelector();
797 $$->attr = QualifiedName(namespacePrefix,
799 static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
800 $$->match = CSSSelector::Set;
802 | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
803 AtomicString namespacePrefix = atomicString($3);
804 CSSParser *p = static_cast<CSSParser *>(parser);
805 $$ = p->createFloatingSelector();
806 $$->attr = QualifiedName(namespacePrefix,
808 static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
809 $$->match = (CSSSelector::Match)$5;
810 $$->value = atomicString($7);
816 $$ = CSSSelector::Exact;
819 $$ = CSSSelector::List;
822 $$ = CSSSelector::Hyphen;
825 $$ = CSSSelector::Begin;
828 $$ = CSSSelector::End;
831 $$ = CSSSelector::Contain;
842 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
843 $$->match = CSSSelector::PseudoClass;
845 $$->value = atomicString($2);
846 if ($$->value == "empty" || $$->value == "only-child" ||
847 $$->value == "first-child" || $$->value == "last-child") {
848 CSSParser *p = static_cast<CSSParser *>(parser);
849 Document *doc = p->document();
851 doc->setUsesSiblingRules(true);
855 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
856 $$->match = CSSSelector::PseudoElement;
858 $$->value = atomicString($3);
861 | ':' FUNCTION IDENT ')' {
862 $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
863 $$->match = CSSSelector::PseudoClass;
864 $$->argument = atomicString($3);
866 $$->value = atomicString($2);
869 | ':' NOTFUNCTION maybe_space simple_selector ')' {
870 CSSParser* p = static_cast<CSSParser*>(parser);
871 $$ = p->createFloatingSelector();
872 $$->match = CSSSelector::PseudoClass;
873 $$->simpleSelector = p->sinkFloatingSelector($4);
875 $$->value = atomicString($2);
883 | decl_list declaration {
891 | error invalid_block_list error {
903 declaration ';' maybe_space {
906 | declaration invalid_block_list ';' maybe_space {
909 | error ';' maybe_space {
912 | error invalid_block_list error ';' maybe_space {
915 | decl_list declaration ';' maybe_space {
920 | decl_list error ';' maybe_space {
923 | decl_list error invalid_block_list error ';' maybe_space {
929 property ':' maybe_space expr prio {
931 CSSParser *p = static_cast<CSSParser *>(parser);
933 p->valueList = p->sinkFloatingValueList($4);
934 int oldParsedProperties = p->numParsedProperties;
935 $$ = p->parseValue($1, $5);
937 p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
947 property ':' maybe_space error expr prio {
948 /* The default movable type template has letter-spacing: .none; Handle this by looking for
949 error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
950 up and deleting the shifted expr. */
954 IMPORTANT_SYM maybe_space {
955 /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
959 property ':' maybe_space {
960 /* div { font-family: } Just reduce away this property with no value. */
968 DeprecatedString str = deprecatedString($1);
969 const char* s = str.ascii();
970 int l = str.length();
971 $$ = getPropertyID(s, l);
974 $$ = SVG::getSVGCSSPropertyID(s, l);
980 IMPORTANT_SYM maybe_space { $$ = true; }
981 | /* empty */ { $$ = false; }
986 CSSParser* p = static_cast<CSSParser*>(parser);
987 $$ = p->createFloatingValueList();
988 $$->addValue(p->sinkFloatingValue($1));
990 | expr operator term {
991 CSSParser* p = static_cast<CSSParser*>(parser);
997 v.unit = Value::Operator;
1001 $$->addValue(p->sinkFloatingValue($3));
1022 unary_term { $$ = $1; }
1023 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1024 | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1025 | IDENT maybe_space {
1026 DeprecatedString str = deprecatedString($1);
1027 $$.id = getValueID(str.lower().latin1(), str.length());
1030 $$.id = SVG::getSVGCSSValueID(str.lower().latin1(), str.length());
1032 $$.unit = CSSPrimitiveValue::CSS_IDENT;
1035 /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1036 | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1037 | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1038 | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1039 | UNICODERANGE maybe_space { $$.id = 0; $$.iValue = 0; $$.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ }
1040 | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
1041 | '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
1042 /* ### according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1049 INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1050 | FLOAT maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1051 | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1052 | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1053 | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
1054 | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
1055 | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
1056 | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
1057 | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
1058 | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
1059 | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
1060 | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
1061 | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
1062 | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
1063 | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
1064 | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
1065 | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
1066 | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS; }
1067 | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
1072 FUNCTION maybe_space expr ')' maybe_space {
1073 CSSParser* p = static_cast<CSSParser*>(parser);
1074 Function* f = p->createFloatingFunction();
1076 f->args = p->sinkFloatingValueList($3);
1078 $$.unit = Value::Function;
1081 FUNCTION maybe_space error {
1082 CSSParser* p = static_cast<CSSParser*>(parser);
1083 Function* f = p->createFloatingFunction();
1087 $$.unit = Value::Function;
1092 * There is a constraint on the color that it must
1093 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
1094 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
1097 HASH maybe_space { $$ = $1; }
1101 /* error handling rules */
1104 '@' error invalid_block {
1119 error invalid_block {
1123 Seems like the two rules below are trying too much and violating
1124 http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
1136 '{' error invalid_block_list error '}'
1142 | invalid_block_list error invalid_block