| Index: third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp
|
| diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2dce0466c826a1e9821b3d23bf477fbfa98aa8cb
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp
|
| @@ -0,0 +1,153 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "core/loader/modulescript/ModuleScriptLoader.h"
|
| +
|
| +#include "core/dom/Modulator.h"
|
| +#include "core/dom/ModuleScript.h"
|
| +#include "core/fetch/ResourceFetcher.h"
|
| +#include "core/loader/modulescript/ModuleScriptLoaderClient.h"
|
| +#include "core/loader/modulescript/ModuleScriptLoaderRegistry.h"
|
| +#include "platform/network/mime/MIMETypeRegistry.h"
|
| +
|
| +namespace blink {
|
| +
|
| +ModuleScriptLoader::ModuleScriptLoader(const KURL& url,
|
| + const KURL& baseURL,
|
| + Modulator* modulator,
|
| + ModuleScriptLoaderRegistry* registry,
|
| + ModuleScriptLoaderClient* client)
|
| + : m_url(url),
|
| + m_baseURL(url),
|
| + m_modulator(modulator),
|
| + m_registry(registry),
|
| + m_client(client) {
|
| + DCHECK(modulator);
|
| + DCHECK(registry);
|
| + DCHECK(client);
|
| +}
|
| +
|
| +ModuleScriptLoader::~ModuleScriptLoader() {}
|
| +
|
| +void ModuleScriptLoader::advanceState(ModuleScriptLoader::State newState) {
|
| + switch (m_state) {
|
| + case State::Initial:
|
| + DCHECK_EQ(newState, State::Fetching);
|
| + break;
|
| + case State::Fetching:
|
| + DCHECK_EQ(newState, State::Finished);
|
| + break;
|
| + case State::Finished:
|
| + NOTREACHED();
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + m_state = newState;
|
| +
|
| + if (m_state == State::Finished) {
|
| + m_registry->releaseFinishedLoader(this);
|
| + m_client->notifyFinishedNewSingleModule(m_moduleScript);
|
| + }
|
| +}
|
| +
|
| +void ModuleScriptLoader::fetch(ResourceFetcher* fetcher) {
|
| + // Step 4. Set moduleMap[url] to "fetching".
|
| + advanceState(State::Fetching);
|
| +
|
| + // Step 5. Let request be a new request whose url is url, destination is
|
| + // destination, type is "script", mode is "cors", credentials mode is
|
| + // credentials mode, cryptographic nonce metadata is cryptographic nonce,
|
| + // parser metadata is parser state, referrer is referrer, and client is
|
| + // fetch client settings object.
|
| + FetchRequest request(ResourceRequest(m_url), "module");
|
| +
|
| + // Modules are always async
|
| + request.setDefer(FetchRequest::LazyLoad);
|
| + ScriptResource* resource = ScriptResource::fetch(request, fetcher);
|
| + setResource(resource);
|
| +
|
| + // Step 6. If the caller specified custom steps to perform the fetch,
|
| + // perform
|
| + // them on request, setting the is top-level flag if the top-level module
|
| + // fetch flag is set. Return from this algorithm, and when the custom
|
| + // perform
|
| + // the fetch steps complete with response response, run the remaining steps.
|
| + // Otherwise, fetch request. Return from this algorithm, and run the
|
| + // remaining
|
| + // steps as part of the fetch's process response for the response response.
|
| + // Note: response is always CORS-same-origin.
|
| +
|
| + // TODO(kouhei): I don't know what Step 6 means. ScriptLoader seems to
|
| + // ignore the step?
|
| +}
|
| +
|
| +bool ModuleScriptLoader::wasModuleLoadSuccessful(Resource* resource) {
|
| + // Implements conditions in Step 7 of
|
| + // https://html.spec.whatwg.org/#fetch-a-single-module-script
|
| +
|
| + // - response's type is "error"
|
| + if (resource->errorOccurred())
|
| + return false;
|
| +
|
| + const auto& response = resource->response();
|
| + // - response's status is not an ok status
|
| + if (response.isHTTP() &&
|
| + (response.httpStatusCode() < 200 || response.httpStatusCode() >= 300)) {
|
| + return false;
|
| + }
|
| +
|
| + // The result of extracting a MIME type from response's header list
|
| + // (ignoring parameters) is not a JavaScript MIME type
|
| + // Note: For historical reasons, fetching a classic script does not include
|
| + // MIME type checking. In contrast, module scripts will fail to load if they
|
| + // are not of a correct MIME type.
|
| + if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(response.mimeType()))
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// ScriptResourceClient callback handler
|
| +void ModuleScriptLoader::notifyFinished(Resource*) {
|
| + printf("notifyFinished!\n");
|
| +
|
| + // Note: "conditions" referred in Step 7 is implemented in
|
| + // wasModuleLoadSuccessful().
|
| + // Step 7. If any of the following conditions are met, set moduleMap[url] to
|
| + // null, asynchronously complete this algorithm with null, and abort these
|
| + // steps.
|
| + if (!wasModuleLoadSuccessful(resource())) {
|
| + printf("notifyFinished but load was not successful\n");
|
| +
|
| + advanceState(State::Finished);
|
| + setResource(nullptr);
|
| + return;
|
| + }
|
| +
|
| + // Step 8. Let source text be the result of UTF-8 decoding response's body.
|
| + String script = resource()->script();
|
| + printf("fetched script: %s\n", script.utf8().data());
|
| +
|
| + // Step 9. Let module script be the result of creating a module script given
|
| + // source text, module map settings object, response's url, cryptographic
|
| + // nonce, parser state, and credentials mode.
|
| +
|
| + // TODO(kouhei): post a task to compile module?
|
| + ScriptModule record = m_modulator->compileModule(script, m_url.getString());
|
| + m_moduleScript = ModuleScript::create(record, m_baseURL);
|
| + advanceState(State::Finished);
|
| + setResource(nullptr);
|
| +}
|
| +
|
| +DEFINE_TRACE(ModuleScriptLoader) {
|
| + visitor->trace(m_modulator);
|
| + visitor->trace(m_moduleScript);
|
| + visitor->trace(m_registry);
|
| + visitor->trace(m_client);
|
| + ResourceOwner<ScriptResource>::trace(visitor);
|
| +}
|
| +
|
| +} // namespace blink
|
|
|