OLD | NEW |
---|---|
(Empty) | |
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 #include "core/loader/modulescript/ModuleScriptLoader.h" | |
6 | |
7 #include "bindings/core/v8/ModuleController.h" | |
8 #include "core/dom/ModuleScript.h" | |
9 #include "core/fetch/ResourceFetcher.h" | |
10 #include "core/loader/modulescript/ModuleScriptLoaderClient.h" | |
11 #include "core/loader/modulescript/ModuleScriptLoaderRegistry.h" | |
12 #include "platform/network/mime/MIMETypeRegistry.h" | |
13 | |
14 namespace blink { | |
15 | |
16 ModuleScriptLoader::ModuleScriptLoader(const KURL& url, | |
17 const KURL& baseURL, | |
18 ModuleController* moduleController, | |
19 ModuleScriptLoaderRegistry* registry, | |
20 ModuleScriptLoaderClient* client) | |
21 : m_url(url), | |
22 m_baseURL(url), | |
23 m_moduleController(moduleController), | |
24 m_registry(registry), | |
25 m_client(client) { | |
26 DCHECK(moduleController); | |
27 DCHECK(registry); | |
28 DCHECK(client); | |
29 } | |
30 | |
31 ModuleScriptLoader::~ModuleScriptLoader() {} | |
32 | |
33 void ModuleScriptLoader::advanceState(ModuleScriptLoader::State newState) { | |
34 switch (m_state) { | |
35 case State::Initial: | |
36 DCHECK_EQ(newState, State::Fetching); | |
37 break; | |
38 case State::Fetching: | |
39 DCHECK_EQ(newState, State::Finished); | |
40 break; | |
41 case State::Finished: | |
42 NOTREACHED(); | |
43 break; | |
44 default: | |
45 NOTREACHED(); | |
46 } | |
47 | |
48 m_state = newState; | |
49 | |
50 if (m_state == State::Finished) { | |
51 m_registry->releaseFinishedLoader(this); | |
52 m_client->notifyFinishedNewSingleModule(m_moduleScript); | |
53 } | |
54 } | |
55 | |
56 void ModuleScriptLoader::fetch(ResourceFetcher* fetcher) { | |
57 // Step 4. Set moduleMap[url] to "fetching". | |
58 advanceState(State::Fetching); | |
59 | |
60 // Step 5. Let request be a new request whose url is url, destination is | |
61 // destination, type is "script", mode is "cors", credentials mode is | |
62 // credentials mode, cryptographic nonce metadata is cryptographic nonce, | |
63 // parser metadata is parser state, referrer is referrer, and client is | |
64 // fetch client settings object. | |
65 FetchRequest request(ResourceRequest(m_url), "module"); | |
66 // request.setDefer(FetchRequest::LazyLoad); //? always async -> defer? | |
67 Member<ScriptResource> resource = ScriptResource::fetch(request, fetcher); | |
yhirano
2017/01/06 07:27:01
Please use a raw ptr here.
kouhei (in TOK)
2017/01/11 01:41:57
Done.
| |
68 setResource(resource); | |
69 | |
70 // Step 6. If the caller specified custom steps to perform the fetch, | |
71 // perform | |
72 // them on request, setting the is top-level flag if the top-level module | |
73 // fetch flag is set. Return from this algorithm, and when the custom | |
74 // perform | |
75 // the fetch steps complete with response response, run the remaining steps. | |
76 // Otherwise, fetch request. Return from this algorithm, and run the | |
77 // remaining | |
78 // steps as part of the fetch's process response for the response response. | |
79 // Note: response is always CORS-same-origin. | |
80 | |
81 // TODO(kouhei): I don't know what Step 6 means. ScriptLoader seems to | |
82 // ignore the step? | |
83 } | |
84 | |
85 bool ModuleScriptLoader::wasModuleLoadSuccessful(Resource* resource) { | |
86 // Implements conditions in Step 7 of | |
87 // https://html.spec.whatwg.org/#fetch-a-single-module-script | |
88 | |
89 // - response's type is "error" | |
90 if (resource->errorOccurred()) | |
91 return false; | |
92 | |
93 const auto& response = resource->response(); | |
94 // - response's status is not an ok status | |
95 if (response.isHTTP() && | |
96 (response.httpStatusCode() < 200 || response.httpStatusCode() >= 300)) { | |
97 return false; | |
98 } | |
99 | |
100 // The result of extracting a MIME type from response's header list | |
101 // (ignoring parameters) is not a JavaScript MIME type | |
102 // Note: For historical reasons, fetching a classic script does not include | |
103 // MIME type checking. In contrast, module scripts will fail to load if they | |
104 // are not of a correct MIME type. | |
105 if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(response.mimeType())) | |
106 return false; | |
107 | |
108 return true; | |
109 } | |
110 | |
111 // ScriptResourceClient callback handler | |
112 void ModuleScriptLoader::notifyFinished(Resource*) { | |
113 printf("notifyFinished!\n"); | |
114 | |
115 // Note: "conditions" referred in Step 7 is implemented in | |
116 // wasModuleLoadSuccessful(). | |
117 // Step 7. If any of the following conditions are met, set moduleMap[url] to | |
118 // null, asynchronously complete this algorithm with null, and abort these | |
119 // steps. | |
120 if (!wasModuleLoadSuccessful(resource())) { | |
121 printf("notifyFinished but load was not successful\n"); | |
122 | |
123 advanceState(State::Finished); | |
124 setResource(nullptr); | |
125 return; | |
126 } | |
127 | |
128 // Step 8. Let source text be the result of UTF-8 decoding response's body. | |
129 String script = resource()->script(); | |
130 printf("fetched script: %s\n", script.utf8().data()); | |
131 | |
132 // Step 9. Let module script be the result of creating a module script given | |
133 // source text, module map settings object, response's url, cryptographic | |
134 // nonce, parser state, and credentials mode. | |
135 | |
136 // TODO(kouhei): post a task to compile module? | |
137 ScriptModule record = | |
138 m_moduleController->compileModule(script, m_url.getString()); | |
139 m_moduleScript = ModuleScript::create(record, m_baseURL); | |
140 advanceState(State::Finished); | |
141 setResource(nullptr); | |
142 } | |
143 | |
144 DEFINE_TRACE(ModuleScriptLoader) { | |
145 visitor->trace(m_moduleController); | |
146 visitor->trace(m_moduleScript); | |
147 visitor->trace(m_registry); | |
148 visitor->trace(m_client); | |
149 ResourceOwner<ScriptResource>::trace(visitor); | |
150 } | |
151 | |
152 } // namespace blink | |
OLD | NEW |