haikuwebkit/Source/WebCore/dom/LoadableModuleScript.h

76 lines
2.9 KiB
C
Raw Permalink Normal View History

[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
/*
* Copyright (C) 2016 Apple, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "LoadableScript.h"
#include <wtf/TypeCasts.h>
namespace WebCore {
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
class ScriptSourceCode;
Support integrity="" on module scripts https://bugs.webkit.org/show_bug.cgi?id=177959 Reviewed by Sam Weinig. Source/JavaScriptCore: This patch adds Subresource Integrity check for module scripts. Currently, only top-level module can be verified with integrity parameter since there is no way to perform integrity check onto the imported modules. In JSC side, we add `parameters` to the entry point of the module loader pipeline. This is fetching parameters and used when fetching modules. We separately pass this parameters to the pipeline along with the script fetcher. The script fetcher is only one for module graph since this is the initiator of this module graph loading. On the other hand, this parameters is for each module fetching. While setting "integrity" parameters to this script fetcher is sufficient to pass parameters to top-level-module's fetching, it is not enough for the future extension. In the future, we will investigate a way to pass parameters to each non-top-level module. At that time, this `parameters` should be per-module. This is because "integrity" value should be different for each module. For example, we will accept some form of syntax to add parameters to `import`. Some proposed syntax is like https://discourse.wicg.io/t/specifying-nonce-or-integrity-when-importing-modules/1861 import "./xxx.js" integrity "xxxxxxx" In this case, this `parameters` will be passed to "./xxx.js" module fetching. This `parameters` should be different from the one of top-level-module's one. That's why we need per-module `parameters` and why this patch adds `parameters` to the module pipeline. On the other hand, we also want to keep script fetcher. This `per-module-graph` thing is important to offer module-graph-wide information. For example, import.meta would have `import.meta.scriptElement`, which is the script element fetching the module graph including this. So, we keep the both, script fetcher and parameters. https://github.com/tc39/proposal-import-meta This parameters will be finally used by pipeline's fetch hook, and WebCore side can use this parameters to fetch modules. We also further clean up the module pipeline by dropping unnecessary features. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/ModuleLoaderPrototype.js: (requestFetch): (requestInstantiate): (requestSatisfy): (loadModule): (loadAndEvaluateModule): This loadAndEvaluateModule should be implemented by just calling loadModule and linkAndEvaluateModule. We can drop requestReady and requestLink. (requestLink): Deleted. (requestImportModule): Deleted. * jsc.cpp: (GlobalObject::moduleLoaderImportModule): (GlobalObject::moduleLoaderFetch): import and fetch hook takes parameters. Currently, we always pass `undefined` for import hook. When dynamic `import()` is extended to accept additional parameters like integrity, this parameters will be replaced with the actual value. (functionLoadModule): (runWithOptions): * runtime/Completion.cpp: (JSC::loadAndEvaluateModule): (JSC::loadModule): (JSC::importModule): * runtime/Completion.h: * runtime/JSGlobalObject.h: * runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncImportModule): * runtime/JSModuleLoader.cpp: (JSC::JSModuleLoader::loadAndEvaluateModule): (JSC::JSModuleLoader::loadModule): (JSC::JSModuleLoader::requestImportModule): (JSC::JSModuleLoader::importModule): (JSC::JSModuleLoader::fetch): * runtime/JSModuleLoader.h: * runtime/JSScriptFetchParameters.cpp: Added. (JSC::JSScriptFetchParameters::destroy): * runtime/JSScriptFetchParameters.h: Added. (JSC::JSScriptFetchParameters::createStructure): (JSC::JSScriptFetchParameters::create): (JSC::JSScriptFetchParameters::parameters const): (JSC::JSScriptFetchParameters::JSScriptFetchParameters): Add ScriptFetchParameters' JSCell wrapper, JSScriptFetchParameters. It is used in the module pipeline. * runtime/JSType.h: * runtime/ModuleLoaderPrototype.cpp: (JSC::moduleLoaderPrototypeFetch): * runtime/ScriptFetchParameters.h: Added. (JSC::ScriptFetchParameters::~ScriptFetchParameters): Add ScriptFetchParameters. We can define our own custom ScriptFetchParameters by inheriting this class. WebCore creates ModuleFetchParameters by inheriting this. * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: Source/WebCore: This patch extends module hooks to accept fetching parameters. When starting fetching modules, WebCore creates ModuleFetchParameters. And this parameters is propagated to the fetch hook. Then, fetch hook can use this parameters to fetch modules. This parameters only contains `integrity` field. This "integrity" is used to perform subresource integrity check in module loader pipeline. And this error is just proparaged as errors in module pipeline, which is the same to the other types of errors in module pipeline. Test: http/tests/subresource-integrity/sri-module.html * ForwardingHeaders/runtime/JSScriptFetchParameters.h: Added. * ForwardingHeaders/runtime/ScriptFetchParameters.h: Added. * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScriptLoader.cpp: (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): Take parameters, which includes "integrity". * bindings/js/CachedModuleScriptLoader.h: * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::moduleLoaderFetch): (WebCore::JSDOMWindowBase::moduleLoaderImportModule): import and fetch hooks take parameters. * bindings/js/JSDOMWindowBase.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): Pass parameters to the entry point of the module pipeline. * bindings/js/ScriptController.h: * bindings/js/ScriptModuleLoader.cpp: (WebCore::ScriptModuleLoader::fetch): If parameters are passed, we set them to CachedModuleScriptLoader. (WebCore::ScriptModuleLoader::importModule): Pass parameters to the entry point of dynamic import. (WebCore::ScriptModuleLoader::notifyFinished): If script loader has parameters, we perform subresource integrity check here. * bindings/js/ScriptModuleLoader.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::load): Create ModuleFetchParameters with "integrity" value. * dom/LoadableModuleScript.h: * dom/ModuleFetchParameters.h: Copied from Source/WebCore/bindings/js/CachedModuleScriptLoader.h. (WebCore::ModuleFetchParameters::create): (WebCore::ModuleFetchParameters::integrity const): (WebCore::ModuleFetchParameters::ModuleFetchParameters): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestModuleScript): Pass "integrity" value to the module script. LayoutTests: * http/tests/subresource-integrity/resources/crossorigin-anon-script-module.js: Added. * http/tests/subresource-integrity/resources/crossorigin-creds-script-module.js: Added. * http/tests/subresource-integrity/resources/crossorigin-ineligible-script-module.js: Added. * http/tests/subresource-integrity/resources/matching-digest-module.js: Added. * http/tests/subresource-integrity/resources/non-matching-digest-module.js: Added. * http/tests/subresource-integrity/resources/sri-utilities.js: (add_result_callback): (SRIModuleTest): (SRIModuleTest.prototype.execute): * http/tests/subresource-integrity/sri-module-expected.txt: Added. * http/tests/subresource-integrity/sri-module.html: Added. * js/dom/modules/module-inline-ignore-integrity-expected.txt: Added. * js/dom/modules/module-inline-ignore-integrity.html: Added. * js/dom/modules/module-integrity-non-top-level-expected.txt: Added. * js/dom/modules/module-integrity-non-top-level.html: Added. * js/dom/modules/script-tests/module-integrity-non-top-level-2.js: Added. * js/dom/modules/script-tests/module-integrity-non-top-level.js: Added. Canonical link: https://commits.webkit.org/194461@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223237 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-12 13:12:48 +00:00
class ModuleFetchParameters;
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
class LoadableModuleScript final : public LoadableScript {
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
public:
virtual ~LoadableModuleScript();
Add referrerpolicy attribute support for <script> elements https://bugs.webkit.org/show_bug.cgi?id=185550 Patch by Rob Buis <rbuis@igalia.com> on 2019-07-17 Reviewed by Youenn Fablet. Source/WebCore: This patch adds 'referrerpolicy' attribute support for script elements. If set, the value is restricted to the ReferrerPolicy enum, and if valid it is used for the script fetch. If not set or invalid, the current behavior is kept. Tests: http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http.html http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https.html http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin.html http/tests/referrer-policy-script/no-referrer/cross-origin-http-http.html http/tests/referrer-policy-script/no-referrer/cross-origin-http.https.html http/tests/referrer-policy-script/no-referrer/same-origin.html http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http.html http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https.html http/tests/referrer-policy-script/origin-when-cross-origin/same-origin.html http/tests/referrer-policy-script/origin/cross-origin-http-http.html http/tests/referrer-policy-script/origin/cross-origin-http.https.html http/tests/referrer-policy-script/origin/same-origin.html http/tests/referrer-policy-script/same-origin/cross-origin-http-http.html http/tests/referrer-policy-script/same-origin/cross-origin-http.https.html http/tests/referrer-policy-script/same-origin/same-origin.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin.html http/tests/referrer-policy-script/strict-origin/cross-origin-http-http.html http/tests/referrer-policy-script/strict-origin/cross-origin-http.https.html http/tests/referrer-policy-script/strict-origin/same-origin.html http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http.html http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https.html http/tests/referrer-policy-script/unsafe-url/same-origin.html * bindings/js/CachedScriptFetcher.cpp: (WebCore::CachedScriptFetcher::requestScriptWithCache const): * bindings/js/CachedScriptFetcher.h: (WebCore::CachedScriptFetcher::CachedScriptFetcher): * dom/InlineClassicScript.h: * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::create): * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): * dom/LoadableModuleScript.h: * dom/LoadableScript.h: (WebCore::LoadableScript::LoadableScript): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): * dom/ScriptElement.h: * dom/ScriptElementCachedScriptFetcher.h: (WebCore::ScriptElementCachedScriptFetcher::ScriptElementCachedScriptFetcher): * html/HTMLIFrameElement.cpp: (WebCore::HTMLIFrameElement::referrerPolicyForBindings const): * html/HTMLScriptElement.cpp: (WebCore::HTMLScriptElement::setReferrerPolicyForBindings): (WebCore::HTMLScriptElement::referrerPolicyForBindings const): (WebCore::HTMLScriptElement::referrerPolicy const): * html/HTMLScriptElement.h: * html/HTMLScriptElement.idl: * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * platform/ReferrerPolicy.cpp: (WebCore::referrerPolicyToString): * platform/ReferrerPolicy.h: * svg/SVGScriptElement.h: LayoutTests: Add tests for scripts with various referrerpolicy attribute values. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin.html: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/no-referrer/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/same-origin.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/same-origin.html: Added. * http/tests/referrer-policy-script/origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/origin/same-origin.html: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/same-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/same-origin.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin.html: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/strict-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/same-origin.html: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/unsafe-url/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/same-origin.html: Added. * http/tests/referrer-policy/resources/script.php: Added. * platform/win/TestExpectations: Canonical link: https://commits.webkit.org/213731@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247509 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-17 09:03:37 +00:00
static Ref<LoadableModuleScript> create(const String& nonce, const String& integrity, ReferrerPolicy, const String& crossOriginMode, const String& charset, const AtomString& initiatorName, bool isInUserAgentShadowTree);
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
bool isLoaded() const final;
Remove WTF::Optional synonym for std::optional, using that class template directly instead https://bugs.webkit.org/show_bug.cgi?id=226433 Reviewed by Chris Dumez. Source/JavaScriptCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py: (ObjCProtocolTypesImplementationGenerator._generate_init_method_for_payload): Use auto instead of Optional<>. Also use * instead of value() and nest the definition of the local inside an if statement in the case where it's an optional. * inspector/scripts/tests/expected/*: Regenerated these results. Source/WebCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebCore/PAL: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebDriver: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKit: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * Scripts/webkit/tests: Regenerated expected results, by running the command "python Scripts/webkit/messages_unittest.py -r". (How am I supposed to know to do that?) Source/WebKitLegacy/ios: * WebCoreSupport/WebChromeClientIOS.h: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/mac: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/win: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WTF: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * wtf/Optional.h: Remove WTF::Optional. Tools: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Canonical link: https://commits.webkit.org/238290@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-30 16:11:40 +00:00
std::optional<Error> error() const final;
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
bool wasCanceled() const final;
Implement dynamic-import for WebCore https://bugs.webkit.org/show_bug.cgi?id=166926 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces browser side dynamic-import implementation. The dynamic-import is new ES feature which is now stage 3. The JSC shell already implements it. The dynamic-import allows us to kick module loading in a dynamic manner. For example, you can write, await module = import(`${HOST}/hello.js`); The dynamic `import` operator (this is not a function) returns a promise with module namespace object if the module loading succeeds. Otherwise, it returns a rejected promise. And importantly, this feature allows us to kick module loading from classic script. Previously, module loading can be only used from <script type="module"> tag. And all the module loading is done statically. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScriptLoader.cpp: (WebCore::CachedModuleScriptLoader::load): * bindings/js/CachedScriptFetcher.cpp: (WebCore::CachedScriptFetcher::create): (WebCore::CachedScriptFetcher::requestModuleScript): requestModuleScript function is used only when loading a new module script. So, LoadableClassicScript should use requestScriptWithCache to load itself. We pass String() for cross origin mode for null cross origin attribute as specified. (WebCore::CachedScriptFetcher::requestScriptWithCache): * bindings/js/CachedScriptFetcher.h: (WebCore::CachedScriptFetcher::CachedScriptFetcher): * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::moduleLoaderImportModule): * bindings/js/JSDOMWindowBase.h: * bindings/js/JSLazyEventListener.cpp: (WebCore::JSLazyEventListener::initializeJSFunction): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::executeScript): * bindings/js/ScriptModuleLoader.cpp: (WebCore::resolveModuleSpecifier): Extract the part of resolving module specifier to a static function to use it in ScriptModuleLoader::resolve and ScriptModuleLoader::importModule. (WebCore::ScriptModuleLoader::resolve): (WebCore::rejectPromise): (WebCore::ScriptModuleLoader::importModule): New hook moduleLoaderImportModule is implemented. This hook is called when `import` operator is used. This hook is responsible to 1. resolve the module name to obtain module specifier. (like, resolve the relative URL to get absolute URL.) 2. kick module loading with the resolved specifier. When resolving the module name, the referrer information is needed. For example, "./script.js" will be resolved to "http://example.com/script.js" if the referrer module specifier is "http://example.com/". If `import("./script.js")` is executed in the classic script src="http://example.com/test.js", it starts loading "http://example.com/script.js". So the information of the caller of `import` operator is necessary here. This appropriate referrer is propagated by SourceOrigin. * bindings/js/ScriptModuleLoader.h: * dom/InlineClassicScript.h: * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::load): * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.h: * dom/LoadableScript.h: (WebCore::LoadableScript::LoadableScript): (WebCore::LoadableScript::isClassicScript): Deleted. (WebCore::LoadableScript::isModuleScript): Deleted. * dom/ScriptElement.h: * dom/ScriptElementCachedScriptFetcher.cpp: Copied from Source/WebCore/dom/InlineClassicScript.h. (WebCore::ScriptElementCachedScriptFetcher::requestModuleScript): This requestModuleScript will be used when the script tag (or modules imported from the script tag) uses `import` operator. In classic scripts, `crossorigin` mode always becomes "omit" while module scripts propagate the original `crossorigin` value. * dom/ScriptElementCachedScriptFetcher.h: Copied from Source/WebCore/bindings/js/CachedScriptFetcher.h. (WebCore::ScriptElementCachedScriptFetcher::crossOriginMode): (WebCore::ScriptElementCachedScriptFetcher::ScriptElementCachedScriptFetcher): LayoutTests: * http/tests/misc/import-absolute-url-expected.txt: Added. * http/tests/misc/import-absolute-url.html: Added. * http/tests/security/contentSecurityPolicy/1.1/import-scriptnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/import-scriptnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed1.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed3.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed4.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed5.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-allowed6.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked1.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked3.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked4.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked5.js: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/import-scriptnonce-blocked6.js: Added. * http/tests/security/import-module-crossorigin-loads-error-expected.txt: Added. * http/tests/security/import-module-crossorigin-loads-error-src-expected.txt: Added. * http/tests/security/import-module-crossorigin-loads-error-src.html: Added. * http/tests/security/import-module-crossorigin-loads-error.html: Added. * http/tests/security/import-module-crossorigin-loads-expected.txt: Added. * http/tests/security/import-module-crossorigin-loads-src-expected.txt: Added. * http/tests/security/import-module-crossorigin-loads-src.html: Added. * http/tests/security/import-module-crossorigin-loads.html: Added. * http/tests/security/import-script-crossorigin-loads-error-expected.txt: Added. * http/tests/security/import-script-crossorigin-loads-error.html: Added. * http/tests/security/import-script-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/import-script-crossorigin-loads-omit.html: Added. * http/tests/security/resources/cors-deny.php: Added. * http/tests/security/resources/import-module-crossorigin-loads-error-src.js: Added. (import.string_appeared_here.then): * http/tests/security/resources/import-module-crossorigin-loads-src.js: Added. (import.string_appeared_here.then): * js/dom/modules/import-execution-order-expected.txt: Added. * js/dom/modules/import-execution-order.html: Copied from LayoutTests/js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html. * js/dom/modules/import-from-handler-expected.txt: Added. * js/dom/modules/import-from-handler.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/import-from-javascript-url-expected.txt: Added. * js/dom/modules/import-from-javascript-url.html: Copied from LayoutTests/js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html. * js/dom/modules/import-from-loaded-classic-expected.txt: Added. * js/dom/modules/import-from-loaded-classic.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/import-from-loaded-module-expected.txt: Added. * js/dom/modules/import-from-loaded-module.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/import-from-module-expected.txt: Added. * js/dom/modules/import-from-module.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/import-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/import-incorrect-relative-specifier.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/import-simple-expected.txt: Added. * js/dom/modules/import-simple.html: Copied from LayoutTests/js/dom/modules/module-src-simple.html. * js/dom/modules/module-document-write-src.html: * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: * js/dom/modules/module-execution-order-mixed.html: * js/dom/modules/module-inline-dynamic.html: * js/dom/modules/module-inline-simple.html: * js/dom/modules/module-load-event-with-src.html: * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: * js/dom/modules/module-load-same-module-from-different-entry-point-in-src.html: * js/dom/modules/module-load-same-module-from-different-entry-point.html: * js/dom/modules/module-not-found-error-event-with-src-and-import.html: * js/dom/modules/module-src-current-script.html: * js/dom/modules/module-src-dynamic.html: * js/dom/modules/module-src-simple.html: * js/dom/modules/module-type-case-insensitive.html: * js/dom/modules/module-will-fire-beforeload.html: * js/dom/modules/nomodule-dynamic-classic-src.html: * js/dom/modules/nomodule-has-no-effect-on-module-inline.html: * js/dom/modules/nomodule-has-no-effect-on-module-src.html: * js/dom/modules/nomodule-prevents-execution-classic-script-src.html: * js/dom/modules/nomodule-reflect.html: * js/dom/modules/resources/error-classic-script.js: Renamed from LayoutTests/js/dom/modules/script-tests/error-classic-script.js. * js/dom/modules/resources/import-from-loaded-classic-finish.js: Added. * js/dom/modules/resources/import-from-loaded-classic.js: Added. * js/dom/modules/resources/import-from-loaded-module-finish.js: Added. * js/dom/modules/resources/import-from-loaded-module.js: Added. * js/dom/modules/resources/module-document-write-src.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-document-write-src.js. * js/dom/modules/resources/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js. * js/dom/modules/resources/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js. * js/dom/modules/resources/module-execution-order-mixed-2.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-2.js. * js/dom/modules/resources/module-execution-order-mixed-cappuccino.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js. * js/dom/modules/resources/module-execution-order-mixed-cocoa.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js. * js/dom/modules/resources/module-execution-order-mixed-matcha.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-matcha.js. * js/dom/modules/resources/module-execution-order-mixed-with-classic-scripts-2.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js. * js/dom/modules/resources/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js. * js/dom/modules/resources/module-execution-order-mixed-with-classic-scripts-cocoa.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js. * js/dom/modules/resources/module-execution-order-mixed-with-classic-scripts-matcha.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js. * js/dom/modules/resources/module-execution-order-mixed-with-classic-scripts.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js. * js/dom/modules/resources/module-execution-order-mixed.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-execution-order-mixed.js. * js/dom/modules/resources/module-inline-dynamic.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-inline-dynamic.js. * js/dom/modules/resources/module-inline-simple.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-inline-simple.js. * js/dom/modules/resources/module-load-event-with-src.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-load-event-with-src.js. * js/dom/modules/resources/module-load-same-module-from-different-entry-point.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js. * js/dom/modules/resources/module-not-found-error-event-with-src-and-import.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js. * js/dom/modules/resources/module-src-current-script.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-src-current-script.js. * js/dom/modules/resources/module-src-dynamic-cocoa.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-src-dynamic-cocoa.js. * js/dom/modules/resources/module-src-dynamic.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-src-dynamic.js. * js/dom/modules/resources/module-src-simple-cocoa.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-src-simple-cocoa.js. * js/dom/modules/resources/module-src-simple.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-src-simple.js. * js/dom/modules/resources/module-will-fire-beforeload.js: Renamed from LayoutTests/js/dom/modules/script-tests/module-will-fire-beforeload.js. Canonical link: https://commits.webkit.org/184534@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-27 10:49:23 +00:00
bool isClassicScript() const final { return false; }
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
bool isModuleScript() const final { return true; }
void execute(ScriptElement&) final;
void setError(Error&&);
void notifyLoadCompleted(UniquedStringImpl&);
void notifyLoadFailed(LoadableScript::Error&&);
void notifyLoadWasCanceled();
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
UniquedStringImpl* moduleKey() const { return m_moduleKey.get(); }
[JSC] ScriptFetcher should be notified directly from module pipeline https://bugs.webkit.org/show_bug.cgi?id=178340 Reviewed by Sam Weinig. Source/JavaScriptCore: Previously, we use JSStdFunction to let WebCore inform the module pipeline results. We setup JSStdFunction to the resulted promise of the module pipeline. It is super ad-hoc since JSStdFunction's lambda need extra-careful to make it non-cyclic-referenced. JSStdFunction's lambda can capture variables, but they are not able to be marked by GC. But now, we have ScriptFetcher. It is introduced after we implemented the module pipeline notification mechanism by using JSStdFunction. But it is appropriate one to receive notification from the module pipeline by observer style. This patch removes the above ad-hoc JSStdFunction use. And now ScriptFetcher receives completion/failure notifications from the module pipeline. * builtins/ModuleLoaderPrototype.js: (loadModule): (loadAndEvaluateModule): * runtime/Completion.cpp: (JSC::loadModule): * runtime/Completion.h: * runtime/JSModuleLoader.cpp: (JSC::jsValueToModuleKey): (JSC::JSModuleLoader::notifyCompleted): (JSC::JSModuleLoader::notifyFailed): * runtime/JSModuleLoader.h: * runtime/ModuleLoaderPrototype.cpp: (JSC::moduleLoaderPrototypeNotifyCompleted): (JSC::moduleLoaderPrototypeNotifyFailed): * runtime/ScriptFetcher.h: (JSC::ScriptFetcher::notifyLoadCompleted): (JSC::ScriptFetcher::notifyLoadFailed): Source/WebCore: No behavior change. * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::jsValueToModuleKey): Deleted. (WebCore::ScriptController::setupModuleScriptHandlers): Deleted. * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::notifyLoadFailed): * dom/LoadableModuleScript.h: LayoutTests: * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: * http/tests/security/module-no-mime-type-expected.txt: * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Canonical link: https://commits.webkit.org/194756@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223744 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 07:19:02 +00:00
JS Modules in Workers https://bugs.webkit.org/show_bug.cgi?id=164860 Reviewed by Saam Barati. LayoutTests/imported/w3c: Some of worklet failures in WPT is because, 1. Previously, worklet does not support module. These tests are passing incorrectly when modules are not supported. Now, modules are supported, and some edge features are missing, so start failing 2. WPT is using www1.localhost in some tests (CSP tests), and this is not supported in WebKit's WPT testing. So failing incorrectly. * web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/non-object.tentative.any.worker-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-module-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker-importScripts-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker.sub-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/evaluation-order-1-nothrow-worker-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/evaluation-order-1-worker-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/evaluation-order-2-import-worker-expected.txt: * web-platform-tests/html/semantics/scripting-1/the-script-element/module/evaluation-order-3-dynamic-worker-expected.txt: * web-platform-tests/service-workers/service-worker/import-module-scripts.https-expected.txt: * web-platform-tests/workers/baseurl/alpha/import-in-moduleworker-expected.txt: * web-platform-tests/workers/baseurl/alpha/importScripts-in-worker-expected.txt: * web-platform-tests/workers/baseurl/alpha/xhr-in-moduleworker-expected.txt: * web-platform-tests/workers/baseurl/alpha/xhr-in-worker-expected.txt: * web-platform-tests/workers/constructors/Worker/same-origin-expected.txt: * web-platform-tests/workers/interfaces/WorkerGlobalScope/location/redirect-expected.txt: * web-platform-tests/workers/interfaces/WorkerGlobalScope/location/redirect-module-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import-blob-url.any-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import-csp-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import-failure-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import-meta-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import-meta.html: * web-platform-tests/workers/modules/dedicated-worker-import-referrer-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-import.any-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-options-type-expected.txt: * web-platform-tests/workers/modules/dedicated-worker-parse-error-failure-expected.txt: * web-platform-tests/workers/name-property-expected.txt: * web-platform-tests/worklets/audio-worklet-credentials.https-expected.txt: * web-platform-tests/worklets/audio-worklet-csp.https-expected.txt: * web-platform-tests/worklets/audio-worklet-import.https-expected.txt: * web-platform-tests/worklets/audio-worklet-referrer.https-expected.txt: * web-platform-tests/xhr/open-url-redirected-worker-origin-expected.txt: Source/JavaScriptCore: Add error information to extract this in WebCore's module loader. Currently, we are using Promise pipeline, and this makes it a bit difficult to extract error information. This error information attached in this patch allows us to extract SyntaxError in WebCore, and throwing JS SyntaxError instead of AbortError. We are planning to update our module pipieline not using Promises in the future. The current design derived from the original module loader pipeline where using Promises is critical. But now, that proposal was abandoned, so we can just simplify the module loader. * runtime/AggregateError.cpp: (JSC::AggregateError::AggregateError): * runtime/Error.cpp: (JSC::createError): (JSC::createEvalError): (JSC::createRangeError): (JSC::createReferenceError): (JSC::createSyntaxError): (JSC::createTypeError): (JSC::createURIError): (JSC::createGetterTypeError): (JSC::throwSyntaxError): * runtime/Error.h: * runtime/ErrorConstructor.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * runtime/ErrorInstance.cpp: (JSC::ErrorInstance::ErrorInstance): (JSC::ErrorInstance::create): (JSC::ErrorInstance::sanitizedMessageString): (JSC::ErrorInstance::sanitizedNameString): (JSC::ErrorInstance::sanitizedToString): * runtime/ErrorInstance.h: (JSC::ErrorInstance::create): (JSC::ErrorInstance::errorType const): * runtime/JSGlobalObjectFunctions.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * runtime/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor<errorType>::constructImpl): (JSC::NativeErrorConstructor<errorType>::callImpl): * runtime/NullSetterFunction.cpp: (JSC::NullSetterFunctionInternal::JSC_DEFINE_HOST_FUNCTION): * wasm/js/JSWebAssemblyCompileError.cpp: (JSC::JSWebAssemblyCompileError::JSWebAssemblyCompileError): * wasm/js/JSWebAssemblyLinkError.cpp: (JSC::JSWebAssemblyLinkError::JSWebAssemblyLinkError): * wasm/js/JSWebAssemblyRuntimeError.cpp: (JSC::JSWebAssemblyRuntimeError::JSWebAssemblyRuntimeError): * wasm/js/WebAssemblyCompileErrorConstructor.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * wasm/js/WebAssemblyLinkErrorConstructor.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): Source/WebCore: This patch implements JS modules in Workers and Worklets. We are not supporting modules in ServiceWorkers' initialization yet. But service-worker can import modules via JS `import()`. The worker can be executed as a module if we pass, `type: "module"` to worker options. Worklet is executed as modules by default. 1. In Worker, we first fetch the initial code. And then, analyze the dependencies and load subsequent modules. We iterate run-loop to load all the dependent modules in the module loader. At that time, we annotate run-loop tasks with special taskMode to iterate tasks with this taskMode. This prevents us from discarding different tasks in this run-loop driving phase. (e.g. postMessage can be called from the main thread while loading module graph, in that case, we should not discard this task.) 2. In Worklet, we just request module loading to ScriptModuleLoader, and run it after loading module graph. This is OK since worklet thread is already running. So we can just request modules and worklet thread automatically drives module loading via run-loop. * Headers.cmake: * Modules/webaudio/AudioWorkletGlobalScope.h: (WebCore::AudioWorkletGlobalScope::currentFrame const): Deleted. (WebCore::AudioWorkletGlobalScope::sampleRate const): Deleted. (WebCore::AudioWorkletGlobalScope::currentTime const): Deleted. * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScriptLoader.cpp: (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: * bindings/js/CachedScriptFetcher.cpp: * bindings/js/JSDOMExceptionHandling.cpp: (WebCore::retrieveErrorMessageWithoutName): (WebCore::createDOMException): * bindings/js/JSDOMExceptionHandling.h: * bindings/js/JSDOMGlobalObject.cpp: (WebCore::scriptModuleLoader): (WebCore::JSDOMGlobalObject::moduleLoaderResolve): (WebCore::JSDOMGlobalObject::moduleLoaderFetch): (WebCore::JSDOMGlobalObject::moduleLoaderEvaluate): (WebCore::JSDOMGlobalObject::moduleLoaderImportModule): (WebCore::JSDOMGlobalObject::moduleLoaderCreateImportMetaProperties): * bindings/js/JSDOMGlobalObject.h: * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::moduleLoaderResolve): Deleted. (WebCore::JSDOMWindowBase::moduleLoaderFetch): Deleted. (WebCore::JSDOMWindowBase::moduleLoaderEvaluate): Deleted. (WebCore::JSDOMWindowBase::moduleLoaderImportModule): Deleted. (WebCore::JSDOMWindowBase::moduleLoaderCreateImportMetaProperties): Deleted. * bindings/js/JSDOMWindowBase.h: * bindings/js/JSWorkerGlobalScopeBase.cpp: * bindings/js/JSWorkletGlobalScopeBase.cpp: * bindings/js/ModuleScriptLoader.h: Copied from Source/WebCore/dom/ModuleFetchParameters.h. (WebCore::ModuleScriptLoader::clearClient): (WebCore::ModuleScriptLoader::scriptFetcher): (WebCore::ModuleScriptLoader::parameters): (WebCore::ModuleScriptLoader::ModuleScriptLoader): * bindings/js/ModuleScriptLoaderClient.h: Renamed from Source/WebCore/bindings/js/CachedModuleScriptLoaderClient.h. * bindings/js/ScriptModuleLoader.cpp: (WebCore::ScriptModuleLoader::ScriptModuleLoader): (WebCore::resolveModuleSpecifier): (WebCore::ScriptModuleLoader::resolve): (WebCore::ScriptModuleLoader::fetch): (WebCore::ScriptModuleLoader::moduleURL): (WebCore::ScriptModuleLoader::responseURLFromRequestURL): (WebCore::ScriptModuleLoader::evaluate): (WebCore::ScriptModuleLoader::importModule): (WebCore::ScriptModuleLoader::notifyFinished): * bindings/js/ScriptModuleLoader.h: * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * bindings/js/WorkerModuleScriptLoader.cpp: Added. (WebCore::WorkerModuleScriptLoader::create): (WebCore::WorkerModuleScriptLoader::WorkerModuleScriptLoader): (WebCore::WorkerModuleScriptLoader::~WorkerModuleScriptLoader): (WebCore::WorkerModuleScriptLoader::load): (WebCore::WorkerModuleScriptLoader::referrerPolicy): (WebCore::WorkerModuleScriptLoader::notifyFinished): (WebCore::WorkerModuleScriptLoader::taskMode): * bindings/js/WorkerModuleScriptLoader.h: Copied from Source/WebCore/dom/ModuleFetchParameters.h. * bindings/js/WorkerScriptFetcher.h: Added. * dom/Document.cpp: * dom/ExceptionCode.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::load): Deleted. * dom/LoadableModuleScript.h: * dom/ModuleFetchParameters.h: (WebCore::ModuleFetchParameters::create): (WebCore::ModuleFetchParameters::isTopLevelModule const): (WebCore::ModuleFetchParameters::ModuleFetchParameters): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestModuleScript): * loader/ThreadableLoader.cpp: (WebCore::ThreadableLoader::create): * loader/ThreadableLoader.h: (WebCore::ThreadableLoader::create): * workers/DedicatedWorkerGlobalScope.h: * workers/Worker.cpp: (WebCore::Worker::Worker): (WebCore::Worker::create): (WebCore::Worker::notifyFinished): * workers/Worker.h: * workers/Worker.idl: * workers/WorkerGlobalScope.cpp: (WebCore::WorkerGlobalScope::WorkerGlobalScope): (WebCore::WorkerGlobalScope::importScripts): * workers/WorkerGlobalScope.h: (WebCore::WorkerGlobalScope::credentials const): * workers/WorkerGlobalScopeProxy.h: * workers/WorkerMessagingProxy.cpp: (WebCore::WorkerMessagingProxy::startWorkerGlobalScope): * workers/WorkerMessagingProxy.h: * workers/WorkerOrWorkletGlobalScope.cpp: (WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope): * workers/WorkerOrWorkletGlobalScope.h: (WebCore::WorkerOrWorkletGlobalScope::moduleLoader): * workers/WorkerOrWorkletScriptController.cpp: (WebCore::jsValueToModuleKey): (WebCore::WorkerOrWorkletScriptController::evaluateModule): (WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously): (WebCore::WorkerOrWorkletScriptController::linkAndEvaluateModule): (WebCore::WorkerOrWorkletScriptController::loadAndEvaluateModule): * workers/WorkerOrWorkletScriptController.h: * workers/WorkerScriptLoader.cpp: (WebCore::WorkerScriptLoader::loadAsynchronously): (WebCore::WorkerScriptLoader::didReceiveResponse): * workers/WorkerScriptLoader.h: (WebCore::WorkerScriptLoader::responseSource const): (WebCore::WorkerScriptLoader::isRedirected const): * workers/WorkerThread.cpp: (WebCore::WorkerParameters::isolatedCopy const): (WebCore::WorkerThread::evaluateScriptIfNecessary): * workers/WorkerThread.h: * workers/WorkerType.h: * workers/service/ServiceWorkerContainer.h: * workers/service/ServiceWorkerGlobalScope.h: * workers/service/ServiceWorkerJob.cpp: (WebCore::ServiceWorkerJob::fetchScriptWithContext): * workers/service/ServiceWorkerRegistrationOptions.h: * workers/service/context/ServiceWorkerThread.cpp: (WebCore::ServiceWorkerThread::ServiceWorkerThread): * workers/service/server/SWServerWorker.h: * worklets/PaintWorkletGlobalScope.h: (WebCore::PaintWorkletGlobalScope::paintDefinitionMap): Deleted. (WebCore::PaintWorkletGlobalScope::paintDefinitionLock): Deleted. (WebCore::PaintWorkletGlobalScope::~PaintWorkletGlobalScope): Deleted. * worklets/WorkletGlobalScope.cpp: (WebCore::WorkletGlobalScope::fetchAndInvokeScript): (WebCore::WorkletGlobalScope::processNextScriptFetchJobIfNeeded): Deleted. (WebCore::WorkletGlobalScope::didReceiveResponse): Deleted. (WebCore::WorkletGlobalScope::notifyFinished): Deleted. (WebCore::WorkletGlobalScope::didCompleteScriptFetchJob): Deleted. * worklets/WorkletGlobalScope.h: LayoutTests: * TestExpectations: * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: * http/tests/subresource-integrity/sri-module-expected.txt: * webaudio/audioworklet-addModule-failure-expected.txt: * webaudio/worklet-crash-expected.txt: Canonical link: https://commits.webkit.org/234389@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@273203 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-20 20:28:27 +00:00
ModuleFetchParameters& parameters() { return m_parameters.get(); }
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
private:
Add referrerpolicy attribute support for <script> elements https://bugs.webkit.org/show_bug.cgi?id=185550 Patch by Rob Buis <rbuis@igalia.com> on 2019-07-17 Reviewed by Youenn Fablet. Source/WebCore: This patch adds 'referrerpolicy' attribute support for script elements. If set, the value is restricted to the ReferrerPolicy enum, and if valid it is used for the script fetch. If not set or invalid, the current behavior is kept. Tests: http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http.html http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https.html http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin.html http/tests/referrer-policy-script/no-referrer/cross-origin-http-http.html http/tests/referrer-policy-script/no-referrer/cross-origin-http.https.html http/tests/referrer-policy-script/no-referrer/same-origin.html http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http.html http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https.html http/tests/referrer-policy-script/origin-when-cross-origin/same-origin.html http/tests/referrer-policy-script/origin/cross-origin-http-http.html http/tests/referrer-policy-script/origin/cross-origin-http.https.html http/tests/referrer-policy-script/origin/same-origin.html http/tests/referrer-policy-script/same-origin/cross-origin-http-http.html http/tests/referrer-policy-script/same-origin/cross-origin-http.https.html http/tests/referrer-policy-script/same-origin/same-origin.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https.html http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin.html http/tests/referrer-policy-script/strict-origin/cross-origin-http-http.html http/tests/referrer-policy-script/strict-origin/cross-origin-http.https.html http/tests/referrer-policy-script/strict-origin/same-origin.html http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http.html http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https.html http/tests/referrer-policy-script/unsafe-url/same-origin.html * bindings/js/CachedScriptFetcher.cpp: (WebCore::CachedScriptFetcher::requestScriptWithCache const): * bindings/js/CachedScriptFetcher.h: (WebCore::CachedScriptFetcher::CachedScriptFetcher): * dom/InlineClassicScript.h: * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::create): * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): * dom/LoadableModuleScript.h: * dom/LoadableScript.h: (WebCore::LoadableScript::LoadableScript): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): * dom/ScriptElement.h: * dom/ScriptElementCachedScriptFetcher.h: (WebCore::ScriptElementCachedScriptFetcher::ScriptElementCachedScriptFetcher): * html/HTMLIFrameElement.cpp: (WebCore::HTMLIFrameElement::referrerPolicyForBindings const): * html/HTMLScriptElement.cpp: (WebCore::HTMLScriptElement::setReferrerPolicyForBindings): (WebCore::HTMLScriptElement::referrerPolicyForBindings const): (WebCore::HTMLScriptElement::referrerPolicy const): * html/HTMLScriptElement.h: * html/HTMLScriptElement.idl: * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * platform/ReferrerPolicy.cpp: (WebCore::referrerPolicyToString): * platform/ReferrerPolicy.h: * svg/SVGScriptElement.h: LayoutTests: Add tests for scripts with various referrerpolicy attribute values. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer-when-downgrade/same-origin.html: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/no-referrer/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/no-referrer/same-origin.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/origin-when-cross-origin/same-origin.html: Added. * http/tests/referrer-policy-script/origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/origin/same-origin.html: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/same-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/same-origin/same-origin.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin-when-cross-origin/same-origin.html: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/strict-origin/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/strict-origin/same-origin.html: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http-http.html: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/cross-origin-http.https.html: Added. * http/tests/referrer-policy-script/unsafe-url/same-origin-expected.txt: Added. * http/tests/referrer-policy-script/unsafe-url/same-origin.html: Added. * http/tests/referrer-policy/resources/script.php: Added. * platform/win/TestExpectations: Canonical link: https://commits.webkit.org/213731@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247509 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-17 09:03:37 +00:00
LoadableModuleScript(const String& nonce, const String& integrity, ReferrerPolicy, const String& crossOriginMode, const String& charset, const AtomString& initiatorName, bool isInUserAgentShadowTree);
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
Support integrity="" on module scripts https://bugs.webkit.org/show_bug.cgi?id=177959 Reviewed by Sam Weinig. Source/JavaScriptCore: This patch adds Subresource Integrity check for module scripts. Currently, only top-level module can be verified with integrity parameter since there is no way to perform integrity check onto the imported modules. In JSC side, we add `parameters` to the entry point of the module loader pipeline. This is fetching parameters and used when fetching modules. We separately pass this parameters to the pipeline along with the script fetcher. The script fetcher is only one for module graph since this is the initiator of this module graph loading. On the other hand, this parameters is for each module fetching. While setting "integrity" parameters to this script fetcher is sufficient to pass parameters to top-level-module's fetching, it is not enough for the future extension. In the future, we will investigate a way to pass parameters to each non-top-level module. At that time, this `parameters` should be per-module. This is because "integrity" value should be different for each module. For example, we will accept some form of syntax to add parameters to `import`. Some proposed syntax is like https://discourse.wicg.io/t/specifying-nonce-or-integrity-when-importing-modules/1861 import "./xxx.js" integrity "xxxxxxx" In this case, this `parameters` will be passed to "./xxx.js" module fetching. This `parameters` should be different from the one of top-level-module's one. That's why we need per-module `parameters` and why this patch adds `parameters` to the module pipeline. On the other hand, we also want to keep script fetcher. This `per-module-graph` thing is important to offer module-graph-wide information. For example, import.meta would have `import.meta.scriptElement`, which is the script element fetching the module graph including this. So, we keep the both, script fetcher and parameters. https://github.com/tc39/proposal-import-meta This parameters will be finally used by pipeline's fetch hook, and WebCore side can use this parameters to fetch modules. We also further clean up the module pipeline by dropping unnecessary features. * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/ModuleLoaderPrototype.js: (requestFetch): (requestInstantiate): (requestSatisfy): (loadModule): (loadAndEvaluateModule): This loadAndEvaluateModule should be implemented by just calling loadModule and linkAndEvaluateModule. We can drop requestReady and requestLink. (requestLink): Deleted. (requestImportModule): Deleted. * jsc.cpp: (GlobalObject::moduleLoaderImportModule): (GlobalObject::moduleLoaderFetch): import and fetch hook takes parameters. Currently, we always pass `undefined` for import hook. When dynamic `import()` is extended to accept additional parameters like integrity, this parameters will be replaced with the actual value. (functionLoadModule): (runWithOptions): * runtime/Completion.cpp: (JSC::loadAndEvaluateModule): (JSC::loadModule): (JSC::importModule): * runtime/Completion.h: * runtime/JSGlobalObject.h: * runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncImportModule): * runtime/JSModuleLoader.cpp: (JSC::JSModuleLoader::loadAndEvaluateModule): (JSC::JSModuleLoader::loadModule): (JSC::JSModuleLoader::requestImportModule): (JSC::JSModuleLoader::importModule): (JSC::JSModuleLoader::fetch): * runtime/JSModuleLoader.h: * runtime/JSScriptFetchParameters.cpp: Added. (JSC::JSScriptFetchParameters::destroy): * runtime/JSScriptFetchParameters.h: Added. (JSC::JSScriptFetchParameters::createStructure): (JSC::JSScriptFetchParameters::create): (JSC::JSScriptFetchParameters::parameters const): (JSC::JSScriptFetchParameters::JSScriptFetchParameters): Add ScriptFetchParameters' JSCell wrapper, JSScriptFetchParameters. It is used in the module pipeline. * runtime/JSType.h: * runtime/ModuleLoaderPrototype.cpp: (JSC::moduleLoaderPrototypeFetch): * runtime/ScriptFetchParameters.h: Added. (JSC::ScriptFetchParameters::~ScriptFetchParameters): Add ScriptFetchParameters. We can define our own custom ScriptFetchParameters by inheriting this class. WebCore creates ModuleFetchParameters by inheriting this. * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: Source/WebCore: This patch extends module hooks to accept fetching parameters. When starting fetching modules, WebCore creates ModuleFetchParameters. And this parameters is propagated to the fetch hook. Then, fetch hook can use this parameters to fetch modules. This parameters only contains `integrity` field. This "integrity" is used to perform subresource integrity check in module loader pipeline. And this error is just proparaged as errors in module pipeline, which is the same to the other types of errors in module pipeline. Test: http/tests/subresource-integrity/sri-module.html * ForwardingHeaders/runtime/JSScriptFetchParameters.h: Added. * ForwardingHeaders/runtime/ScriptFetchParameters.h: Added. * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScriptLoader.cpp: (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): Take parameters, which includes "integrity". * bindings/js/CachedModuleScriptLoader.h: * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::moduleLoaderFetch): (WebCore::JSDOMWindowBase::moduleLoaderImportModule): import and fetch hooks take parameters. * bindings/js/JSDOMWindowBase.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): Pass parameters to the entry point of the module pipeline. * bindings/js/ScriptController.h: * bindings/js/ScriptModuleLoader.cpp: (WebCore::ScriptModuleLoader::fetch): If parameters are passed, we set them to CachedModuleScriptLoader. (WebCore::ScriptModuleLoader::importModule): Pass parameters to the entry point of dynamic import. (WebCore::ScriptModuleLoader::notifyFinished): If script loader has parameters, we perform subresource integrity check here. * bindings/js/ScriptModuleLoader.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::load): Create ModuleFetchParameters with "integrity" value. * dom/LoadableModuleScript.h: * dom/ModuleFetchParameters.h: Copied from Source/WebCore/bindings/js/CachedModuleScriptLoader.h. (WebCore::ModuleFetchParameters::create): (WebCore::ModuleFetchParameters::integrity const): (WebCore::ModuleFetchParameters::ModuleFetchParameters): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestModuleScript): Pass "integrity" value to the module script. LayoutTests: * http/tests/subresource-integrity/resources/crossorigin-anon-script-module.js: Added. * http/tests/subresource-integrity/resources/crossorigin-creds-script-module.js: Added. * http/tests/subresource-integrity/resources/crossorigin-ineligible-script-module.js: Added. * http/tests/subresource-integrity/resources/matching-digest-module.js: Added. * http/tests/subresource-integrity/resources/non-matching-digest-module.js: Added. * http/tests/subresource-integrity/resources/sri-utilities.js: (add_result_callback): (SRIModuleTest): (SRIModuleTest.prototype.execute): * http/tests/subresource-integrity/sri-module-expected.txt: Added. * http/tests/subresource-integrity/sri-module.html: Added. * js/dom/modules/module-inline-ignore-integrity-expected.txt: Added. * js/dom/modules/module-inline-ignore-integrity.html: Added. * js/dom/modules/module-integrity-non-top-level-expected.txt: Added. * js/dom/modules/module-integrity-non-top-level.html: Added. * js/dom/modules/script-tests/module-integrity-non-top-level-2.js: Added. * js/dom/modules/script-tests/module-integrity-non-top-level.js: Added. Canonical link: https://commits.webkit.org/194461@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223237 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-12 13:12:48 +00:00
Ref<ModuleFetchParameters> m_parameters;
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
RefPtr<UniquedStringImpl> m_moduleKey;
Remove WTF::Optional synonym for std::optional, using that class template directly instead https://bugs.webkit.org/show_bug.cgi?id=226433 Reviewed by Chris Dumez. Source/JavaScriptCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py: (ObjCProtocolTypesImplementationGenerator._generate_init_method_for_payload): Use auto instead of Optional<>. Also use * instead of value() and nest the definition of the local inside an if statement in the case where it's an optional. * inspector/scripts/tests/expected/*: Regenerated these results. Source/WebCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebCore/PAL: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebDriver: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKit: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * Scripts/webkit/tests: Regenerated expected results, by running the command "python Scripts/webkit/messages_unittest.py -r". (How am I supposed to know to do that?) Source/WebKitLegacy/ios: * WebCoreSupport/WebChromeClientIOS.h: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/mac: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/win: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WTF: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * wtf/Optional.h: Remove WTF::Optional. Tools: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Canonical link: https://commits.webkit.org/238290@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-30 16:11:40 +00:00
std::optional<LoadableScript::Error> m_error;
Merge CachedModuleScript and LoadableModuleScript https://bugs.webkit.org/show_bug.cgi?id=167500 Reviewed by Darin Adler. CachedModuleScript becomes duplicate with LoadableModuleScript. And CachedModuleScript does not offer any meaningful functionality to LoadableModuleScript. This patch merges CachedModuleScript to LoadableModuleScript. No behavior change. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Removed. * bindings/js/CachedModuleScript.h: Removed. * bindings/js/CachedModuleScriptClient.h: Removed. * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/ScriptController.cpp: (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): (WebCore::ScriptController::setupModuleScriptHandlers): * bindings/js/ScriptController.h: * dom/LoadableModuleScript.cpp: (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyLoadCompleted): (WebCore::LoadableModuleScript::notifyLoadFailed): (WebCore::LoadableModuleScript::notifyLoadWasCanceled): (WebCore::LoadableModuleScript::execute): (WebCore::LoadableModuleScript::load): (WebCore::LoadableModuleScript::notifyFinished): Deleted. * dom/LoadableModuleScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::executeModuleScript): * dom/ScriptElement.h: Canonical link: https://commits.webkit.org/184562@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-01-28 00:47:30 +00:00
bool m_wasCanceled { false };
bool m_isLoaded { false };
[ES6] Integrate ES6 Modules into WebCore https://bugs.webkit.org/show_bug.cgi?id=148897 Reviewed by Ryosuke Niwa. Source/WebCore: This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. JSC constructs the module loader pipeline by the chains of the promises. To handle this, the following components are added. 1. CachedModuleScript CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers similar APIs to CachedScript. ScriptElement and PendingScript interact with CachedModuleScript when the script tag is the module tag instead of CachedScript. ScriptElement and PendingScript will receive the notification from CachedModuleScript by implementing CachedModuleScriptClient. 2. ScriptModuleLoader This is the module loader instantiated per document. It manages fetching and offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader will receive the notification by implementing CachedModuleScriptLoaderClient. When the resource is fetched, the module loader will drive the promise resolve/reject chain. 3. CachedModuleScriptLoader This fetches the resource by using CachedScript. Using CachedScript means that it automatically reports the resource to the inspector. CachedModuleScriptLoader notify to ScriptModuleLoader when the resource is fetched. One tricky point is that the fetch requests issued from one module-graph should share the same nonce, crossorigin attributes etc. Here, we wrote the module graph like `A -> B (A depends on B)`. <script tag> -> A -> B -> C -> D When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration derived from the original script tag. So per module-graph information should be shared throughout the module loader pipeline. To do so, JSC's module loader implementation can take the value called `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the initiator. Each fetch request is created by using this initiator script element. More integration into the inspector should be done in the subsequent patch. * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/CachedModuleScript.cpp: Added. CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. (WebCore::CachedModuleScript::create): (WebCore::CachedModuleScript::CachedModuleScript): (WebCore::CachedModuleScript::load): (WebCore::CachedModuleScript::notifyLoadCompleted): (WebCore::CachedModuleScript::notifyLoadFailed): (WebCore::CachedModuleScript::notifyLoadWasCanceled): (WebCore::CachedModuleScript::notifyClientFinished): (WebCore::CachedModuleScript::addClient): (WebCore::CachedModuleScript::removeClient): * bindings/js/CachedModuleScript.h: Added. (WebCore::CachedModuleScript::moduleKey): (WebCore::CachedModuleScript::error): (WebCore::CachedModuleScript::wasCanceled): (WebCore::CachedModuleScript::isLoaded): (WebCore::CachedModuleScript::nonce): (WebCore::CachedModuleScript::crossOriginMode): Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): * bindings/js/CachedModuleScriptLoader.cpp: Added. CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the client. Currently, ScriptModuleLoader implements this client interface. (WebCore::CachedModuleScriptLoader::create): (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): (WebCore::CachedModuleScriptLoader::load): Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, nonce and crossorigin (and charset) attributes of this element are applied to the new request. (WebCore::CachedModuleScriptLoader::notifyFinished): * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): * bindings/js/CachedScriptSourceProvider.h: (WebCore::CachedScriptSourceProvider::create): (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): (WebCore::makeSource): * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSDOMBinding.cpp: (WebCore::retrieveErrorMessage): (WebCore::reportException): * bindings/js/JSDOMBinding.h: * bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::loadModule): (WebCore::JSMainThreadExecState::linkAndEvaluateModule): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::loadModuleScript): This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to the given CachedModuleScript. (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScript): This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. (WebCore::ScriptController::evaluateModule): Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function to actually evaluate the module. (WebCore::jsValueToModuleKey): (WebCore::ScriptController::setupModuleScriptHandlers): The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. (WebCore::ScriptController::executeScript): * bindings/js/ScriptController.h: (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): * bindings/js/ScriptModuleLoader.cpp: We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are suspended, the module loader propagation stops. (WebCore::ScriptModuleLoader::~ScriptModuleLoader): Clear the clients of the fetchers issued from this loader. (WebCore::isRootModule): (WebCore::ScriptModuleLoader::resolve): Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL for that. Instead of URL, we use symbol at that time. (WebCore::ScriptModuleLoader::fetch): Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. This offers the way to distinguish the canceled error from the other errors. (WebCore::ScriptModuleLoader::evaluate): This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. (WebCore::ScriptModuleLoader::notifyFinished): This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. The module loader pipeline is constructed as a chain of promises. Rejecting a promise when some error occurs is important because the execution flow of the promise chain is driven by "rejected" or "fulfilled" events. If the promise is not rejected while error occurs, reject handler won't be executed and all the subsequent promise chain will wait the result forever. As a result, even if the error is already reported to the inspector elsewhere, it should be propagated in the pipeline. For example, the error of loading CachedResource is already reported to the inspector by the loader. But we still need to reject the promise to propagate this error to the script element. At that time, we don't want to report the same error twice. When we propagate the error that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised when checking syntax of a module script from errors reported already. In the reject handler of the promise, we only report a error that is not this symbol. And mime type checking is done here since the module script always require this check. * bindings/js/ScriptModuleLoader.h: (WebCore::ScriptModuleLoader::document): Deleted. * bindings/js/ScriptSourceCode.h: (WebCore::ScriptSourceCode::ScriptSourceCode): * dom/CurrentScriptIncrementer.h: (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): * dom/LoadableClassicScript.cpp: (WebCore::LoadableClassicScript::error): (WebCore::LoadableClassicScript::execute): (WebCore::LoadableClassicScript::wasErrored): Deleted. * dom/LoadableClassicScript.h: * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. This is the derived class from LoadableScript. It is used for the script module graphs. (WebCore::LoadableModuleScript::create): (WebCore::LoadableModuleScript::LoadableModuleScript): (WebCore::LoadableModuleScript::~LoadableModuleScript): (WebCore::LoadableModuleScript::isLoaded): (WebCore::LoadableModuleScript::error): (WebCore::LoadableModuleScript::wasCanceled): (WebCore::LoadableModuleScript::notifyFinished): (WebCore::LoadableModuleScript::execute): * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. (isType): * dom/LoadableScript.h: (WebCore::LoadableScript::isModuleScript): (WebCore::LoadableScript::isModuleGraph): Deleted. * dom/PendingScript.cpp: (WebCore::PendingScript::error): (WebCore::PendingScript::wasErrored): Deleted. * dom/PendingScript.h: * dom/ScriptElement.cpp: (WebCore::ScriptElement::ScriptElement): (WebCore::ScriptElement::determineScriptType): (WebCore::ScriptElement::prepareScript): prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup the CachedModuleScript. (WebCore::ScriptElement::requestClassicScript): (WebCore::ScriptElement::requestModuleScript): We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the above values in CachedModuleScript. Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's inline script rules. (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): The module loader will construct the fetching request by calling this function. This should be here since we would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this script tag will be used. (WebCore::ScriptElement::requestScriptWithCache): (WebCore::ScriptElement::executeScript): (WebCore::ScriptElement::executeModuleScript): The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, we have the different entry point from ScriptElement::executeScript. (WebCore::ScriptElement::executeScriptAndDispatchEvent): (WebCore::ScriptElement::executeScriptForScriptRunner): * dom/ScriptElement.h: (WebCore::ScriptElement::scriptType): * html/parser/CSSPreloadScanner.cpp: (WebCore::CSSPreloadScanner::emitRule): * html/parser/HTMLPreloadScanner.cpp: (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): According to the spec, the module tag ignores the "charset" attribute as the same to the worker's importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): * html/parser/HTMLResourcePreloader.cpp: (WebCore::PreloadRequest::resourceRequest): * html/parser/HTMLResourcePreloader.h: (WebCore::PreloadRequest::PreloadRequest): * html/parser/HTMLScriptRunner.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): * xml/parser/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::notifyFinished): LayoutTests: * TestExpectations: * http/tests/misc/module-absolute-url-expected.txt: Added. * http/tests/misc/module-absolute-url.html: Added. * http/tests/misc/module-script-async-expected.txt: Added. * http/tests/misc/module-script-async.html: Added. * http/tests/misc/resources/module-absolute-url.js: Added. * http/tests/misc/resources/module-absolute-url2.js: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. (testPreescapedPolicy): (testExperimentalPolicy): (test): (iframe.onload): (testImpl): (finishTesting): * http/tests/security/module-correct-mime-types-expected.txt: Added. * http/tests/security/module-correct-mime-types.html: Added. * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. * http/tests/security/module-crossorigin-error-event-information.html: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. * http/tests/security/module-crossorigin-loads-omit.html: Added. * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. * http/tests/security/module-crossorigin-loads-same-origin.html: Added. * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. * http/tests/security/module-crossorigin-onerror-information.html: Added. * http/tests/security/module-incorrect-mime-types-expected.txt: Added. * http/tests/security/module-incorrect-mime-types.html: Added. * http/tests/security/module-no-mime-type-expected.txt: Added. * http/tests/security/module-no-mime-type.html: Added. * http/tests/security/resources/cors-script.php: * http/tests/security/resources/module-local-script.js: Added. * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. * js/dom/modules/module-and-dom-content-loaded.html: Added. * js/dom/modules/module-and-window-load-expected.txt: Added. * js/dom/modules/module-and-window-load.html: Added. * js/dom/modules/module-async-and-window-load-expected.txt: Added. * js/dom/modules/module-async-and-window-load.html: Added. * js/dom/modules/module-document-write-expected.txt: Added. * js/dom/modules/module-document-write-src-expected.txt: Added. * js/dom/modules/module-document-write-src.html: Added. * js/dom/modules/module-document-write.html: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. * js/dom/modules/module-execution-order-inline-expected.txt: Added. * js/dom/modules/module-execution-order-inline.html: Added. * js/dom/modules/module-execution-order-mixed-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. * js/dom/modules/module-execution-order-mixed.html: Added. * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. * js/dom/modules/module-incorrect-relative-specifier.html: Added. * js/dom/modules/module-incorrect-tag-expected.txt: Added. * js/dom/modules/module-incorrect-tag.html: Added. * js/dom/modules/module-inline-current-script-expected.txt: Added. * js/dom/modules/module-inline-current-script.html: Added. * js/dom/modules/module-inline-dynamic-expected.txt: Added. * js/dom/modules/module-inline-dynamic.html: Added. * js/dom/modules/module-inline-simple-expected.txt: Added. * js/dom/modules/module-inline-simple.html: Added. * js/dom/modules/module-load-event-expected.txt: Added. * js/dom/modules/module-load-event-with-src-expected.txt: Added. * js/dom/modules/module-load-event-with-src.html: Added. * js/dom/modules/module-load-event.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. * js/dom/modules/module-not-found-error-event-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. * js/dom/modules/module-not-found-error-event-with-src.html: Added. * js/dom/modules/module-not-found-error-event.html: Added. * js/dom/modules/module-src-current-script-expected.txt: Added. * js/dom/modules/module-src-current-script.html: Added. * js/dom/modules/module-src-dynamic-expected.txt: Added. * js/dom/modules/module-src-dynamic.html: Added. * js/dom/modules/module-src-simple-expected.txt: Added. * js/dom/modules/module-src-simple.html: Added. * js/dom/modules/module-type-case-insensitive-expected.txt: Added. * js/dom/modules/module-type-case-insensitive.html: Added. * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. * js/dom/modules/module-will-fire-beforeload.html: Added. * js/dom/modules/script-tests/module-document-write-src.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. * js/dom/modules/script-tests/module-inline-dynamic.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-inline-simple.js: Added. (export.default.Cocoa.prototype.taste): (export.default.Cocoa): * js/dom/modules/script-tests/module-load-event-with-src.js: Added. * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. * js/dom/modules/script-tests/module-src-current-script.js: Added. * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-dynamic.js: Added. * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. (Cocoa.prototype.taste): (Cocoa): * js/dom/modules/script-tests/module-src-simple.js: Added. * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. Canonical link: https://commits.webkit.org/182502@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208788 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-16 11:39:43 +00:00
};
}
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LoadableModuleScript)
static bool isType(const WebCore::LoadableScript& script) { return script.isModuleScript(); }
SPECIALIZE_TYPE_TRAITS_END()