| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +15 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2017-02-02  Yusuke Suzuki  <utatane.tea@gmail.com>
2
3
        Web Inspector: allow import() inside the inspector
4
        https://bugs.webkit.org/show_bug.cgi?id=167457
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        We relax import module hook to accept null SourceOrigin.
9
        Such a script can be evaluated from the inspector console.
10
11
        * jsc.cpp:
12
        (GlobalObject::moduleLoaderImportModule):
13
        * runtime/JSGlobalObjectFunctions.cpp:
14
        (JSC::globalFuncImportModule):
15
1
2017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
16
2017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
2
17
3
        Removed unused m_errorHandlingModeReentry from Interpreter
18
        Removed unused m_errorHandlingModeReentry from Interpreter
- a/Source/WebCore/ChangeLog +30 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2017-02-02  Yusuke Suzuki  <utatane.tea@gmail.com>
2
3
        Web Inspector: allow import() inside the inspector
4
        https://bugs.webkit.org/show_bug.cgi?id=167457
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        When evaluating `import("...")`, we need the caller's context to resolve
9
        the module specifier correctly. For example, if `import("./cocoa.js")` is
10
        evaluated in the script "drinks/hot.js", this module name is resolved to
11
        "drinks/cocoa.js". If the same import operator is evaluated in the script
12
        "menu/all.js", the module specifier becomes "menu/cocoa.js".
13
14
        Previously we reject the import operator if the caller does not have such
15
        a context. These context is SourceOrigin and its ScriptFetcher. While they
16
        are offered in the script tag and other code evaluations, the inspector
17
        console does not offer that. These class are offered in the WebCore side
18
        and we should not touch these classes in the JSC's inspector code.
19
20
        Now we relax the above restriction. If the above caller information is not
21
        offered, we fallback to the default one. In the web page, we use the page's
22
        URL as the caller's source origin. This allows us to evaluate the import
23
        operator in the inspector console.
24
25
        And as of r167698, the console recognizes `await import("...")` form. We use
26
        this to test this `import()` in the console functionality.
27
28
        * bindings/js/ScriptModuleLoader.cpp:
29
        (WebCore::ScriptModuleLoader::importModule):
30
1
2017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
31
2017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
2
32
3
        Removed unused m_navigationStart from NavigatorGamepad
33
        Removed unused m_navigationStart from NavigatorGamepad
- a/Source/JavaScriptCore/jsc.cpp +3 lines
Lines 1551-1556 JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* global a/Source/JavaScriptCore/jsc.cpp_sec1
1551
        return JSInternalPromiseDeferred::create(exec, globalObject)->reject(exec, error);
1551
        return JSInternalPromiseDeferred::create(exec, globalObject)->reject(exec, error);
1552
    };
1552
    };
1553
1553
1554
    if (sourceOrigin.isNull())
1555
        return rejectPromise(createError(exec, ASCIILiteral("Could not resolve the module specifier.")));
1556
1554
    auto referrer = sourceOrigin.string();
1557
    auto referrer = sourceOrigin.string();
1555
    auto moduleName = moduleNameValue->value(exec);
1558
    auto moduleName = moduleNameValue->value(exec);
