Bug 1498300 - Add top-level await support to the Browser Console; r=bgrins.

This patch moves the parserService from the toolbox,
which isn't accessible in the case of the Browser Console,
to the console itself.
A lightweight test is added to ensure top-level await is
supported in the browser console.

Differential Revision: https://phabricator.services.mozilla.com/D8816

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Chevobbe 2018-10-16 13:57:32 +00:00
parent e1e432ca29
commit b093e93392
4 changed files with 75 additions and 26 deletions

View File

@ -685,21 +685,6 @@ Toolbox.prototype = {
return this._createSourceMapService();
},
/**
* A common access point for the client-side parser service that any panel can use.
*/
get parserService() {
if (this._parserService) {
return this._parserService;
}
this._parserService =
this.browserRequire("devtools/client/debugger/new/src/workers/parser/index");
this._parserService
.start("resource://devtools/client/debugger/new/dist/parser-worker.js", this.win);
return this._parserService;
},
/**
* Clients wishing to use source maps but that want the toolbox to
* track the source and style sheet actor mapping can use this
@ -2875,11 +2860,6 @@ Toolbox.prototype = {
this._sourceMapService = null;
}
if (this._parserService) {
this._parserService.stop();
this._parserService = null;
}
if (this.webconsolePanel) {
this._saveSplitConsoleHeight();
this.webconsolePanel.removeEventListener("resize",

View File

@ -173,6 +173,7 @@ skip-if = (os == "linux" && (debug || ccov)) # Bug 1440059
[browser_console_devtools_loader_exception.js]
[browser_console_error_source_click.js]
[browser_console_filters.js]
[browser_console_jsterm_await.js]
[browser_console_nsiconsolemessage.js]
[browser_console_open_or_focus.js]
skip-if = (verify && debug && (os == 'mac' || os == 'linux'))

View File

@ -0,0 +1,46 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// This is a lightweight version of browser_jsterm_await.js to only ensure top-level await
// support in the Browser Console.
"use strict";
const TEST_URI = "data:text/html;charset=utf-8,Top-level await Browser Console test";
add_task(async function() {
// Enable await mapping.
await pushPref("devtools.debugger.features.map-await-expression", true);
// Run test with legacy JsTerm
await pushPref("devtools.webconsole.jsterm.codeMirror", false);
await performTests();
// And then run it with the CodeMirror-powered one.
await pushPref("devtools.webconsole.jsterm.codeMirror", true);
await performTests();
});
async function performTests() {
await addTab(TEST_URI);
const hud = await HUDService.toggleBrowserConsole();
const executeAndWaitForResultMessage = (input, expectedOutput) =>
executeAndWaitForMessage(hud, input, expectedOutput, ".result");
info("Evaluate a top-level await expression");
const simpleAwait = `await new Promise(r => setTimeout(() => r(["await1"]), 500))`;
await executeAndWaitForResultMessage(
simpleAwait,
`Array [ "await1" ]`,
);
// Check that the resulting promise of the async iife is not displayed.
const messages = hud.ui.outputNode.querySelectorAll(".message .message-body");
const messagesText = Array.from(messages).map(n => n.textContent).join(" - ");
is(messagesText.includes("Promise {"), false, "The output does not contain a Promise");
ok(messagesText.includes(simpleAwait) && messagesText.includes(`Array [ "await1" ]`),
"The output contains the the expected messages");
info("Close the Browser console");
await HUDService.toggleBrowserConsole();
}

View File

@ -243,22 +243,39 @@ WebConsole.prototype = {
*/
getMappedExpression(expression) {
const toolbox = gDevTools.getToolbox(this.target);
if (!toolbox) {
return null;
}
const panel = toolbox.getPanel("jsdebugger");
// We need to check if the debugger is open, since it may perform a variable name
// substitution for sourcemapped script (i.e. evaluated `myVar.trim()` might need to
// be transformed into `a.trim()`).
const panel = toolbox && toolbox.getPanel("jsdebugger");
if (panel) {
return panel.getMappedExpression(expression);
}
if (toolbox.parserService && expression.includes("await ")) {
return toolbox.parserService.mapExpression(expression);
if (this.parserService && expression.includes("await ")) {
return this.parserService.mapExpression(expression);
}
return null;
},
/**
* A common access point for the client-side parser service that any panel can use.
*/
get parserService() {
if (this._parserService) {
return this._parserService;
}
this._parserService =
require("devtools/client/debugger/new/src/workers/parser/index");
this._parserService.start(
"resource://devtools/client/debugger/new/dist/parser-worker.js",
this.browserWindow);
return this._parserService;
},
/**
* Retrieves the current selection from the Inspector, if such a selection
* exists. This is used to pass the ID of the selected actor to the Web
@ -309,6 +326,11 @@ WebConsole.prototype = {
}
}
if (this._parserService) {
this._parserService.stop();
this._parserService = null;
}
const id = Utils.supportsString(this.hudId);
Services.obs.notifyObservers(id, "web-console-destroyed");
})();