4
* This file is part of the KDE libraries
5
4
* Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
6
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc.
5
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7
6
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
9
9
* This library is free software; you can redistribute it and/or
10
10
* modify it under the terms of the GNU Lesser General Public
27
27
#include "CSSMediaRule.h"
28
28
#include "CSSParser.h"
29
#include "CSSPrimitiveValue.h"
31
29
#include "CSSRuleList.h"
32
30
#include "CSSSelector.h"
33
31
#include "CSSStyleSheet.h"
34
32
#include "Document.h"
35
33
#include "HTMLNames.h"
36
34
#include "MediaList.h"
37
#include "MediaQuery.h"
38
#include "MediaQueryExp.h"
39
#include "PlatformString.h"
40
35
#include <stdlib.h>
41
36
#include <string.h>
44
#include "ksvgcssproperties.h"
45
#include "ksvgcssvalues.h"
48
38
using namespace WebCore;
49
39
using namespace HTMLNames;
51
// The following file defines the function
52
// const struct props *findProp(const char *word, int len)
54
// with 'props->id' a CSS property in the range from CSS_PROP_MIN to
55
// (and including) CSS_PROP_TOTAL-1
57
#include "CSSPropertyNames.c"
58
#include "CSSValueKeywords.c"
62
int getPropertyID(const char* tagStr, int len)
64
DeprecatedString prop;
66
if (len && tagStr[0] == '-') {
67
prop = DeprecatedString(tagStr, len);
68
if (prop.startsWith("-apple-")) {
69
prop = "-webkit-" + prop.mid(7);
70
tagStr = prop.ascii();
72
} else if (prop.startsWith("-khtml-")) {
73
prop = "-webkit-" + prop.mid(7);
75
tagStr = prop.ascii();
78
// Honor the use of old-style opacity (for Safari 1.1).
79
if (prop == "-webkit-opacity") {
80
const char * const opacity = "opacity";
82
len = strlen(opacity);
86
const struct props* propsPtr = findProp(tagStr, len);
93
} // namespace WebCore
95
static inline int getValueID(const char* tagStr, int len)
97
DeprecatedString prop;
98
if (len && tagStr[0] == '-') {
99
prop = DeprecatedString(tagStr, len);
100
if (prop.startsWith("-apple-")) {
101
prop = "-webkit-" + prop.mid(7);
102
tagStr = prop.ascii();
104
} else if (prop.startsWith("-khtml-")) {
105
prop = "-webkit-" + prop.mid(7);
107
tagStr = prop.ascii();
111
const struct css_value* val = findValue(tagStr, len);
118
41
#define YYENABLE_NLS 0
119
42
#define YYLTYPE_IS_TRIVIAL 1
120
43
#define YYMAXDEPTH 10000
46
// FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
122
47
#define YYPARSE_PARAM parser
48
#define YYLEX_PARAM parser
62
CSSRuleList* ruleList;
130
63
CSSSelector* selector;
132
MediaList *mediaList;
133
CSSMediaRule* mediaRule;
134
CSSRuleList* ruleList;
139
64
CSSSelector::Relation relation;
66
MediaQuery* mediaQuery;
67
MediaQuery::Restrictor mediaQueryRestrictor;
68
MediaQueryExp* mediaQueryExp;
144
70
ValueList* valueList;
146
MediaQuery* mediaQuery;
147
MediaQueryExp* mediaQueryExp;
148
71
Vector<MediaQueryExp*>* mediaQueryExpList;
149
MediaQuery::Restrictor mediaQueryRestrictor;
154
static inline int cssyyerror(const char*) { return 1; }
155
static int cssyylex(YYSTYPE* yylval) { return CSSParser::current()->lex(yylval); }
76
static inline int cssyyerror(const char*)
81
static int cssyylex(YYSTYPE* yylval, void* parser)
83
return static_cast<CSSParser*>(parser)->lex(yylval);
161
90
%left UNIMPORTANT_TOK
255
185
%type <valueList> maybe_media_value
256
186
%type <mediaQueryExp> media_query_exp
257
187
%type <mediaQueryExpList> media_query_exp_list
258
%type <mediaQueryExpList> maybe_media_query_exp_list
188
%type <mediaQueryExpList> maybe_and_media_query_exp_list
260
190
%type <ruleList> ruleset_list
262
%type <prop_id> property
192
%type <integer> property
264
194
%type <selector> specifier
265
195
%type <selector> specifier_list
266
196
%type <selector> simple_selector
267
197
%type <selector> selector
268
198
%type <selector> selector_list
199
%type <selector> selector_with_trailing_whitespace
269
200
%type <selector> class
270
201
%type <selector> attrib
271
202
%type <selector> pseudo
273
%type <ok> declaration_list
275
%type <ok> declaration
280
%type <i> unary_operator
204
%type <boolean> declaration_list
205
%type <boolean> decl_list
206
%type <boolean> declaration
210
%type <integer> match
211
%type <integer> unary_operator
212
%type <character> operator
283
214
%type <valueList> expr
284
215
%type <value> term
319
250
WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
320
251
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);
253
p->m_valueList = p->sinkFloatingValueList($4);
254
int oldParsedProperties = p->m_numParsedProperties;
255
if (!p->parseValue(p->m_id, p->m_important))
256
p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
257
delete p->m_valueList;
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);
385
'(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
387
$$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5);
456
391
media_query_exp_list:
457
392
media_query_exp {
458
CSSParser* p = static_cast<CSSParser*>(parser);
459
$$ = p->createFloatingMediaQueryExpList();
460
$$->append(p->sinkFloatingMediaQueryExp($1));
393
CSSParser* p = static_cast<CSSParser*>(parser);
394
$$ = p->createFloatingMediaQueryExpList();
395
$$->append(p->sinkFloatingMediaQueryExp($1));
462
| media_query_exp_list media_query_exp {
464
$$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
397
| media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
399
$$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
468
maybe_media_query_exp_list:
403
maybe_and_media_query_exp_list:
470
405
$$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
472
| media_query_exp_list
407
| MEDIA_AND maybe_space media_query_exp_list {
475
412
maybe_media_restrictor:
645
611
| '*' '|' { static UChar star = '*'; $$.characters = ☆ $$.length = 1; }
646
612
| IDENT '|' { $$ = $1; }
650
element_name maybe_space {
651
617
CSSParser* p = static_cast<CSSParser*>(parser);
652
618
$$ = p->createFloatingSelector();
653
$$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
619
$$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
655
| element_name specifier_list maybe_space {
621
| element_name specifier_list {
658
624
CSSParser* p = static_cast<CSSParser*>(parser);
659
$$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
625
$$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
662
| specifier_list maybe_space {
664
630
CSSParser* p = static_cast<CSSParser*>(parser);
665
if ($$ && p->defaultNamespace != starAtom)
666
$$->m_tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
631
if ($$ && p->m_defaultNamespace != starAtom)
632
$$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace);
668
| namespace_selector element_name maybe_space {
669
AtomicString namespacePrefix = atomicString($1);
634
| namespace_selector element_name {
635
AtomicString namespacePrefix = $1;
670
636
CSSParser* p = static_cast<CSSParser*>(parser);
671
637
$$ = p->createFloatingSelector();
672
if (p->styleElement && p->styleElement->isCSSStyleSheet())
673
$$->m_tag = QualifiedName(namespacePrefix,
675
static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
639
$$->m_tag = QualifiedName(namespacePrefix, $2,
640
p->m_styleSheet->determineNamespace(namespacePrefix));
676
641
else // FIXME: Shouldn't this case be an error?
677
$$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
642
$$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
679
| namespace_selector element_name specifier_list maybe_space {
644
| namespace_selector element_name specifier_list {
682
AtomicString namespacePrefix = atomicString($1);
647
AtomicString namespacePrefix = $1;
683
648
CSSParser* p = static_cast<CSSParser*>(parser);
684
if (p->styleElement && p->styleElement->isCSSStyleSheet())
685
$$->m_tag = QualifiedName(namespacePrefix,
687
static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
650
$$->m_tag = QualifiedName(namespacePrefix, $2,
651
p->m_styleSheet->determineNamespace(namespacePrefix));
688
652
else // FIXME: Shouldn't this case be an error?
689
$$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
653
$$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
692
| namespace_selector specifier_list maybe_space {
656
| namespace_selector specifier_list {
695
AtomicString namespacePrefix = atomicString($1);
659
AtomicString namespacePrefix = $1;
696
660
CSSParser* p = static_cast<CSSParser*>(parser);
697
if (p->styleElement && p->styleElement->isCSSStyleSheet())
698
$$->m_tag = QualifiedName(namespacePrefix,
700
static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
662
$$->m_tag = QualifiedName(namespacePrefix, starAtom,
663
p->m_styleSheet->determineNamespace(namespacePrefix));
795
758
'[' maybe_space attr_name ']' {
796
759
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
797
$$->m_attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
760
$$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
798
761
$$->m_match = CSSSelector::Set;
800
763
| '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
801
764
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
802
$$->m_attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
765
$$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
803
766
$$->m_match = (CSSSelector::Match)$4;
804
$$->m_value = atomicString($6);
806
769
| '[' maybe_space namespace_selector attr_name ']' {
807
AtomicString namespacePrefix = atomicString($3);
770
AtomicString namespacePrefix = $3;
808
771
CSSParser* p = static_cast<CSSParser*>(parser);
809
772
$$ = p->createFloatingSelector();
810
$$->m_attr = QualifiedName(namespacePrefix,
812
static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
773
$$->m_attr = QualifiedName(namespacePrefix, $4,
774
p->m_styleSheet->determineNamespace(namespacePrefix));
813
775
$$->m_match = CSSSelector::Set;
815
777
| '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
816
AtomicString namespacePrefix = atomicString($3);
778
AtomicString namespacePrefix = $3;
817
779
CSSParser* p = static_cast<CSSParser*>(parser);
818
780
$$ = p->createFloatingSelector();
819
$$->m_attr = QualifiedName(namespacePrefix,
821
static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
781
$$->m_attr = QualifiedName(namespacePrefix, $4,
782
p->m_styleSheet->determineNamespace(namespacePrefix));
822
783
$$->m_match = (CSSSelector::Match)$5;
823
$$->m_value = atomicString($7);
855
816
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
856
817
$$->m_match = CSSSelector::PseudoClass;
858
$$->m_value = atomicString($2);
859
820
CSSSelector::PseudoType type = $$->pseudoType();
860
821
if (type == CSSSelector::PseudoUnknown)
862
823
else if (type == CSSSelector::PseudoEmpty ||
863
type == CSSSelector::PseudoFirstChild) {
824
type == CSSSelector::PseudoFirstChild ||
825
type == CSSSelector::PseudoFirstOfType ||
826
type == CSSSelector::PseudoLastChild ||
827
type == CSSSelector::PseudoLastOfType ||
828
type == CSSSelector::PseudoOnlyChild ||
829
type == CSSSelector::PseudoOnlyOfType) {
864
830
CSSParser* p = static_cast<CSSParser*>(parser);
865
831
Document* doc = p->document();
885
851
doc->setUsesFirstLineRules(true);
854
// used by :nth-*(ax+b)
855
| ':' FUNCTION NTH ')' {
856
CSSParser *p = static_cast<CSSParser*>(parser);
857
$$ = p->createFloatingSelector();
858
$$->m_match = CSSSelector::PseudoClass;
861
CSSSelector::PseudoType type = $$->pseudoType();
862
if (type == CSSSelector::PseudoUnknown)
864
else if (type == CSSSelector::PseudoNthChild ||
865
type == CSSSelector::PseudoNthOfType ||
866
type == CSSSelector::PseudoNthLastChild ||
867
type == CSSSelector::PseudoNthLastOfType) {
869
p->document()->setUsesSiblingRules(true);
873
| ':' FUNCTION INTEGER ')' {
874
CSSParser *p = static_cast<CSSParser*>(parser);
875
$$ = p->createFloatingSelector();
876
$$->m_match = CSSSelector::PseudoClass;
877
$$->m_argument = String::number($3);
879
CSSSelector::PseudoType type = $$->pseudoType();
880
if (type == CSSSelector::PseudoUnknown)
882
else if (type == CSSSelector::PseudoNthChild ||
883
type == CSSSelector::PseudoNthOfType ||
884
type == CSSSelector::PseudoNthLastChild ||
885
type == CSSSelector::PseudoNthLastOfType) {
887
p->document()->setUsesSiblingRules(true);
890
// used by :nth-*(odd/even) and :lang
889
891
| ':' FUNCTION IDENT ')' {
890
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
892
CSSParser *p = static_cast<CSSParser*>(parser);
893
$$ = p->createFloatingSelector();
891
894
$$->m_match = CSSSelector::PseudoClass;
892
$$->m_argument = atomicString($3);
894
$$->m_value = atomicString($2);
895
if ($$->pseudoType() == CSSSelector::PseudoUnknown)
898
CSSSelector::PseudoType type = $$->pseudoType();
899
if (type == CSSSelector::PseudoUnknown)
901
else if (type == CSSSelector::PseudoNthChild ||
902
type == CSSSelector::PseudoNthOfType ||
903
type == CSSSelector::PseudoNthLastChild ||
904
type == CSSSelector::PseudoNthLastOfType) {
906
p->document()->setUsesSiblingRules(true);
899
| ':' NOTFUNCTION maybe_space simple_selector ')' {
910
| ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
1070
1073
| DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1071
1074
| unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1072
1075
| URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1073
| UNICODERANGE maybe_space { $$.id = 0; $$.iValue = 0; $$.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ }
1076
| UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
1074
1077
| hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
1075
1078
| '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
1076
/* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1079
/* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1083
| '%' maybe_space {} /* Handle width: %; */
1083
1087
INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1084
| FLOAT maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1088
| FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1085
1089
| PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1086
1090
| PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1087
1091
| CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }