1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_IMPL_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_IMPL_H_
7 
8 #include <memory>
9 
10 #include "base/macros.h"
11 #include "third_party/blink/renderer/core/core_export.h"
12 #include "third_party/blink/renderer/core/css/css_property_names.h"
13 #include "third_party/blink/renderer/core/css/css_property_source_data.h"
14 #include "third_party/blink/renderer/core/css/css_property_value.h"
15 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
16 #include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
17 #include "third_party/blink/renderer/platform/heap/handle.h"
18 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
19 #include "third_party/blink/renderer/platform/wtf/vector.h"
20 
21 namespace blink {
22 
23 class CSSLazyParsingState;
24 class CSSParserContext;
25 class CSSParserObserver;
26 class CSSParserTokenStream;
27 class StyleRule;
28 class StyleRuleBase;
29 class StyleRuleCharset;
30 class StyleRuleFontFace;
31 class StyleRuleImport;
32 class StyleRuleKeyframe;
33 class StyleRuleKeyframes;
34 class StyleRuleMedia;
35 class StyleRuleNamespace;
36 class StyleRulePage;
37 class StyleRuleProperty;
38 class StyleRuleSupports;
39 class StyleRuleViewport;
40 class StyleSheetContents;
41 class Element;
42 
43 enum class ParseSheetResult {
44   kSucceeded,
45   kHasUnallowedImportRule,
46 };
47 
48 class CORE_EXPORT CSSParserImpl {
49   STACK_ALLOCATED();
50 
51  public:
52   CSSParserImpl(const CSSParserContext*, StyleSheetContents* = nullptr);
53 
54   enum AllowedRulesType {
55     // As per css-syntax, css-cascade and css-namespaces, @charset rules
56     // must come first, followed by @import then @namespace.
57     // AllowImportRules actually means we allow @import and any rules thay
58     // may follow it, i.e. @namespace rules and regular rules.
59     // AllowCharsetRules and AllowNamespaceRules behave similarly.
60     kAllowCharsetRules,
61     kAllowImportRules,
62     kAllowNamespaceRules,
63     kRegularRules,
64     kKeyframeRules,
65     kFontFeatureRules,
66     kNoRules,  // For parsing at-rules inside declaration lists
67   };
68 
69   // Represents the start and end offsets of a CSSParserTokenRange.
70   struct RangeOffset {
71     wtf_size_t start, end;
72 
RangeOffsetRangeOffset73     RangeOffset(wtf_size_t start, wtf_size_t end) : start(start), end(end) {
74       DCHECK(start <= end);
75     }
76 
77     // Used when we don't care what the offset is (typically when we don't have
78     // an observer).
IgnoreRangeOffset79     static RangeOffset Ignore() { return {0, 0}; }
80   };
81 
82   static MutableCSSPropertyValueSet::SetResult ParseValue(
83       MutableCSSPropertyValueSet*,
84       CSSPropertyID,
85       const String&,
86       bool important,
87       const CSSParserContext*);
88   static MutableCSSPropertyValueSet::SetResult ParseVariableValue(
89       MutableCSSPropertyValueSet*,
90       const AtomicString& property_name,
91       const String&,
92       bool important,
93       const CSSParserContext*,
94       bool is_animation_tainted);
95   static ImmutableCSSPropertyValueSet* ParseInlineStyleDeclaration(
96       const String&,
97       Element*);
98   static ImmutableCSSPropertyValueSet*
99   ParseInlineStyleDeclaration(const String&, CSSParserMode, SecureContextMode);
100   static bool ParseDeclarationList(MutableCSSPropertyValueSet*,
101                                    const String&,
102                                    const CSSParserContext*);
103   static StyleRuleBase* ParseRule(const String&,
104                                   const CSSParserContext*,
105                                   StyleSheetContents*,
106                                   AllowedRulesType);
107   static ParseSheetResult ParseStyleSheet(
108       const String&,
109       const CSSParserContext*,
110       StyleSheetContents*,
111       CSSDeferPropertyParsing = CSSDeferPropertyParsing::kNo,
112       bool allow_import_rules = true);
113   static CSSSelectorList ParsePageSelector(CSSParserTokenRange,
114                                            StyleSheetContents*);
115 
116   static std::unique_ptr<Vector<double>> ParseKeyframeKeyList(const String&);
117 
118   bool SupportsDeclaration(CSSParserTokenRange&);
GetContext()119   const CSSParserContext* GetContext() const { return context_; }
120 
121   static void ParseDeclarationListForInspector(const String&,
122                                                const CSSParserContext*,
123                                                CSSParserObserver&);
124   static void ParseStyleSheetForInspector(const String&,
125                                           const CSSParserContext*,
126                                           StyleSheetContents*,
127                                           CSSParserObserver&);
128 
129   static CSSPropertyValueSet* ParseDeclarationListForLazyStyle(
130       const String&,
131       wtf_size_t offset,
132       const CSSParserContext*);
133 
134  private:
135   enum RuleListType {
136     kTopLevelRuleList,
137     kRegularRuleList,
138     kKeyframesRuleList,
139     kFontFeatureRuleList,
140   };
141 
142   // Returns whether the first encountered rule was valid
143   template <typename T>
144   bool ConsumeRuleList(CSSParserTokenStream&, RuleListType, T callback);
145 
146   // These functions update the range/stream they're given
147   StyleRuleBase* ConsumeAtRule(CSSParserTokenStream&, AllowedRulesType);
148   StyleRuleBase* ConsumeQualifiedRule(CSSParserTokenStream&, AllowedRulesType);
149 
150   static StyleRuleCharset* ConsumeCharsetRule(CSSParserTokenRange prelude);
151   StyleRuleImport* ConsumeImportRule(AtomicString prelude_uri,
152                                      CSSParserTokenRange prelude,
153                                      const RangeOffset& prelude_offset);
154   StyleRuleNamespace* ConsumeNamespaceRule(CSSParserTokenRange prelude);
155   StyleRuleMedia* ConsumeMediaRule(CSSParserTokenRange prelude,
156                                    const RangeOffset& prelude_offset,
157                                    CSSParserTokenStream& block);
158   StyleRuleSupports* ConsumeSupportsRule(CSSParserTokenRange prelude,
159                                          const RangeOffset& prelude_offset,
160                                          CSSParserTokenStream& block);
161   StyleRuleViewport* ConsumeViewportRule(CSSParserTokenRange prelude,
162                                          const RangeOffset& prelude_offset,
163                                          CSSParserTokenStream& block);
164   StyleRuleFontFace* ConsumeFontFaceRule(CSSParserTokenRange prelude,
165                                          const RangeOffset& prelude_offset,
166                                          CSSParserTokenStream& block);
167   StyleRuleKeyframes* ConsumeKeyframesRule(bool webkit_prefixed,
168                                            CSSParserTokenRange prelude,
169                                            const RangeOffset& prelude_offset,
170                                            CSSParserTokenStream& block);
171   StyleRulePage* ConsumePageRule(CSSParserTokenRange prelude,
172                                  const RangeOffset& prelude_offset,
173                                  CSSParserTokenStream& block);
174   StyleRuleProperty* ConsumePropertyRule(CSSParserTokenRange prelude,
175                                          const RangeOffset& prelude_offset,
176                                          CSSParserTokenStream& block);
177 
178   StyleRuleKeyframe* ConsumeKeyframeStyleRule(CSSParserTokenRange prelude,
179                                               const RangeOffset& prelude_offset,
180                                               CSSParserTokenStream& block);
181   StyleRule* ConsumeStyleRule(CSSParserTokenStream&);
182 
183   void ConsumeDeclarationList(CSSParserTokenStream&, StyleRule::RuleType);
184   void ConsumeDeclaration(CSSParserTokenRange,
185                           const RangeOffset& decl_offset,
186                           StyleRule::RuleType);
187   void ConsumeDeclarationValue(CSSParserTokenRange,
188                                CSSPropertyID,
189                                bool important,
190                                StyleRule::RuleType);
191   void ConsumeVariableValue(CSSParserTokenRange,
192                             const AtomicString& property_name,
193                             bool important,
194                             bool is_animation_tainted);
195 
196   static std::unique_ptr<Vector<double>> ConsumeKeyframeKeyList(
197       CSSParserTokenRange);
198 
199   // FIXME: Can we build CSSPropertyValueSets directly?
200   // FIXME: Investigate using a smaller inline buffer
201   HeapVector<CSSPropertyValue, 256> parsed_properties_;
202 
203   const CSSParserContext* context_;
204   StyleSheetContents* style_sheet_;
205 
206   // For the inspector
207   CSSParserObserver* observer_;
208 
209   CSSLazyParsingState* lazy_state_;
210   DISALLOW_COPY_AND_ASSIGN(CSSParserImpl);
211 };
212 
213 }  // namespace blink
214 
215 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_IMPL_H_
216