1/*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
4 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifndef CSSParser_h
24#define CSSParser_h
25
26#include "CSSCalculationValue.h"
27#include "CSSGradientValue.h"
28#include "CSSParserMode.h"
29#include "CSSParserValues.h"
30#include "CSSProperty.h"
31#include "CSSPropertyNames.h"
32#include "CSSPropertySourceData.h"
33#include "Color.h"
34#include "MediaQuery.h"
35#include <wtf/HashMap.h>
36#include <wtf/HashSet.h>
37#include <wtf/OwnArrayPtr.h>
38#include <wtf/Vector.h>
39#include <wtf/text/AtomicString.h>
40
41#if ENABLE(CSS_FILTERS)
42#include "WebKitCSSFilterValue.h"
43#endif
44
45namespace WebCore {
46
47class AnimationParseContext;
48class CSSBorderImageSliceValue;
49class CSSPrimitiveValue;
50class CSSSelectorList;
51class CSSValue;
52class CSSValueList;
53class CSSBasicShape;
54class Document;
55class Element;
56class ImmutableStylePropertySet;
57class MediaQueryExp;
58class MediaQuerySet;
59class MutableStylePropertySet;
60class StyleKeyframe;
61class StylePropertyShorthand;
62class StyleRuleBase;
63class StyleRuleKeyframes;
64class StyleKeyframe;
65class StyleSheetContents;
66class StyledElement;
67
68#if ENABLE(CSS_SHADERS)
69class WebKitCSSArrayFunctionValue;
70class WebKitCSSMatFunctionValue;
71class WebKitCSSMixFunctionValue;
72class WebKitCSSShaderValue;
73#endif
74
75class CSSParser {
76    friend inline int cssyylex(void*, CSSParser*);
77
78public:
79    struct Location;
80    enum SyntaxErrorType {
81        PropertyDeclarationError,
82        GeneralSyntaxError
83    };
84
85    CSSParser(const CSSParserContext&);
86
87    ~CSSParser();
88
89    void parseSheet(StyleSheetContents*, const String&, int startLineNumber = 0, RuleSourceDataList* = 0, bool = false);
90    PassRefPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
91    PassRefPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
92#if ENABLE(CSS3_CONDITIONAL_RULES)
93    bool parseSupportsCondition(const String&);
94#endif
95    static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
96    static bool parseColor(RGBA32& color, const String&, bool strict = false);
97    static bool parseSystemColor(RGBA32& color, const String&, Document*);
98    static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
99    PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(int ident, CSSParserValue*);
100    bool parseDeclaration(MutableStylePropertySet*, const String&, PassRefPtr<CSSRuleSourceData>, StyleSheetContents* contextStyleSheet);
101    static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
102    PassOwnPtr<MediaQuery> parseMediaQuery(const String&);
103
104    void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
105    void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
106    void rollbackLastProperties(int num);
107    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
108    void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue>, bool);
109
110    bool parseValue(CSSPropertyID, bool important);
111    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
112    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
113    bool parseContent(CSSPropertyID, bool important);
114    bool parseQuotes(CSSPropertyID, bool important);
115
116#if ENABLE(CSS_VARIABLES)
117    static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, Document*);
118    bool cssVariablesEnabled() const;
119    void storeVariableDeclaration(const CSSParserString&, PassOwnPtr<CSSParserValueList>, bool important);
120#endif
121
122    PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args);
123
124    PassRefPtr<CSSValue> parseBackgroundColor();
125
126    bool parseFillImage(CSSParserValueList*, RefPtr<CSSValue>&);
127
128    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
129    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
130    PassRefPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
131    PassRefPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
132    PassRefPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
133    void parse2ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
134    bool isPotentialPositionValue(CSSParserValue*);
135    void parseFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
136    void parse3ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
137    void parse4ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
138
139    void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
140    PassRefPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
141
142    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
143    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
144
145    void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
146
147    void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
148
149    PassRefPtr<CSSValue> parseAnimationDelay();
150    PassRefPtr<CSSValue> parseAnimationDirection();
151    PassRefPtr<CSSValue> parseAnimationDuration();
152    PassRefPtr<CSSValue> parseAnimationFillMode();
153    PassRefPtr<CSSValue> parseAnimationIterationCount();
154    PassRefPtr<CSSValue> parseAnimationName();
155    PassRefPtr<CSSValue> parseAnimationPlayState();
156    PassRefPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
157    PassRefPtr<CSSValue> parseAnimationTimingFunction();
158
159    bool parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
160    bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
161    bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&, AnimationParseContext&);
162    bool parseTransitionShorthand(CSSPropertyID, bool important);
163    bool parseAnimationShorthand(bool important);
164
165    bool cssGridLayoutEnabled() const;
166    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
167    bool parseGridTrackList(CSSPropertyID, bool important);
168    PassRefPtr<CSSPrimitiveValue> parseGridTrackSize();
169    PassRefPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
170
171    bool parseDashboardRegions(CSSPropertyID, bool important);
172
173    bool parseClipShape(CSSPropertyID, bool important);
174
175    bool parseBasicShape(CSSPropertyID, bool important);
176    PassRefPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList* args);
177    PassRefPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList* args);
178    PassRefPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList* args);
179    PassRefPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList* args);
180    PassRefPtr<CSSBasicShape> parseBasicShapeInsetRectangle(CSSParserValueList* args);
181
182    bool parseFont(bool important);
183    PassRefPtr<CSSValueList> parseFontFamily();
184
185    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
186    PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
187
188    bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
189    bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
190    PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
191    bool parseColorFromValue(CSSParserValue*, RGBA32&);
192    void parseSelector(const String&, CSSSelectorList&);
193
194    template<typename StringType>
195    static bool fastParseColor(RGBA32&, const StringType&, bool strict);
196
197    bool parseLineHeight(bool important);
198    bool parseFontSize(bool important);
199    bool parseFontVariant(bool important);
200    bool parseFontWeight(bool important);
201    bool parseFontFaceSrc();
202    bool parseFontFaceUnicodeRange();
203
204#if ENABLE(SVG)
205    bool parseSVGValue(CSSPropertyID propId, bool important);
206    PassRefPtr<CSSValue> parseSVGPaint();
207    PassRefPtr<CSSValue> parseSVGColor();
208    PassRefPtr<CSSValue> parseSVGStrokeDasharray();
209#endif
210
211    // CSS3 Parsing Routines (for properties specific to CSS3)
212    PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
213    bool parseBorderImage(CSSPropertyID, RefPtr<CSSValue>&, bool important = false);
214    bool parseBorderImageRepeat(RefPtr<CSSValue>&);
215    bool parseBorderImageSlice(CSSPropertyID, RefPtr<CSSBorderImageSliceValue>&);
216    bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&);
217    bool parseBorderImageOutset(RefPtr<CSSPrimitiveValue>&);
218    bool parseBorderRadius(CSSPropertyID, bool important);
219
220    bool parseAspectRatio(bool important);
221
222    bool parseReflect(CSSPropertyID, bool important);
223
224    bool parseFlex(CSSParserValueList* args, bool important);
225
226    // Image generators
227    bool parseCanvas(CSSParserValueList*, RefPtr<CSSValue>&);
228
229    bool parseDeprecatedGradient(CSSParserValueList*, RefPtr<CSSValue>&);
230    bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
231    bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
232    bool parseLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
233    bool parseRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
234    bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
235
236    bool parseCrossfade(CSSParserValueList*, RefPtr<CSSValue>&);
237
238#if ENABLE(CSS_IMAGE_RESOLUTION)
239    PassRefPtr<CSSValue> parseImageResolution();
240#endif
241
242#if ENABLE(CSS_IMAGE_SET)
243    PassRefPtr<CSSValue> parseImageSet();
244#endif
245
246#if ENABLE(CSS_FILTERS)
247    PassRefPtr<CSSValueList> parseFilter();
248    PassRefPtr<WebKitCSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, WebKitCSSFilterValue::FilterOperationType);
249#if ENABLE(CSS_SHADERS)
250    PassRefPtr<WebKitCSSMatFunctionValue> parseMatValue(CSSParserValue*);
251    PassRefPtr<WebKitCSSMixFunctionValue> parseMixFunction(CSSParserValue*);
252    PassRefPtr<WebKitCSSArrayFunctionValue> parseCustomFilterArrayFunction(CSSParserValue*);
253    PassRefPtr<CSSValueList> parseCustomFilterTransform(CSSParserValueList*);
254    PassRefPtr<CSSValueList> parseCustomFilterParameters(CSSParserValueList*);
255    PassRefPtr<WebKitCSSFilterValue> parseCustomFilterFunctionWithAtRuleReferenceSyntax(CSSParserValue*);
256    PassRefPtr<WebKitCSSFilterValue> parseCustomFilterFunctionWithInlineSyntax(CSSParserValue*);
257    PassRefPtr<WebKitCSSFilterValue> parseCustomFilterFunction(CSSParserValue*);
258    bool parseFilterRuleSrc();
259    bool parseFilterRuleMix();
260    bool parseGeometry(CSSPropertyID, CSSParserValue*, bool);
261    bool parseGridDimensions(CSSParserValueList*, RefPtr<CSSValueList>&);
262    bool parseFilterRuleParameters();
263    PassRefPtr<WebKitCSSShaderValue> parseFilterRuleSrcUriAndFormat(CSSParserValueList*);
264#endif
265#endif
266
267    static bool isBlendMode(int ident);
268    static bool isCompositeOperator(int ident);
269
270    PassRefPtr<CSSValueList> parseTransform();
271    PassRefPtr<CSSValue> parseTransformValue(CSSParserValue*);
272    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
273    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,  RefPtr<CSSValue>&, RefPtr<CSSValue>&);
274
275    bool parseTextEmphasisStyle(bool important);
276
277    void addTextDecorationProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important);
278    bool parseTextDecoration(CSSPropertyID propId, bool important);
279#if ENABLE(CSS3_TEXT)
280    bool parseTextUnderlinePosition(bool important);
281#endif // CSS3_TEXT
282
283    PassRefPtr<CSSValue> parseTextIndent();
284
285    bool parseLineBoxContain(bool important);
286    bool parseCalculation(CSSParserValue*, CalculationPermittedValueRange);
287
288    bool parseFontFeatureTag(CSSValueList*);
289    bool parseFontFeatureSettings(bool important);
290
291    bool cssRegionsEnabled() const;
292    bool cssCompositingEnabled() const;
293    bool parseFlowThread(const String& flowName);
294    bool parseFlowThread(CSSPropertyID, bool important);
295    bool parseRegionThread(CSSPropertyID, bool important);
296
297    bool parseFontVariantLigatures(bool important);
298
299    CSSParserSelector* createFloatingSelector();
300    CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
301    PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
302
303    Vector<OwnPtr<CSSParserSelector> >* createFloatingSelectorVector();
304    PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >*);
305
306    CSSParserValueList* createFloatingValueList();
307    PassOwnPtr<CSSParserValueList> sinkFloatingValueList(CSSParserValueList*);
308
309    CSSParserFunction* createFloatingFunction();
310    PassOwnPtr<CSSParserFunction> sinkFloatingFunction(CSSParserFunction*);
311
312    CSSParserValue& sinkFloatingValue(CSSParserValue&);
313
314    MediaQuerySet* createMediaQuerySet();
315    StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*);
316    StyleKeyframe* createKeyframe(CSSParserValueList*);
317    StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtr<Vector<RefPtr<StyleKeyframe> > >);
318
319    typedef Vector<RefPtr<StyleRuleBase> > RuleList;
320    StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
321    RuleList* createRuleList();
322    StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
323    StyleRuleBase* createFontFaceRule();
324    StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
325    StyleRuleBase* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules);
326    StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
327#if ENABLE(CSS3_CONDITIONAL_RULES)
328    StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
329    void markSupportsRuleHeaderStart();
330    void markSupportsRuleHeaderEnd();
331    PassRefPtr<CSSRuleSourceData> popSupportsRuleData();
332#endif
333#if ENABLE(SHADOW_DOM)
334    StyleRuleBase* createHostRule(RuleList* rules);
335#endif
336#if ENABLE(CSS_SHADERS)
337    StyleRuleBase* createFilterRule(const CSSParserString&);
338#endif
339
340    void startDeclarationsForMarginBox();
341    void endDeclarationsForMarginBox();
342
343    MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
344    PassOwnPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
345    Vector<OwnPtr<MediaQueryExp> >* createFloatingMediaQueryExpList();
346    PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >*);
347    MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
348    MediaQuery* createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
349    PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
350
351    Vector<RefPtr<StyleKeyframe> >* createFloatingKeyframeVector();
352    PassOwnPtr<Vector<RefPtr<StyleKeyframe> > > sinkFloatingKeyframeVector(Vector<RefPtr<StyleKeyframe> >*);
353
354    void addNamespace(const AtomicString& prefix, const AtomicString& uri);
355    QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
356
357    CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false);
358    CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*);
359    CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*);
360
361    void invalidBlockHit();
362
363    Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
364
365    void setReusableRegionSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectors);
366    Vector<OwnPtr<CSSParserSelector> >* reusableRegionSelectorVector() { return &m_reusableRegionSelectorVector; }
367
368    void updateLastSelectorLineAndPosition();
369    void updateLastMediaLine(MediaQuerySet*);
370
371    void clearProperties();
372
373    PassRefPtr<ImmutableStylePropertySet> createStylePropertySet();
374
375    CSSParserContext m_context;
376
377    bool m_important;
378    CSSPropertyID m_id;
379    StyleSheetContents* m_styleSheet;
380    RefPtr<StyleRuleBase> m_rule;
381    RefPtr<StyleKeyframe> m_keyframe;
382    OwnPtr<MediaQuery> m_mediaQuery;
383    OwnPtr<CSSParserValueList> m_valueList;
384#if ENABLE(CSS3_CONDITIONAL_RULES)
385    bool m_supportsCondition;
386#endif
387
388    typedef Vector<CSSProperty, 256> ParsedPropertyVector;
389    ParsedPropertyVector m_parsedProperties;
390    CSSSelectorList* m_selectorListForParseSelector;
391
392    unsigned m_numParsedPropertiesBeforeMarginBox;
393
394    int m_inParseShorthand;
395    CSSPropertyID m_currentShorthand;
396    bool m_implicitShorthand;
397
398    bool m_hasFontFaceOnlyValues;
399    bool m_hadSyntacticallyValidCSSRule;
400    bool m_logErrors;
401    bool m_ignoreErrorsInDeclaration;
402
403#if ENABLE(CSS_SHADERS)
404    bool m_inFilterRule;
405#endif
406
407    AtomicString m_defaultNamespace;
408
409    // tokenizer methods and data
410    size_t m_parsedTextPrefixLength;
411    SourceRange m_selectorRange;
412    SourceRange m_propertyRange;
413    OwnPtr<RuleSourceDataList> m_currentRuleDataStack;
414    RefPtr<CSSRuleSourceData> m_currentRuleData;
415    RuleSourceDataList* m_ruleSourceDataResult;
416
417    void fixUnparsedPropertyRanges(CSSRuleSourceData*);
418    void markRuleHeaderStart(CSSRuleSourceData::Type);
419    void markRuleHeaderEnd();
420    void markSelectorStart();
421    void markSelectorEnd();
422    void markRuleBodyStart();
423    void markRuleBodyEnd();
424    void markPropertyStart();
425    void markPropertyEnd(bool isImportantFound, bool isPropertyParsed);
426    void processAndAddNewRuleToSourceTreeIfNeeded();
427    void addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData>);
428    PassRefPtr<CSSRuleSourceData> popRuleData();
429    void resetPropertyRange() { m_propertyRange.start = m_propertyRange.end = UINT_MAX; }
430    bool isExtractingSourceData() const { return !!m_currentRuleDataStack; }
431    void syntaxError(const Location&, SyntaxErrorType = GeneralSyntaxError);
432
433    inline int lex(void* yylval) { return (this->*m_lexFunc)(yylval); }
434
435    int token() { return m_token; }
436
437#if ENABLE(CSS_DEVICE_ADAPTATION)
438    void markViewportRuleBodyStart() { m_inViewport = true; }
439    void markViewportRuleBodyEnd() { m_inViewport = false; }
440    StyleRuleBase* createViewportRule();
441#endif
442
443    PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
444    PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
445#if ENABLE(CSS_VARIABLES)
446    PassRefPtr<CSSPrimitiveValue> createPrimitiveVariableNameValue(CSSParserValue*);
447#endif
448
449    static KURL completeURL(const CSSParserContext&, const String& url);
450
451    Location currentLocation();
452
453private:
454    bool is8BitSource() { return m_is8BitSource; }
455
456    template <typename SourceCharacterType>
457    int realLex(void* yylval);
458
459    UChar*& currentCharacter16();
460
461    template <typename CharacterType>
462    inline CharacterType*& currentCharacter();
463
464    template <typename CharacterType>
465    inline CharacterType* tokenStart();
466
467    template <typename CharacterType>
468    inline void setTokenStart(CharacterType*);
469
470    inline unsigned tokenStartOffset();
471    inline UChar tokenStartChar();
472
473    template <typename CharacterType>
474    inline bool isIdentifierStart();
475
476    template <typename CharacterType>
477    unsigned parseEscape(CharacterType*&);
478    template <typename DestCharacterType>
479    inline void UnicodeToChars(DestCharacterType*&, unsigned);
480    template <typename SrcCharacterType, typename DestCharacterType>
481    inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
482
483    template <typename CharacterType>
484    inline void parseIdentifier(CharacterType*&, CSSParserString&, bool&);
485
486    template <typename SrcCharacterType, typename DestCharacterType>
487    inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
488
489    template <typename CharacterType>
490    inline void parseString(CharacterType*&, CSSParserString& resultString, UChar);
491
492    template <typename CharacterType>
493    inline bool findURI(CharacterType*& start, CharacterType*& end, UChar& quote);
494
495    template <typename SrcCharacterType, typename DestCharacterType>
496    inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
497
498    template <typename CharacterType>
499    inline void parseURI(CSSParserString&);
500    template <typename CharacterType>
501    inline bool parseUnicodeRange();
502    template <typename CharacterType>
503    bool parseNthChild();
504    template <typename CharacterType>
505    bool parseNthChildExtra();
506    template <typename CharacterType>
507    inline bool detectFunctionTypeToken(int);
508    template <typename CharacterType>
509    inline void detectMediaQueryToken(int);
510    template <typename CharacterType>
511    inline void detectNumberToken(CharacterType*, int);
512    template <typename CharacterType>
513    inline void detectDashToken(int);
514    template <typename CharacterType>
515    inline void detectAtToken(int, bool);
516#if ENABLE(CSS3_CONDITIONAL_RULES)
517    template <typename CharacterType>
518    inline void detectSupportsToken(int);
519#endif
520
521    template <typename CharacterType>
522    inline void setRuleHeaderEnd(const CharacterType*);
523
524    void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
525
526    inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; }
527    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
528
529    KURL completeURL(const String& url) const;
530
531    void recheckAtKeyword(const UChar* str, int len);
532
533    template<unsigned prefixLength, unsigned suffixLength>
534    inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
535    {
536        setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
537    }
538    void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
539    bool inShorthand() const { return m_inParseShorthand; }
540
541    bool validWidth(CSSParserValue*);
542    bool validHeight(CSSParserValue*);
543
544    void deleteFontFaceOnlyValues();
545
546    bool isGeneratedImageValue(CSSParserValue*) const;
547    bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&);
548
549    bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
550    PassRefPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
551
552    enum SizeParameterType {
553        None,
554        Auto,
555        Length,
556        PageSize,
557        Orientation,
558    };
559
560    bool parsePage(CSSPropertyID propId, bool important);
561    bool parseSize(CSSPropertyID propId, bool important);
562    SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType);
563
564    bool parseFontFaceSrcURI(CSSValueList*);
565    bool parseFontFaceSrcLocal(CSSValueList*);
566
567    bool parseColor(const String&);
568
569    enum ParsingMode {
570        NormalMode,
571        MediaQueryMode,
572#if ENABLE(CSS3_CONDITIONAL_RULES)
573        SupportsMode,
574#endif
575        NthChildMode
576    };
577
578    ParsingMode m_parsingMode;
579    bool m_is8BitSource;
580    OwnArrayPtr<LChar> m_dataStart8;
581    OwnArrayPtr<UChar> m_dataStart16;
582    LChar* m_currentCharacter8;
583    UChar* m_currentCharacter16;
584    union {
585        LChar* ptr8;
586        UChar* ptr16;
587    } m_tokenStart;
588    unsigned m_length;
589    int m_token;
590    int m_lineNumber;
591    int m_tokenStartLineNumber;
592    int m_lastSelectorLineNumber;
593
594    bool m_allowImportRules;
595    bool m_allowNamespaceDeclarations;
596
597#if ENABLE(CSS_DEVICE_ADAPTATION)
598    bool parseViewportProperty(CSSPropertyID propId, bool important);
599    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
600
601    bool inViewport() const { return m_inViewport; }
602    bool m_inViewport;
603#endif
604
605    bool useLegacyBackgroundSizeShorthandBehavior() const;
606
607    int (CSSParser::*m_lexFunc)(void*);
608
609    Vector<RefPtr<StyleRuleBase> > m_parsedRules;
610    Vector<RefPtr<StyleKeyframe> > m_parsedKeyframes;
611    Vector<RefPtr<MediaQuerySet> > m_parsedMediaQuerySets;
612    Vector<OwnPtr<RuleList> > m_parsedRuleLists;
613    HashSet<CSSParserSelector*> m_floatingSelectors;
614    HashSet<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
615    HashSet<CSSParserValueList*> m_floatingValueLists;
616    HashSet<CSSParserFunction*> m_floatingFunctions;
617
618    OwnPtr<MediaQuery> m_floatingMediaQuery;
619    OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
620    OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
621
622    OwnPtr<Vector<RefPtr<StyleKeyframe> > > m_floatingKeyframeVector;
623
624    Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
625    Vector<OwnPtr<CSSParserSelector> > m_reusableRegionSelectorVector;
626
627    RefPtr<CSSCalcValue> m_parsedCalculation;
628
629#if ENABLE(CSS3_CONDITIONAL_RULES)
630    OwnPtr<RuleSourceDataList> m_supportsRuleDataStack;
631#endif
632
633    // defines units allowed for a certain property, used in parseUnit
634    enum Units {
635        FUnknown = 0x0000,
636        FInteger = 0x0001,
637        FNumber = 0x0002, // Real Numbers
638        FPercent = 0x0004,
639        FLength = 0x0008,
640        FAngle = 0x0010,
641        FTime = 0x0020,
642        FFrequency = 0x0040,
643        FPositiveInteger = 0x0080,
644        FRelative = 0x0100,
645#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
646        FResolution = 0x0200,
647#endif
648        FNonNeg = 0x0400
649    };
650
651    friend inline Units operator|(Units a, Units b)
652    {
653        return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
654    }
655
656    enum ReleaseParsedCalcValueCondition {
657        ReleaseParsedCalcValue,
658        DoNotReleaseParsedCalcValue
659    };
660
661    bool isLoggingErrors();
662    void logError(const String& message, int lineNumber);
663
664    bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
665
666    bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
667
668    inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode, releaseCalc); }
669    bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
670
671    bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
672    int colorIntFromValue(CSSParserValue*);
673    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
674    bool isCalculation(CSSParserValue*);
675
676    friend class TransformOperationInfo;
677#if ENABLE(CSS_FILTERS)
678    friend class FilterOperationInfo;
679#endif
680};
681
682CSSPropertyID cssPropertyID(const CSSParserString&);
683CSSPropertyID cssPropertyID(const String&);
684int cssValueKeywordID(const CSSParserString&);
685#if PLATFORM(IOS)
686void cssPropertyNameIOSAliasing(const char* propertyName, const char*& propertyNameAlias, unsigned& newLength);
687#endif
688
689class ShorthandScope {
690    WTF_MAKE_FAST_ALLOCATED;
691public:
692    ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser)
693    {
694        if (!(m_parser->m_inParseShorthand++))
695            m_parser->m_currentShorthand = propId;
696    }
697    ~ShorthandScope()
698    {
699        if (!(--m_parser->m_inParseShorthand))
700            m_parser->m_currentShorthand = CSSPropertyInvalid;
701    }
702
703private:
704    CSSParser* m_parser;
705};
706
707struct CSSParser::Location {
708    int lineNumber;
709    CSSParserString token;
710};
711
712String quoteCSSString(const String&);
713String quoteCSSStringIfNeeded(const String&);
714String quoteCSSURLIfNeeded(const String&);
715
716bool isValidNthToken(const CSSParserString&);
717
718template <>
719inline void CSSParser::setTokenStart<LChar>(LChar* tokenStart)
720{
721    m_tokenStart.ptr8 = tokenStart;
722}
723
724template <>
725inline void CSSParser::setTokenStart<UChar>(UChar* tokenStart)
726{
727    m_tokenStart.ptr16 = tokenStart;
728}
729
730inline unsigned CSSParser::tokenStartOffset()
731{
732    if (is8BitSource())
733        return m_tokenStart.ptr8 - m_dataStart8.get();
734    return m_tokenStart.ptr16 - m_dataStart16.get();
735}
736
737inline UChar CSSParser::tokenStartChar()
738{
739    if (is8BitSource())
740        return *m_tokenStart.ptr8;
741    return *m_tokenStart.ptr16;
742}
743
744inline int cssyylex(void* yylval, CSSParser* parser)
745{
746    return parser->lex(yylval);
747}
748
749} // namespace WebCore
750
751#endif // CSSParser_h
752