Changeset 208788 in webkit
- Timestamp:
- Nov 16, 2016 3:39:43 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 136 added
- 31 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r208779 r208788 1 2016-11-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Integrate ES6 Modules into WebCore 4 https://bugs.webkit.org/show_bug.cgi?id=148897 5 6 Reviewed by Ryosuke Niwa. 7 8 * TestExpectations: 9 * http/tests/misc/module-absolute-url-expected.txt: Added. 10 * http/tests/misc/module-absolute-url.html: Added. 11 * http/tests/misc/module-script-async-expected.txt: Added. 12 * http/tests/misc/module-script-async.html: Added. 13 * http/tests/misc/resources/module-absolute-url.js: Added. 14 * http/tests/misc/resources/module-absolute-url2.js: Added. 15 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed-expected.txt: Added. 16 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html: Added. 17 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash-expected.txt: Added. 18 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html: Added. 19 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked-expected.txt: Added. 20 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html: Added. 21 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked-expected.txt: Added. 22 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html: Added. 23 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline-expected.txt: Added. 24 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html: Added. 25 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only-expected.txt: Added. 26 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html: Added. 27 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy-expected.txt: Added. 28 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html: Added. 29 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce-expected.txt: Added. 30 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html: Added. 31 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies-expected.txt: Added. 32 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html: Added. 33 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-expected.txt: Added. 34 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin-expected.txt: Added. 35 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html: Added. 36 * http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html: Added. 37 * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-enforced-policy-and-not-in-report-only.php: Added. 38 * http/tests/security/contentSecurityPolicy/1.1/resources/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.php: Added. 39 * http/tests/security/contentSecurityPolicy/module-eval-blocked-expected.txt: Added. 40 * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script-expected.txt: Added. 41 * http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html: Added. 42 * http/tests/security/contentSecurityPolicy/module-eval-blocked.html: Added. 43 * http/tests/security/contentSecurityPolicy/resources/echo-module-script-src.pl: Added. 44 * http/tests/security/contentSecurityPolicy/resources/multiple-iframe-module-test.js: Added. 45 (testPreescapedPolicy): 46 (testExperimentalPolicy): 47 (test): 48 (iframe.onload): 49 (testImpl): 50 (finishTesting): 51 * http/tests/security/module-correct-mime-types-expected.txt: Added. 52 * http/tests/security/module-correct-mime-types.html: Added. 53 * http/tests/security/module-crossorigin-error-event-information-expected.txt: Added. 54 * http/tests/security/module-crossorigin-error-event-information.html: Added. 55 * http/tests/security/module-crossorigin-loads-correctly-credentials-expected.txt: Added. 56 * http/tests/security/module-crossorigin-loads-correctly-credentials.html: Added. 57 * http/tests/security/module-crossorigin-loads-omit-expected.txt: Added. 58 * http/tests/security/module-crossorigin-loads-omit.html: Added. 59 * http/tests/security/module-crossorigin-loads-same-origin-expected.txt: Added. 60 * http/tests/security/module-crossorigin-loads-same-origin.html: Added. 61 * http/tests/security/module-crossorigin-onerror-information-expected.txt: Added. 62 * http/tests/security/module-crossorigin-onerror-information.html: Added. 63 * http/tests/security/module-incorrect-mime-types-expected.txt: Added. 64 * http/tests/security/module-incorrect-mime-types.html: Added. 65 * http/tests/security/module-no-mime-type-expected.txt: Added. 66 * http/tests/security/module-no-mime-type.html: Added. 67 * http/tests/security/resources/cors-script.php: 68 * http/tests/security/resources/module-local-script.js: Added. 69 * js/dom/modules/module-and-dom-content-loaded-expected.txt: Added. 70 * js/dom/modules/module-and-dom-content-loaded.html: Added. 71 * js/dom/modules/module-and-window-load-expected.txt: Added. 72 * js/dom/modules/module-and-window-load.html: Added. 73 * js/dom/modules/module-async-and-window-load-expected.txt: Added. 74 * js/dom/modules/module-async-and-window-load.html: Added. 75 * js/dom/modules/module-document-write-expected.txt: Added. 76 * js/dom/modules/module-document-write-src-expected.txt: Added. 77 * js/dom/modules/module-document-write-src.html: Added. 78 * js/dom/modules/module-document-write.html: Added. 79 * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-expected.txt: Added. 80 * js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html: Added. 81 * js/dom/modules/module-execution-error-should-be-propagated-to-onerror-expected.txt: Added. 82 * js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html: Added. 83 * js/dom/modules/module-execution-order-inline-expected.txt: Added. 84 * js/dom/modules/module-execution-order-inline.html: Added. 85 * js/dom/modules/module-execution-order-mixed-expected.txt: Added. 86 * js/dom/modules/module-execution-order-mixed-with-classic-scripts-expected.txt: Added. 87 * js/dom/modules/module-execution-order-mixed-with-classic-scripts.html: Added. 88 * js/dom/modules/module-execution-order-mixed.html: Added. 89 * js/dom/modules/module-incorrect-relative-specifier-expected.txt: Added. 90 * js/dom/modules/module-incorrect-relative-specifier.html: Added. 91 * js/dom/modules/module-incorrect-tag-expected.txt: Added. 92 * js/dom/modules/module-incorrect-tag.html: Added. 93 * js/dom/modules/module-inline-current-script-expected.txt: Added. 94 * js/dom/modules/module-inline-current-script.html: Added. 95 * js/dom/modules/module-inline-dynamic-expected.txt: Added. 96 * js/dom/modules/module-inline-dynamic.html: Added. 97 * js/dom/modules/module-inline-simple-expected.txt: Added. 98 * js/dom/modules/module-inline-simple.html: Added. 99 * js/dom/modules/module-load-event-expected.txt: Added. 100 * js/dom/modules/module-load-event-with-src-expected.txt: Added. 101 * js/dom/modules/module-load-event-with-src.html: Added. 102 * js/dom/modules/module-load-event.html: Added. 103 * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic-expected.txt: Added. 104 * js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html: Added. 105 * js/dom/modules/module-load-same-module-from-different-entry-point-expected.txt: Added. 106 * js/dom/modules/module-load-same-module-from-different-entry-point.html: Added. 107 * js/dom/modules/module-not-found-error-event-expected.txt: Added. 108 * js/dom/modules/module-not-found-error-event-with-src-and-import-expected.txt: Added. 109 * js/dom/modules/module-not-found-error-event-with-src-and-import.html: Added. 110 * js/dom/modules/module-not-found-error-event-with-src-expected.txt: Added. 111 * js/dom/modules/module-not-found-error-event-with-src.html: Added. 112 * js/dom/modules/module-not-found-error-event.html: Added. 113 * js/dom/modules/module-src-current-script-expected.txt: Added. 114 * js/dom/modules/module-src-current-script.html: Added. 115 * js/dom/modules/module-src-dynamic-expected.txt: Added. 116 * js/dom/modules/module-src-dynamic.html: Added. 117 * js/dom/modules/module-src-simple-expected.txt: Added. 118 * js/dom/modules/module-src-simple.html: Added. 119 * js/dom/modules/module-type-case-insensitive-expected.txt: Added. 120 * js/dom/modules/module-type-case-insensitive.html: Added. 121 * js/dom/modules/module-will-fire-beforeload-expected.txt: Added. 122 * js/dom/modules/module-will-fire-beforeload.html: Added. 123 * js/dom/modules/script-tests/module-document-write-src.js: Added. 124 * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror-throw.js: Added. 125 * js/dom/modules/script-tests/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.js: Added. 126 * js/dom/modules/script-tests/module-execution-order-mixed-2.js: Added. 127 * js/dom/modules/script-tests/module-execution-order-mixed-cappuccino.js: Added. 128 * js/dom/modules/script-tests/module-execution-order-mixed-cocoa.js: Added. 129 * js/dom/modules/script-tests/module-execution-order-mixed-matcha.js: Added. 130 * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-2.js: Added. 131 * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cappuccino.js: Added. 132 * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-cocoa.js: Added. 133 * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts-matcha.js: Added. 134 * js/dom/modules/script-tests/module-execution-order-mixed-with-classic-scripts.js: Added. 135 * js/dom/modules/script-tests/module-execution-order-mixed.js: Added. 136 * js/dom/modules/script-tests/module-inline-dynamic.js: Added. 137 (export.default.Cocoa.prototype.taste): 138 (export.default.Cocoa): 139 * js/dom/modules/script-tests/module-inline-simple.js: Added. 140 (export.default.Cocoa.prototype.taste): 141 (export.default.Cocoa): 142 * js/dom/modules/script-tests/module-load-event-with-src.js: Added. 143 * js/dom/modules/script-tests/module-load-same-module-from-different-entry-point.js: Added. 144 * js/dom/modules/script-tests/module-not-found-error-event-with-src-and-import.js: Added. 145 * js/dom/modules/script-tests/module-src-current-script.js: Added. 146 * js/dom/modules/script-tests/module-src-dynamic-cocoa.js: Added. 147 (Cocoa.prototype.taste): 148 (Cocoa): 149 * js/dom/modules/script-tests/module-src-dynamic.js: Added. 150 * js/dom/modules/script-tests/module-src-simple-cocoa.js: Added. 151 (Cocoa.prototype.taste): 152 (Cocoa): 153 * js/dom/modules/script-tests/module-src-simple.js: Added. 154 * js/dom/modules/script-tests/module-will-fire-beforeload.js: Added. 155 1 156 2016-11-15 Joseph Pecoraro <pecoraro@apple.com> 2 157 -
trunk/LayoutTests/TestExpectations
r208771 r208788 985 985 webkit.org/b/164080 http/tests/websocket/tests/hybi/closed-when-entering-page-cache.html [ Pass Failure ] 986 986 webkit.org/b/164080 http/tests/websocket/tests/hybi/stop-on-resume-in-error-handler.html [ Pass Failure ] 987 988 # ES6 Modules are not yet enabled by default: ENABLE(ES6_MODULES) 989 http/tests/misc/module-absolute-url.html [ Skip ] 990 http/tests/misc/module-script-async.html [ Skip ] 991 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-allowed.html [ Skip ] 992 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-and-scripthash.html [ Skip ] 993 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-basic-blocked.html [ Skip ] 994 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-blocked.html [ Skip ] 995 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-ignore-unsafeinline.html [ Skip ] 996 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-enforced-policy-and-not-in-report-only.html [ Skip ] 997 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-in-one-enforced-policy-neither-in-another-enforced-policy-nor-report-policy.html [ Skip ] 998 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-invalidnonce.html [ Skip ] 999 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-multiple-policies.html [ Skip ] 1000 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect-same-origin.html [ Skip ] 1001 http/tests/security/contentSecurityPolicy/1.1/module-scriptnonce-redirect.html [ Skip ] 1002 http/tests/security/contentSecurityPolicy/module-eval-blocked-in-external-script.html [ Skip ] 1003 http/tests/security/contentSecurityPolicy/module-eval-blocked.html [ Skip ] 1004 http/tests/security/module-correct-mime-types.html [ Skip ] 1005 http/tests/security/module-crossorigin-loads-correctly-credentials.html [ Skip ] 1006 http/tests/security/module-crossorigin-loads-omit.html [ Skip ] 1007 http/tests/security/module-crossorigin-loads-same-origin.html [ Skip ] 1008 http/tests/security/module-incorrect-mime-types.html [ Skip ] 1009 http/tests/security/module-no-mime-type.html [ Skip ] 1010 js/dom/modules/module-and-dom-content-loaded.html [ Skip ] 1011 js/dom/modules/module-and-window-load.html [ Skip ] 1012 js/dom/modules/module-async-and-window-load.html [ Skip ] 1013 js/dom/modules/module-document-write-src.html [ Skip ] 1014 js/dom/modules/module-document-write.html [ Skip ] 1015 js/dom/modules/module-execution-error-inside-dependent-module-should-be-propagated-to-onerror.html [ Skip ] 1016 js/dom/modules/module-execution-error-should-be-propagated-to-onerror.html [ Skip ] 1017 js/dom/modules/module-execution-order-inline.html [ Skip ] 1018 js/dom/modules/module-execution-order-mixed-with-classic-scripts.html [ Skip ] 1019 js/dom/modules/module-execution-order-mixed.html [ Skip ] 1020 js/dom/modules/module-incorrect-relative-specifier.html [ Skip ] 1021 js/dom/modules/module-incorrect-tag.html [ Skip ] 1022 js/dom/modules/module-inline-current-script.html [ Skip ] 1023 js/dom/modules/module-inline-dynamic.html [ Skip ] 1024 js/dom/modules/module-inline-simple.html [ Skip ] 1025 js/dom/modules/module-load-event-with-src.html [ Skip ] 1026 js/dom/modules/module-load-event.html [ Skip ] 1027 js/dom/modules/module-load-same-module-from-different-entry-point-dynamic.html [ Skip ] 1028 js/dom/modules/module-load-same-module-from-different-entry-point.html [ Skip ] 1029 js/dom/modules/module-not-found-error-event-with-src-and-import.html [ Skip ] 1030 js/dom/modules/module-not-found-error-event-with-src.html [ Skip ] 1031 js/dom/modules/module-not-found-error-event.html [ Skip ] 1032 js/dom/modules/module-src-current-script.html [ Skip ] 1033 js/dom/modules/module-src-dynamic.html [ Skip ] 1034 js/dom/modules/module-src-simple.html [ Skip ] 1035 js/dom/modules/module-type-case-insensitive.html [ Skip ] 1036 js/dom/modules/module-will-fire-beforeload.html [ Skip ] 1037 webkit.org/b/164539 http/tests/security/module-crossorigin-error-event-information.html [ Failure ] 1038 webkit.org/b/164539 http/tests/security/module-crossorigin-onerror-information.html [ Failure ] -
trunk/LayoutTests/http/tests/security/resources/cors-script.php
-
Property
svn:executable
set to
*
r205854 r208788 3 3 header("Content-Type: application/javascript"); 4 4 5 if (strtolower($_GET["credentials"]) == "true") { 6 header("Access-Control-Allow-Credentials: true"); 5 if (isset($_GET["credentials"])) { 6 if (strtolower($_GET["credentials"]) == "true") { 7 header("Access-Control-Allow-Credentials: true"); 8 } else { 9 header("Access-Control-Allow-Credentials: false"); 10 } 7 11 } 8 12 -
Property
svn:executable
set to
-
trunk/Source/WebCore/CMakeLists.txt
r208705 r208788 1069 1069 1070 1070 bindings/js/ArrayValue.cpp 1071 bindings/js/CachedModuleScript.cpp 1072 bindings/js/CachedModuleScriptLoader.cpp 1071 1073 bindings/js/CallbackFunction.cpp 1072 1074 bindings/js/DOMWrapperWorld.cpp … … 1466 1468 dom/LiveNodeList.cpp 1467 1469 dom/LoadableClassicScript.cpp 1470 dom/LoadableModuleScript.cpp 1468 1471 dom/LoadableScript.cpp 1469 1472 dom/MessageChannel.cpp -
trunk/Source/WebCore/ChangeLog
r208786 r208788 1 2016-11-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Integrate ES6 Modules into WebCore 4 https://bugs.webkit.org/show_bug.cgi?id=148897 5 6 Reviewed by Ryosuke Niwa. 7 8 This patch introduces ES6 Modules into WebCore. We integrate JSC's JSModuleLoader into WebCore. 9 JSC constructs the module loader pipeline by the chains of the promises. To handle this, 10 the following components are added. 11 12 1. CachedModuleScript 13 14 CachedModuleScript wraps the promise based JSModuleLoader pipeline and offers 15 similar APIs to CachedScript. ScriptElement and PendingScript interact with 16 CachedModuleScript when the script tag is the module tag instead of CachedScript. 17 ScriptElement and PendingScript will receive the notification from 18 CachedModuleScript by implementing CachedModuleScriptClient. 19 20 2. ScriptModuleLoader 21 22 This is the module loader instantiated per document. It manages fetching and 23 offers the callbacks for the JSC's JSModuleLoader implementation. ScriptModuleLoader 24 will fetch the resource by creating CachedModuleScriptLoader per resource. ScriptModuleLoader 25 will receive the notification by implementing CachedModuleScriptLoaderClient. When the 26 resource is fetched, the module loader will drive the promise resolve/reject chain. 27 28 3. CachedModuleScriptLoader 29 30 This fetches the resource by using CachedScript. Using CachedScript means that it 31 automatically reports the resource to the inspector. CachedModuleScriptLoader notify to 32 ScriptModuleLoader when the resource is fetched. 33 34 One tricky point is that the fetch requests issued from one module-graph should share the same 35 nonce, crossorigin attributes etc. 36 37 Here, we wrote the module graph like `A -> B (A depends on B)`. 38 39 <script tag> -> A -> B -> C -> D 40 41 When fetching A, B, C, and D modules, we need to set the same nonce, crossorigin etc. configuration 42 derived from the original script tag. So per module-graph information should be shared throughout 43 the module loader pipeline. To do so, JSC's module loader implementation can take the value called 44 `initiator`. Since the loader will propagate & share this `initiator` throughout the pipeline, 45 we can transfer and share some metadata. Currently, we pass the JSWrapper of the script tag as the 46 initiator. Each fetch request is created by using this initiator script element. 47 48 More integration into the inspector should be done in the subsequent patch. 49 50 * CMakeLists.txt: 51 * WebCore.xcodeproj/project.pbxproj: 52 * bindings/js/CachedModuleScript.cpp: Added. 53 CachedModuleScript offers similar interface to CachedScript to make ScriptElement things easier. It encapsulates the 54 detail of the JSC JSModuleLoader that this module loader is driven by the chain of the promises. CachedModuleScript's 55 callbacks are called from the promise's handlers configured in ScriptController::loadModuleScript. 56 (WebCore::CachedModuleScript::create): 57 (WebCore::CachedModuleScript::CachedModuleScript): 58 (WebCore::CachedModuleScript::load): 59 (WebCore::CachedModuleScript::notifyLoadCompleted): 60 (WebCore::CachedModuleScript::notifyLoadFailed): 61 (WebCore::CachedModuleScript::notifyLoadWasCanceled): 62 (WebCore::CachedModuleScript::notifyClientFinished): 63 (WebCore::CachedModuleScript::addClient): 64 (WebCore::CachedModuleScript::removeClient): 65 * bindings/js/CachedModuleScript.h: Added. 66 (WebCore::CachedModuleScript::moduleKey): 67 (WebCore::CachedModuleScript::error): 68 (WebCore::CachedModuleScript::wasCanceled): 69 (WebCore::CachedModuleScript::isLoaded): 70 (WebCore::CachedModuleScript::nonce): 71 (WebCore::CachedModuleScript::crossOriginMode): 72 Save nonce and crossorigin attributes when we start ScriptElement::prepareScript. 73 * bindings/js/CachedModuleScriptClient.h: Copied from Source/WebCore/dom/LoadableScript.h. 74 (WebCore::CachedModuleScriptClient::~CachedModuleScriptClient): 75 * bindings/js/CachedModuleScriptLoader.cpp: Added. 76 CachedModuleScriptLoader is responsible to fetching the resource for the module script. It uses propagated `initiator` 77 to create the request. This initiator is the JS wrapper of the script element issuing this fetching request. The name 78 `initiator` is derived from the request.setInitiator(). Once the resource is fetched, the fetcher will notify to the 79 client. Currently, ScriptModuleLoader implements this client interface. 80 (WebCore::CachedModuleScriptLoader::create): 81 (WebCore::CachedModuleScriptLoader::CachedModuleScriptLoader): 82 (WebCore::CachedModuleScriptLoader::~CachedModuleScriptLoader): 83 (WebCore::CachedModuleScriptLoader::load): 84 Create the request. We call ScriptElement::requestCachedScript to initiate a new fetching request. At that time, 85 nonce and crossorigin (and charset) attributes of this element are applied to the new request. 86 (WebCore::CachedModuleScriptLoader::notifyFinished): 87 * bindings/js/CachedModuleScriptLoader.h: Copied from Source/WebCore/bindings/js/ScriptModuleLoader.h. 88 * bindings/js/CachedModuleScriptLoaderClient.h: Copied from Source/WebCore/dom/LoadableScript.h. 89 (WebCore::CachedModuleScriptLoaderClient::~CachedModuleScriptLoaderClient): 90 * bindings/js/CachedScriptSourceProvider.h: 91 (WebCore::CachedScriptSourceProvider::create): 92 (WebCore::CachedScriptSourceProvider::CachedScriptSourceProvider): 93 (WebCore::makeSource): 94 * bindings/js/JSBindingsAllInOne.cpp: 95 * bindings/js/JSDOMBinding.cpp: 96 (WebCore::retrieveErrorMessage): 97 (WebCore::reportException): 98 * bindings/js/JSDOMBinding.h: 99 * bindings/js/JSMainThreadExecState.h: 100 (WebCore::JSMainThreadExecState::loadModule): 101 (WebCore::JSMainThreadExecState::linkAndEvaluateModule): 102 * bindings/js/ScriptController.cpp: 103 (WebCore::ScriptController::evaluateInWorld): 104 (WebCore::ScriptController::loadModuleScriptInWorld): 105 (WebCore::ScriptController::loadModuleScript): 106 This just performs loading and not executing the module graph. Once the module graph is loaded, it is notified to 107 the given CachedModuleScript. 108 (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): 109 (WebCore::ScriptController::linkAndEvaluateModuleScript): 110 This executes the linking and evaluation of the already instantiated module graph. After loading the module graph, 111 we call this function for the module to evaluate it. This is called from ScriptElement::executeModuleScript. 112 (WebCore::ScriptController::evaluateModule): 113 Every time we evaluate the module, the ScriptModuleLoader::evaluate hook is called. So the loader calls this function 114 to actually evaluate the module. 115 (WebCore::jsValueToModuleKey): 116 (WebCore::ScriptController::setupModuleScriptHandlers): 117 The JSC's module loader is driven by the chain of the promise. So here, we convert this to CachedModuleScript / 118 CachedModuleScriptClient style and encapsulate the details. This encapsulation makes CachedModuleScript similar 119 to CachedScript and it makes things simple in the rest of WebCore. If the propagated error is already reported 120 to the inspector, we receive moduleLoaderAlreadyReportedErrorSymbol as the error value. So at that case, we 121 don't report it twice. If the rejection is caused due to the canceled fetching, moduleLoaderFetchingIsCanceledSymbol 122 appears as the error value. In that case, we will call CachedModuleScript::notifyLoadWasCanceled. 123 (WebCore::ScriptController::executeScript): 124 * bindings/js/ScriptController.h: 125 (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): 126 (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): 127 * bindings/js/ScriptModuleLoader.cpp: 128 We use DeferredWrapper to resolve promises used for the module pipeline. Thus, once the active DOM objects are 129 suspended, the module loader propagation stops. 130 (WebCore::ScriptModuleLoader::~ScriptModuleLoader): 131 Clear the clients of the fetchers issued from this loader. 132 (WebCore::isRootModule): 133 (WebCore::ScriptModuleLoader::resolve): 134 Resolve the module specifier (that is written in `import from "XXX"`) to the unique module key. We use URL 135 string as module key. The edge case is that the module is inlined one. In that case, we don't have any URL 136 for that. Instead of URL, we use symbol at that time. 137 (WebCore::ScriptModuleLoader::fetch): 138 Start fetching for the requested module. It returns the promise that is resolved when the fetching is done. 139 The loader creates the fetcher, and the fetcher start loading the resource. Once the fetcher loads the resource, 140 it notify to the loader through CachedModuleScriptLoaderClient interface. Since we pass the original script 141 element as the `initiator` here, the fetcher can use this initiator to create the request. While the result of 142 CachedResource has 3 variations (loaded, canceled, error occurred), Promise only tells us whether it is resolved 143 or rejected. When CachedModuleScript gets the result from the promise chain, it needs to know which the result is. 144 To transfer the canceled information, we reject the promise with the special symbol `moduleLoaderAlreadyReportedErrorSymbol`. 145 This offers the way to distinguish the canceled error from the other errors. 146 (WebCore::ScriptModuleLoader::evaluate): 147 This is the hook function that is called when JSC's JSModuleLoader attempts to execute each module. 148 (WebCore::ScriptModuleLoader::notifyFinished): 149 This function is called when the fetcher completes. We will resolve the promise with the result of the fetching. 150 The module loader pipeline is constructed as a chain of promises. 151 Rejecting a promise when some error occurs is important because the execution flow of 152 the promise chain is driven by "rejected" or "fulfilled" events. 153 If the promise is not rejected while error occurs, reject handler won't be executed 154 and all the subsequent promise chain will wait the result forever. 155 As a result, even if the error is already reported to the inspector elsewhere, 156 it should be propagated in the pipeline. For example, the error of loading 157 CachedResource is already reported to the inspector by the loader. But we still need 158 to reject the promise to propagate this error to the script element. 159 At that time, we don't want to report the same error twice. When we propagate the error 160 that is already reported to the inspector, we throw moduleLoaderAlreadyReportedErrorSymbol 161 symbol instead. By comparing the thrown error with this symbol, we can distinguish errors raised 162 when checking syntax of a module script from errors reported already. 163 In the reject handler of the promise, we only report a error that is not this symbol. 164 And mime type checking is done here since the module script always require this check. 165 * bindings/js/ScriptModuleLoader.h: 166 (WebCore::ScriptModuleLoader::document): Deleted. 167 * bindings/js/ScriptSourceCode.h: 168 (WebCore::ScriptSourceCode::ScriptSourceCode): 169 * dom/CurrentScriptIncrementer.h: 170 (WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer): 171 * dom/LoadableClassicScript.cpp: 172 (WebCore::LoadableClassicScript::error): 173 (WebCore::LoadableClassicScript::execute): 174 (WebCore::LoadableClassicScript::wasErrored): Deleted. 175 * dom/LoadableClassicScript.h: 176 * dom/LoadableModuleScript.cpp: Copied from Source/WebCore/dom/LoadableScript.h. 177 This is the derived class from LoadableScript. It is used for the script module graphs. 178 (WebCore::LoadableModuleScript::create): 179 (WebCore::LoadableModuleScript::LoadableModuleScript): 180 (WebCore::LoadableModuleScript::~LoadableModuleScript): 181 (WebCore::LoadableModuleScript::isLoaded): 182 (WebCore::LoadableModuleScript::error): 183 (WebCore::LoadableModuleScript::wasCanceled): 184 (WebCore::LoadableModuleScript::notifyFinished): 185 (WebCore::LoadableModuleScript::execute): 186 * dom/LoadableModuleScript.h: Copied from Source/WebCore/dom/LoadableScript.h. 187 (isType): 188 * dom/LoadableScript.h: 189 (WebCore::LoadableScript::isModuleScript): 190 (WebCore::LoadableScript::isModuleGraph): Deleted. 191 * dom/PendingScript.cpp: 192 (WebCore::PendingScript::error): 193 (WebCore::PendingScript::wasErrored): Deleted. 194 * dom/PendingScript.h: 195 * dom/ScriptElement.cpp: 196 (WebCore::ScriptElement::ScriptElement): 197 (WebCore::ScriptElement::determineScriptType): 198 (WebCore::ScriptElement::prepareScript): 199 prepareScript is aligned to whatwg spec: the last sequence to setup flags has one-on-one correspondence to 200 the spec now. And prepareScript recognizes the type="module" case and call the requestModuleScript to setup 201 the CachedModuleScript. 202 (WebCore::ScriptElement::requestClassicScript): 203 (WebCore::ScriptElement::requestModuleScript): 204 We use the nonce and crossorigin attributes at the time of preparing the script tag. To do so, we store the 205 above values in CachedModuleScript. 206 Since inlined module scripts does not have "src" attribute, it is also affected by Content Security Policy's 207 inline script rules. 208 (WebCore::ScriptElement::requestScriptWithCacheForModuleScript): 209 The module loader will construct the fetching request by calling this function. This should be here since we 210 would like to set this Element to the initiator of the request. And nonce and crossorigin attributes of this 211 script tag will be used. 212 (WebCore::ScriptElement::requestScriptWithCache): 213 (WebCore::ScriptElement::executeScript): 214 (WebCore::ScriptElement::executeModuleScript): 215 The entry point to execute the module graph. Since the module graph is beyond the multiple CachedScript code, 216 we have the different entry point from ScriptElement::executeScript. 217 (WebCore::ScriptElement::executeScriptAndDispatchEvent): 218 (WebCore::ScriptElement::executeScriptForScriptRunner): 219 * dom/ScriptElement.h: 220 (WebCore::ScriptElement::scriptType): 221 * html/parser/CSSPreloadScanner.cpp: 222 (WebCore::CSSPreloadScanner::emitRule): 223 * html/parser/HTMLPreloadScanner.cpp: 224 (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): 225 According to the spec, the module tag ignores the "charset" attribute as the same to the worker's 226 importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, 227 even for the module tags, we handle the "charset" attribute. We explicitly note about it in the preloader. 228 (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): 229 * html/parser/HTMLResourcePreloader.cpp: 230 (WebCore::PreloadRequest::resourceRequest): 231 * html/parser/HTMLResourcePreloader.h: 232 (WebCore::PreloadRequest::PreloadRequest): 233 * html/parser/HTMLScriptRunner.h: 234 * loader/cache/CachedResourceRequest.cpp: 235 (WebCore::CachedResourceRequest::setAsPotentiallyCrossOrigin): 236 * xml/parser/XMLDocumentParser.cpp: 237 (WebCore::XMLDocumentParser::notifyFinished): 238 1 239 2016-11-15 Alejandro G. Castro <alex@igalia.com> 2 240 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r208705 r208788 6259 6259 E1FF8F6C180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F6A180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp */; }; 6260 6260 E1FF8F6D180DB5BE00132674 /* CryptoAlgorithmRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */; }; 6261 E307DECC1D81E4B300141CAF /* CachedModuleScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E307DEC91D81E46E00141CAF /* CachedModuleScript.cpp */; }; 6262 E307DECD1D81E4B600141CAF /* CachedModuleScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E307DECA1D81E46E00141CAF /* CachedModuleScript.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6263 E307DECE1D81E4BA00141CAF /* CachedModuleScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E307DECB1D81E49500141CAF /* CachedModuleScriptClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6264 E307DECF1D81E4C300141CAF /* CachedModuleScriptLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E307DEC61D81E44800141CAF /* CachedModuleScriptLoader.cpp */; }; 6265 E307DED01D81E4C700141CAF /* CachedModuleScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E307DEC71D81E44800141CAF /* CachedModuleScriptLoader.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6266 E307DED11D81E4CB00141CAF /* CachedModuleScriptLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E307DEC81D81E44800141CAF /* CachedModuleScriptLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6267 E307DED41D81E4F000141CAF /* LoadableModuleScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E307DED21D81E4ED00141CAF /* LoadableModuleScript.cpp */; }; 6268 E307DED51D81E4F200141CAF /* LoadableModuleScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6261 6269 E3150EA61DA7219000194012 /* JSNodeDOMJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3AFA9641DA6E908002861BD /* JSNodeDOMJIT.cpp */; }; 6262 6270 E3150EA71DA7219300194012 /* DOMJITHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E3150EA51DA7218D00194012 /* DOMJITHelpers.h */; }; … … 14202 14210 E1FF8F6A180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRegistry.cpp; sourceTree = "<group>"; }; 14203 14211 E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRegistry.h; sourceTree = "<group>"; }; 14212 E307DEC61D81E44800141CAF /* CachedModuleScriptLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedModuleScriptLoader.cpp; sourceTree = "<group>"; }; 14213 E307DEC71D81E44800141CAF /* CachedModuleScriptLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedModuleScriptLoader.h; sourceTree = "<group>"; }; 14214 E307DEC81D81E44800141CAF /* CachedModuleScriptLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedModuleScriptLoaderClient.h; sourceTree = "<group>"; }; 14215 E307DEC91D81E46E00141CAF /* CachedModuleScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedModuleScript.cpp; sourceTree = "<group>"; }; 14216 E307DECA1D81E46E00141CAF /* CachedModuleScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedModuleScript.h; sourceTree = "<group>"; }; 14217 E307DECB1D81E49500141CAF /* CachedModuleScriptClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedModuleScriptClient.h; sourceTree = "<group>"; }; 14218 E307DED21D81E4ED00141CAF /* LoadableModuleScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableModuleScript.cpp; sourceTree = "<group>"; }; 14219 E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableModuleScript.h; sourceTree = "<group>"; }; 14204 14220 E3150EA51DA7218D00194012 /* DOMJITHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITHelpers.h; sourceTree = "<group>"; }; 14205 14221 E334825E1DC93AA0009C9544 /* DOMJITAbstractHeapRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeapRepository.h; sourceTree = "<group>"; }; … … 21782 21798 49B3760B15C6C6840059131D /* ArrayValue.h */, 21783 21799 2DFA488E1DB541C200362B99 /* BufferSource.h */, 21800 E307DEC61D81E44800141CAF /* CachedModuleScriptLoader.cpp */, 21801 E307DEC71D81E44800141CAF /* CachedModuleScriptLoader.h */, 21802 E307DEC81D81E44800141CAF /* CachedModuleScriptLoaderClient.h */, 21784 21803 BCD533630ED6848900887468 /* CachedScriptSourceProvider.h */, 21785 21804 93F8B3060A300FEA00F61AB8 /* CodeGeneratorJS.pm */, … … 21862 21881 E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */, 21863 21882 E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */, 21883 E307DEC91D81E46E00141CAF /* CachedModuleScript.cpp */, 21884 E307DECA1D81E46E00141CAF /* CachedModuleScript.h */, 21885 E307DECB1D81E49500141CAF /* CachedModuleScriptClient.h */, 21864 21886 934CC1090EDB223900A658F2 /* ScriptSourceCode.h */, 21865 21887 4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */, … … 24004 24026 E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */, 24005 24027 E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */, 24028 E307DED21D81E4ED00141CAF /* LoadableModuleScript.cpp */, 24029 E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */, 24006 24030 E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */, 24007 24031 BC9A6144146859D9006057FD /* make_dom_exceptions.pl */, … … 24911 24935 7C3A91E61C963B8800D1A7E3 /* ClipboardAccessPolicy.h in Headers */, 24912 24936 85031B400A44EFC700F992E0 /* ClipboardEvent.h in Headers */, 24937 E307DED01D81E4C700141CAF /* CachedModuleScriptLoader.h in Headers */, 24913 24938 FB92DF4B15FED08700994433 /* ClipPathOperation.h in Headers */, 24914 24939 580371621A66F00A00BAF519 /* ClipRect.h in Headers */, … … 25725 25750 510A58FA1BACC7F200C19282 /* IDBRequestData.h in Headers */, 25726 25751 5145B10A1BC48E2E00E86219 /* IDBResourceIdentifier.h in Headers */, 25752 E307DED11D81E4CB00141CAF /* CachedModuleScriptLoaderClient.h in Headers */, 25727 25753 51D7236D1BB6174900478CA3 /* IDBResultData.h in Headers */, 25728 25754 511EC1281C50AACA0032F983 /* IDBSerialization.h in Headers */, … … 25974 26000 2E37E00612DBC5A400A6B233 /* JSDOMURL.h in Headers */, 25975 26001 BC6932740D7E293900AE44D1 /* JSDOMWindowBase.h in Headers */, 26002 E307DECE1D81E4BA00141CAF /* CachedModuleScriptClient.h in Headers */, 25976 26003 652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */, 25977 26004 460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */, … … 26854 26881 2D5C9D0019C7B52E00B3C5C1 /* PageOverlay.h in Headers */, 26855 26882 2D5C9D0219C7B52E00B3C5C1 /* PageOverlayController.h in Headers */, 26883 E307DED51D81E4F200141CAF /* LoadableModuleScript.h in Headers */, 26856 26884 FBDB61A116D6037E00BB3394 /* PageRuleCollector.h in Headers */, 26857 26885 F3820895147D35F90010BC06 /* PageRuntimeAgent.h in Headers */, … … 27495 27523 E1B25107152A0BB00069B779 /* StylePropertyShorthand.h in Headers */, 27496 27524 83C05A5B1A686212007E5DEA /* StylePropertyShorthandFunctions.h in Headers */, 27525 E307DECD1D81E4B600141CAF /* CachedModuleScript.h in Headers */, 27497 27526 BC2272E40E82EE9B00E7F975 /* StyleRareInheritedData.h in Headers */, 27498 27527 BC2272BD0E82EAAE00E7F975 /* StyleRareNonInheritedData.h in Headers */, … … 28941 28970 9444CBD91D88483A0073A074 /* CSSVariableParser.cpp in Sources */, 28942 28971 9444CBE91D8861CA0073A074 /* CSSVariableReferenceValue.cpp in Sources */, 28972 E307DECF1D81E4C300141CAF /* CachedModuleScriptLoader.cpp in Sources */, 28943 28973 BC1790C01BBF2C430006D13E /* CSSVariableValue.cpp in Sources */, 28944 28974 E11AF15111B9A1A300805103 /* Cursor.cpp in Sources */, … … 29442 29472 5185FCA31BB4C4E80012898F /* IDBOpenDBRequest.cpp in Sources */, 29443 29473 5185FCA81BB4C4E80012898F /* IDBRequest.cpp in Sources */, 29474 E307DECC1D81E4B300141CAF /* CachedModuleScript.cpp in Sources */, 29444 29475 514129981C6976900059E714 /* IDBRequestCompletionEvent.cpp in Sources */, 29445 29476 510A58F91BACC7F200C19282 /* IDBRequestData.cpp in Sources */, … … 30085 30116 8542A79A0AE5C94400DF58DF /* JSSVGElementWrapperFactory.cpp in Sources */, 30086 30117 B2FA3D680AB75A6F000E5AC4 /* JSSVGEllipseElement.cpp in Sources */, 30118 E307DED41D81E4F000141CAF /* LoadableModuleScript.cpp in Sources */, 30087 30119 B266CD4D0C3AEC6500EB08D2 /* JSSVGException.cpp in Sources */, 30088 30120 B2FA3D6A0AB75A6F000E5AC4 /* JSSVGFEBlendElement.cpp in Sources */, -
trunk/Source/WebCore/bindings/js/CachedModuleScriptClient.h
r208787 r208788 26 26 #pragma once 27 27 28 #include <runtime/ConsoleTypes.h>29 #include <wtf/HashCountedSet.h>30 #include <wtf/RefCounted.h>31 #include <wtf/text/WTFString.h>32 33 28 namespace WebCore { 34 29 35 class LoadableScriptClient; 36 class ScriptElement; 30 class CachedModuleScript; 37 31 38 class LoadableScript : public RefCounted<LoadableScript>{32 class CachedModuleScriptClient { 39 33 public: 40 enum class ErrorType { 41 CachedScript, 42 CrossOriginLoad, 43 Nosniff, 44 }; 34 virtual ~CachedModuleScriptClient() { } 45 35 46 struct ConsoleMessage { 47 MessageSource source; 48 MessageLevel level; 49 String message; 50 }; 51 52 struct Error { 53 ErrorType type; 54 Optional<ConsoleMessage> consoleMessage; 55 }; 56 57 virtual ~LoadableScript() { } 58 59 virtual bool isLoaded() const = 0; 60 virtual Optional<Error> wasErrored() const = 0; 61 virtual bool wasCanceled() const = 0; 62 63 virtual void execute(ScriptElement&) = 0; 64 65 void addClient(LoadableScriptClient&); 66 void removeClient(LoadableScriptClient&); 67 68 virtual bool isClassicScript() const { return false; } 69 virtual bool isModuleGraph() const { return false; } 70 71 protected: 72 void notifyClientFinished(); 73 74 private: 75 HashCountedSet<LoadableScriptClient*> m_clients; 36 virtual void notifyFinished(CachedModuleScript&) = 0; 76 37 }; 77 38 -
trunk/Source/WebCore/bindings/js/CachedModuleScriptLoader.h
r208787 r208788 26 26 #pragma once 27 27 28 #include <runtime/JSCJSValue.h> 29 #include <wtf/Noncopyable.h> 30 31 namespace JSC { 32 33 class ExecState; 34 class JSGlobalObject; 35 class JSInternalPromise; 36 class JSModuleLoader; 37 38 } 28 #include "CachedResourceClient.h" 29 #include "CachedResourceHandle.h" 30 #include <wtf/Ref.h> 31 #include <wtf/RefCounted.h> 32 #include <wtf/RefPtr.h> 39 33 40 34 namespace WebCore { 41 35 42 class Document; 36 class CachedModuleScriptLoaderClient; 37 class CachedScript; 38 class DeferredPromise; 39 class JSDOMGlobalObject; 40 class ScriptElement; 41 class URL; 43 42 44 class ScriptModuleLoader { 45 WTF_MAKE_NONCOPYABLE(ScriptModuleLoader); WTF_MAKE_FAST_ALLOCATED; 43 class CachedModuleScriptLoader final : public RefCounted<CachedModuleScriptLoader>, private CachedResourceClient { 46 44 public: 47 explicit ScriptModuleLoader(Document&);45 static Ref<CachedModuleScriptLoader> create(CachedModuleScriptLoaderClient&, DeferredPromise&); 48 46 49 Document& document() { return m_document; }47 virtual ~CachedModuleScriptLoader(); 50 48 51 JSC::JSInternalPromise* resolve(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSModuleLoader*, JSC::JSValue moduleName, JSC::JSValue importerModuleKey, JSC::JSValue initiator); 52 JSC::JSInternalPromise* fetch(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSModuleLoader*, JSC::JSValue moduleKey, JSC::JSValue initiator); 53 JSC::JSValue evaluate(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSModuleLoader*, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue initiator); 49 bool load(ScriptElement&, const URL& sourceURL); 50 51 CachedScript* cachedScript() { return m_cachedScript.get(); } 52 53 void clearClient() 54 { 55 ASSERT(m_client); 56 m_client = nullptr; 57 } 54 58 55 59 private: 56 Document& m_document; 60 CachedModuleScriptLoader(CachedModuleScriptLoaderClient&, DeferredPromise&); 61 62 void notifyFinished(CachedResource&) final; 63 64 CachedModuleScriptLoaderClient* m_client { nullptr }; 65 RefPtr<DeferredPromise> m_promise; 66 CachedResourceHandle<CachedScript> m_cachedScript; 57 67 }; 58 68 -
trunk/Source/WebCore/bindings/js/CachedModuleScriptLoaderClient.h
r208787 r208788 26 26 #pragma once 27 27 28 #include <runtime/ConsoleTypes.h> 29 #include <wtf/HashCountedSet.h> 30 #include <wtf/RefCounted.h> 31 #include <wtf/text/WTFString.h> 28 #include "JSDOMPromise.h" 32 29 33 30 namespace WebCore { 34 31 35 class LoadableScriptClient; 36 class ScriptElement; 32 class CachedModuleScriptLoader; 37 33 38 class LoadableScript : public RefCounted<LoadableScript>{34 class CachedModuleScriptLoaderClient { 39 35 public: 40 enum class ErrorType { 41 CachedScript, 42 CrossOriginLoad, 43 Nosniff, 44 }; 36 virtual ~CachedModuleScriptLoaderClient() { } 45 37 46 struct ConsoleMessage { 47 MessageSource source; 48 MessageLevel level; 49 String message; 50 }; 51 52 struct Error { 53 ErrorType type; 54 Optional<ConsoleMessage> consoleMessage; 55 }; 56 57 virtual ~LoadableScript() { } 58 59 virtual bool isLoaded() const = 0; 60 virtual Optional<Error> wasErrored() const = 0; 61 virtual bool wasCanceled() const = 0; 62 63 virtual void execute(ScriptElement&) = 0; 64 65 void addClient(LoadableScriptClient&); 66 void removeClient(LoadableScriptClient&); 67 68 virtual bool isClassicScript() const { return false; } 69 virtual bool isModuleGraph() const { return false; } 70 71 protected: 72 void notifyClientFinished(); 73 74 private: 75 HashCountedSet<LoadableScriptClient*> m_clients; 38 virtual void notifyFinished(CachedModuleScriptLoader&, RefPtr<DeferredPromise>) = 0; 76 39 }; 77 40 -
trunk/Source/WebCore/bindings/js/CachedScriptSourceProvider.h
r208179 r208788 37 37 WTF_MAKE_FAST_ALLOCATED; 38 38 public: 39 static Ref<CachedScriptSourceProvider> create(CachedScript* cachedScript ) { return adoptRef(*new CachedScriptSourceProvider(cachedScript)); }39 static Ref<CachedScriptSourceProvider> create(CachedScript* cachedScript, JSC::SourceProviderSourceType sourceType) { return adoptRef(*new CachedScriptSourceProvider(cachedScript, sourceType)); } 40 40 41 41 virtual ~CachedScriptSourceProvider() … … 48 48 49 49 private: 50 CachedScriptSourceProvider(CachedScript* cachedScript )51 : SourceProvider(cachedScript->response().url(), TextPosition::minimumPosition(), JSC::SourceProviderSourceType::Program)50 CachedScriptSourceProvider(CachedScript* cachedScript, JSC::SourceProviderSourceType sourceType) 51 : SourceProvider(cachedScript->response().url(), TextPosition::minimumPosition(), sourceType) 52 52 , m_cachedScript(cachedScript) 53 53 { … … 60 60 inline JSC::SourceCode makeSource(CachedScript* cachedScript) 61 61 { 62 return JSC::SourceCode(CachedScriptSourceProvider::create(cachedScript ));62 return JSC::SourceCode(CachedScriptSourceProvider::create(cachedScript, JSC::SourceProviderSourceType::Program)); 63 63 } 64 64 -
trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
r208705 r208788 27 27 28 28 #include "ArrayValue.cpp" 29 #include "CachedModuleScript.cpp" 30 #include "CachedModuleScriptLoader.cpp" 29 31 #include "CallbackFunction.cpp" 30 32 #include "DOMWrapperWorld.cpp" -
trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp
r208124 r208788 157 157 } 158 158 159 String retrieveErrorMessage(ExecState& state, VM& vm, JSValue exception, CatchScope& catchScope) 160 { 161 if (auto* exceptionBase = toExceptionBase(exception)) 162 return exceptionBase->toString(); 163 164 // FIXME: <http://webkit.org/b/115087> Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions 165 // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception. 166 String errorMessage; 167 if (auto* error = jsDynamicDowncast<ErrorInstance*>(exception)) 168 errorMessage = error->sanitizedToString(&state); 169 else 170 errorMessage = exception.toWTFString(&state); 171 172 // We need to clear any new exception that may be thrown in the toString() call above. 173 // reportException() is not supposed to be making new exceptions. 174 catchScope.clearException(); 175 vm.clearLastException(); 176 return errorMessage; 177 } 178 159 179 void reportException(ExecState* exec, JSC::Exception* exception, CachedScript* cachedScript, ExceptionDetails* exceptionDetails) 160 180 { … … 187 207 } 188 208 189 String errorMessage; 190 JSValue exceptionValue = exception->value(); 191 if (ExceptionBase* exceptionBase = toExceptionBase(exceptionValue)) 192 errorMessage = exceptionBase->toString(); 193 else { 194 // FIXME: <http://webkit.org/b/115087> Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions 195 // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception. 196 if (ErrorInstance* error = jsDynamicDowncast<ErrorInstance*>(exceptionValue)) 197 errorMessage = error->sanitizedToString(exec); 198 else 199 errorMessage = exceptionValue.toString(exec)->value(exec); 200 201 // We need to clear any new exception that may be thrown in the toString() call above. 202 // reportException() is not supposed to be making new exceptions. 203 scope.clearException(); 204 vm.clearLastException(); 205 } 206 209 String errorMessage = retrieveErrorMessage(*exec, vm, exception->value(), scope); 207 210 ScriptExecutionContext* scriptExecutionContext = globalObject->scriptExecutionContext(); 208 211 scriptExecutionContext->reportException(errorMessage, lineNumber, columnNumber, exceptionSourceURL, exception, callStack->size() ? callStack : nullptr, cachedScript); -
trunk/Source/WebCore/bindings/js/JSDOMBinding.h
r208209 r208788 183 183 const JSC::HashTable& getHashTableForGlobalData(JSC::VM&, const JSC::HashTable& staticTable); 184 184 185 String retrieveErrorMessage(JSC::ExecState&, JSC::VM&, JSC::JSValue exception, JSC::CatchScope&); 185 186 WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::JSValue exception, CachedScript* = nullptr); 186 187 WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::Exception*, CachedScript* = nullptr, ExceptionDetails* = nullptr); -
trunk/Source/WebCore/bindings/js/JSMainThreadExecState.h
r208256 r208788 94 94 } 95 95 96 static JSC::JSInternalPromise * loadModule(JSC::ExecState* exec, const String& moduleName, JSC::JSValue initiator)96 static JSC::JSInternalPromise& loadModule(JSC::ExecState& state, const String& moduleName, JSC::JSValue initiator) 97 97 { 98 JSMainThreadExecState currentState( exec);99 return JSC::loadModule(exec, moduleName, initiator);98 JSMainThreadExecState currentState(&state); 99 return *JSC::loadModule(&state, moduleName, initiator); 100 100 } 101 101 102 static JSC::JSInternalPromise * loadModule(JSC::ExecState* exec, const JSC::SourceCode& sourceCode, JSC::JSValue initiator)102 static JSC::JSInternalPromise& loadModule(JSC::ExecState& state, const JSC::SourceCode& sourceCode, JSC::JSValue initiator) 103 103 { 104 JSMainThreadExecState currentState( exec);105 return JSC::loadModule(exec, sourceCode, initiator);104 JSMainThreadExecState currentState(&state); 105 return *JSC::loadModule(&state, sourceCode, initiator); 106 106 } 107 107 108 static JSC::JSValue linkAndEvaluateModule(JSC::ExecState * exec, const JSC::Identifier& moduleKey, JSC::JSValue initiator, NakedPtr<JSC::Exception>& returnedException)108 static JSC::JSValue linkAndEvaluateModule(JSC::ExecState& state, const JSC::Identifier& moduleKey, JSC::JSValue initiator, NakedPtr<JSC::Exception>& returnedException) 109 109 { 110 JSC::VM& vm = exec->vm();110 JSC::VM& vm = state.vm(); 111 111 auto scope = DECLARE_CATCH_SCOPE(vm); 112 112 113 JSMainThreadExecState currentState( exec);114 JSC::JSValue returnValue = JSC::linkAndEvaluateModule(exec, moduleKey, initiator);113 JSMainThreadExecState currentState(&state); 114 auto returnValue = JSC::linkAndEvaluateModule(&state, moduleKey, initiator); 115 115 if (UNLIKELY(scope.exception())) { 116 116 returnedException = scope.exception(); -
trunk/Source/WebCore/bindings/js/ScriptController.cpp
r208112 r208788 23 23 24 24 #include "BridgeJSC.h" 25 #include "CachedModuleScript.h" 25 26 #include "ContentSecurityPolicy.h" 26 27 #include "DocumentLoader.h" … … 42 43 #include "PageGroup.h" 43 44 #include "PluginViewBase.h" 45 #include "ScriptElement.h" 44 46 #include "ScriptSourceCode.h" 45 47 #include "ScriptableDocumentParser.h" … … 53 55 #include <inspector/ScriptCallStack.h> 54 56 #include <runtime/InitializeThreading.h> 57 #include <runtime/JSFunction.h> 58 #include <runtime/JSInternalPromise.h> 55 59 #include <runtime/JSLock.h> 60 #include <runtime/JSModuleRecord.h> 61 #include <runtime/JSNativeStdFunction.h> 62 #include <wtf/TemporaryChange.h> 56 63 #include <wtf/Threading.h> 57 64 #include <wtf/text/TextPosition.h> … … 155 162 m_sourceURL = &sourceURL; 156 163 157 Ref<Frame> protect (m_frame);164 Ref<Frame> protector(m_frame); 158 165 159 166 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL, sourceCode.startLine()); … … 177 184 { 178 185 return evaluateInWorld(sourceCode, mainThreadNormalWorld(), exceptionDetails); 186 } 187 188 void ScriptController::loadModuleScriptInWorld(CachedModuleScript& moduleScript, const String& moduleName, DOMWrapperWorld& world, Element& element) 189 { 190 JSLockHolder lock(world.vm()); 191 192 auto& shell = *windowShell(world); 193 auto& state = *shell.window()->globalExec(); 194 195 auto& promise = JSMainThreadExecState::loadModule(state, moduleName, toJS(&state, shell.window(), &element)); 196 setupModuleScriptHandlers(moduleScript, promise, world); 197 } 198 199 void ScriptController::loadModuleScript(CachedModuleScript& moduleScript, const String& moduleName, Element& element) 200 { 201 loadModuleScriptInWorld(moduleScript, moduleName, mainThreadNormalWorld(), element); 202 } 203 204 void ScriptController::loadModuleScriptInWorld(CachedModuleScript& moduleScript, const ScriptSourceCode& sourceCode, DOMWrapperWorld& world, Element& element) 205 { 206 JSLockHolder lock(world.vm()); 207 208 auto& shell = *windowShell(world); 209 auto& state = *shell.window()->globalExec(); 210 211 auto& promise = JSMainThreadExecState::loadModule(state, sourceCode.jsSourceCode(), toJS(&state, shell.window(), &element)); 212 setupModuleScriptHandlers(moduleScript, promise, world); 213 } 214 215 void ScriptController::loadModuleScript(CachedModuleScript& moduleScript, const ScriptSourceCode& sourceCode, Element& element) 216 { 217 loadModuleScriptInWorld(moduleScript, sourceCode, mainThreadNormalWorld(), element); 218 } 219 220 JSC::JSValue ScriptController::linkAndEvaluateModuleScriptInWorld(CachedModuleScript& moduleScript, DOMWrapperWorld& world, Element& element) 221 { 222 JSLockHolder lock(world.vm()); 223 224 auto& shell = *windowShell(world); 225 auto& state = *shell.window()->globalExec(); 226 227 // FIXME: Preventing Frame from being destroyed is essentially unnecessary. 228 // https://bugs.webkit.org/show_bug.cgi?id=164763 229 Ref<Frame> protector(m_frame); 230 231 NakedPtr<JSC::Exception> evaluationException; 232 auto returnValue = JSMainThreadExecState::linkAndEvaluateModule(state, Identifier::fromUid(&state.vm(), moduleScript.moduleKey()), toJS(&state, shell.window(), &element), evaluationException); 233 if (evaluationException) { 234 // FIXME: Give a chance to dump the stack trace if the "crossorigin" attribute allows. 235 // https://bugs.webkit.org/show_bug.cgi?id=164539 236 reportException(&state, evaluationException, nullptr); 237 return jsUndefined(); 238 } 239 return returnValue; 240 } 241 242 JSC::JSValue ScriptController::linkAndEvaluateModuleScript(CachedModuleScript& moduleScript, Element& element) 243 { 244 return linkAndEvaluateModuleScriptInWorld(moduleScript, mainThreadNormalWorld(), element); 245 } 246 247 JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord, DOMWrapperWorld& world) 248 { 249 JSLockHolder lock(world.vm()); 250 251 const auto& jsSourceCode = moduleRecord.sourceCode(); 252 253 auto& shell = *windowShell(world); 254 auto& state = *shell.window()->globalExec(); 255 TemporaryChange<const String*> sourceURLScope(m_sourceURL, &sourceURL.string()); 256 257 Ref<Frame> protector(m_frame); 258 259 auto cookie = InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL, jsSourceCode.firstLine()); 260 261 auto returnValue = moduleRecord.evaluate(&state); 262 InspectorInstrumentation::didEvaluateScript(cookie, m_frame); 263 264 return returnValue; 265 } 266 267 JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord) 268 { 269 return evaluateModule(sourceURL, moduleRecord, mainThreadNormalWorld()); 179 270 } 180 271 … … 257 348 258 349 return &windowShell; 350 } 351 352 static Identifier jsValueToModuleKey(ExecState* exec, JSValue value) 353 { 354 if (value.isSymbol()) 355 return Identifier::fromUid(jsCast<Symbol*>(value)->privateName()); 356 ASSERT(value.isString()); 357 return Identifier::fromString(exec, jsCast<JSString*>(value)->value(exec)); 358 } 359 360 void ScriptController::setupModuleScriptHandlers(CachedModuleScript& moduleScriptRef, JSInternalPromise& promise, DOMWrapperWorld& world) 361 { 362 auto& shell = *windowShell(world); 363 auto& state = *shell.window()->globalExec(); 364 365 // It is not guaranteed that either fulfillHandler or rejectHandler is eventually called. 366 // For example, if the page load is canceled, the DeferredPromise used in the module loader pipeline will stop executing JS code. 367 // Thus the promise returned from this function could remain unresolved. 368 369 JSC::PrivateName moduleLoaderAlreadyReportedErrorSymbol = m_moduleLoaderAlreadyReportedErrorSymbol; 370 JSC::PrivateName moduleLoaderFetchingIsCanceledSymbol = m_moduleLoaderFetchingIsCanceledSymbol; 371 372 RefPtr<CachedModuleScript> moduleScript(&moduleScriptRef); 373 374 auto& fulfillHandler = *JSNativeStdFunction::create(state.vm(), shell.window(), 1, String(), [moduleScript](ExecState* exec) { 375 Identifier moduleKey = jsValueToModuleKey(exec, exec->argument(0)); 376 moduleScript->notifyLoadCompleted(*moduleKey.impl()); 377 return JSValue::encode(jsUndefined()); 378 }); 379 380 auto& rejectHandler = *JSNativeStdFunction::create(state.vm(), shell.window(), 1, String(), [moduleScript, moduleLoaderAlreadyReportedErrorSymbol, moduleLoaderFetchingIsCanceledSymbol](ExecState* exec) { 381 JSValue error = exec->argument(0); 382 if (auto* symbol = jsDynamicCast<Symbol*>(error)) { 383 if (symbol->privateName() == moduleLoaderAlreadyReportedErrorSymbol) { 384 moduleScript->notifyLoadFailed(LoadableScript::Error { 385 LoadableScript::ErrorType::CachedScript, 386 Nullopt 387 }); 388 return JSValue::encode(jsUndefined()); 389 } 390 391 if (symbol->privateName() == moduleLoaderFetchingIsCanceledSymbol) { 392 moduleScript->notifyLoadWasCanceled(); 393 return JSValue::encode(jsUndefined()); 394 } 395 } 396 397 VM& vm = exec->vm(); 398 auto scope = DECLARE_CATCH_SCOPE(vm); 399 moduleScript->notifyLoadFailed(LoadableScript::Error { 400 LoadableScript::ErrorType::CachedScript, 401 LoadableScript::ConsoleMessage { 402 MessageSource::JS, 403 MessageLevel::Error, 404 retrieveErrorMessage(*exec, vm, error, scope), 405 } 406 }); 407 return JSValue::encode(jsUndefined()); 408 }); 409 410 promise.then(&state, &fulfillHandler, &rejectHandler); 259 411 } 260 412 … … 521 673 return { }; // FIXME: Would jsNull be better? 522 674 523 Ref<Frame> protect(m_frame); // Script execution can destroy the frame, and thus the ScriptController. 675 // FIXME: Preventing Frame from being destroyed is essentially unnecessary. 676 // https://bugs.webkit.org/show_bug.cgi?id=164763 677 Ref<Frame> protector(m_frame); // Script execution can destroy the frame, and thus the ScriptController. 524 678 525 679 return evaluate(sourceCode, exceptionDetails); -
trunk/Source/WebCore/bindings/js/ScriptController.h
r208179 r208788 43 43 44 44 namespace JSC { 45 class ExecState; 45 46 class JSGlobalObject; 46 class ExecState; 47 class JSInternalPromise; 48 class JSModuleRecord; 47 49 48 50 namespace Bindings { … … 54 56 namespace WebCore { 55 57 58 class CachedModuleScript; 56 59 class Frame; 57 60 class HTMLDocument; 58 61 class HTMLPlugInElement; 62 class SecurityOrigin; 59 63 class ScriptSourceCode; 60 class SecurityOrigin;61 64 class Widget; 62 65 … … 115 118 JSC::JSValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld&, ExceptionDetails* = nullptr); 116 119 120 void loadModuleScriptInWorld(CachedModuleScript&, const String& moduleName, DOMWrapperWorld&, Element&); 121 void loadModuleScript(CachedModuleScript&, const String& moduleName, Element&); 122 void loadModuleScriptInWorld(CachedModuleScript&, const ScriptSourceCode&, DOMWrapperWorld&, Element&); 123 void loadModuleScript(CachedModuleScript&, const ScriptSourceCode&, Element&); 124 125 JSC::JSValue linkAndEvaluateModuleScriptInWorld(CachedModuleScript& , DOMWrapperWorld&, Element&); 126 JSC::JSValue linkAndEvaluateModuleScript(CachedModuleScript&, Element&); 127 128 JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, DOMWrapperWorld&); 129 JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&); 130 117 131 WTF::TextPosition eventHandlerPosition() const; 118 132 … … 134 148 135 149 const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script 150 151 const JSC::PrivateName& moduleLoaderAlreadyReportedErrorSymbol() const { return m_moduleLoaderAlreadyReportedErrorSymbol; } 152 const JSC::PrivateName& moduleLoaderFetchingIsCanceledSymbol() const { return m_moduleLoaderFetchingIsCanceledSymbol; } 136 153 137 154 void clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache); … … 167 184 private: 168 185 WEBCORE_EXPORT JSDOMWindowShell* initScript(DOMWrapperWorld&); 186 void setupModuleScriptHandlers(CachedModuleScript&, JSC::JSInternalPromise&, DOMWrapperWorld&); 169 187 170 188 void disconnectPlatformScriptObjects(); … … 175 193 176 194 bool m_paused; 195 JSC::PrivateName m_moduleLoaderAlreadyReportedErrorSymbol; 196 JSC::PrivateName m_moduleLoaderFetchingIsCanceledSymbol; 177 197 178 198 // The root object used for objects bound outside the context of a plugin, such -
trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp
r208688 r208788 27 27 #include "ScriptModuleLoader.h" 28 28 29 #include "CachedModuleScriptLoader.h" 30 #include "CachedScript.h" 29 31 #include "Document.h" 30 32 #include "Frame.h" 31 33 #include "JSDOMBinding.h" 34 #include "JSElement.h" 35 #include "LoadableModuleScript.h" 36 #include "MIMETypeRegistry.h" 37 #include "ScriptController.h" 38 #include "ScriptElement.h" 39 #include "ScriptSourceCode.h" 40 #include <runtime/JSInternalPromise.h> 32 41 #include <runtime/JSInternalPromiseDeferred.h> 33 42 #include <runtime/JSModuleRecord.h> … … 42 51 } 43 52 44 JSC::JSInternalPromise* ScriptModuleLoader::resolve(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleNameValue, JSC::JSValue importerModuleKey, JSC::JSValue) 45 { 46 JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject); 53 ScriptModuleLoader::~ScriptModuleLoader() 54 { 55 for (auto& loader : m_loaders) 56 const_cast<CachedModuleScriptLoader&>(loader.get()).clearClient(); 57 } 58 59 60 static bool isRootModule(JSC::JSValue importerModuleKey) 61 { 62 return importerModuleKey.isSymbol() || importerModuleKey.isUndefined(); 63 } 64 65 JSC::JSInternalPromise* ScriptModuleLoader::resolve(JSC::JSGlobalObject* jsGlobalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleNameValue, JSC::JSValue importerModuleKey, JSC::JSValue) 66 { 67 auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject); 68 auto& jsPromise = *JSC::JSInternalPromiseDeferred::create(exec, &globalObject); 69 auto promise = DeferredPromise::create(globalObject, jsPromise); 47 70 48 71 // We use a Symbol as a special purpose; It means this module is an inline module. 49 72 // So there is no correct URL to retrieve the module source code. If the module name 50 73 // value is a Symbol, it is used directly as a module key. 51 // 52 // FIXME: Using symbols for an inline module is a current implementation details of WebKit. 53 // Once the spec of this part is specified, we will recast these part. 54 if (moduleNameValue.isSymbol()) 55 return deferred->resolve(exec, moduleNameValue); 56 57 if (!moduleNameValue.isString()) 58 return deferred->reject(exec, JSC::createTypeError(exec, "Module name is not Symbol or String.")); 59 60 String moduleName = asString(moduleNameValue)->value(exec); 61 62 // Now, we consider the given moduleName as the same to the `import "..."` in the module code. 63 // We use the completed URL as the unique module key. 64 URL completedUrl; 65 66 if (importerModuleKey.isSymbol()) 67 completedUrl = m_document.completeURL(moduleName); 68 else if (importerModuleKey.isUndefined()) 69 completedUrl = m_document.completeURL(moduleName); 74 if (moduleNameValue.isSymbol()) { 75 promise->resolve(asSymbol(moduleNameValue)->privateName()); 76 return jsPromise.promise(); 77 } 78 79 // https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier 80 81 if (!moduleNameValue.isString()) { 82 promise->reject(TypeError, ASCIILiteral("Module specifier is not Symbol or String.")); 83 return jsPromise.promise(); 84 } 85 86 String specifier = asString(moduleNameValue)->value(exec); 87 88 // 1. Apply the URL parser to specifier. If the result is not failure, return the result. 89 URL absoluteURL(URL(), specifier); 90 if (absoluteURL.isValid()) { 91 promise->resolve(absoluteURL.string()); 92 return jsPromise.promise(); 93 } 94 95 // 2. If specifier does not start with the character U+002F SOLIDUS (/), the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./), 96 // or the three-character sequence U+002E FULL STOP, U+002E FULL STOP, U+002F SOLIDUS (../), return failure and abort these steps. 97 if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../")) { 98 promise->reject(TypeError, ASCIILiteral("Module specifier does not start with \"/\", \"./\", or \"../\".")); 99 return jsPromise.promise(); 100 } 101 102 // 3. Return the result of applying the URL parser to specifier with script's base URL as the base URL. 103 104 URL completedURL; 105 106 if (isRootModule(importerModuleKey)) 107 completedURL = m_document.completeURL(specifier); 70 108 else if (importerModuleKey.isString()) { 71 URL importerModuleUrl(URL(), asString(importerModuleKey)->value(exec)); 72 if (!importerModuleUrl.isValid()) 73 return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is an invalid URL.")); 74 completedUrl = m_document.completeURL(moduleName, importerModuleUrl); 75 } else 76 return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is not Symbol or String.")); 77 78 if (!completedUrl.isValid()) 79 return deferred->reject(exec, JSC::createTypeError(exec, "Module name constructs an invalid URL.")); 80 81 return deferred->resolve(exec, jsString(exec, completedUrl.string())); 82 } 83 84 JSC::JSInternalPromise* ScriptModuleLoader::fetch(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue) 85 { 86 JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject); 87 88 if (moduleKeyValue.isSymbol()) 89 return deferred->reject(exec, JSC::createTypeError(exec, "Symbol module key should be already fulfilled with the inlined resource.")); 90 91 if (!moduleKeyValue.isString()) 92 return deferred->reject(exec, JSC::createTypeError(exec, "Module key is not Symbol or String.")); 93 94 URL completedUrl(URL(), asString(moduleKeyValue)->value(exec)); 95 if (!completedUrl.isValid()) 96 return deferred->reject(exec, JSC::createTypeError(exec, "Module key is an invalid URL.")); 97 98 // FIXME: Implement the module fetcher. 99 100 return deferred->promise(); 109 URL importerModuleRequestURL(URL(), asString(importerModuleKey)->value(exec)); 110 if (!importerModuleRequestURL.isValid()) { 111 promise->reject(TypeError, ASCIILiteral("Importer module key is an invalid URL.")); 112 return jsPromise.promise(); 113 } 114 115 URL importerModuleResponseURL = m_requestURLToResponseURLMap.get(importerModuleRequestURL); 116 if (!importerModuleResponseURL.isValid()) { 117 promise->reject(TypeError, ASCIILiteral("Importer module has an invalid response URL.")); 118 return jsPromise.promise(); 119 } 120 121 completedURL = m_document.completeURL(specifier, importerModuleResponseURL); 122 } else { 123 promise->reject(TypeError, ASCIILiteral("Importer module key is not Symbol or String.")); 124 return jsPromise.promise(); 125 } 126 127 if (!completedURL.isValid()) { 128 promise->reject(TypeError, ASCIILiteral("Module name constructs an invalid URL.")); 129 return jsPromise.promise(); 130 } 131 132 promise->resolve(completedURL.string()); 133 return jsPromise.promise(); 134 } 135 136 JSC::JSInternalPromise* ScriptModuleLoader::fetch(JSC::JSGlobalObject* jsGlobalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue initiator) 137 { 138 auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject); 139 auto& jsPromise = *JSC::JSInternalPromiseDeferred::create(exec, &globalObject); 140 auto deferred = DeferredPromise::create(globalObject, jsPromise); 141 if (moduleKeyValue.isSymbol()) { 142 deferred->reject(TypeError, ASCIILiteral("Symbol module key should be already fulfilled with the inlined resource.")); 143 return jsPromise.promise(); 144 } 145 146 if (!moduleKeyValue.isString()) { 147 deferred->reject(TypeError, ASCIILiteral("Module key is not Symbol or String.")); 148 return jsPromise.promise(); 149 } 150 151 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script 152 153 URL completedURL(URL(), asString(moduleKeyValue)->value(exec)); 154 if (!completedURL.isValid()) { 155 deferred->reject(TypeError, ASCIILiteral("Module key is a valid URL.")); 156 return jsPromise.promise(); 157 } 158 159 ASSERT_WITH_MESSAGE(JSC::jsDynamicCast<JSElement*>(initiator), "Initiator should be an JSElement"); 160 auto* scriptElement = toScriptElementIfPossible(&JSC::jsCast<JSElement*>(initiator)->wrapped()); 161 ASSERT_WITH_MESSAGE(scriptElement, "Initiator should be ScriptElement."); 162 163 if (auto* frame = m_document.frame()) { 164 auto loader = CachedModuleScriptLoader::create(*this, deferred.get()); 165 m_loaders.add(loader.copyRef()); 166 if (!loader->load(*scriptElement, completedURL)) { 167 loader->clearClient(); 168 m_loaders.remove(WTFMove(loader)); 169 170 deferred->reject(frame->script().moduleLoaderAlreadyReportedErrorSymbol()); 171 return jsPromise.promise(); 172 } 173 } 174 175 return jsPromise.promise(); 101 176 } 102 177 … … 109 184 // Once the reflective part of the module loader is supported, we will handle arbitrary values. 110 185 // https://whatwg.github.io/loader/#registry-prototype-provide 111 JSC::JSModuleRecord* moduleRecord = jsDynamicDowncast<JSC::JSModuleRecord*>(moduleRecordValue);186 auto* moduleRecord = jsDynamicDowncast<JSC::JSModuleRecord*>(moduleRecordValue); 112 187 if (!moduleRecord) 113 188 return JSC::jsUndefined(); 114 189 115 URL sourceU rl;190 URL sourceURL; 116 191 if (moduleKeyValue.isSymbol()) 117 sourceU rl= m_document.url();192 sourceURL = m_document.url(); 118 193 else if (moduleKeyValue.isString()) 119 sourceU rl= URL(URL(), asString(moduleKeyValue)->value(exec));194 sourceURL = URL(URL(), asString(moduleKeyValue)->value(exec)); 120 195 else 121 196 return JSC::throwTypeError(exec, scope, ASCIILiteral("Module key is not Symbol or String.")); 122 197 123 if (!sourceU rl.isValid())198 if (!sourceURL.isValid()) 124 199 return JSC::throwTypeError(exec, scope, ASCIILiteral("Module key is an invalid URL.")); 125 200 126 // FIXME: Implement evaluating module code.127 201 if (auto* frame = m_document.frame()) 202 return frame->script().evaluateModule(sourceURL, *moduleRecord); 128 203 return JSC::jsUndefined(); 129 204 } 130 205 131 } 206 void ScriptModuleLoader::notifyFinished(CachedModuleScriptLoader& loader, RefPtr<DeferredPromise> promise) 207 { 208 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script 209 210 if (!m_loaders.remove(&loader)) 211 return; 212 loader.clearClient(); 213 214 auto& cachedScript = *loader.cachedScript(); 215 216 bool failed = false; 217 218 if (cachedScript.resourceError().isAccessControl()) { 219 promise->reject(TypeError, ASCIILiteral("Cross-origin script load denied by Cross-Origin Resource Sharing policy.")); 220 return; 221 } 222 223 if (cachedScript.errorOccurred()) 224 failed = true; 225 else if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(cachedScript.response().mimeType())) { 226 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script 227 // The result of extracting a MIME type from response's header list (ignoring parameters) is not a JavaScript MIME type. 228 // For historical reasons, fetching a classic script does not include MIME type checking. In contrast, module scripts will fail to load if they are not of a correct MIME type. 229 promise->reject(TypeError, makeString("'", cachedScript.response().mimeType(), "' is not a valid JavaScript MIME type.")); 230 return; 231 } 232 233 auto* frame = m_document.frame(); 234 if (!frame) 235 return; 236 237 if (failed) { 238 // Reject a promise to propagate the error back all the way through module promise chains to the script element. 239 promise->reject(frame->script().moduleLoaderAlreadyReportedErrorSymbol()); 240 return; 241 } 242 243 if (cachedScript.wasCanceled()) { 244 promise->reject(frame->script().moduleLoaderFetchingIsCanceledSymbol()); 245 return; 246 } 247 248 m_requestURLToResponseURLMap.add(cachedScript.url(), cachedScript.response().url()); 249 // FIXME: Let's wrap around ScriptSourceCode to propagate it directly through the module pipeline. 250 promise->resolve(ScriptSourceCode(&cachedScript, JSC::SourceProviderSourceType::Module).source().toString()); 251 } 252 253 } -
trunk/Source/WebCore/bindings/js/ScriptModuleLoader.h
r205278 r208788 26 26 #pragma once 27 27 28 #include "CachedModuleScriptLoader.h" 29 #include "CachedModuleScriptLoaderClient.h" 30 #include "URL.h" 31 #include "URLHash.h" 28 32 #include <runtime/JSCJSValue.h> 29 33 #include <wtf/Noncopyable.h> … … 41 45 42 46 class Document; 47 class JSDOMGlobalObject; 43 48 44 class ScriptModuleLoader {49 class ScriptModuleLoader final : private CachedModuleScriptLoaderClient { 45 50 WTF_MAKE_NONCOPYABLE(ScriptModuleLoader); WTF_MAKE_FAST_ALLOCATED; 46 51 public: 47 52 explicit ScriptModuleLoader(Document&); 53 ~ScriptModuleLoader(); 48 54 49 55 Document& document() { return m_document; } … … 54 60 55 61 private: 62 void notifyFinished(CachedModuleScriptLoader&, RefPtr<DeferredPromise>) final; 63 56 64 Document& m_document; 65 HashMap<URL, URL> m_requestURLToResponseURLMap; 66 HashSet<Ref<CachedModuleScriptLoader>> m_loaders; 57 67 }; 58 68 -
trunk/Source/WebCore/bindings/js/ScriptSourceCode.h
r208179 r208788 43 43 class ScriptSourceCode { 44 44 public: 45 ScriptSourceCode(const String& source, const URL& url = URL(), const TextPosition& startPosition = TextPosition::minimumPosition() )46 : m_provider(JSC::StringSourceProvider::create(source, url.isNull() ? String() : url.string(), startPosition ))45 ScriptSourceCode(const String& source, const URL& url = URL(), const TextPosition& startPosition = TextPosition::minimumPosition(), JSC::SourceProviderSourceType sourceType = JSC::SourceProviderSourceType::Program) 46 : m_provider(JSC::StringSourceProvider::create(source, url.isNull() ? String() : url.string(), startPosition, sourceType)) 47 47 , m_code(m_provider, startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt()) 48 48 , m_url(url) … … 50 50 } 51 51 52 explicit ScriptSourceCode(CachedScript* cachedScript )53 : m_provider(CachedScriptSourceProvider::create(cachedScript ))52 explicit ScriptSourceCode(CachedScript* cachedScript, JSC::SourceProviderSourceType sourceType) 53 : m_provider(CachedScriptSourceProvider::create(cachedScript, sourceType)) 54 54 , m_code(m_provider) 55 55 , m_cachedScript(cachedScript) -
trunk/Source/WebCore/dom/CurrentScriptIncrementer.h
r208660 r208788 44 44 return; 45 45 auto& scriptElement = downcast<HTMLScriptElement>(element); 46 m_document.pushCurrentScript(scriptElement.isInShadowTree() ? nullptr : &scriptElement); 46 bool shouldPushNullForCurrentScript = scriptElement.isInShadowTree() || scriptElement.scriptType() == ScriptElement::ScriptType::Module; 47 m_document.pushCurrentScript(shouldPushNullForCurrentScript ? nullptr : &scriptElement); 47 48 } 48 49 -
trunk/Source/WebCore/dom/LoadableClassicScript.cpp
r206903 r208788 52 52 } 53 53 54 Optional<LoadableScript::Error> LoadableClassicScript:: wasErrored() const54 Optional<LoadableScript::Error> LoadableClassicScript::error() const 55 55 { 56 56 if (m_error) … … 102 102 void LoadableClassicScript::execute(ScriptElement& scriptElement) 103 103 { 104 ASSERT(! wasErrored());105 scriptElement.executeScript(ScriptSourceCode(m_cachedScript.get() ));104 ASSERT(!error()); 105 scriptElement.executeScript(ScriptSourceCode(m_cachedScript.get(), JSC::SourceProviderSourceType::Program)); 106 106 } 107 107 -
trunk/Source/WebCore/dom/LoadableClassicScript.h
r206903 r208788 41 41 class LoadableClassicScript final : public LoadableScript, private CachedResourceClient { 42 42 public: 43 ~LoadableClassicScript();43 virtual ~LoadableClassicScript(); 44 44 45 45 static Ref<LoadableClassicScript> create(CachedResourceHandle<CachedScript>&&); 46 bool isLoaded() const override;47 Optional<Error> wasErrored() const override;48 bool wasCanceled() const override;46 bool isLoaded() const final; 47 Optional<Error> error() const final; 48 bool wasCanceled() const final; 49 49 50 50 CachedScript& cachedScript() { return *m_cachedScript; } 51 51 bool isClassicScript() const final { return true; } 52 52 53 void execute(ScriptElement&) override;53 void execute(ScriptElement&) final; 54 54 55 55 private: -
trunk/Source/WebCore/dom/LoadableModuleScript.cpp
r208787 r208788 24 24 */ 25 25 26 #pragma once 26 #include "config.h" 27 #include "LoadableModuleScript.h" 27 28 28 #include <runtime/ConsoleTypes.h> 29 #include <wtf/HashCountedSet.h> 30 #include <wtf/RefCounted.h> 31 #include <wtf/text/WTFString.h> 29 #include "ScriptElement.h" 32 30 33 31 namespace WebCore { 34 32 35 class LoadableScriptClient; 36 class ScriptElement; 33 Ref<LoadableModuleScript> LoadableModuleScript::create(CachedModuleScript& moduleScript) 34 { 35 auto script = adoptRef(*new LoadableModuleScript(moduleScript)); 36 moduleScript.addClient(script.get()); 37 return script; 38 } 37 39 38 class LoadableScript : public RefCounted<LoadableScript> { 39 public: 40 enum class ErrorType { 41 CachedScript, 42 CrossOriginLoad, 43 Nosniff, 44 }; 40 LoadableModuleScript::LoadableModuleScript(CachedModuleScript& moduleScript) 41 : m_moduleScript(moduleScript) 42 { 43 } 45 44 46 struct ConsoleMessage { 47 MessageSource source; 48 MessageLevel level; 49 String message; 50 }; 45 LoadableModuleScript::~LoadableModuleScript() 46 { 47 m_moduleScript->removeClient(*this); 48 } 51 49 52 struct Error { 53 ErrorType type; 54 Optional<ConsoleMessage> consoleMessage;55 }; 50 bool LoadableModuleScript::isLoaded() const 51 { 52 return m_moduleScript->isLoaded(); 53 } 56 54 57 virtual ~LoadableScript() { } 55 Optional<LoadableScript::Error> LoadableModuleScript::error() const 56 { 57 return m_moduleScript->error(); 58 } 58 59 59 virtual bool isLoaded() const = 0; 60 virtual Optional<Error> wasErrored() const = 0; 61 virtual bool wasCanceled() const = 0; 60 bool LoadableModuleScript::wasCanceled() const 61 { 62 return m_moduleScript->wasCanceled(); 63 } 62 64 63 virtual void execute(ScriptElement&) = 0; 65 void LoadableModuleScript::notifyFinished(CachedModuleScript&) 66 { 67 notifyClientFinished(); 68 } 64 69 65 void addClient(LoadableScriptClient&); 66 void removeClient(LoadableScriptClient&); 67 68 virtual bool isClassicScript() const { return false; } 69 virtual bool isModuleGraph() const { return false; } 70 71 protected: 72 void notifyClientFinished(); 73 74 private: 75 HashCountedSet<LoadableScriptClient*> m_clients; 76 }; 70 void LoadableModuleScript::execute(ScriptElement& scriptElement) 71 { 72 scriptElement.executeModuleScript(m_moduleScript.get()); 73 } 77 74 78 75 } -
trunk/Source/WebCore/dom/LoadableModuleScript.h
r208787 r208788 26 26 #pragma once 27 27 28 #include <runtime/ConsoleTypes.h>29 #include <wtf/HashCountedSet.h>30 #include <wtf/RefCounted.h>31 #include <wtf/ text/WTFString.h>28 #include "CachedModuleScript.h" 29 #include "CachedModuleScriptClient.h" 30 #include "LoadableScript.h" 31 #include <wtf/TypeCasts.h> 32 32 33 33 namespace WebCore { 34 34 35 class LoadableScriptClient; 36 class ScriptElement; 35 class LoadableModuleScript final : public LoadableScript, private CachedModuleScriptClient { 36 public: 37 virtual ~LoadableModuleScript(); 37 38 38 class LoadableScript : public RefCounted<LoadableScript> { 39 public: 40 enum class ErrorType { 41 CachedScript, 42 CrossOriginLoad, 43 Nosniff, 44 }; 39 static Ref<LoadableModuleScript> create(CachedModuleScript&); 45 40 46 struct ConsoleMessage { 47 MessageSource source; 48 MessageLevel level; 49 String message; 50 }; 41 bool isLoaded() const final; 42 Optional<Error> error() const final; 43 bool wasCanceled() const final; 51 44 52 struct Error { 53 ErrorType type; 54 Optional<ConsoleMessage> consoleMessage; 55 }; 45 CachedModuleScript& moduleScript() { return m_moduleScript.get(); } 46 bool isModuleScript() const final { return true; } 56 47 57 v irtual ~LoadableScript() { }48 void execute(ScriptElement&) final; 58 49 59 virtual bool isLoaded() const = 0; 60 virtual Optional<Error> wasErrored() const = 0; 61 virtual bool wasCanceled() const = 0; 62 63 virtual void execute(ScriptElement&) = 0; 64 65 void addClient(LoadableScriptClient&); 66 void removeClient(LoadableScriptClient&); 67 68 virtual bool isClassicScript() const { return false; } 69 virtual bool isModuleGraph() const { return false; } 70 71 protected: 72 void notifyClientFinished(); 50 void setError(Error&&); 73 51 74 52 private: 75 HashCountedSet<LoadableScriptClient*> m_clients; 53 LoadableModuleScript(CachedModuleScript&); 54 55 void notifyFinished(CachedModuleScript&) final; 56 57 Ref<CachedModuleScript> m_moduleScript; 76 58 }; 77 59 78 60 } 61 62 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LoadableModuleScript) 63 static bool isType(const WebCore::LoadableScript& script) { return script.isModuleScript(); } 64 SPECIALIZE_TYPE_TRAITS_END() -
trunk/Source/WebCore/dom/LoadableScript.h
r205581 r208788 58 58 59 59 virtual bool isLoaded() const = 0; 60 virtual Optional<Error> wasErrored() const = 0;60 virtual Optional<Error> error() const = 0; 61 61 virtual bool wasCanceled() const = 0; 62 62 … … 67 67 68 68 virtual bool isClassicScript() const { return false; } 69 virtual bool isModule Graph() const { return false; }69 virtual bool isModuleScript() const { return false; } 70 70 71 71 protected: -
trunk/Source/WebCore/dom/PendingScript.cpp
r205581 r208788 84 84 } 85 85 86 bool PendingScript:: wasErrored() const86 bool PendingScript::error() const 87 87 { 88 return m_loadableScript && m_loadableScript-> wasErrored();88 return m_loadableScript && m_loadableScript->error(); 89 89 } 90 90 -
trunk/Source/WebCore/dom/PendingScript.h
r205581 r208788 59 59 60 60 bool isLoaded() const; 61 bool wasErrored() const;61 bool error() const; 62 62 63 63 void notifyFinished(LoadableScript&) override; -
trunk/Source/WebCore/dom/ScriptElement.cpp
r208112 r208788 25 25 #include "ScriptElement.h" 26 26 27 #include "CachedModuleScript.h" 27 28 #include "CachedResourceLoader.h" 28 29 #include "CachedResourceRequest.h" … … 39 40 #include "IgnoreDestructiveWriteCountIncrementer.h" 40 41 #include "LoadableClassicScript.h" 42 #include "LoadableModuleScript.h" 41 43 #include "MIMETypeRegistry.h" 42 44 #include "Page.h" … … 69 71 , m_forceAsync(!parserInserted) 70 72 , m_willExecuteInOrder(false) 73 , m_isModuleScript(false) 71 74 { 72 75 if (parserInserted && m_element.document().scriptableDocumentParser() && !m_element.document().isInDocumentWrite()) … … 192 195 return false; 193 196 194 if (!determineScriptType(supportLegacyTypes)) 195 return false; 197 ScriptType scriptType = ScriptType::Classic; 198 if (Optional<ScriptType> result = determineScriptType(supportLegacyTypes)) 199 scriptType = result.value(); 200 else 201 return false; 202 m_isModuleScript = scriptType == ScriptType::Module; 196 203 197 204 if (wasParserInserted) { … … 214 221 return false; 215 222 216 if (!isScriptForEventSupported()) 217 return false; 218 223 if (scriptType == ScriptType::Classic && !isScriptForEventSupported()) 224 return false; 225 226 // According to the spec, the module tag ignores the "charset" attribute as the same to the worker's 227 // importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, 228 // even for the module tags, we handle the "charset" attribute. 219 229 if (!charsetAttributeValue().isEmpty()) 220 230 m_characterEncoding = charsetAttributeValue(); … … 222 232 m_characterEncoding = document.charset(); 223 233 224 if (hasSourceAttribute()) { 225 if (!requestClassicScript(sourceAttributeValue())) 226 return false; 227 } 228 229 if (hasSourceAttribute() && deferAttributeValue() && m_parserInserted && !asyncAttributeValue()) { 234 if (scriptType == ScriptType::Classic) { 235 if (hasSourceAttribute()) { 236 if (!requestClassicScript(sourceAttributeValue())) 237 return false; 238 } 239 } else { 240 ASSERT(scriptType == ScriptType::Module); 241 if (!requestModuleScript(scriptStartPosition)) 242 return false; 243 } 244 245 // All the inlined module script is handled by requestModuleScript. It produces LoadableModuleScript and inlined module script 246 // is handled as the same to the external module script. 247 248 bool isClassicExternalScript = scriptType == ScriptType::Classic && hasSourceAttribute(); 249 bool isParserInsertedDeferredScript = ((isClassicExternalScript && deferAttributeValue()) || scriptType == ScriptType::Module) 250 && m_parserInserted && !asyncAttributeValue(); 251 if (isParserInsertedDeferredScript) { 230 252 m_willExecuteWhenDocumentFinishedParsing = true; 231 253 m_willBeParserExecuted = true; 232 } else if (hasSourceAttribute() && m_parserInserted && !asyncAttributeValue()) 254 } else if (isClassicExternalScript && m_parserInserted && !asyncAttributeValue()) { 255 ASSERT(scriptType == ScriptType::Classic); 233 256 m_willBeParserExecuted = true; 234 else if (!hasSourceAttribute() && m_parserInserted && !document.haveStylesheetsLoaded()) { 257 } else if ((isClassicExternalScript || scriptType == ScriptType::Module) && !asyncAttributeValue() && !m_forceAsync) { 258 m_willExecuteInOrder = true; 259 ASSERT(m_loadableScript); 260 document.scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::IN_ORDER_EXECUTION); 261 } else if (hasSourceAttribute() || scriptType == ScriptType::Module) { 262 ASSERT(m_loadableScript); 263 ASSERT(asyncAttributeValue() || m_forceAsync); 264 document.scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::ASYNC_EXECUTION); 265 } else if (!hasSourceAttribute() && m_parserInserted && !document.haveStylesheetsLoaded()) { 266 ASSERT(scriptType == ScriptType::Classic); 235 267 m_willBeParserExecuted = true; 236 268 m_readyToBeParserExecuted = true; 237 } else if (hasSourceAttribute() && !asyncAttributeValue() && !m_forceAsync) {238 ASSERT(m_loadableScript);239 m_willExecuteInOrder = true;240 document.scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::IN_ORDER_EXECUTION);241 } else if (hasSourceAttribute()) {242 ASSERT(m_loadableScript);243 m_element.document().scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::ASYNC_EXECUTION);244 269 } else { 245 // Reset line numbering for nested writes.270 ASSERT(scriptType == ScriptType::Classic); 246 271 TextPosition position = document.isInDocumentWrite() ? TextPosition() : scriptStartPosition; 247 executeScript(ScriptSourceCode(scriptContent(), document.url(), position ));272 executeScript(ScriptSourceCode(scriptContent(), document.url(), position, JSC::SourceProviderSourceType::Program)); 248 273 } 249 274 … … 262 287 ASSERT(!m_loadableScript); 263 288 if (!stripLeadingAndTrailingHTMLSpaces(sourceURL).isEmpty()) { 264 auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr)); 289 String nonceAttribute = m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr); 290 String crossOriginMode = m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr); 291 auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), nonceAttribute, crossOriginMode); 265 292 if (request) { 266 293 m_loadableScript = LoadableClassicScript::create(WTFMove(request)); … … 278 305 } 279 306 280 CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute) 307 bool ScriptElement::requestModuleScript(const TextPosition& scriptStartPosition) 308 { 309 String nonce = m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr); 310 String crossOriginMode = m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr); 311 if (crossOriginMode.isNull()) 312 crossOriginMode = ASCIILiteral("omit"); 313 314 if (hasSourceAttribute()) { 315 String sourceURL = sourceAttributeValue(); 316 Ref<Document> originalDocument(m_element.document()); 317 if (!m_element.dispatchBeforeLoadEvent(sourceURL)) 318 return false; 319 320 bool didEventListenerDisconnectThisElement = !m_element.inDocument() || &m_element.document() != originalDocument.ptr(); 321 if (didEventListenerDisconnectThisElement) 322 return false; 323 324 if (stripLeadingAndTrailingHTMLSpaces(sourceURL).isEmpty()) { 325 dispatchErrorEvent(); 326 return false; 327 } 328 329 auto moduleScriptRootURL = m_element.document().completeURL(sourceURL); 330 if (!moduleScriptRootURL.isValid()) { 331 dispatchErrorEvent(); 332 return false; 333 } 334 335 m_isExternalScript = true; 336 auto moduleScript = CachedModuleScript::create(nonce, crossOriginMode); 337 m_loadableScript = LoadableModuleScript::create(moduleScript.get()); 338 moduleScript->load(m_element, moduleScriptRootURL); 339 return true; 340 } 341 342 TextPosition position = m_element.document().isInDocumentWrite() ? TextPosition() : scriptStartPosition; 343 ScriptSourceCode sourceCode(scriptContent(), m_element.document().url(), position, JSC::SourceProviderSourceType::Module); 344 345 ASSERT(m_element.document().contentSecurityPolicy()); 346 const auto& contentSecurityPolicy = *m_element.document().contentSecurityPolicy(); 347 bool hasKnownNonce = contentSecurityPolicy.allowScriptWithNonce(nonce, m_element.isInUserAgentShadowTree()); 348 if (!contentSecurityPolicy.allowInlineScript(m_element.document().url(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), hasKnownNonce)) 349 return false; 350 351 auto moduleScript = CachedModuleScript::create(nonce, crossOriginMode); 352 m_loadableScript = LoadableModuleScript::create(moduleScript.get()); 353 moduleScript->load(m_element, sourceCode); 354 return true; 355 } 356 357 CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCacheForModuleScript(const URL& sourceURL) 358 { 359 ASSERT(m_loadableScript); 360 ASSERT(is<LoadableModuleScript>(*m_loadableScript)); 361 auto& moduleScript = downcast<LoadableModuleScript>(*m_loadableScript); 362 return requestScriptWithCache(sourceURL, moduleScript.moduleScript().nonce(), moduleScript.moduleScript().crossOriginMode()); 363 } 364 365 CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute, const String& crossOriginMode) 281 366 { 282 367 Document& document = m_element.document(); … … 291 376 292 377 CachedResourceRequest request(ResourceRequest(sourceURL), options); 293 request.setAsPotentiallyCrossOrigin( m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), document);378 request.setAsPotentiallyCrossOrigin(crossOriginMode, document); 294 379 request.upgradeInsecureRequestIfNeeded(document); 295 380 … … 315 400 } 316 401 317 Ref<Document> document(m_element.document()); 318 if (Frame* frame = document->frame()) { 319 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.ptr() : nullptr); 320 CurrentScriptIncrementer currentScriptIncrementer(document, m_element); 321 322 // Create a script from the script element node, using the script 323 // block's source and the script block's type. 324 // Note: This is where the script is compiled and actually executed. 325 frame->script().evaluate(sourceCode); 326 } 402 auto& document = m_element.document(); 403 auto* frame = document.frame(); 404 if (!frame) 405 return; 406 407 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? &document : nullptr); 408 CurrentScriptIncrementer currentScriptIncrementer(document, m_element); 409 410 frame->script().evaluate(sourceCode); 411 } 412 413 void ScriptElement::executeModuleScript(CachedModuleScript& moduleScript) 414 { 415 // https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block 416 417 ASSERT(!moduleScript.error()); 418 419 auto& document = m_element.document(); 420 auto* frame = document.frame(); 421 if (!frame) 422 return; 423 424 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(&document); 425 CurrentScriptIncrementer currentScriptIncrementer(document, m_element); 426 427 frame->script().linkAndEvaluateModuleScript(moduleScript, element()); 327 428 } 328 429 329 430 void ScriptElement::executeScriptAndDispatchEvent(LoadableScript& loadableScript) 330 431 { 331 if (Optional<LoadableScript::Error> error = loadableScript. wasErrored()) {432 if (Optional<LoadableScript::Error> error = loadableScript.error()) { 332 433 if (Optional<LoadableScript::ConsoleMessage> message = error->consoleMessage) 333 434 m_element.document().addConsoleMessage(message->source, message->level, message->message); 334 435 dispatchErrorEvent(); 335 436 } else if (!loadableScript.wasCanceled()) { 336 ASSERT(!loadableScript. wasErrored());437 ASSERT(!loadableScript.error()); 337 438 loadableScript.execute(*this); 338 439 dispatchLoadEvent(); … … 345 446 executeScriptAndDispatchEvent(*loadableScript); 346 447 else { 347 ASSERT(!pendingScript.wasErrored()); 348 executeScript(ScriptSourceCode(scriptContent(), m_element.document().url(), pendingScript.startingPosition())); 448 ASSERT(!pendingScript.error()); 449 JSC::SourceProviderSourceType sourceType = scriptType() == ScriptType::Module ? JSC::SourceProviderSourceType::Module : JSC::SourceProviderSourceType::Program; 450 executeScript(ScriptSourceCode(scriptContent(), m_element.document().url(), pendingScript.startingPosition(), sourceType)); 349 451 dispatchLoadEvent(); 350 452 } -
trunk/Source/WebCore/dom/ScriptElement.h
r205854 r208788 38 38 class ScriptElement; 39 39 class ScriptSourceCode; 40 class CachedModuleScript; 40 41 41 42 class ScriptElement { … … 52 53 WEBCORE_EXPORT String scriptContent() const; 53 54 void executeScript(const ScriptSourceCode&); 55 void executeModuleScript(CachedModuleScript&); 54 56 55 57 void executeScriptForScriptRunner(PendingScript&); … … 65 67 bool willExecuteInOrder() const { return m_willExecuteInOrder; } 66 68 LoadableScript* loadableScript() { return m_loadableScript.get(); } 69 70 CachedResourceHandle<CachedScript> requestScriptWithCacheForModuleScript(const URL&); 71 72 // https://html.spec.whatwg.org/multipage/scripting.html#concept-script-type 73 enum class ScriptType { Classic, Module }; 74 ScriptType scriptType() const { return m_isModuleScript ? ScriptType::Module : ScriptType::Classic; } 67 75 68 76 protected: … … 84 92 void executeScriptAndDispatchEvent(LoadableScript&); 85 93 86 // https://html.spec.whatwg.org/multipage/scripting.html#concept-script-type87 enum class ScriptType { Classic, Module };88 94 Optional<ScriptType> determineScriptType(LegacyTypeSupport) const; 89 95 bool ignoresLoadRequest() const; 90 96 bool isScriptForEventSupported() const; 91 97 92 CachedResourceHandle<CachedScript> requestScriptWithCache(const URL&, const String& );98 CachedResourceHandle<CachedScript> requestScriptWithCache(const URL&, const String& nonceAttribute, const String& crossoriginAttribute); 93 99 94 100 bool requestClassicScript(const String& sourceURL); 101 bool requestModuleScript(const TextPosition& scriptStartPosition); 95 102 96 103 virtual String sourceAttributeValue() const = 0; … … 115 122 bool m_forceAsync : 1; 116 123 bool m_willExecuteInOrder : 1; 124 bool m_isModuleScript : 1; 117 125 String m_characterEncoding; 118 126 String m_fallbackCharacterEncoding; -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp
r195743 r208788 204 204 URL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScanner via scan(): without it we will get relative URLs wrong. 205 205 // FIXME: Should this be including the charset in the preload request? 206 m_requests->append(std::make_unique<PreloadRequest>("css", url, baseElementURL, CachedResource::CSSStyleSheet, String() ));206 m_requests->append(std::make_unique<PreloadRequest>("css", url, baseElementURL, CachedResource::CSSStyleSheet, String(), PreloadRequest::ModuleScript::No)); 207 207 } 208 208 m_state = Initial; -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
r205905 r208788 145 145 return nullptr; 146 146 147 auto request = std::make_unique<PreloadRequest>(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute );147 auto request = std::make_unique<PreloadRequest>(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute, m_moduleScript); 148 148 request->setCrossOriginMode(m_crossOriginMode); 149 150 // According to the spec, the module tag ignores the "charset" attribute as the same to the worker's 151 // importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent, 152 // even for the module tags, we handle the "charset" attribute. 149 153 request->setCharset(charset()); 150 154 return request; … … 206 210 break; 207 211 case TagId::Script: 212 if (match(attributeName, typeAttr)) { 213 m_moduleScript = equalLettersIgnoringASCIICase(attributeValue, "module") ? PreloadRequest::ModuleScript::Yes : PreloadRequest::ModuleScript::No; 214 break; 215 } 208 216 processImageAndScriptAttribute(attributeName, attributeValue); 209 217 break; … … 319 327 bool m_inputIsImage; 320 328 float m_deviceScaleFactor; 329 PreloadRequest::ModuleScript m_moduleScript { PreloadRequest::ModuleScript::No }; 321 330 }; 322 331 -
trunk/Source/WebCore/html/parser/HTMLResourcePreloader.cpp
r208049 r208788 46 46 CachedResourceRequest request(completeURL(document), CachedResourceLoader::defaultCachedResourceOptions()); 47 47 request.setInitiator(m_initiator); 48 request.setAsPotentiallyCrossOrigin(m_crossOriginMode, document); 48 String crossOriginMode = m_crossOriginMode; 49 if (m_moduleScript == ModuleScript::Yes) { 50 if (crossOriginMode.isNull()) 51 crossOriginMode = ASCIILiteral("omit"); 52 } 53 request.setAsPotentiallyCrossOrigin(crossOriginMode, document); 49 54 return request; 50 55 } -
trunk/Source/WebCore/html/parser/HTMLResourcePreloader.h
r208179 r208788 34 34 WTF_MAKE_FAST_ALLOCATED; 35 35 public: 36 PreloadRequest(const String& initiator, const String& resourceURL, const URL& baseURL, CachedResource::Type resourceType, const String& mediaAttribute) 36 enum class ModuleScript { 37 Yes, 38 No, 39 }; 40 PreloadRequest(const String& initiator, const String& resourceURL, const URL& baseURL, CachedResource::Type resourceType, const String& mediaAttribute, ModuleScript moduleScript) 37 41 : m_initiator(initiator) 38 42 , m_resourceURL(resourceURL) … … 40 44 , m_resourceType(resourceType) 41 45 , m_mediaAttribute(mediaAttribute) 46 , m_moduleScript(moduleScript) 42 47 { 43 48 } … … 61 66 String m_mediaAttribute; 62 67 String m_crossOriginMode; 68 ModuleScript m_moduleScript; 63 69 }; 64 70 -
trunk/Source/WebCore/html/parser/HTMLScriptRunner.h
r208179 r208788 73 73 void stopWatchingForLoad(PendingScript&); 74 74 bool isPendingScriptReady(const PendingScript&); 75 ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred) const;76 75 77 76 Document* m_document; -
trunk/Source/WebCore/loader/cache/CachedResourceRequest.cpp
r207817 r208788 92 92 if (mode.isNull()) 93 93 return; 94 94 95 m_options.mode = FetchOptions::Mode::Cors; 95 m_options.credentials = equalLettersIgnoringASCIICase(mode, "use-credentials") ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin; 96 m_options.allowCredentials = equalLettersIgnoringASCIICase(mode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; 97 96 97 FetchOptions::Credentials credentials = equalLettersIgnoringASCIICase(mode, "omit") 98 ? FetchOptions::Credentials::Omit : equalLettersIgnoringASCIICase(mode, "use-credentials") 99 ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin; 100 m_options.credentials = credentials; 101 m_options.allowCredentials = credentials == FetchOptions::Credentials::Include ? AllowStoredCredentials : DoNotAllowStoredCredentials; 98 102 WebCore::updateRequestForAccessControl(m_resourceRequest, *document.securityOrigin(), m_options.allowCredentials); 99 103 } -
trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp
r208658 r208788 233 233 ASSERT(m_pendingScript->accessCount() > 0); 234 234 235 ScriptSourceCode sourceCode(m_pendingScript.get()); 235 // FIXME: Support ES6 modules in XML document. 236 // https://bugs.webkit.org/show_bug.cgi?id=161651 237 ScriptSourceCode sourceCode(m_pendingScript.get(), JSC::SourceProviderSourceType::Program); 236 238 bool errorOccurred = m_pendingScript->errorOccurred(); 237 239 bool wasCanceled = m_pendingScript->wasCanceled();
Note: See TracChangeset
for help on using the changeset viewer.