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 "CSSValueKeywords.h"
34#include "Color.h"
35#include "MediaQuery.h"
36#include "SourceSizeList.h"
37#include <memory>
38#include <wtf/HashMap.h>
39#include <wtf/HashSet.h>
40#include <wtf/Vector.h>
41#include <wtf/text/AtomicString.h>
42
43#if ENABLE(CSS_FILTERS)
44#include "WebKitCSSFilterValue.h"
45#endif
46
47#if ENABLE(CSS_GRID_LAYOUT)
48#include "CSSGridTemplateAreasValue.h"
49#endif
50
51namespace WebCore {
52
53class AnimationParseContext;
54class CSSBorderImageSliceValue;
55class CSSPrimitiveValue;
56class CSSSelectorList;
57class CSSValue;
58class CSSValueList;
59class CSSBasicShape;
60class CSSBasicShapeInset;
61class CSSGridLineNamesValue;
62class Document;
63class Element;
64class ImmutableStyleProperties;
65class MediaQueryExp;
66class MediaQuerySet;
67class MutableStyleProperties;
68class StyleKeyframe;
69class StylePropertyShorthand;
70class StyleRuleBase;
71class StyleRuleKeyframes;
72class StyleKeyframe;
73class StyleSheetContents;
74class StyledElement;
75
76class CSSParser {
77    friend inline int cssyylex(void*, CSSParser*);
78
79public:
80    struct Location;
81    enum SyntaxErrorType {
82        PropertyDeclarationError,
83        GeneralSyntaxError
84    };
85
86    CSSParser(const CSSParserContext&);
87
88    ~CSSParser();
89
90    void parseSheet(StyleSheetContents*, const String&, int startLineNumber = 0, RuleSourceDataList* = 0, bool = false);
91    PassRefPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
92    PassRefPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
93#if ENABLE(CSS3_CONDITIONAL_RULES)
94    bool parseSupportsCondition(const String&);
95#endif
96    static bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
97    static bool parseColor(RGBA32& color, const String&, bool strict = false);
98    static bool parseSystemColor(RGBA32& color, const String&, Document*);
99    static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
100    PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(CSSValueID ident, CSSParserValue*);
101    bool parseDeclaration(MutableStyleProperties*, const String&, PassRefPtr<CSSRuleSourceData>, StyleSheetContents* contextStyleSheet);
102    static PassRef<ImmutableStyleProperties> parseInlineStyleDeclaration(const String&, Element*);
103    std::unique_ptr<MediaQuery> parseMediaQuery(const String&);
104#if ENABLE(PICTURE_SIZES)
105    std::unique_ptr<SourceSizeList> parseSizesAttribute(const String&);
106#endif
107
108    void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
109    void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
110    void rollbackLastProperties(int num);
111    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
112    void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue>, bool);
113
114    bool parseValue(CSSPropertyID, bool important);
115    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
116    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
117    bool parseContent(CSSPropertyID, bool important);
118    bool parseQuotes(CSSPropertyID, bool important);
119    bool parseAlt(CSSPropertyID, bool important);
120
121    PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args);
122
123    PassRefPtr<CSSValue> parseBackgroundColor();
124
125    bool parseFillImage(CSSParserValueList*, RefPtr<CSSValue>&);
126
127    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
128    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
129    PassRefPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
130    PassRefPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
131    PassRefPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
132    void parse2ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
133    bool isPotentialPositionValue(CSSParserValue*);
134    void parseFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
135    void parse3ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
136    void parse4ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
137
138    void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
139    PassRefPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
140
141    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
142    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
143
144    void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
145
146    void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
147
148    PassRefPtr<CSSValue> parseAnimationDelay();
149    PassRefPtr<CSSValue> parseAnimationDirection();
150    PassRefPtr<CSSValue> parseAnimationDuration();
151    PassRefPtr<CSSValue> parseAnimationFillMode();
152    PassRefPtr<CSSValue> parseAnimationIterationCount();
153    PassRefPtr<CSSValue> parseAnimationName();
154    PassRefPtr<CSSValue> parseAnimationPlayState();
155    PassRefPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
156    PassRefPtr<CSSValue> parseAnimationTimingFunction();
157
158    bool parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
159    bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
160    bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&, AnimationParseContext&);
161    bool parseTransitionShorthand(CSSPropertyID, bool important);
162    bool parseAnimationShorthand(bool important);
163
164#if ENABLE(CSS_GRID_LAYOUT)
165    PassRefPtr<CSSValue> parseGridPosition();
166    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
167    bool parseGridTemplateRowsAndAreas(PassRefPtr<CSSValue>, bool important);
168    bool parseGridTemplateShorthand(bool important);
169    bool parseGridShorthand(bool important);
170    bool parseGridAreaShorthand(bool important);
171    bool parseSingleGridAreaLonghand(RefPtr<CSSValue>&);
172    PassRefPtr<CSSValue> parseGridTrackList();
173    bool parseGridTrackRepeatFunction(CSSValueList&);
174    PassRefPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
175    PassRefPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
176    bool parseGridTemplateAreasRow(NamedGridAreaMap&, const unsigned, unsigned&);
177    PassRefPtr<CSSValue> parseGridTemplateAreas();
178    void parseGridLineNames(CSSParserValueList&, CSSValueList&, CSSGridLineNamesValue* = nullptr);
179    PassRefPtr<CSSValue> parseGridAutoFlow(CSSParserValueList&);
180#endif
181
182    bool parseDashboardRegions(CSSPropertyID, bool important);
183
184    bool parseClipShape(CSSPropertyID, bool important);
185
186    bool parseJustifySelf(CSSPropertyID, bool important);
187
188#if ENABLE(CSS_SHAPES)
189    PassRefPtr<CSSValue> parseShapeProperty(CSSPropertyID);
190#endif
191
192    PassRefPtr<CSSValue> parseBasicShapeAndOrBox(CSSPropertyID propId);
193    PassRefPtr<CSSPrimitiveValue> parseBasicShape();
194    PassRefPtr<CSSPrimitiveValue> parseShapeRadius(CSSParserValue*);
195    PassRefPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList*);
196    PassRefPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList*);
197    PassRefPtr<CSSBasicShape> parseDeprecatedBasicShapeCircle(CSSParserValueList*);
198    PassRefPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList*);
199    PassRefPtr<CSSBasicShape> parseDeprecatedBasicShapeEllipse(CSSParserValueList*);
200    PassRefPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList*);
201    PassRefPtr<CSSBasicShape> parseBasicShapeInsetRectangle(CSSParserValueList*);
202    PassRefPtr<CSSBasicShape> parseBasicShapeInset(CSSParserValueList*);
203
204    bool parseFont(bool important);
205    PassRefPtr<CSSValueList> parseFontFamily();
206
207    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
208    PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
209
210    bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
211    bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
212    PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
213    bool parseColorFromValue(CSSParserValue*, RGBA32&);
214    void parseSelector(const String&, CSSSelectorList&);
215
216    template<typename StringType>
217    static bool fastParseColor(RGBA32&, const StringType&, bool strict);
218
219    bool parseLineHeight(bool important);
220    bool parseFontSize(bool important);
221    bool parseFontVariant(bool important);
222    bool parseFontWeight(bool important);
223    bool parseFontFaceSrc();
224    bool parseFontFaceUnicodeRange();
225
226    bool parseSVGValue(CSSPropertyID propId, bool important);
227    PassRefPtr<CSSValue> parseSVGPaint();
228    PassRefPtr<CSSValue> parseSVGColor();
229    PassRefPtr<CSSValue> parseSVGStrokeDasharray();
230    PassRefPtr<CSSValue> parsePaintOrder();
231
232    // CSS3 Parsing Routines (for properties specific to CSS3)
233    PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
234    bool parseBorderImage(CSSPropertyID, RefPtr<CSSValue>&, bool important = false);
235    bool parseBorderImageRepeat(RefPtr<CSSValue>&);
236    bool parseBorderImageSlice(CSSPropertyID, RefPtr<CSSBorderImageSliceValue>&);
237    bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&);
238    bool parseBorderImageOutset(RefPtr<CSSPrimitiveValue>&);
239    bool parseBorderRadius(CSSPropertyID, bool important);
240
241    bool parseAspectRatio(bool important);
242
243    bool parseReflect(CSSPropertyID, bool important);
244
245    bool parseFlex(CSSParserValueList* args, bool important);
246
247    // Image generators
248    bool parseCanvas(CSSParserValueList*, RefPtr<CSSValue>&);
249
250    bool parseDeprecatedGradient(CSSParserValueList*, RefPtr<CSSValue>&);
251    bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
252    bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
253    bool parseLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
254    bool parseRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
255    bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
256
257    bool parseCrossfade(CSSParserValueList*, RefPtr<CSSValue>&);
258
259#if ENABLE(CSS_IMAGE_RESOLUTION)
260    PassRefPtr<CSSValue> parseImageResolution();
261#endif
262
263#if ENABLE(CSS_IMAGE_SET)
264    PassRefPtr<CSSValue> parseImageSet();
265#endif
266
267#if ENABLE(CSS_FILTERS)
268    bool parseFilterImage(CSSParserValueList*, RefPtr<CSSValue>&);
269
270    bool parseFilter(CSSParserValueList*, RefPtr<CSSValue>&);
271    PassRefPtr<WebKitCSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, WebKitCSSFilterValue::FilterOperationType);
272#endif
273
274    PassRefPtr<CSSValue> parseClipPath();
275
276    static bool isBlendMode(CSSValueID);
277    static bool isCompositeOperator(CSSValueID);
278
279    PassRefPtr<CSSValueList> parseTransform();
280    PassRefPtr<CSSValue> parseTransformValue(CSSParserValue*);
281    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
282    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,  RefPtr<CSSValue>&, RefPtr<CSSValue>&);
283
284    bool parseTextEmphasisStyle(bool important);
285    bool parseTextEmphasisPosition(bool important);
286
287    void addTextDecorationProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important);
288    bool parseTextDecoration(CSSPropertyID propId, bool important);
289    bool parseTextDecorationSkip(bool important);
290    bool parseTextUnderlinePosition(bool important);
291
292    PassRefPtr<CSSValue> parseTextIndent();
293
294    bool parseLineBoxContain(bool important);
295    bool parseCalculation(CSSParserValue*, CalculationPermittedValueRange);
296
297    bool parseFontFeatureTag(CSSValueList*);
298    bool parseFontFeatureSettings(bool important);
299
300    bool cssRegionsEnabled() const;
301    bool cssCompositingEnabled() const;
302    bool parseFlowThread(CSSPropertyID, bool important);
303    bool parseRegionThread(CSSPropertyID, bool important);
304
305    bool parseFontVariantLigatures(bool important);
306
307    // Faster than doing a new/delete each time since it keeps one vector.
308    std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> createSelectorVector();
309    void recycleSelectorVector(std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>);
310
311    PassRefPtr<StyleRuleBase> createImportRule(const CSSParserString&, PassRefPtr<MediaQuerySet>);
312    PassRefPtr<StyleKeyframe> createKeyframe(CSSParserValueList&);
313    PassRefPtr<StyleRuleKeyframes> createKeyframesRule(const String&, std::unique_ptr<Vector<RefPtr<StyleKeyframe>>>);
314
315    typedef Vector<RefPtr<StyleRuleBase>> RuleList;
316    PassRefPtr<StyleRuleBase> createMediaRule(PassRefPtr<MediaQuerySet>, RuleList*);
317    PassRefPtr<StyleRuleBase> createEmptyMediaRule(RuleList*);
318    PassRefPtr<StyleRuleBase> createStyleRule(Vector<std::unique_ptr<CSSParserSelector>>* selectors);
319    PassRefPtr<StyleRuleBase> createFontFaceRule();
320    PassRefPtr<StyleRuleBase> createPageRule(std::unique_ptr<CSSParserSelector> pageSelector);
321    PassRefPtr<StyleRuleBase> createRegionRule(Vector<std::unique_ptr<CSSParserSelector>>* regionSelector, RuleList* rules);
322    void createMarginAtRule(CSSSelector::MarginBoxType);
323#if ENABLE(CSS3_CONDITIONAL_RULES)
324    PassRefPtr<StyleRuleBase> createSupportsRule(bool conditionIsSupported, RuleList*);
325    void markSupportsRuleHeaderStart();
326    void markSupportsRuleHeaderEnd();
327    PassRefPtr<CSSRuleSourceData> popSupportsRuleData();
328#endif
329
330    void startDeclarationsForMarginBox();
331    void endDeclarationsForMarginBox();
332
333    void addNamespace(const AtomicString& prefix, const AtomicString& uri);
334    QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
335
336    void rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector&, bool isNamespacePlaceholder = false);
337    void rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector&);
338    std::unique_ptr<CSSParserSelector> rewriteSpecifiers(std::unique_ptr<CSSParserSelector>, std::unique_ptr<CSSParserSelector>);
339
340    void invalidBlockHit();
341
342    void updateLastSelectorLineAndPosition();
343    void updateLastMediaLine(MediaQuerySet*);
344
345    void clearProperties();
346
347    PassRef<ImmutableStyleProperties> createStyleProperties();
348
349    CSSParserContext m_context;
350
351    bool m_important;
352    CSSPropertyID m_id;
353    StyleSheetContents* m_styleSheet;
354    RefPtr<StyleRuleBase> m_rule;
355    RefPtr<StyleKeyframe> m_keyframe;
356    std::unique_ptr<MediaQuery> m_mediaQuery;
357#if ENABLE(PICTURE_SIZES)
358    std::unique_ptr<SourceSizeList> m_sourceSizeList;
359#endif
360    std::unique_ptr<CSSParserValueList> m_valueList;
361#if ENABLE(CSS3_CONDITIONAL_RULES)
362    bool m_supportsCondition;
363#endif
364
365    typedef Vector<CSSProperty, 256> ParsedPropertyVector;
366    ParsedPropertyVector m_parsedProperties;
367    CSSSelectorList* m_selectorListForParseSelector;
368
369    unsigned m_numParsedPropertiesBeforeMarginBox;
370
371    int m_inParseShorthand;
372    CSSPropertyID m_currentShorthand;
373    bool m_implicitShorthand;
374
375    bool m_hasFontFaceOnlyValues;
376    bool m_hadSyntacticallyValidCSSRule;
377    bool m_logErrors;
378    bool m_ignoreErrorsInDeclaration;
379
380    AtomicString m_defaultNamespace;
381
382    // tokenizer methods and data
383    size_t m_parsedTextPrefixLength;
384    SourceRange m_selectorRange;
385    SourceRange m_propertyRange;
386    std::unique_ptr<RuleSourceDataList> m_currentRuleDataStack;
387    RefPtr<CSSRuleSourceData> m_currentRuleData;
388    RuleSourceDataList* m_ruleSourceDataResult;
389
390    void fixUnparsedPropertyRanges(CSSRuleSourceData*);
391    void markRuleHeaderStart(CSSRuleSourceData::Type);
392    void markRuleHeaderEnd();
393    void markSelectorStart();
394    void markSelectorEnd();
395    void markRuleBodyStart();
396    void markRuleBodyEnd();
397    void markPropertyStart();
398    void markPropertyEnd(bool isImportantFound, bool isPropertyParsed);
399    void processAndAddNewRuleToSourceTreeIfNeeded();
400    void addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData>);
401    PassRefPtr<CSSRuleSourceData> popRuleData();
402    void resetPropertyRange() { m_propertyRange.start = m_propertyRange.end = UINT_MAX; }
403    bool isExtractingSourceData() const { return !!m_currentRuleDataStack; }
404    void syntaxError(const Location&, SyntaxErrorType = GeneralSyntaxError);
405
406    inline int lex(void* yylval) { return (this->*m_lexFunc)(yylval); }
407
408    int token() { return m_token; }
409
410#if ENABLE(CSS_DEVICE_ADAPTATION)
411    void markViewportRuleBodyStart() { m_inViewport = true; }
412    void markViewportRuleBodyEnd() { m_inViewport = false; }
413    PassRefPtr<StyleRuleBase> createViewportRule();
414#endif
415
416    PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
417    PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
418
419    static URL completeURL(const CSSParserContext&, const String& url);
420
421    Location currentLocation();
422    static bool isCalculation(CSSParserValue*);
423
424private:
425    bool is8BitSource() { return m_is8BitSource; }
426
427    template <typename SourceCharacterType>
428    int realLex(void* yylval);
429
430    UChar*& currentCharacter16();
431
432    template <typename CharacterType>
433    inline CharacterType*& currentCharacter();
434
435    template <typename CharacterType>
436    inline CharacterType* tokenStart();
437
438    template <typename CharacterType>
439    inline void setTokenStart(CharacterType*);
440
441    inline unsigned tokenStartOffset();
442    inline UChar tokenStartChar();
443
444    template <typename CharacterType>
445    inline bool isIdentifierStart();
446
447    template <typename CharacterType>
448    unsigned parseEscape(CharacterType*&);
449    template <typename DestCharacterType>
450    inline void UnicodeToChars(DestCharacterType*&, unsigned);
451    template <typename SrcCharacterType, typename DestCharacterType>
452    inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
453
454    template <typename CharacterType>
455    inline void parseIdentifier(CharacterType*&, CSSParserString&, bool&);
456
457    template <typename SrcCharacterType, typename DestCharacterType>
458    inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
459
460    template <typename CharacterType>
461    inline void parseString(CharacterType*&, CSSParserString& resultString, UChar);
462
463    template <typename CharacterType>
464    inline bool findURI(CharacterType*& start, CharacterType*& end, UChar& quote);
465
466    template <typename SrcCharacterType, typename DestCharacterType>
467    inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
468
469    template <typename CharacterType>
470    inline void parseURI(CSSParserString&);
471    template <typename CharacterType>
472    inline bool parseUnicodeRange();
473    template <typename CharacterType>
474    bool parseNthChild();
475    template <typename CharacterType>
476    bool parseNthChildExtra();
477    template <typename CharacterType>
478    inline bool detectFunctionTypeToken(int);
479    template <typename CharacterType>
480    inline void detectMediaQueryToken(int);
481    template <typename CharacterType>
482    inline void detectNumberToken(CharacterType*, int);
483    template <typename CharacterType>
484    inline void detectDashToken(int);
485    template <typename CharacterType>
486    inline void detectAtToken(int, bool);
487#if ENABLE(CSS3_CONDITIONAL_RULES)
488    template <typename CharacterType>
489    inline void detectSupportsToken(int);
490#endif
491
492    template <typename CharacterType>
493    inline void setRuleHeaderEnd(const CharacterType*);
494
495    void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
496
497    inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; }
498    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
499
500    URL completeURL(const String& url) const;
501
502    void recheckAtKeyword(const UChar* str, int len);
503
504    template<unsigned prefixLength, unsigned suffixLength>
505    inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
506    {
507        setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
508    }
509    void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
510    bool inShorthand() const { return m_inParseShorthand; }
511
512    bool validWidth(CSSParserValue*);
513    bool validHeight(CSSParserValue*);
514
515    void deleteFontFaceOnlyValues();
516
517    bool isGeneratedImageValue(CSSParserValue*) const;
518    bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&);
519
520    bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
521    PassRef<ImmutableStyleProperties> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
522
523    PassRefPtr<CSSBasicShape> parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset>, CSSParserValueList*);
524
525    enum SizeParameterType {
526        None,
527        Auto,
528        Length,
529        PageSize,
530        Orientation,
531    };
532
533    bool parsePage(CSSPropertyID propId, bool important);
534    bool parseSize(CSSPropertyID propId, bool important);
535    SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType);
536
537    bool parseFontFaceSrcURI(CSSValueList*);
538    bool parseFontFaceSrcLocal(CSSValueList*);
539
540    bool parseColor(const String&);
541
542#if ENABLE(CSS_GRID_LAYOUT)
543    bool parseIntegerOrCustomIdentFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName);
544#endif
545
546    enum ParsingMode {
547        NormalMode,
548        MediaQueryMode,
549#if ENABLE(CSS3_CONDITIONAL_RULES)
550        SupportsMode,
551#endif
552        NthChildMode
553    };
554
555    ParsingMode m_parsingMode;
556    bool m_is8BitSource;
557    std::unique_ptr<LChar[]> m_dataStart8;
558    std::unique_ptr<UChar[]> m_dataStart16;
559    LChar* m_currentCharacter8;
560    UChar* m_currentCharacter16;
561    union {
562        LChar* ptr8;
563        UChar* ptr16;
564    } m_tokenStart;
565    unsigned m_length;
566    int m_token;
567    int m_lineNumber;
568    int m_tokenStartLineNumber;
569    int m_lastSelectorLineNumber;
570
571    bool m_allowImportRules;
572    bool m_allowNamespaceDeclarations;
573
574#if ENABLE(CSS_DEVICE_ADAPTATION)
575    bool parseViewportProperty(CSSPropertyID propId, bool important);
576    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
577
578    bool inViewport() const { return m_inViewport; }
579    bool m_inViewport;
580#endif
581
582    bool useLegacyBackgroundSizeShorthandBehavior() const;
583
584    int (CSSParser::*m_lexFunc)(void*);
585
586    std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> m_recycledSelectorVector;
587
588    RefPtr<CSSCalcValue> m_parsedCalculation;
589
590#if ENABLE(CSS3_CONDITIONAL_RULES)
591    std::unique_ptr<RuleSourceDataList> m_supportsRuleDataStack;
592#endif
593
594    // defines units allowed for a certain property, used in parseUnit
595    enum Units {
596        FUnknown = 0x0000,
597        FInteger = 0x0001,
598        FNumber = 0x0002, // Real Numbers
599        FPercent = 0x0004,
600        FLength = 0x0008,
601        FAngle = 0x0010,
602        FTime = 0x0020,
603        FFrequency = 0x0040,
604        FPositiveInteger = 0x0080,
605        FRelative = 0x0100,
606#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
607        FResolution = 0x0200,
608#endif
609        FNonNeg = 0x0400
610    };
611
612    friend inline Units operator|(Units a, Units b)
613    {
614        return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
615    }
616
617    enum ReleaseParsedCalcValueCondition {
618        ReleaseParsedCalcValue,
619        DoNotReleaseParsedCalcValue
620    };
621
622    bool isLoggingErrors();
623    void logError(const String& message, int lineNumber);
624
625    bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
626
627    bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
628
629    inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode, releaseCalc); }
630    bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
631
632    bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
633    int colorIntFromValue(CSSParserValue*);
634    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
635
636    friend class TransformOperationInfo;
637#if ENABLE(CSS_FILTERS)
638    friend class FilterOperationInfo;
639#endif
640};
641
642CSSPropertyID cssPropertyID(const CSSParserString&);
643CSSPropertyID cssPropertyID(const String&);
644CSSValueID cssValueKeywordID(const CSSParserString&);
645#if PLATFORM(IOS)
646void cssPropertyNameIOSAliasing(const char* propertyName, const char*& propertyNameAlias, unsigned& newLength);
647#endif
648
649class ShorthandScope {
650    WTF_MAKE_FAST_ALLOCATED;
651public:
652    ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser)
653    {
654        if (!(m_parser->m_inParseShorthand++))
655            m_parser->m_currentShorthand = propId;
656    }
657    ~ShorthandScope()
658    {
659        if (!(--m_parser->m_inParseShorthand))
660            m_parser->m_currentShorthand = CSSPropertyInvalid;
661    }
662
663private:
664    CSSParser* m_parser;
665};
666
667struct CSSParser::Location {
668    int lineNumber;
669    CSSParserString token;
670};
671
672String quoteCSSString(const String&);
673String quoteCSSStringIfNeeded(const String&);
674String quoteCSSURLIfNeeded(const String&);
675
676bool isValidNthToken(const CSSParserString&);
677
678template <>
679inline void CSSParser::setTokenStart<LChar>(LChar* tokenStart)
680{
681    m_tokenStart.ptr8 = tokenStart;
682}
683
684template <>
685inline void CSSParser::setTokenStart<UChar>(UChar* tokenStart)
686{
687    m_tokenStart.ptr16 = tokenStart;
688}
689
690inline unsigned CSSParser::tokenStartOffset()
691{
692    if (is8BitSource())
693        return m_tokenStart.ptr8 - m_dataStart8.get();
694    return m_tokenStart.ptr16 - m_dataStart16.get();
695}
696
697inline UChar CSSParser::tokenStartChar()
698{
699    if (is8BitSource())
700        return *m_tokenStart.ptr8;
701    return *m_tokenStart.ptr16;
702}
703
704inline int cssyylex(void* yylval, CSSParser* parser)
705{
706    return parser->lex(yylval);
707}
708
709} // namespace WebCore
710
711#endif // CSSParser_h
712