1556
    if (UNLIKELY(scope.exception())) {
1559
    if (UNLIKELY(scope.exception())) {
- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp -5 lines
Lines 944-954 EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState* exec) a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp_sec1
944
    RETURN_IF_EXCEPTION(catchScope, { });
944
    RETURN_IF_EXCEPTION(catchScope, { });
945
945
946
    auto sourceOrigin = exec->callerSourceOrigin();
946
    auto sourceOrigin = exec->callerSourceOrigin();
947
    if (sourceOrigin.isNull()) {
948
        promise->reject(exec, createError(exec, ASCIILiteral("Could not resolve the module specifier.")));
949
        return JSValue::encode(promise->promise());
950
    }
951
952
    RELEASE_ASSERT(exec->argumentCount() == 1);
947
    RELEASE_ASSERT(exec->argumentCount() == 1);
953
    auto* specifier = exec->uncheckedArgument(0).toString(exec);
948
    auto* specifier = exec->uncheckedArgument(0).toString(exec);
954
    if (Exception* exception = catchScope.exception()) {
949
    if (Exception* exception = catchScope.exception()) {
- a/Source/WebCore/bindings/js/ScriptModuleLoader.cpp -10 / +23 lines
Lines 218-239 JSC::JSInternalPromise* ScriptModuleLoader::importModule(JSC::JSGlobalObject* js a/Source/WebCore/bindings/js/ScriptModuleLoader.cpp_sec1
218
    JSC::VM& vm = exec->vm();
218
    JSC::VM& vm = exec->vm();
219
    auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
219
    auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
220
220
221
    // FIXME: setTimeout and setInterval with "string()" should propagate SourceOrigin.
221
    // If SourceOrigin and/or CachedScriptFetcher is null, we import the module with the default fetcher.
222
    // https://webkit.org/b/167097
222
    // SourceOrigin can be null if the source code is not coupled with the script file.
223
    ASSERT_WITH_MESSAGE(!sourceOrigin.isNull(), "If SourceOrigin is null, this function is not invoked.");
223
    // The examples,
224
    if (!sourceOrigin.fetcher())
224
    //     1. The code evaluated by the inspector.
225
        return rejectPromise(state, globalObject, TypeError, ASCIILiteral("Could not use import operator in this context."));
225
    //     2. The other unusual code execution like the evaluation through the NPAPI.
226
226
    URL baseURL;
227
    URL baseURL(URL(), sourceOrigin.string());
227
    RefPtr<JSC::ScriptFetcher> scriptFetcher;
228
    if (!baseURL.isValid())
228
    if (sourceOrigin.isNull()) {
229
        return rejectPromise(state, globalObject, TypeError, ASCIILiteral("Importer module key is not Symbol or String."));
229
        baseURL = m_document.baseURL();
230
        scriptFetcher = CachedScriptFetcher::create(m_document.charset());
231
    } else {
232
        baseURL = URL(URL(), sourceOrigin.string());
233
        if (!baseURL.isValid())
234
            return rejectPromise(state, globalObject, TypeError, ASCIILiteral("Importer module key is not a Symbol or a String."));
235
236
        if (sourceOrigin.fetcher())
237
            scriptFetcher = sourceOrigin.fetcher();
238
        else
239
            scriptFetcher = CachedScriptFetcher::create(m_document.charset());
240
    }
241
    ASSERT(baseURL.isValid());
242
    ASSERT(scriptFetcher);
230
243
231
    auto specifier = moduleName->value(exec);
244
    auto specifier = moduleName->value(exec);
232
    auto result = resolveModuleSpecifier(m_document, specifier, baseURL);
245
    auto result = resolveModuleSpecifier(m_document, specifier, baseURL);
233
    if (!result)
246
    if (!result)
234
        return rejectPromise(state, globalObject, TypeError, result.error());
247
        return rejectPromise(state, globalObject, TypeError, result.error());
235
248
236
    return JSC::importModule(exec, JSC::Identifier::fromString(&vm, result->string()), JSC::JSScriptFetcher::create(vm, sourceOrigin.fetcher() ));
249
    return JSC::importModule(exec, JSC::Identifier::fromString(&vm, result->string()), JSC::JSScriptFetcher::create(vm, WTFMove(scriptFetcher) ));
237
}
250
}
238
251
239
void ScriptModuleLoader::notifyFinished(CachedModuleScriptLoader& loader, RefPtr<DeferredPromise> promise)
252
void ScriptModuleLoader::notifyFinished(CachedModuleScriptLoader& loader, RefPtr<DeferredPromise> promise)
- a/LayoutTests/ChangeLog +13 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2017-02-02  Yusuke Suzuki  <utatane.tea@gmail.com>
2
3
        Web Inspector: allow import() inside the inspector
4
        https://bugs.webkit.org/show_bug.cgi?id=167457
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * inspector/controller/resources/cappuccino.js: Added.
9
        * inspector/controller/resources/cocoa.js: Added.
10
        * inspector/controller/resources/drink.js: Added.
11
        * inspector/controller/runtime-controller-expected.txt:
12
        * inspector/controller/runtime-controller.html:
13
1
2017-02-01  Yusuke Suzuki  <utatane.tea@gmail.com>
14
2017-02-01  Yusuke Suzuki  <utatane.tea@gmail.com>
2
15
3
        Web Inspector: Upgrade Esprima to the latest one to support dynamic import
16
        Web Inspector: Upgrade Esprima to the latest one to support dynamic import
- a/LayoutTests/inspector/controller/resources/cappuccino.js +2 lines
Line 0 a/LayoutTests/inspector/controller/resources/cappuccino.js_sec1
1
export let name = "Cappuccino";
2
export let taste = "Awesome";
- a/LayoutTests/inspector/controller/resources/cocoa.js +2 lines
Line 0 a/LayoutTests/inspector/controller/resources/cocoa.js_sec1
1
export let name = "Cocoa";
2
export let taste = "Sweet";
- a/LayoutTests/inspector/controller/resources/drink.js +7 lines
Line 0 a/LayoutTests/inspector/controller/resources/drink.js_sec1
1
import * as Cocoa from './cocoa.js'
2
import * as Cappuccino from './cappuccino.js'
3
4
export {
5
    Cocoa,
6
    Cappuccino
7
}
- a/LayoutTests/inspector/controller/runtime-controller-expected.txt +16 lines
Lines 7-12 CONSOLE MESSAGE: line 9: Promise.reject a/LayoutTests/inspector/controller/runtime-controller-expected.txt_sec1
7
CONSOLE MESSAGE: line 9: Rejection
7
CONSOLE MESSAGE: line 9: Rejection
8
CONSOLE MESSAGE: line 7: %o
8
CONSOLE MESSAGE: line 7: %o
9
CONSOLE MESSAGE: line 7: %o
9
CONSOLE MESSAGE: line 7: %o
10
CONSOLE MESSAGE: line 9: TypeError: Module specifier does not start with "/", "./", or "../".
11
CONSOLE MESSAGE: line 9: TypeError: Importing a module script failed.
12
CONSOLE MESSAGE: line 6: Cocoa is Sweet.
13
CONSOLE MESSAGE: line 7: %o
14
CONSOLE MESSAGE: line 6: Cocoa is Sweet. Cappuccino is Awesome.
15
CONSOLE MESSAGE: line 7: %o
10
Tests for RuntimeManager operations.
16
Tests for RuntimeManager operations.
11
17
12
18
Lines 58-60 PASS: Exception. Should not get transformed and produce a SyntaxError. a/LayoutTests/inspector/controller/runtime-controller-expected.txt_sec2
58
Source: x = y = await 10
64
Source: x = y = await 10
59
PASS: Exception. Should not get transformed and produce a SyntaxError.
65
PASS: Exception. Should not get transformed and produce a SyntaxError.
60
66
67
-- Running test case: RuntimeManager.prototype.evaluateInInspectedWindow.ImportFromConsole
68
Source: await import('')
69
PASS: Transformed. Should log the value or an exception.
70
Source: await import('./not-found.js')
71
PASS: Transformed. Should log the value or an exception.
72
Source: await import('./resources/cocoa.js').then((cocoa) => console.log(`${cocoa.name} is ${cocoa.taste}.`))
73
PASS: Transformed. Should log the value or an exception.
74
Source: await import('./resources/drink.js').then((ns) => console.log(`${ns.Cocoa.name} is ${ns.Cocoa.taste}. ${ns.Cappuccino.name} is ${ns.Cappuccino.taste}.`))
75
PASS: Transformed. Should log the value or an exception.
76
- a/LayoutTests/inspector/controller/runtime-controller.html +24 lines
Lines 124-129 a/LayoutTests/inspector/controller/runtime-controller.html_sec1
124
        }
124
        }
