Diff
Modified: trunk/ChangeLog (211472 => 211473)
--- trunk/ChangeLog 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/ChangeLog 2017-02-01 10:00:32 UTC (rev 211473)
@@ -1,3 +1,12 @@
+2017-02-01 Yusuke Suzuki <utatane....@gmail.com>
+
+ Propagate networking errors correctly for import() operator
+ https://bugs.webkit.org/show_bug.cgi?id=167501
+
+ Reviewed by Ryosuke Niwa.
+
+ * Source/ModuleFetchFailureKind.h: Added.
+
2017-01-31 Carlos Garcia Campos <cgar...@igalia.com>
Unreviewed. Update OptionsGTK.cmake and NEWS for 2.15.4 release.
Modified: trunk/LayoutTests/ChangeLog (211472 => 211473)
--- trunk/LayoutTests/ChangeLog 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/LayoutTests/ChangeLog 2017-02-01 10:00:32 UTC (rev 211473)
@@ -1,3 +1,16 @@
+2017-02-01 Yusuke Suzuki <utatane....@gmail.com>
+
+ Propagate networking errors correctly for import() operator
+ https://bugs.webkit.org/show_bug.cgi?id=167501
+
+ Reviewed by Ryosuke Niwa.
+
+ * http/tests/security/mixedContent/import-insecure-script-in-iframe-expected.txt: Added.
+ * http/tests/security/mixedContent/import-insecure-script-in-iframe.html: Added.
+ * http/tests/security/mixedContent/resources/frame-with-insecure-import.html: Added.
+ * js/dom/modules/import-not-found-error-expected.txt: Added.
+ * js/dom/modules/import-not-found-error.html: Added.
+
2017-01-31 Wenson Hsieh <wenson_hs...@apple.com>
Regression (Safari 10.1): Pressing Return in a contenteditable no longer inserts a line break under certain conditions
Added: trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe-expected.txt (0 => 211473)
--- trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe-expected.txt 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: line 1: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/frame-with-insecure-import.html was not allowed to run insecure content from http://127.0.0.1:8080/security/mixedContent/resources/script.js.
+
+This test loads a secure iframe that attempt to import() a module script via HTTP. Since the iframe's content is of a secure origin, importing a module script via HTTP should result in a mixed content error.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.data is "TypeError: Importing a module script failed."
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe.html (0 => 211473)
--- trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/mixedContent/import-insecure-script-in-iframe.html 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,21 @@
+<html>
+<body>
+<script src=""
+<script>
+description(`This test loads a secure iframe that attempt to import() a module script via HTTP.
+Since the iframe's content is of a secure origin, importing a module script via HTTP should result
+in a mixed content error.
+`);
+window.jsTestIsAsync = true;
+window.data = ""
+window.addEventListener("message", function (error) {
+ window.data = ""
+ shouldBe(`window.data`, `"TypeError: Importing a module script failed."`);
+ finishJSTest();
+}, false);
+</script>
+<script src=""
+<p></p>
+<iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/mixedContent/resources/frame-with-insecure-import.html (0 => 211473)
--- trunk/LayoutTests/http/tests/security/mixedContent/resources/frame-with-insecure-import.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/mixedContent/resources/frame-with-insecure-import.html 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,8 @@
+<script>
+window._onload_ = function() {
+ import("http://127.0.0.1:8080/security/mixedContent/resources/script.js").catch(function (error) {
+ if (window.parent)
+ window.parent.postMessage(String(error), '*');
+ });
+};
+</script>
Added: trunk/LayoutTests/js/dom/modules/import-not-found-error-expected.txt (0 => 211473)
--- trunk/LayoutTests/js/dom/modules/import-not-found-error-expected.txt (rev 0)
+++ trunk/LayoutTests/js/dom/modules/import-not-found-error-expected.txt 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,10 @@
+Test import with non existing module.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS String(error) is "TypeError: Importing a module script failed."
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/dom/modules/import-not-found-error.html (0 => 211473)
--- trunk/LayoutTests/js/dom/modules/import-not-found-error.html (rev 0)
+++ trunk/LayoutTests/js/dom/modules/import-not-found-error.html 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description('Test import with non existing module.');
+
+window.jsTestIsAsync = true;
+</script>
+<script src=""
+<script>
+var error = null;
+(async function () {
+ try {
+ await import(`./resources/import-not-found.js`);
+ } catch (e) {
+ error = e;
+ }
+ shouldBeEqualToString(`String(error)`, `TypeError: Importing a module script failed.`);
+ finishJSTest();
+}());
+</script>
+</body>
+</html>
Added: trunk/Source/ModuleFetchFailureKind.h (0 => 211473)
--- trunk/Source/ModuleFetchFailureKind.h (rev 0)
+++ trunk/Source/ModuleFetchFailureKind.h 2017-02-01 10:00:32 UTC (rev 211473)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 Yusuke Suzuki <utatane....@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+enum class ModuleFetchFailureKind {
+ WasErrored,
+ WasCanceled,
+};
+
+} // namespace WebCore
+
Modified: trunk/Source/WebCore/ChangeLog (211472 => 211473)
--- trunk/Source/WebCore/ChangeLog 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/ChangeLog 2017-02-01 10:00:32 UTC (rev 211473)
@@ -1,3 +1,55 @@
+2017-02-01 Yusuke Suzuki <utatane....@gmail.com>
+
+ Propagate networking errors correctly for import() operator
+ https://bugs.webkit.org/show_bug.cgi?id=167501
+
+ Reviewed by Ryosuke Niwa.
+
+ We use the promise chain inside the module loader pipeline.
+ The problem is that,
+
+ 1. The errors of loading module scripts are propagated through the promise's rejection.
+ 2. Some module related errors like syntax error (when scanning module dependencies) are
+ reported at loading time (evaluating time). These errors are propagated through the
+ promise rejections and dumped to the console. LoadableModuleScript set catch handler
+ for that and print these errors to the console for ScriptElement.
+ 3. Some of errors are already reported to the console. For example, networking errors
+ are reported by the CachedModuleLoader.
+ 4. But there is no way to distinguish between (2) and (3) at the catch handler.
+
+ Previously, we propagate the special symbol for the already reported errors to distinguish
+ that. This was OK because these errors cannot be catched by the user code. However,
+ recent `import()` call needs to expose these errors to the user code. So now, accidentally,
+ the special purpose symbol is exposed.
+
+ Instead of propagating the special symbol, this patch just propagates the errors. But these
+ error objects are annotated with the private symbol. So these errors can be distinguished
+ from the other ones.
+
+ Currently, we do not have the way to expose the error details to the client of the
+ CachedScript. So we just report the error with the failed / canceled. This should be
+ more descriptive error messages in the separate patch[1].
+
+ [1]: https://bugs.webkit.org/show_bug.cgi?id=167553
+
+ Tests: http/tests/security/mixedContent/import-insecure-script-in-iframe.html
+ js/dom/modules/import-not-found-error.html
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSDOMPromise.h:
+ (WebCore::DeferredPromise::resolveWithCallback):
+ (WebCore::DeferredPromise::rejectWithCallback):
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::setupModuleScriptHandlers):
+ * bindings/js/ScriptController.h:
+ (WebCore::ScriptController::moduleLoaderAlreadyReportedErrorSymbol): Deleted.
+ (WebCore::ScriptController::moduleLoaderFetchingIsCanceledSymbol): Deleted.
+ * bindings/js/ScriptModuleLoader.cpp:
+ (WebCore::rejectToPropagateNetworkError):
+ (WebCore::ScriptModuleLoader::fetch):
+ (WebCore::ScriptModuleLoader::notifyFinished):
+ * bindings/js/WebCoreBuiltinNames.h:
+
2017-01-31 Wenson Hsieh <wenson_hs...@apple.com>
Regression (Safari 10.1): Pressing Return in a contenteditable no longer inserts a line break under certain conditions
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (211472 => 211473)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-02-01 10:00:32 UTC (rev 211473)
@@ -2675,6 +2675,7 @@
6F995A391A70833700A735F4 /* JSWebGLVertexArrayObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F995A2F1A70833700A735F4 /* JSWebGLVertexArrayObject.cpp */; };
6F995A3A1A70833700A735F4 /* JSWebGLVertexArrayObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */; };
6FA4454E898F2FC168BC38C1 /* JSBeforeUnloadEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E04A27BED2F81F98E9022B /* JSBeforeUnloadEvent.h */; };
+ 709A01FE1E3D0BDD006B0D4C /* ModuleFetchFailureKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
70F546E8B8B5D7DC54EE144E /* JSBeforeUnloadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8225432CA9D4B4CF4628EC7F /* JSBeforeUnloadEvent.cpp */; };
7117445914BC34EC00EE5FC8 /* SVGTextMetricsBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7117445714BC34E200EE5FC8 /* SVGTextMetricsBuilder.h */; };
7118FED415685CC60030B79A /* JSSVGViewSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7118FED215685CC60030B79A /* JSSVGViewSpec.cpp */; };
@@ -10045,6 +10046,7 @@
6F995A2F1A70833700A735F4 /* JSWebGLVertexArrayObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLVertexArrayObject.cpp; sourceTree = "<group>"; };
6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLVertexArrayObject.h; sourceTree = "<group>"; };
6FAD4A561A9D0FAE009F7D3C /* OpenGLESSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGLESSPI.h; sourceTree = "<group>"; };
+ 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleFetchFailureKind.h; sourceTree = "<group>"; };
71004B9A1DC1109300A52A38 /* elapsed-time-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "elapsed-time-support.js"; sourceTree = "<group>"; };
71004B9B1DC1109300A52A38 /* remaining-time-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "remaining-time-support.js"; sourceTree = "<group>"; };
71004B9D1DC1398800A52A38 /* playback-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "playback-support.js"; sourceTree = "<group>"; };
@@ -22198,6 +22200,7 @@
BC53DA2D1143121E000D817E /* DOMWrapperWorld.h */,
1432E8480C51493F00B1500F /* GCController.cpp */,
1432E8460C51493800B1500F /* GCController.h */,
+ 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */,
C585A66011D4FAC5004C3E4B /* IDBBindingUtilities.cpp */,
C585A66111D4FAC5004C3E4B /* IDBBindingUtilities.h */,
E157A8EE18185425009F821D /* JSCryptoAlgorithmBuilder.cpp */,
@@ -25990,6 +25993,7 @@
A81369D0097374F600D74463 /* HTMLFormElement.h in Headers */,
A871DE2B0A152AC800B12A68 /* HTMLFrameElement.h in Headers */,
14FFE31D0AE1963300136BF5 /* HTMLFrameElementBase.h in Headers */,
+ 709A01FE1E3D0BDD006B0D4C /* ModuleFetchFailureKind.h in Headers */,
93E241FF0B2B4E4000C732A1 /* HTMLFrameOwnerElement.h in Headers */,
A871DE280A152AC800B12A68 /* HTMLFrameSetElement.h in Headers */,
A871DE2D0A152AC800B12A68 /* HTMLHeadElement.h in Headers */,
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.h (211472 => 211473)
--- trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2017-02-01 10:00:32 UTC (rev 211473)
@@ -94,8 +94,8 @@
void reject(ExceptionCode, const String& = { });
void reject(const JSC::PrivateName&);
- template<typename Callback, typename Value>
- void resolveWithCallback(Callback callback, Value value)
+ template<typename Callback>
+ void resolveWithCallback(Callback callback)
{
if (isSuspended())
return;
@@ -103,9 +103,21 @@
ASSERT(m_globalObject);
JSC::ExecState* exec = m_globalObject->globalExec();
JSC::JSLockHolder locker(exec);
- resolve(*exec, callback(*exec, *m_globalObject.get(), std::forward<Value>(value)));
+ resolve(*exec, callback(*exec, *m_globalObject.get()));
}
+ template<typename Callback>
+ void rejectWithCallback(Callback callback)
+ {
+ if (isSuspended())
+ return;
+ ASSERT(m_deferred);
+ ASSERT(m_globalObject);
+ JSC::ExecState* exec = m_globalObject->globalExec();
+ JSC::JSLockHolder locker(exec);
+ reject(*exec, callback(*exec, *m_globalObject.get()));
+ }
+
JSC::JSValue promise() const;
bool isSuspended() { return !m_deferred || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended.
Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (211472 => 211473)
--- trunk/Source/WebCore/bindings/js/ScriptController.cpp 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp 2017-02-01 10:00:32 UTC (rev 211473)
@@ -40,6 +40,7 @@
#include "LoadableModuleScript.h"
#include "MainFrame.h"
#include "MemoryPressureHandler.h"
+#include "ModuleFetchFailureKind.h"
#include "NP_jsobject.h"
#include "Page.h"
#include "PageConsoleClient.h"
@@ -379,9 +380,6 @@
// For example, if the page load is canceled, the DeferredPromise used in the module loader pipeline will stop executing JS code.
// Thus the promise returned from this function could remain unresolved.
- JSC::PrivateName moduleLoaderAlreadyReportedErrorSymbol = m_moduleLoaderAlreadyReportedErrorSymbol;
- JSC::PrivateName moduleLoaderFetchingIsCanceledSymbol = m_moduleLoaderFetchingIsCanceledSymbol;
-
RefPtr<LoadableModuleScript> moduleScript(&moduleScriptRef);
auto& fulfillHandler = *JSNativeStdFunction::create(state.vm(), shell.window(), 1, String(), [moduleScript](ExecState* exec) {
@@ -390,22 +388,26 @@
return JSValue::encode(jsUndefined());
});
- auto& rejectHandler = *JSNativeStdFunction::create(state.vm(), shell.window(), 1, String(), [moduleScript, moduleLoaderAlreadyReportedErrorSymbol, moduleLoaderFetchingIsCanceledSymbol](ExecState* exec) {
- JSValue error = exec->argument(0);
+ auto& rejectHandler = *JSNativeStdFunction::create(state.vm(), shell.window(), 1, String(), [moduleScript](ExecState* exec) {
VM& vm = exec->vm();
- if (auto* symbol = jsDynamicCast<Symbol*>(vm, error)) {
- if (symbol->privateName() == moduleLoaderAlreadyReportedErrorSymbol) {
- moduleScript->notifyLoadFailed(LoadableScript::Error {
- LoadableScript::ErrorType::CachedScript,
- std::nullopt
- });
+ JSValue errorValue = exec->argument(0);
+ if (errorValue.isObject()) {
+ auto* object = JSC::asObject(errorValue);
+ if (JSValue failureKindValue = object->getDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName())) {
+ // This is host propagated error in the module loader pipeline.
+ switch (static_cast<ModuleFetchFailureKind>(failureKindValue.asInt32())) {
+ case ModuleFetchFailureKind::WasErrored:
+ moduleScript->notifyLoadFailed(LoadableScript::Error {
+ LoadableScript::ErrorType::CachedScript,
+ std::nullopt
+ });
+ break;
+ case ModuleFetchFailureKind::WasCanceled:
+ moduleScript->notifyLoadWasCanceled();
+ break;
+ }
return JSValue::encode(jsUndefined());
}
-
- if (symbol->privateName() == moduleLoaderFetchingIsCanceledSymbol) {
- moduleScript->notifyLoadWasCanceled();
- return JSValue::encode(jsUndefined());
- }
}
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -414,7 +416,7 @@
LoadableScript::ConsoleMessage {
MessageSource::JS,
MessageLevel::Error,
- retrieveErrorMessage(*exec, vm, error, scope),
+ retrieveErrorMessage(*exec, vm, errorValue, scope),
}
});
return JSValue::encode(jsUndefined());
Modified: trunk/Source/WebCore/bindings/js/ScriptController.h (211472 => 211473)
--- trunk/Source/WebCore/bindings/js/ScriptController.h 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/bindings/js/ScriptController.h 2017-02-01 10:00:32 UTC (rev 211473)
@@ -147,9 +147,6 @@
const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script
- const JSC::PrivateName& moduleLoaderAlreadyReportedErrorSymbol() const { return m_moduleLoaderAlreadyReportedErrorSymbol; }
- const JSC::PrivateName& moduleLoaderFetchingIsCanceledSymbol() const { return m_moduleLoaderFetchingIsCanceledSymbol; }
-
void clearWindowShellsNotMatchingDOMWindow(DOMWindow*, bool goingIntoPageCache);
void setDOMWindowForWindowShell(DOMWindow*);
void updateDocument();
@@ -192,8 +189,6 @@
const String* m_sourceURL;
bool m_paused;
- JSC::PrivateName m_moduleLoaderAlreadyReportedErrorSymbol;
- JSC::PrivateName m_moduleLoaderFetchingIsCanceledSymbol;
// The root object used for objects bound outside the context of a plugin, such
// as NPAPI plugins. The plugins using these objects prevent a page from being cached so they
Modified: trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp (211472 => 211473)
--- trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp 2017-02-01 10:00:32 UTC (rev 211473)
@@ -34,8 +34,10 @@
#include "JSDOMBinding.h"
#include "LoadableModuleScript.h"
#include "MIMETypeRegistry.h"
+#include "ModuleFetchFailureKind.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
+#include "WebCoreJSClientData.h"
#include <runtime/Completion.h>
#include <runtime/JSInternalPromise.h>
#include <runtime/JSInternalPromiseDeferred.h>
@@ -123,6 +125,20 @@
return jsPromise.promise();
}
+void rejectToPropagateNetworkError(DeferredPromise& deferred, ModuleFetchFailureKind failureKind, ASCIILiteral message)
+{
+ deferred.rejectWithCallback([&] (JSC::ExecState& state, JSDOMGlobalObject&) {
+ // We annotate exception with special private symbol. It allows us to distinguish these errors from the user thrown ones.
+ JSC::VM& vm = state.vm();
+ // FIXME: Propagate more descriptive error.
+ // https://bugs.webkit.org/show_bug.cgi?id=167553
+ auto* error = JSC::createTypeError(&state, message);
+ ASSERT(error);
+ error->putDirect(vm, static_cast<JSVMClientData&>(*vm.clientData).builtinNames().failureKindPrivateName(), JSC::jsNumber(static_cast<int32_t>(failureKind)));
+ return error;
+ });
+}
+
JSC::JSInternalPromise* ScriptModuleLoader::fetch(JSC::JSGlobalObject* jsGlobalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue scriptFetcher)
{
ASSERT(JSC::jsDynamicCast<JSC::JSScriptFetcher*>(exec->vm(), scriptFetcher));
@@ -148,15 +164,13 @@
return jsPromise.promise();
}
- if (auto* frame = m_document.frame()) {
- auto loader = CachedModuleScriptLoader::create(*this, deferred.get(), *static_cast<CachedScriptFetcher*>(JSC::jsCast<JSC::JSScriptFetcher*>(scriptFetcher)->fetcher()));
- m_loaders.add(loader.copyRef());
- if (!loader->load(m_document, completedURL)) {
- loader->clearClient();
- m_loaders.remove(WTFMove(loader));
- deferred->reject(frame->script().moduleLoaderAlreadyReportedErrorSymbol());
- return jsPromise.promise();
- }
+ auto loader = CachedModuleScriptLoader::create(*this, deferred.get(), *static_cast<CachedScriptFetcher*>(JSC::jsCast<JSC::JSScriptFetcher*>(scriptFetcher)->fetcher()));
+ m_loaders.add(loader.copyRef());
+ if (!loader->load(m_document, completedURL)) {
+ loader->clearClient();
+ m_loaders.remove(WTFMove(loader));
+ rejectToPropagateNetworkError(deferred.get(), ModuleFetchFailureKind::WasErrored, ASCIILiteral("Importing a module script failed."));
+ return jsPromise.promise();
}
return jsPromise.promise();
@@ -232,43 +246,34 @@
auto& cachedScript = *loader.cachedScript();
- bool failed = false;
-
if (cachedScript.resourceError().isAccessControl()) {
promise->reject(TypeError, ASCIILiteral("Cross-origin script load denied by Cross-Origin Resource Sharing policy."));
return;
}
- if (cachedScript.errorOccurred())
- failed = true;
- else if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(cachedScript.response().mimeType())) {
- // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
- // The result of extracting a MIME type from response's header list (ignoring parameters) is not a _javascript_ MIME type.
- // 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.
- promise->reject(TypeError, makeString("'", cachedScript.response().mimeType(), "' is not a valid _javascript_ MIME type."));
+ if (cachedScript.errorOccurred()) {
+ rejectToPropagateNetworkError(*promise, ModuleFetchFailureKind::WasErrored, ASCIILiteral("Importing a module script failed."));
return;
}
- auto* frame = m_document.frame();
- if (!frame)
+ if (cachedScript.wasCanceled()) {
+ rejectToPropagateNetworkError(*promise, ModuleFetchFailureKind::WasCanceled, ASCIILiteral("Importing a module script is canceled."));
return;
-
- if (failed) {
- // Reject a promise to propagate the error back all the way through module promise chains to the script element.
- promise->reject(frame->script().moduleLoaderAlreadyReportedErrorSymbol());
- return;
}
- if (cachedScript.wasCanceled()) {
- promise->reject(frame->script().moduleLoaderFetchingIsCanceledSymbol());
+ if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(cachedScript.response().mimeType())) {
+ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
+ // The result of extracting a MIME type from response's header list (ignoring parameters) is not a _javascript_ MIME type.
+ // 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.
+ promise->reject(TypeError, makeString("'", cachedScript.response().mimeType(), "' is not a valid _javascript_ MIME type."));
return;
}
m_requestURLToResponseURLMap.add(cachedScript.url(), cachedScript.response().url());
- ScriptSourceCode scriptSourceCode(&cachedScript, JSC::SourceProviderSourceType::Module, loader.scriptFetcher());
- promise->resolveWithCallback([] (JSC::ExecState& state, JSDOMGlobalObject&, JSC::SourceCode sourceCode) {
- return JSC::JSSourceCode::create(state.vm(), WTFMove(sourceCode));
- }, scriptSourceCode.jsSourceCode());
+ promise->resolveWithCallback([&] (JSC::ExecState& state, JSDOMGlobalObject&) {
+ return JSC::JSSourceCode::create(state.vm(),
+ JSC::SourceCode { ScriptSourceCode { &cachedScript, JSC::SourceProviderSourceType::Module, loader.scriptFetcher() }.jsSourceCode() });
+ });
}
}
Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (211472 => 211473)
--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2017-02-01 07:55:44 UTC (rev 211472)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2017-02-01 10:00:32 UTC (rev 211473)
@@ -45,6 +45,7 @@
macro(controller) \
macro(createReadableStreamSource) \
macro(disturbed) \
+ macro(failureKind) \
macro(fetchRequest) \
macro(fillFromJS) \
macro(finishConsumingStream) \