[ES Modules] Allow .mjs content when loaded from file://
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:26:44 +0000 (18:26 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:26:44 +0000 (18:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192100
<rdar://problem/46320065>

Reviewed by Sam Weinig.

Source/WebCore:

Node JS requires ES Module files to be identified by the file
extension of ".mjs" (no relation to Maciej Stachowiak). This new
extension causes issues because it isn't recognised as a JavaScript
file. When using the script tag, the author is able to force the type
of the referenced file using an attribute, but this isn't possible
for the import() function or import statement.

Add a new entry into our table that maps file extensions to MIME types
so that when a .mjs file is loaded from a file:// reference it is
identified as JavaScript.

Test: js/dom/modules/import-mjs-module.html

* platform/network/mac/WebCoreURLResponse.mm: Add .mjs to the existing dictionary.
(WebCore::createExtensionToMIMETypeMap):
* platform/network/ios/WebCoreURLResponseIOS.mm: Add code just for .mjs.
(WebCore::createExtensionToMIMETypeMap):

Source/WebInspectorUI:

Add a mapping from .mjs to application/javascript.

* UserInterface/Base/MIMETypeUtilities.js:
(WI.mimeTypeForFileExtension):

LayoutTests:

Test for both import() function and the import statement loading
from .mjs files.

* js/dom/modules/import-mjs-module-expected.txt: Added.
* js/dom/modules/import-mjs-module.html: Added.
* js/dom/modules/resources/module-simple-A.mjs: Added.
* js/dom/modules/resources/module-simple-B.mjs: Added.
* platform/win/TestExpectations: Skip this on Windows. Just wait for Windows
  to recognise the extension.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238673 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/js/dom/modules/import-mjs-module-expected.txt [new file with mode: 0644]
LayoutTests/js/dom/modules/import-mjs-module.html [new file with mode: 0644]
LayoutTests/js/dom/modules/resources/module-simple-A.mjs [new file with mode: 0644]
LayoutTests/js/dom/modules/resources/module-simple-B.mjs [new file with mode: 0644]
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/network/ios/WebCoreURLResponseIOS.mm
Source/WebCore/platform/network/mac/WebCoreURLResponse.mm
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Base/MIMETypeUtilities.js

index ec8cc3e..eebab66 100644 (file)
@@ -1,3 +1,21 @@
+2018-11-28  Dean Jackson  <dino@apple.com>
+
+        [ES Modules] Allow .mjs content when loaded from file://
+        https://bugs.webkit.org/show_bug.cgi?id=192100
+        <rdar://problem/46320065>
+
+        Reviewed by Sam Weinig.
+
+        Test for both import() function and the import statement loading
+        from .mjs files.
+
+        * js/dom/modules/import-mjs-module-expected.txt: Added.
+        * js/dom/modules/import-mjs-module.html: Added.
+        * js/dom/modules/resources/module-simple-A.mjs: Added.
+        * js/dom/modules/resources/module-simple-B.mjs: Added.
+        * platform/win/TestExpectations: Skip this on Windows. Just wait for Windows
+          to recognise the extension.
+
 2018-11-29  Guillaume Emont  <guijemont@igalia.com>
 
         Gardening: skip test that newly times out on Armv7
diff --git a/LayoutTests/js/dom/modules/import-mjs-module-expected.txt b/LayoutTests/js/dom/modules/import-mjs-module-expected.txt
new file mode 100644 (file)
index 0000000..a8b8908
--- /dev/null
@@ -0,0 +1,13 @@
+Test import of a .mjs module.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Module is not executed yet.
+Module B was imported.
+Module A was imported.
+Exported B was visible.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/dom/modules/import-mjs-module.html b/LayoutTests/js/dom/modules/import-mjs-module.html
new file mode 100644 (file)
index 0000000..47df8e6
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+description("Test import of a .mjs module.");
+
+// Module will be executed asynchronously.
+window.jsTestIsAsync = true;
+</script>
+<script>
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+<script>
+(async function() {
+    debug("Module is not executed yet.");
+    try {
+        await import("./resources/module-simple-A.mjs");
+    } catch (e) {
+        debug("Module import failed.");
+    } finally {
+        finishJSTest();
+    }
+}());
+</script>
+</body>
+</html>
diff --git a/LayoutTests/js/dom/modules/resources/module-simple-A.mjs b/LayoutTests/js/dom/modules/resources/module-simple-A.mjs
new file mode 100644 (file)
index 0000000..02b458e
--- /dev/null
@@ -0,0 +1,5 @@
+import { B } from "./module-simple-B.mjs";
+debug("Module A was imported.");
+
+if (B == 42)
+    debug("Exported B was visible.");
diff --git a/LayoutTests/js/dom/modules/resources/module-simple-B.mjs b/LayoutTests/js/dom/modules/resources/module-simple-B.mjs
new file mode 100644 (file)
index 0000000..7a6ac21
--- /dev/null
@@ -0,0 +1,5 @@
+debug("Module B was imported.");
+
+export let B = 42;
+
+export { B as default };
index 85b5138..f9f235e 100644 (file)
@@ -4269,3 +4269,7 @@ webkit.org/b/192010 fast/inline/simple-inline-with-out-of-flow-descendant.html [
 webkit.org/b/192010 fast/inline/simple-inline-with-out-of-flow-descendant2.html [ Failure ]
 
 webkit.org/b/192011 svg/text/monospace-text-size-in-img.html [ ImageOnlyFailure ]
+
+# This only applies to file:// loading of ES6 Modules via the import syntax. When
+# Windows recognizes .mjs files as JavaScript, this will just work.
+js/dom/modules/import-mjs-module.html [ Skip ]
index a81dde3..526aa70 100644 (file)
@@ -1,3 +1,29 @@
+2018-11-28  Dean Jackson  <dino@apple.com>
+
+        [ES Modules] Allow .mjs content when loaded from file://
+        https://bugs.webkit.org/show_bug.cgi?id=192100
+        <rdar://problem/46320065>
+
+        Reviewed by Sam Weinig.
+
+        Node JS requires ES Module files to be identified by the file
+        extension of ".mjs" (no relation to Maciej Stachowiak). This new
+        extension causes issues because it isn't recognised as a JavaScript
+        file. When using the script tag, the author is able to force the type
+        of the referenced file using an attribute, but this isn't possible
+        for the import() function or import statement.
+
+        Add a new entry into our table that maps file extensions to MIME types
+        so that when a .mjs file is loaded from a file:// reference it is
+        identified as JavaScript.
+
+        Test: js/dom/modules/import-mjs-module.html
+
+        * platform/network/mac/WebCoreURLResponse.mm: Add .mjs to the existing dictionary.
+        (WebCore::createExtensionToMIMETypeMap):
+        * platform/network/ios/WebCoreURLResponseIOS.mm: Add code just for .mjs.
+        (WebCore::createExtensionToMIMETypeMap):
+
 2018-11-29  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][BFC][Quirk] Width does not need stretching quirk.
index 4912052..0509ed6 100644 (file)
 
 namespace WebCore {
 
+// <rdar://problem/46332893> Register .mjs files as whatever UTI indicates JavaScript
+static CFDictionaryRef createExtensionToMIMETypeMap()
+{
+    CFStringRef keys[] = {
+        CFSTR("mjs")
+    };
+
+    CFStringRef values[] = {
+        CFSTR("application/javascript")
+    };
+
+    ASSERT(sizeof(keys) == sizeof(values));
+    return CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(CFStringRef), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+}
+
 void adjustMIMETypeIfNecessary(CFURLResponseRef cfResponse, bool isMainResourceLoad)
 {
     RetainPtr<CFStringRef> mimeType = CFURLResponseGetMIMEType(cfResponse);
@@ -46,6 +61,21 @@ void adjustMIMETypeIfNecessary(CFURLResponseRef cfResponse, bool isMainResourceL
     if (!updatedMIMEType)
         updatedMIMEType = defaultMIMEType().createCFString();
 
+    // <rdar://problem/46332893> Register .mjs files as whatever UTI indicates JavaScript
+    if (!mimeType) {
+        auto url = CFURLResponseGetURL(cfResponse);
+        if ([(__bridge NSURL *)url isFileURL]) {
+            RetainPtr<CFStringRef> extension = adoptCF(CFURLCopyPathExtension(url));
+            if (extension) {
+                static CFDictionaryRef extensionMap = createExtensionToMIMETypeMap();
+                CFMutableStringRef mutableExtension = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, extension.get());
+                CFStringLowercase(mutableExtension, NULL);
+                extension = adoptCF(mutableExtension);
+                updatedMIMEType = (CFStringRef)CFDictionaryGetValue(extensionMap, extension.get());
+            }
+        }
+    }
+
 #if USE(QUICK_LOOK)
     // We must ensure that the MIME type is correct, so that QuickLook's web plugin is called when needed.
     // We filter the basic MIME types so that we don't do unnecessary work in standard browsing situations.
index 1dc6df7..2f1f6ec 100644 (file)
@@ -92,6 +92,7 @@ static CFDictionaryRef createExtensionToMIMETypeMap()
         CFSTR("me"),
         CFSTR("mesh"),
         CFSTR("mif"),
+        CFSTR("mjs"),
         CFSTR("movie"),
         CFSTR("mp2"),
         CFSTR("mpga"),
@@ -211,6 +212,7 @@ static CFDictionaryRef createExtensionToMIMETypeMap()
         CFSTR("application/x-troff-me"),
         CFSTR("model/mesh"),
         CFSTR("application/vnd.mif"),
+        CFSTR("application/javascript"),
         CFSTR("video/x-sgi-movie"),
         CFSTR("audio/mpeg"),
         CFSTR("audio/mpeg"),
index 604a070..d7e6e9c 100644 (file)
@@ -1,3 +1,16 @@
+2018-11-28  Dean Jackson  <dino@apple.com>
+
+        [ES Modules] Allow .mjs content when loaded from file://
+        https://bugs.webkit.org/show_bug.cgi?id=192100
+        <rdar://problem/46320065>
+
+        Reviewed by Sam Weinig.
+
+        Add a mapping from .mjs to application/javascript.
+
+        * UserInterface/Base/MIMETypeUtilities.js:
+        (WI.mimeTypeForFileExtension):
+
 2018-11-29  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Elements: selecting more than one DOM node causes the scope highlight to contrast
index 4c1f0f6..87dfa14 100644 (file)
@@ -49,6 +49,7 @@ WI.mimeTypeForFileExtension = function(extension)
 
         // Script types.
         "js": "application/javascript",
+        "mjs": "application/javascript",
         "json": "application/json",
         "clj": "text/x-clojure",
         "coffee": "text/x-coffeescript",