1 // Copyright 2017 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_SCRIPT_MODULATOR_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_MODULATOR_H_
7 
8 #include "base/single_thread_task_runner.h"
9 #include "base/util/type_safety/pass_key.h"
10 #include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
11 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
12 #include "third_party/blink/public/platform/web_url_request.h"
13 #include "third_party/blink/renderer/bindings/core/v8/module_record.h"
14 #include "third_party/blink/renderer/bindings/core/v8/module_request.h"
15 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
16 #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
17 #include "third_party/blink/renderer/core/core_export.h"
18 #include "third_party/blink/renderer/core/script/module_import_meta.h"
19 #include "third_party/blink/renderer/platform/bindings/name_client.h"
20 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
21 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
22 #include "third_party/blink/renderer/platform/heap/handle.h"
23 #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
24 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
25 #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
26 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
27 
28 namespace blink {
29 
30 class ModuleScript;
31 class ModuleScriptFetchRequest;
32 class ModuleScriptFetcher;
33 class ModuleScriptLoader;
34 class ImportMap;
35 class ReferrerScriptInfo;
36 class ResourceFetcher;
37 class ModuleRecordResolver;
38 class ScriptPromiseResolver;
39 class ScriptState;
40 class ScriptValue;
41 
42 // A SingleModuleClient is notified when single module script node (node as in a
43 // module tree graph) load is complete and its corresponding entry is created in
44 // module map.
45 class CORE_EXPORT SingleModuleClient
46     : public GarbageCollected<SingleModuleClient>,
47       public NameClient {
48  public:
49   virtual ~SingleModuleClient() = default;
Trace(Visitor * visitor)50   virtual void Trace(Visitor* visitor) const {}
NameInHeapSnapshot()51   const char* NameInHeapSnapshot() const override {
52     return "SingleModuleClient";
53   }
54 
55   virtual void NotifyModuleLoadFinished(ModuleScript*) = 0;
56 };
57 
58 // A ModuleTreeClient is notified when a module script and its whole descendent
59 // tree load is complete.
60 class CORE_EXPORT ModuleTreeClient : public GarbageCollected<ModuleTreeClient>,
61                                      public NameClient {
62  public:
63   virtual ~ModuleTreeClient() = default;
Trace(Visitor * visitor)64   virtual void Trace(Visitor* visitor) const {}
NameInHeapSnapshot()65   const char* NameInHeapSnapshot() const override { return "ModuleTreeClient"; }
66 
67   virtual void NotifyModuleTreeLoadFinished(ModuleScript*) = 0;
68 };
69 
70 // spec: "top-level module fetch flag"
71 // https://html.spec.whatwg.org/C/#fetching-scripts-is-top-level
72 enum class ModuleGraphLevel { kTopLevelModuleFetch, kDependentModuleFetch };
73 
74 // spec: "custom peform the fetch hook"
75 // https://html.spec.whatwg.org/C/#fetching-scripts-perform-fetch
76 enum class ModuleScriptCustomFetchType {
77   // Fetch module scripts without invoking custom fetch steps.
78   kNone,
79 
80   // Perform custom fetch steps for worker's constructor defined in the HTML
81   // spec:
82   // https://html.spec.whatwg.org/C/#worker-processing-model
83   kWorkerConstructor,
84 
85   // Perform custom fetch steps for Worklet's addModule() function defined in
86   // the Worklet spec:
87   // https://drafts.css-houdini.org/worklets/#fetch-a-worklet-script
88   kWorkletAddModule,
89 
90   // Fetch a Service Worker's installed module script from the Service Worker's
91   // script storage.
92   kInstalledServiceWorker
93 };
94 
95 // A Modulator is an interface for "environment settings object" concept for
96 // module scripts.
97 // https://html.spec.whatwg.org/C/#environment-settings-object
98 //
99 // A Modulator also serves as an entry point for various module spec algorithms.
100 class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
101                               public V8PerContextData::Data,
102                               public NameClient {
103  public:
104   static Modulator* From(ScriptState*);
105   virtual ~Modulator();
106 
107   static void SetModulator(ScriptState*, Modulator*);
108   static void ClearModulator(ScriptState*);
109 
Trace(Visitor * visitor)110   void Trace(Visitor* visitor) const override {}
NameInHeapSnapshot()111   const char* NameInHeapSnapshot() const override { return "Modulator"; }
112 
113   virtual ModuleRecordResolver* GetModuleRecordResolver() = 0;
114   virtual base::SingleThreadTaskRunner* TaskRunner() = 0;
115 
116   virtual ScriptState* GetScriptState() = 0;
117 
118   virtual mojom::blink::V8CacheOptions GetV8CacheOptions() const = 0;
119 
120   // https://html.spec.whatwg.org/C/#concept-bc-noscript
121   // "scripting is disabled for settings's responsible browsing context"
122   virtual bool IsScriptingDisabled() const = 0;
123 
124   virtual bool ImportMapsEnabled() const = 0;
125 
126   // https://html.spec.whatwg.org/C/#fetch-a-module-script-tree
127   // https://html.spec.whatwg.org/C/#fetch-a-module-worker-script-tree
128   // Note that |this| is the "module map settings object" and
129   // ResourceFetcher represents "fetch client settings object"
130   // used in the "fetch a module worker script graph" algorithm.
131   virtual void FetchTree(const KURL&,
132                          ResourceFetcher* fetch_client_settings_object_fetcher,
133                          mojom::blink::RequestContextType context_type,
134                          network::mojom::RequestDestination destination,
135                          const ScriptFetchOptions&,
136                          ModuleScriptCustomFetchType,
137                          ModuleTreeClient*) = 0;
138 
139   // Asynchronously retrieve a module script from the module map, or fetch it
140   // and put it in the map if it's not there already.
141   // https://html.spec.whatwg.org/C/#fetch-a-single-module-script
142   // Note that |this| is the "module map settings object" and
143   // |fetch_client_settings_object_fetcher| represents
144   // "fetch client settings object", which can be different from the
145   // ResourceFetcher associated with |this|.
146   virtual void FetchSingle(
147       const ModuleScriptFetchRequest&,
148       ResourceFetcher* fetch_client_settings_object_fetcher,
149       ModuleGraphLevel,
150       ModuleScriptCustomFetchType,
151       SingleModuleClient*) = 0;
152 
153   virtual void FetchDescendantsForInlineScript(
154       ModuleScript*,
155       ResourceFetcher* fetch_client_settings_object_fetcher,
156       mojom::blink::RequestContextType context_type,
157       network::mojom::RequestDestination destination,
158       ModuleTreeClient*) = 0;
159 
160   // Synchronously retrieves a single module script from existing module map
161   // entry.
162   // Note: returns nullptr if the module map entry doesn't exist, or
163   // is still "fetching".
164   virtual ModuleScript* GetFetchedModuleScript(const KURL&) = 0;
165 
166   // https://html.spec.whatwg.org/C/#resolve-a-module-specifier
167   virtual KURL ResolveModuleSpecifier(const String& module_request,
168                                       const KURL& base_url,
169                                       String* failure_reason = nullptr) = 0;
170 
171   // https://tc39.github.io/proposal-dynamic-import/#sec-hostimportmoduledynamically
172   virtual void ResolveDynamically(const String& specifier,
173                                   const KURL&,
174                                   const ReferrerScriptInfo&,
175                                   ScriptPromiseResolver*) = 0;
176 
177   virtual ScriptValue CreateTypeError(const String& message) const = 0;
178   virtual ScriptValue CreateSyntaxError(const String& message) const = 0;
179 
180   // Import maps. https://github.com/WICG/import-maps
181   virtual void RegisterImportMap(const ImportMap*,
182                                  ScriptValue error_to_rethrow) = 0;
183   virtual bool IsAcquiringImportMaps() const = 0;
184   virtual void ClearIsAcquiringImportMaps() = 0;
185   virtual const ImportMap* GetImportMapForTest() const = 0;
186 
187   // https://html.spec.whatwg.org/C/#hostgetimportmetaproperties
188   virtual ModuleImportMeta HostGetImportMetaProperties(
189       v8::Local<v8::Module>) const = 0;
190 
191   virtual bool HasValidContext() = 0;
192 
193   virtual ScriptValue InstantiateModule(v8::Local<v8::Module>, const KURL&) = 0;
194 
195   virtual Vector<ModuleRequest> ModuleRequestsFromModuleRecord(
196       v8::Local<v8::Module>) = 0;
197 
198   virtual ModuleScriptFetcher* CreateModuleScriptFetcher(
199       ModuleScriptCustomFetchType,
200       util::PassKey<ModuleScriptLoader> pass_key) = 0;
201 
202   // Produce V8 code cache for the given ModuleScript and its submodules.
203   virtual void ProduceCacheModuleTreeTopLevel(ModuleScript*) = 0;
204 };
205 
206 }  // namespace blink
207 
208 #endif
209