1 // Copyright 2016 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_CONTEXT_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_CONTEXT_H_
7 
8 #include "base/memory/scoped_refptr.h"
9 #include "third_party/blink/renderer/core/core_export.h"
10 #include "third_party/blink/renderer/core/css/css_property_names.h"
11 #include "third_party/blink/renderer/core/css/css_resource_fetch_restriction.h"
12 #include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
13 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
14 #include "third_party/blink/renderer/core/frame/web_feature_forward.h"
15 #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
16 #include "third_party/blink/renderer/platform/heap/handle.h"
17 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
18 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
19 #include "third_party/blink/renderer/platform/weborigin/referrer.h"
20 #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
21 
22 namespace blink {
23 
24 class CSSStyleSheet;
25 class Document;
26 class StyleRuleKeyframe;
27 class StyleSheetContents;
28 
29 class CORE_EXPORT CSSParserContext final
30     : public GarbageCollected<CSSParserContext> {
31  public:
32   // https://drafts.csswg.org/selectors/#profiles
33   enum SelectorProfile : uint8_t { kLiveProfile, kSnapshotProfile };
34 
35   // All three of these constructors copy the context and override the current
36   // Document handle used for UseCounter.
37   CSSParserContext(const CSSParserContext*, const CSSStyleSheet*);
38   CSSParserContext(const CSSParserContext*, const StyleSheetContents*);
39   // FIXME: This constructor shouldn't exist if we properly piped the UseCounter
40   // through the CSS subsystem. Currently the UseCounter life time is too crazy
41   // and we need a way to override it.
42   explicit CSSParserContext(const CSSParserContext* other,
43                             const Document* use_counter_document = nullptr);
44 
45   CSSParserContext(const CSSParserContext* other,
46                    const KURL& base_url_override,
47                    bool origin_clean,
48                    network::mojom::ReferrerPolicy referrer_policy_override,
49                    const WTF::TextEncoding& charset_override,
50                    const Document* use_counter_document);
51   CSSParserContext(CSSParserMode,
52                    SecureContextMode,
53                    SelectorProfile = kLiveProfile,
54                    const Document* use_counter_document = nullptr);
55   explicit CSSParserContext(const Document&);
56   CSSParserContext(const Document&,
57                    const KURL& base_url_override,
58                    bool origin_clean,
59                    network::mojom::ReferrerPolicy referrer_policy_override,
60                    const WTF::TextEncoding& charset = WTF::TextEncoding(),
61                    SelectorProfile = kLiveProfile,
62                    ResourceFetchRestriction resource_fetch_restriction =
63                        ResourceFetchRestriction::kNone);
64 
65   // This is used for workers, where we don't have a document.
66   CSSParserContext(const ExecutionContext& context);
67 
68   CSSParserContext(const KURL& base_url,
69                    bool origin_clean,
70                    const WTF::TextEncoding& charset,
71                    CSSParserMode,
72                    CSSParserMode match_mode,
73                    SelectorProfile,
74                    const Referrer&,
75                    bool is_html_document,
76                    bool use_legacy_background_size_shorthand_behavior,
77                    SecureContextMode,
78                    scoped_refptr<const DOMWrapperWorld> world,
79                    const Document* use_counter_document,
80                    ResourceFetchRestriction resource_fetch_restriction);
81 
82   bool operator==(const CSSParserContext&) const;
83   bool operator!=(const CSSParserContext& other) const {
84     return !(*this == other);
85   }
86 
Mode()87   CSSParserMode Mode() const { return mode_; }
MatchMode()88   CSSParserMode MatchMode() const { return match_mode_; }
BaseURL()89   const KURL& BaseURL() const { return base_url_; }
Charset()90   const WTF::TextEncoding& Charset() const { return charset_; }
GetReferrer()91   const Referrer& GetReferrer() const { return referrer_; }
IsAdRelated()92   bool IsAdRelated() const { return is_ad_related_; }
IsHTMLDocument()93   bool IsHTMLDocument() const { return is_html_document_; }
ResourceFetchRestriction()94   enum ResourceFetchRestriction ResourceFetchRestriction() const {
95     return resource_fetch_restriction_;
96   }
IsLiveProfile()97   bool IsLiveProfile() const { return profile_ == kLiveProfile; }
98 
99   bool IsOriginClean() const;
100   bool IsSecureContext() const;
101 
102   // This quirk is to maintain compatibility with Android apps built on
103   // the Android SDK prior to and including version 18. Presumably, this
104   // can be removed any time after 2015. See http://crbug.com/277157.
UseLegacyBackgroundSizeShorthandBehavior()105   bool UseLegacyBackgroundSizeShorthandBehavior() const {
106     return use_legacy_background_size_shorthand_behavior_;
107   }
108 
109   // FIXME: This setter shouldn't exist, however the current lifetime of
110   // CSSParserContext is not well understood and thus we sometimes need to
111   // override this field.
SetMode(CSSParserMode mode)112   void SetMode(CSSParserMode mode) { mode_ = mode; }
113 
SetIsAdRelated()114   void SetIsAdRelated() { is_ad_related_ = true; }
115 
116   KURL CompleteURL(const String& url) const;
117 
GetSecureContextMode()118   SecureContextMode GetSecureContextMode() const {
119     return secure_context_mode_;
120   }
121 
122   void Count(WebFeature) const;
123   void Count(CSSParserMode, CSSPropertyID) const;
124   void CountDeprecation(WebFeature) const;
IsUseCounterRecordingEnabled()125   bool IsUseCounterRecordingEnabled() const { return document_; }
126   bool IsDocumentHandleEqual(const Document* other) const;
127   const Document* GetDocument() const;
128   const ExecutionContext* GetExecutionContext() const;
129 
JavascriptWorld()130   const scoped_refptr<const DOMWrapperWorld>& JavascriptWorld() const {
131     return world_;
132   }
133 
134   // TODO(ekaramad): We currently only report @keyframes violations. We need to
135   // report CSS transitions as well (https://crbug.com/906147).
136   // TODO(ekaramad): We should provide a source location in the violation
137   // report (https://crbug.com/906150, ).
138   void ReportLayoutAnimationsViolationIfNeeded(const StyleRuleKeyframe&) const;
139 
140   // TODO(yoichio): Remove when CustomElementsV0 is removed. crrev.com/660759.
141   bool CustomElementsV0Enabled() const;
142 
143   bool IsForMarkupSanitization() const;
144 
145   // Overrides |mode_| of a CSSParserContext within the scope, allowing us to
146   // switching parsing mode while parsing different parts of a style sheet.
147   // TODO(xiaochengh): This isn't the right approach, as it breaks the
148   // immutability of CSSParserContext. We should introduce some local context.
149   class ParserModeOverridingScope {
150     STACK_ALLOCATED();
151 
152    public:
ParserModeOverridingScope(const CSSParserContext & context,CSSParserMode mode)153     ParserModeOverridingScope(const CSSParserContext& context,
154                               CSSParserMode mode)
155         : mode_reset_(const_cast<CSSParserMode*>(&context.mode_), mode) {}
156 
157    private:
158     base::AutoReset<CSSParserMode> mode_reset_;
159   };
160 
161   void Trace(Visitor*) const;
162 
163  private:
164   friend class ParserModeOverridingScope;
165 
166   KURL base_url_;
167 
168   scoped_refptr<const DOMWrapperWorld> world_;
169 
170   // If true, allows reading and modifying of the CSS rules.
171   // https://drafts.csswg.org/cssom/#concept-css-style-sheet-origin-clean-flag
172   const bool origin_clean_;
173 
174   CSSParserMode mode_;
175   CSSParserMode match_mode_;
176   SelectorProfile profile_ = kLiveProfile;
177   Referrer referrer_;
178 
179   // Whether the associated stylesheet's ResourceRequest is an ad resource. If
180   // there is no associated ResourceRequest, whether ad script is on the v8 call
181   // stack at stylesheet creation. Not set for presentation attributes.
182   bool is_ad_related_ = false;
183   bool is_html_document_;
184   bool use_legacy_background_size_shorthand_behavior_;
185   SecureContextMode secure_context_mode_;
186 
187   WTF::TextEncoding charset_;
188 
189   WeakMember<const Document> document_;
190 
191   // Flag indicating whether images with a URL scheme other than "data" are
192   // allowed.
193   const enum ResourceFetchRestriction resource_fetch_restriction_;
194 };
195 
196 CORE_EXPORT const CSSParserContext* StrictCSSParserContext(SecureContextMode);
197 
198 }  // namespace blink
199 
200 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_CONTEXT_H_
201