125
    });
125
    });
126
126
127
    suite.addTestCase({
128
        name: "RuntimeManager.prototype.evaluateInInspectedWindow.ImportFromConsole",
129
        description: "Test evaluating an import expression from console.",
130
        test(resolve, reject) {
131
            function testSource(expression, callback) {
132
                WebInspector.runtimeManager.evaluateInInspectedWindow(expression, {objectGroup: "test"}, (result, wasThrown) => {
133
                    InspectorTest.log("Source: " + expression);
134
                    callback(result, wasThrown);
135
                });
136
            }
137
138
            function expectUndefined(result, wasThrown) {
139
                InspectorTest.expectThat(result.isUndefined(), "Transformed. Should log the value or an exception.");
140
            }
141
142
            testSource("await import('')", expectUndefined);
143
            testSource("await import('./not-found.js')", expectUndefined);
144
            testSource("await import('./resources/cocoa.js').then((cocoa) => console.log(`${cocoa.name} is ${cocoa.taste}.`))", expectUndefined);
145
            testSource("await import('./resources/drink.js').then((ns) => console.log(`${ns.Cocoa.name} is ${ns.Cocoa.taste}. ${ns.Cappuccino.name} is ${ns.Cappuccino.taste}.`))", expectUndefined);
146
147
            InspectorBackend.runAfterPendingDispatches(resolve);
148
        }
149
    });
150
127
    suite.runTestCasesAndFinish();
151
    suite.runTestCasesAndFinish();
128
}
152
}
129
</script>
153
</script>

Return to Bug 167457