1/*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB.  If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#ifndef CSSParser_h
23#define CSSParser_h
24
25#include "AtomicString.h"
26#include "Color.h"
27#include "CSSParserValues.h"
28#include "CSSSelectorList.h"
29#include "MediaQuery.h"
30#include <wtf/HashSet.h>
31#include <wtf/Vector.h>
32
33namespace WebCore {
34
35    class CSSMutableStyleDeclaration;
36    class CSSPrimitiveValue;
37    class CSSProperty;
38    class CSSRule;
39    class CSSRuleList;
40    class CSSSelector;
41    class CSSStyleSheet;
42    class CSSValue;
43    class CSSValueList;
44    class CSSVariablesDeclaration;
45    class Document;
46    class MediaList;
47    class MediaQueryExp;
48    class StyleBase;
49    class StyleList;
50    class WebKitCSSKeyframeRule;
51    class WebKitCSSKeyframesRule;
52
53    class CSSParser {
54    public:
55        CSSParser(bool strictParsing = true);
56        ~CSSParser();
57
58        void parseSheet(CSSStyleSheet*, const String&);
59        PassRefPtr<CSSRule> parseRule(CSSStyleSheet*, const String&);
60        PassRefPtr<CSSRule> parseKeyframeRule(CSSStyleSheet*, const String&);
61        bool parseValue(CSSMutableStyleDeclaration*, int propId, const String&, bool important);
62        static bool parseColor(RGBA32& color, const String&, bool strict = false);
63        bool parseColor(CSSMutableStyleDeclaration*, const String&);
64        bool parseDeclaration(CSSMutableStyleDeclaration*, const String&);
65        bool parseMediaQuery(MediaList*, const String&);
66
67        Document* document() const;
68
69        void addProperty(int propId, PassRefPtr<CSSValue>, bool important);
70        void rollbackLastProperties(int num);
71        bool hasProperties() const { return m_numParsedProperties > 0; }
72
73        bool parseValue(int propId, bool important);
74        bool parseShorthand(int propId, const int* properties, int numProperties, bool important);
75        bool parse4Values(int propId, const int* properties, bool important);
76        bool parseContent(int propId, bool important);
77
78        PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args);
79
80        PassRefPtr<CSSValue> parseBackgroundColor();
81
82        bool parseFillImage(RefPtr<CSSValue>&);
83        PassRefPtr<CSSValue> parseFillPositionXY(bool& xFound, bool& yFound);
84        void parseFillPosition(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
85        void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
86        PassRefPtr<CSSValue> parseFillSize(int propId, bool &allowComma);
87
88        bool parseFillProperty(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
89        bool parseFillShorthand(int propId, const int* properties, int numProperties, bool important);
90
91        void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
92
93        void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
94
95        PassRefPtr<CSSValue> parseAnimationDelay();
96        PassRefPtr<CSSValue> parseAnimationDirection();
97        PassRefPtr<CSSValue> parseAnimationDuration();
98        PassRefPtr<CSSValue> parseAnimationIterationCount();
99        PassRefPtr<CSSValue> parseAnimationName();
100        PassRefPtr<CSSValue> parseAnimationPlayState();
101        PassRefPtr<CSSValue> parseAnimationProperty();
102        PassRefPtr<CSSValue> parseAnimationTimingFunction();
103
104        void parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
105        bool parseTimingFunctionValue(CSSParserValueList*& args, double& result);
106        bool parseAnimationProperty(int propId, RefPtr<CSSValue>&);
107        bool parseTransitionShorthand(bool important);
108        bool parseAnimationShorthand(bool important);
109
110        bool parseDashboardRegions(int propId, bool important);
111
112        bool parseShape(int propId, bool important);
113
114        bool parseFont(bool important);
115        PassRefPtr<CSSValueList> parseFontFamily();
116
117        bool parseCounter(int propId, int defaultValue, bool important);
118        PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
119
120        bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
121        bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
122        PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
123        bool parseColorFromValue(CSSParserValue*, RGBA32&, bool = false);
124        void parseSelector(const String&, Document* doc, CSSSelectorList&);
125
126        static bool parseColor(const String&, RGBA32& rgb, bool strict);
127
128        bool parseFontStyle(bool important);
129        bool parseFontVariant(bool important);
130        bool parseFontWeight(bool important);
131        bool parseFontFaceSrc();
132        bool parseFontFaceUnicodeRange();
133
134#if ENABLE(SVG)
135        bool parseSVGValue(int propId, bool important);
136        PassRefPtr<CSSValue> parseSVGPaint();
137        PassRefPtr<CSSValue> parseSVGColor();
138        PassRefPtr<CSSValue> parseSVGStrokeDasharray();
139#endif
140
141        // CSS3 Parsing Routines (for properties specific to CSS3)
142        bool parseShadow(int propId, bool important);
143        bool parseBorderImage(int propId, bool important, RefPtr<CSSValue>&);
144        bool parseBorderRadius(int propId, bool important);
145
146        bool parseReflect(int propId, bool important);
147
148        // Image generators
149        bool parseCanvas(RefPtr<CSSValue>&);
150        bool parseGradient(RefPtr<CSSValue>&);
151
152        PassRefPtr<CSSValueList> parseTransform();
153        bool parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
154        bool parsePerspectiveOrigin(int propId, int& propId1, int& propId2,  RefPtr<CSSValue>&, RefPtr<CSSValue>&);
155        bool parseVariable(CSSVariablesDeclaration*, const String& variableName, const String& variableValue);
156        void parsePropertyWithResolvedVariables(int propId, bool important, CSSMutableStyleDeclaration*, CSSParserValueList*);
157
158        int yyparse();
159
160        CSSSelector* createFloatingSelector();
161        CSSSelector* sinkFloatingSelector(CSSSelector*);
162
163        CSSParserValueList* createFloatingValueList();
164        CSSParserValueList* sinkFloatingValueList(CSSParserValueList*);
165
166        CSSParserFunction* createFloatingFunction();
167        CSSParserFunction* sinkFloatingFunction(CSSParserFunction*);
168
169        CSSParserValue& sinkFloatingValue(CSSParserValue&);
170
171        MediaList* createMediaList();
172        CSSRule* createCharsetRule(const CSSParserString&);
173        CSSRule* createImportRule(const CSSParserString&, MediaList*);
174        WebKitCSSKeyframeRule* createKeyframeRule(CSSParserValueList*);
175        WebKitCSSKeyframesRule* createKeyframesRule();
176        CSSRule* createMediaRule(MediaList*, CSSRuleList*);
177        CSSRuleList* createRuleList();
178        CSSRule* createStyleRule(Vector<CSSSelector*>* selectors);
179        CSSRule* createFontFaceRule();
180        CSSRule* createVariablesRule(MediaList*, bool variablesKeyword);
181
182        MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
183        MediaQueryExp* sinkFloatingMediaQueryExp(MediaQueryExp*);
184        Vector<MediaQueryExp*>* createFloatingMediaQueryExpList();
185        Vector<MediaQueryExp*>* sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>*);
186        MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, Vector<MediaQueryExp*>*);
187        MediaQuery* createFloatingMediaQuery(Vector<MediaQueryExp*>*);
188        MediaQuery* sinkFloatingMediaQuery(MediaQuery*);
189
190        void addNamespace(const AtomicString& prefix, const AtomicString& uri);
191
192        bool addVariable(const CSSParserString&, CSSParserValueList*);
193        bool addVariableDeclarationBlock(const CSSParserString&);
194        bool checkForVariables(CSSParserValueList*);
195        void addUnresolvedProperty(int propId, bool important);
196        void invalidBlockHit();
197
198        Vector<CSSSelector*>* reusableSelectorVector() { return &m_reusableSelectorVector; }
199
200        bool m_strict;
201        bool m_important;
202        int m_id;
203        CSSStyleSheet* m_styleSheet;
204        RefPtr<CSSRule> m_rule;
205        RefPtr<CSSRule> m_keyframe;
206        MediaQuery* m_mediaQuery;
207        CSSParserValueList* m_valueList;
208        CSSProperty** m_parsedProperties;
209        CSSSelectorList* m_selectorListForParseSelector;
210        unsigned m_numParsedProperties;
211        unsigned m_maxParsedProperties;
212
213        int m_inParseShorthand;
214        int m_currentShorthand;
215        bool m_implicitShorthand;
216
217        bool m_hasFontFaceOnlyValues;
218        bool m_hadSyntacticallyValidCSSRule;
219
220        Vector<String> m_variableNames;
221        Vector<RefPtr<CSSValue> > m_variableValues;
222
223        AtomicString m_defaultNamespace;
224
225        // tokenizer methods and data
226        int lex(void* yylval);
227        int token() { return yyTok; }
228        UChar* text(int* length);
229        int lex();
230
231    private:
232        void recheckAtKeyword(const UChar* str, int len);
233
234        void clearProperties();
235
236        void setupParser(const char* prefix, const String&, const char* suffix);
237
238        bool inShorthand() const { return m_inParseShorthand; }
239
240        void checkForOrphanedUnits();
241
242        void clearVariables();
243
244        void deleteFontFaceOnlyValues();
245
246        UChar* m_data;
247        UChar* yytext;
248        UChar* yy_c_buf_p;
249        UChar yy_hold_char;
250        int yy_last_accepting_state;
251        UChar* yy_last_accepting_cpos;
252        int yyleng;
253        int yyTok;
254        int yy_start;
255
256        bool m_allowImportRules;
257        bool m_allowVariablesRules;
258        bool m_allowNamespaceDeclarations;
259
260        Vector<RefPtr<StyleBase> > m_parsedStyleObjects;
261        Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
262        HashSet<CSSSelector*> m_floatingSelectors;
263        HashSet<CSSParserValueList*> m_floatingValueLists;
264        HashSet<CSSParserFunction*> m_floatingFunctions;
265
266        MediaQuery* m_floatingMediaQuery;
267        MediaQueryExp* m_floatingMediaQueryExp;
268        Vector<MediaQueryExp*>* m_floatingMediaQueryExpList;
269
270        Vector<CSSSelector*> m_reusableSelectorVector;
271
272        // defines units allowed for a certain property, used in parseUnit
273        enum Units {
274            FUnknown   = 0x0000,
275            FInteger   = 0x0001,
276            FNumber    = 0x0002,  // Real Numbers
277            FPercent   = 0x0004,
278            FLength    = 0x0008,
279            FAngle     = 0x0010,
280            FTime      = 0x0020,
281            FFrequency = 0x0040,
282            FRelative  = 0x0100,
283            FNonNeg    = 0x0200
284        };
285
286        friend inline Units operator|(Units a, Units b)
287        {
288            return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
289        }
290
291        static bool validUnit(CSSParserValue*, Units, bool strict);
292
293        friend class TransformOperationInfo;
294    };
295
296    int cssPropertyID(const CSSParserString&);
297    int cssPropertyID(const String&);
298    int cssValueKeywordID(const CSSParserString&);
299
300    class ShorthandScope : public FastAllocBase {
301    public:
302        ShorthandScope(CSSParser* parser, int propId) : m_parser(parser)
303        {
304            if (!(m_parser->m_inParseShorthand++))
305                m_parser->m_currentShorthand = propId;
306        }
307        ~ShorthandScope()
308        {
309            if (!(--m_parser->m_inParseShorthand))
310                m_parser->m_currentShorthand = 0;
311        }
312
313    private:
314        CSSParser* m_parser;
315    };
316
317} // namespace WebCore
318
319#endif // CSSParser_h
320