1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Copyright (C) 2016 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#pragma once
31
32#include "CSSDeferredParser.h"
33#include "CSSParser.h"
34#include "CSSParserTokenRange.h"
35#include "CSSPropertyNames.h"
36#include "StyleRule.h"
37
38#include <memory>
39#include <wtf/Vector.h>
40#include <wtf/text/WTFString.h>
41
42namespace WebCore {
43
44class CSSParserObserver;
45class CSSParserObserverWrapper;
46class CSSSelectorList;
47class CSSTokenizer;
48class StyleRuleKeyframe;
49class StyleRule;
50class StyleRuleBase;
51class StyleRuleCharset;
52class StyleRuleFontFace;
53class StyleRuleImport;
54class StyleRuleKeyframes;
55class StyleRuleMedia;
56class StyleRuleNamespace;
57class StyleRulePage;
58class StyleRuleSupports;
59class StyleRuleViewport;
60class StyleSheetContents;
61class ImmutableStyleProperties;
62class Element;
63class MutableStyleProperties;
64
65class CSSParserImpl {
66 WTF_MAKE_NONCOPYABLE(CSSParserImpl);
67public:
68 CSSParserImpl(const CSSParserContext&, const String&, StyleSheetContents* = nullptr, CSSParserObserverWrapper* = nullptr, CSSParser::RuleParsing = CSSParser::RuleParsing::Normal);
69
70 enum AllowedRulesType {
71 // As per css-syntax, css-cascade and css-namespaces, @charset rules
72 // must come first, followed by @import then @namespace.
73 // AllowImportRules actually means we allow @import and any rules thay
74 // may follow it, i.e. @namespace rules and regular rules.
75 // AllowCharsetRules and AllowNamespaceRules behave similarly.
76 AllowCharsetRules,
77 AllowImportRules,
78 AllowNamespaceRules,
79 RegularRules,
80 KeyframeRules,
81 ApplyRules, // For @apply inside style rules
82 NoRules, // For parsing at-rules inside declaration lists
83 };
84
85 static CSSParser::ParseResult parseValue(MutableStyleProperties*, CSSPropertyID, const String&, bool important, const CSSParserContext&);
86 static CSSParser::ParseResult parseCustomPropertyValue(MutableStyleProperties*, const AtomicString& propertyName, const String&, bool important, const CSSParserContext&);
87 static Ref<ImmutableStyleProperties> parseInlineStyleDeclaration(const String&, const Element*);
88 static bool parseDeclarationList(MutableStyleProperties*, const String&, const CSSParserContext&);
89 static RefPtr<StyleRuleBase> parseRule(const String&, const CSSParserContext&, StyleSheetContents*, AllowedRulesType);
90 static void parseStyleSheet(const String&, const CSSParserContext&, StyleSheetContents*, CSSParser::RuleParsing);
91 static CSSSelectorList parsePageSelector(CSSParserTokenRange, StyleSheetContents*);
92
93 static std::unique_ptr<Vector<double>> parseKeyframeKeyList(const String&);
94
95 bool supportsDeclaration(CSSParserTokenRange&);
96
97 static void parseDeclarationListForInspector(const String&, const CSSParserContext&, CSSParserObserver&);
98 static void parseStyleSheetForInspector(const String&, const CSSParserContext&, StyleSheetContents*, CSSParserObserver&);
99
100 static Ref<ImmutableStyleProperties> parseDeferredDeclaration(CSSParserTokenRange, const CSSParserContext&, StyleSheetContents*);
101 static void parseDeferredRuleList(CSSParserTokenRange, CSSDeferredParser&, Vector<RefPtr<StyleRuleBase>>&);
102 static void parseDeferredKeyframeList(CSSParserTokenRange, CSSDeferredParser&, StyleRuleKeyframes&);
103
104 CSSTokenizer* tokenizer() const { return m_tokenizer.get(); };
105 CSSDeferredParser* deferredParser() const { return m_deferredParser.get(); }
106
107private:
108 CSSParserImpl(const CSSParserContext&, StyleSheetContents*);
109 CSSParserImpl(CSSDeferredParser&);
110
111 enum RuleListType {
112 TopLevelRuleList,
113 RegularRuleList,
114 KeyframesRuleList
115 };
116
117 // Returns whether the first encountered rule was valid
118 template<typename T>
119 bool consumeRuleList(CSSParserTokenRange, RuleListType, T callback);
120
121 // These two functions update the range they're given
122 RefPtr<StyleRuleBase> consumeAtRule(CSSParserTokenRange&, AllowedRulesType);
123 RefPtr<StyleRuleBase> consumeQualifiedRule(CSSParserTokenRange&, AllowedRulesType);
124
125 static RefPtr<StyleRuleCharset> consumeCharsetRule(CSSParserTokenRange prelude);
126 RefPtr<StyleRuleImport> consumeImportRule(CSSParserTokenRange prelude);
127 RefPtr<StyleRuleNamespace> consumeNamespaceRule(CSSParserTokenRange prelude);
128 RefPtr<StyleRuleMedia> consumeMediaRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
129 RefPtr<StyleRuleSupports> consumeSupportsRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
130 RefPtr<StyleRuleViewport> consumeViewportRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
131 RefPtr<StyleRuleFontFace> consumeFontFaceRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
132 RefPtr<StyleRuleKeyframes> consumeKeyframesRule(bool webkitPrefixed, CSSParserTokenRange prelude, CSSParserTokenRange block);
133 RefPtr<StyleRulePage> consumePageRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
134
135 // FIXME-NEWPARSER: Support "apply"
136 // void consumeApplyRule(CSSParserTokenRange prelude);
137
138 RefPtr<StyleRuleKeyframe> consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
139 RefPtr<StyleRule> consumeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
140
141 void consumeDeclarationList(CSSParserTokenRange, StyleRule::Type);
142 void consumeDeclaration(CSSParserTokenRange, StyleRule::Type);
143 void consumeDeclarationValue(CSSParserTokenRange, CSSPropertyID, bool important, StyleRule::Type);
144 void consumeCustomPropertyValue(CSSParserTokenRange, const AtomicString& propertyName, bool important);
145
146 static std::unique_ptr<Vector<double>> consumeKeyframeKeyList(CSSParserTokenRange);
147
148 Ref<DeferredStyleProperties> createDeferredStyleProperties(const CSSParserTokenRange& propertyRange);
149
150 void adoptTokenizerEscapedStrings();
151
152 // FIXME: Can we build StylePropertySets directly?
153 // FIXME: Investigate using a smaller inline buffer
154 ParsedPropertyVector m_parsedProperties;
155 const CSSParserContext& m_context;
156
157 RefPtr<StyleSheetContents> m_styleSheet;
158
159 // For deferred property parsing.
160 RefPtr<CSSDeferredParser> m_deferredParser;
161
162 // For normal parsing.
163 std::unique_ptr<CSSTokenizer> m_tokenizer;
164
165 // For the inspector
166 CSSParserObserverWrapper* m_observerWrapper { nullptr };
167};
168
169} // namespace WebCore
170