Chromium Code Reviews| 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 |