Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: third_party/WebKit/Source/core/dom/ModuleMap.h

Issue 2555653002: [WIP Prototype] ES6 https://html.spec.whatwg.org/#fetch-a-single-module-script implementation (Closed)
Patch Set: latest working ver that compiles modules but crashes inside V8 when executing Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 ModuleMap_h
6 #define ModuleMap_h
7
8 #include "bindings/core/v8/ScriptModule.h"
9 #include "core/loader/resource/ScriptResource.h"
10 #include "core/fetch/ResourceOwner.h"
11 #include "platform/heap/Handle.h"
12 #include "platform/weborigin/KURL.h"
13 #include "platform/weborigin/KURLHash.h"
14 #include "wtf/HashMap.h"
15 #include "wtf/HashTableDeletedValueType.h"
16
17 namespace blink {
18
19 class ResourceFetcher;
20 class ModuleLoader;
21
22 enum class ModuleLoaderState {
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Since this is idiosyncratic to ModuleLoader, why n
kouhei (in TOK) 2016/12/19 04:49:40 Done.
23 Initial,
24 // FetchRequest is being processed, and ModuleLoader hasn't notifyFinished().
25 Fetching,
26 // Finished successfully or w/ error.
27 Finished,
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Do we need a separate ModuleLoaderClient::notifyFi
kouhei (in TOK) 2016/12/19 04:49:40 Done.
28 };
29
30 class ModuleLoaderClient : public GarbageCollectedMixin {
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Would it be simpler to make this all abstract and
kouhei (in TOK) 2016/12/15 04:56:26 ResourceClient has a similar design to your propos
31 public:
32 DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_loader); }
33
34 protected:
35 ModuleLoaderClient(){};
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Maybe = default instead of {}?
kouhei (in TOK) 2016/12/15 04:56:26 Done.
36 virtual ~ModuleLoaderClient();
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Maybe = default; instead of the out-of-line declar
kouhei (in TOK) 2016/12/15 04:56:26 Done.
37
38 ModuleLoader* loader() { return m_loader.get(); }
39 void dispose() { m_loader = nullptr; }
40
41 private:
42 friend class ModuleLoader;
43 void setLoader(ModuleLoader* loader) {
44 DCHECK(!m_loader);
45 m_loader = loader;
46 }
47 virtual void notifyFinished() = 0;
48
49 // Called by ModuleLoader to catch up the client to the latest ModuleLoader
dominicc (has gone to gerrit) 2016/12/13 07:45:29 The comment doesn't add a ton to the method name.
kouhei (in TOK) 2016/12/15 04:56:26 Done.
50 // ModuleLoaderState.
51 virtual void catchUpToLatestStateIfNeeded(ModuleLoaderState);
52
53 Member<ModuleLoader> m_loader;
54 ModuleLoaderState m_state = ModuleLoaderState::Initial;
55 };
56
57 // A ModuleLoader is responsible for loading a single ScriptModule.
58 //
59 // A ModuleLoader constructs and emit FetchRequest to RequestFetcher (via
60 // ScriptResource::fetch).
61 // Then, it keeps track of the fetch progress by being a ScriptResourceClient.
62 //
63 // either a module script, null (used to represent failed fetches), or a
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Disfluency here, looks like something was cut and
64 // placeholder value "fetching". Module maps are used to ensure that imported
65 // JavaScript modules are only fetched, parsed, and evaluated once per
66 // Document or worker.
67 class ModuleLoader final : public GarbageCollectedFinalized<ModuleLoader>,
68 public ResourceOwner<ScriptResource> {
69 WTF_MAKE_NONCOPYABLE(ModuleLoader);
70 USING_GARBAGE_COLLECTED_MIXIN(ModuleLoader);
71
72 public:
73 static ModuleLoader* create(const KURL& url) { return new ModuleLoader(url); }
74
75 ~ModuleLoader();
76
77 // TODO(kouhei): This should be static and return ModuleLoader*
78 void fetch(ResourceFetcher* fetcher);
79 bool isFetching() const { return m_state == ModuleLoaderState::Fetching; }
dominicc (has gone to gerrit) 2016/12/13 07:45:29 Since there's a 1:1 mapping to states, why not jus
80 bool hasFinished() const { return m_state == ModuleLoaderState::Finished; }
81 bool hasFinishedSuccessfully() const {
82 if (m_wasLoadSuccessful) {
83 DCHECK_EQ(m_state, ModuleLoaderState::Finished);
84 return true;
85 }
86 return false;
87 }
88
89 // Run callbacks for the given client till current state, and register the
90 // client to receive further callbacks if !isFinished() loading.
91 void addClient(ModuleLoaderClient*);
92
93 ScriptModule& scriptModule() {
94 if (m_scriptModule.isNull())
95 return m_scriptModule;
96
97 DCHECK(hasFinishedSuccessfully());
98 return m_scriptModule;
99 }
100
101 DECLARE_TRACE();
102
103 private:
104 ModuleLoader(const KURL& url);
105
106 void advanceState(ModuleLoaderState newState);
107
108 // Ensure all clients (including those added during notification callbacks)
109 // receives notifications up to m_state.
110 void notifyAndFlushPendingClients();
111 void addSinglePendingClient();
112
113 // Implements ScriptResourceClient
114 void notifyFinished(Resource*) override;
115 String debugName() const override { return "ModuleLoader"; }
116
117 // TODO(kouhei): May be this method should live in ModuleResource? or should
118 // it be here to consolidate the spec impl code in ModuleMap.cpp?
119 static bool wasModuleLoadSuccessful(Resource*);
120
121 KURL m_url;
122 ModuleLoaderState m_state = ModuleLoaderState::Initial;
123 bool m_wasLoadSuccessful = true;
124 ScriptModule m_scriptModule;
125
126 // TODO(kouhei): Isolate below and their related logic to
127 // ModuleLoaderClientRegistry.
128
129 bool m_isFlushingPendingClients = false;
130 // m_lastClientNotifiedState should be only modified within
131 // notifyAndFlushPendingClients().
132 ModuleLoaderState m_lastClientNotifiedState = ModuleLoaderState::Initial;
133 HeapHashSet<Member<ModuleLoaderClient>> m_clients;
134 HeapHashSet<Member<ModuleLoaderClient>> m_pendingClients;
135 };
136
137 class ModuleMap : public GarbageCollected<ModuleMap> {
138 WTF_MAKE_NONCOPYABLE(ModuleMap);
139
140 public:
141 static ModuleMap* create(LocalFrame* frame, ResourceFetcher* fetcher) {
142 return new ModuleMap(frame, fetcher);
143 }
144 DECLARE_TRACE();
145
146 // https://html.spec.whatwg.org/#fetch-a-single-module-script
147 void fetch(
148 const KURL& url,
149 ModuleLoaderClient* client
150 /*, a fetch client settings object, a destination, a cryptographic nonce, a parser state, a credentials mode, a module map settings object, a referrer, an d a top-level module fetch flag*/); // => ScriptModule*
151
152 private:
153 ModuleMap(LocalFrame*, ResourceFetcher*);
154 ModuleMap() = delete;
155
156 using MapImpl = HeapHashMap<KURL, Member<ModuleLoader>>;
157
158 // A module map is a map of absolute URLs to values
dominicc (has gone to gerrit) 2016/12/13 07:45:29 What about fragments?
kouhei (in TOK) 2016/12/19 04:49:40 Good point. I found the spec text "the module map
159 MapImpl m_map;
160
161 Member<LocalFrame> m_frame;
162 Member<ResourceFetcher> m_fetcher;
163 };
164
165 } // namespace blink
166
167 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698