diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 49ca9c53d961..f2848bf404b2 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -468,6 +468,12 @@ Toolbox.prototype = { this._threadClient = await attachThread(this); await domReady; + // The web console is immediately loaded when replaying, so that the + // timeline will always be populated with generated messages. + if (this.target.isReplayEnabled()) { + await this.loadTool("webconsole"); + } + this.isReady = true; const framesPromise = this._listFrames(); diff --git a/devtools/client/webconsole/webconsole-connection-proxy.js b/devtools/client/webconsole/webconsole-connection-proxy.js index c9ee9b255ba5..2cf3412878f4 100644 --- a/devtools/client/webconsole/webconsole-connection-proxy.js +++ b/devtools/client/webconsole/webconsole-connection-proxy.js @@ -30,6 +30,7 @@ function WebConsoleConnectionProxy(webConsoleFrame, target) { this._onPageError = this._onPageError.bind(this); this._onLogMessage = this._onLogMessage.bind(this); this._onConsoleAPICall = this._onConsoleAPICall.bind(this); + this._onVirtualConsoleLog = this._onVirtualConsoleLog.bind(this); this._onNetworkEvent = this._onNetworkEvent.bind(this); this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this); this._onTabNavigated = this._onTabNavigated.bind(this); @@ -127,6 +128,8 @@ WebConsoleConnectionProxy.prototype = { client.addListener("consoleAPICall", this._onConsoleAPICall); client.addListener("lastPrivateContextExited", this._onLastPrivateContextExited); + client.addListener("virtualConsoleLog", + this._onVirtualConsoleLog); this.target.on("will-navigate", this._onTabWillNavigate); this.target.on("navigate", this._onTabNavigated); @@ -310,6 +313,20 @@ WebConsoleConnectionProxy.prototype = { } this.dispatchMessageAdd(packet); }, + + _onVirtualConsoleLog: function(type, packet) { + if (!this.webConsoleFrame) { + return; + } + this.dispatchMessageAdd({ + type: "consoleAPICall", + message: { + executionPoint: packet.executionPoint, + "arguments": [packet.url + ":" + packet.line, packet.message], + }, + }); + }, + /** * The "networkEvent" message type handler. We redirect any message to * the UI for displaying. @@ -423,6 +440,8 @@ WebConsoleConnectionProxy.prototype = { this.client.removeListener("consoleAPICall", this._onConsoleAPICall); this.client.removeListener("lastPrivateContextExited", this._onLastPrivateContextExited); + this.client.removeListener("virtualConsoleLog", + this._onVirtualConsoleLog); this.webConsoleClient.off("networkEvent", this._onNetworkEvent); this.webConsoleClient.off("networkEventUpdate", this._onNetworkEventUpdate); this.target.off("will-navigate", this._onTabWillNavigate); diff --git a/devtools/shared/client/constants.js b/devtools/shared/client/constants.js index 131c2fa0bb2b..f584a7f6e94f 100644 --- a/devtools/shared/client/constants.js +++ b/devtools/shared/client/constants.js @@ -37,6 +37,7 @@ const UnsolicitedNotifications = { "evaluationResult": "evaluationResult", "updatedSource": "updatedSource", "inspectObject": "inspectObject", + "virtualConsoleLog": "virtualConsoleLog", // newSource is still emitted on the ThreadActor, in addition to the // BrowsingContextActor we have to keep it here until ThreadClient is converted to