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