From 1e63b6e777e41d7aa433ce675859ee2a9d7733e1 Mon Sep 17 00:00:00 2001 From: Brian Grinstead Date: Mon, 26 Oct 2015 09:13:11 -0700 Subject: [PATCH] Bug 1215117 - Make console input field work inside a worker toolbox;r=ejpbruel --HG-- extra : commitid : 284VqUOwCvf --- .../debugger/test/mochitest/browser.ini | 2 + .../browser_dbg_break-on-next-console.js | 18 +-- .../browser_dbg_split-console-keypress.js | 15 -- .../mochitest/browser_dbg_worker-console.js | 145 ++++++++++++++++++ .../client/debugger/test/mochitest/head.js | 25 +++ devtools/client/framework/target.js | 8 +- devtools/client/webconsole/webconsole.js | 18 ++- devtools/server/actors/webconsole.js | 66 ++++---- devtools/server/actors/worker.js | 7 +- devtools/server/main.js | 18 +-- devtools/server/worker.js | 32 ++-- devtools/shared/client/main.js | 26 +++- devtools/shared/webconsole/client.js | 7 + devtools/shared/webconsole/moz.build | 1 + devtools/shared/webconsole/worker-utils.js | 13 ++ devtools/shared/worker/loader.js | 6 +- 16 files changed, 302 insertions(+), 105 deletions(-) create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-console.js create mode 100644 devtools/shared/webconsole/worker-utils.js diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini index be8b6b90e9bb..3083a63cc8f1 100644 --- a/devtools/client/debugger/test/mochitest/browser.ini +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -574,6 +574,8 @@ skip-if = e10s && debug skip-if = e10s && debug [browser_dbg_watch-expressions-02.js] skip-if = e10s && debug +[browser_dbg_worker-console.js] +skip-if = e10s && debug [browser_dbg_worker-window.js] skip-if = e10s && debug [browser_dbg_WorkerActor.attach.js] diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js index 4fe42eb6438f..c63170d35c6b 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js @@ -33,7 +33,7 @@ function test() { let oncePaused = gTarget.once("thread-paused"); EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); - let jsterm = yield getSplitConsole(); + let jsterm = yield getSplitConsole(gDevTools.getToolbox(gPanel.target)); let executed = jsterm.execute("1+1"); yield oncePaused; @@ -54,20 +54,4 @@ function test() { yield executed; }); - - function getSplitConsole() { - return new Promise(resolve => { - let toolbox = gDevTools.getToolbox(gPanel.target); - toolbox.once("webconsole-ready", () => { - ok(toolbox.splitConsole, "Split console is shown."); - let jsterm = toolbox.getPanel("webconsole").hud.jsterm; - resolve(jsterm); - }); - EventUtils.synthesizeKey("VK_ESCAPE", {}, gDebugger); - }); - } } - -registerCleanupFunction(() => { - Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); -}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_split-console-keypress.js b/devtools/client/debugger/test/mochitest/browser_dbg_split-console-keypress.js index df12e1668531..66c111ad8d36 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_split-console-keypress.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_split-console-keypress.js @@ -94,19 +94,4 @@ function test() { closeDebuggerAndFinish(gPanel); }); }); - - function getSplitConsole(toolbox, theDebugger) { - return new Promise(resolve => { - toolbox.once("webconsole-ready", () => { - let jsterm = toolbox.getPanel("webconsole").hud.jsterm; - resolve(jsterm); - }); - EventUtils.synthesizeKey("VK_ESCAPE", {}, theDebugger); - }); - } } - -registerCleanupFunction(() => { - // We don't want the open split console to confuse other tests.. - Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); -}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_worker-console.js b/devtools/client/debugger/test/mochitest/browser_dbg_worker-console.js new file mode 100644 index 000000000000..86e51d7f8c8c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_worker-console.js @@ -0,0 +1,145 @@ +// Check to make sure that a worker can be attached to a toolbox +// and that the console works. + +var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html"; +var WORKER_URL = "code_WorkerActor.attachThread-worker.js"; + +function* initWorkerDebugger(TAB_URL, WORKER_URL) { + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let client = new DebuggerClient(DebuggerServer.connectPipe()); + yield connect(client); + + let tab = yield addTab(TAB_URL); + let { tabs } = yield listTabs(client); + let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL)); + + yield createWorkerInTab(tab, WORKER_URL); + + let { workers } = yield listWorkers(tabClient); + let [, workerClient] = yield attachWorker(tabClient, + findWorker(workers, WORKER_URL)); + + let toolbox = yield gDevTools.showToolbox(TargetFactory.forWorker(workerClient), + "jsdebugger", + Toolbox.HostType.WINDOW); + + let debuggerPanel = toolbox.getCurrentPanel(); + let gDebugger = debuggerPanel.panelWin; + + return {client,tab,tabClient,workerClient,toolbox,gDebugger}; +} + +add_task(function* testNormalExecution() { + let {client,tab,tabClient,workerClient,toolbox,gDebugger} = + yield initWorkerDebugger(TAB_URL, WORKER_URL); + + let jsterm = yield getSplitConsole(toolbox); + let executed = yield jsterm.execute("this.location.toString()"); + ok(executed.textContent.includes(WORKER_URL), + "Evaluating the global's location works"); + + yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient)); + terminateWorkerInTab(tab, WORKER_URL); + yield waitForWorkerClose(workerClient); + yield close(client); + yield removeTab(tab); +}); + +add_task(function* testWhilePaused() { + let {client,tab,tabClient,workerClient,toolbox,gDebugger} = + yield initWorkerDebugger(TAB_URL, WORKER_URL); + + let gTarget = gDebugger.gTarget; + let gResumeButton = gDebugger.document.getElementById("resume"); + let gResumeKey = gDebugger.document.getElementById("resumeKey"); + + // Execute some basic math to make sure evaluations are working. + let jsterm = yield getSplitConsole(toolbox); + let executed = yield jsterm.execute("10000+1"); + ok(executed.textContent.includes("10001"), "Text for message appeared correct"); + + // Pause the worker by waiting for next execution and then sending a message to + // it from the main thread. + let oncePaused = gTarget.once("thread-paused"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + once(gDebugger.gClient, "willInterrupt").then(() => { + info("Posting message to worker, then waiting for a pause"); + postMessageToWorkerInTab(tab, WORKER_URL, "ping"); + }); + yield oncePaused; + + let command1 = jsterm.execute("10000+2"); + let command2 = jsterm.execute("10000+3"); + let command3 = jsterm.execute("foobar"); // throw an error + + info ("Trying to get the result of command1"); + executed = yield command1; + ok(executed.textContent.includes("10002"), + "command1 executed successfully"); + + info ("Trying to get the result of command2"); + executed = yield command2; + ok(executed.textContent.includes("10003"), + "command2 executed successfully"); + + info ("Trying to get the result of command3") + executed = yield command3; + // XXXworkers This is failing until Bug 1215120 is resolved. + todo(executed.textContent.includes("ReferenceError: foobar is not defined"), + "command3 executed successfully"); + + let onceResumed = gTarget.once("thread-resumed"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield onceResumed; + + yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient)); + terminateWorkerInTab(tab, WORKER_URL); + yield waitForWorkerClose(workerClient); + yield close(client); + yield removeTab(tab); +}); + +// Test to see if creating the pause from the console works. +add_task(function* testPausedByConsole() { + let {client,tab,tabClient,workerClient,toolbox,gDebugger} = + yield initWorkerDebugger(TAB_URL, WORKER_URL); + + let gTarget = gDebugger.gTarget; + let gResumeButton = gDebugger.document.getElementById("resume"); + let gResumeKey = gDebugger.document.getElementById("resumeKey"); + + let jsterm = yield getSplitConsole(toolbox); + let executed = yield jsterm.execute("10000+1"); + ok(executed.textContent.includes("10001"), + "Text for message appeared correct"); + + let oncePaused = gTarget.once("thread-paused"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + let pausedExecution = jsterm.execute("10000+2"); + + info("Executed a command with 'break on next' active, waiting for pause"); + yield oncePaused; + + executed = yield jsterm.execute("10000+3"); + ok(executed.textContent.includes("10003"), + "Text for message appeared correct"); + + info("Waiting for a resume"); + let onceResumed = gTarget.once("thread-resumed"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield onceResumed; + + executed = yield pausedExecution; + ok(executed.textContent.includes("10002"), + "Text for message appeared correct"); + + yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient)); + terminateWorkerInTab(tab, WORKER_URL); + yield waitForWorkerClose(workerClient); + yield close(client); + yield removeTab(tab); +}); diff --git a/devtools/client/debugger/test/mochitest/head.js b/devtools/client/debugger/test/mochitest/head.js index f1aa75815d57..673b16a73d7e 100644 --- a/devtools/client/debugger/test/mochitest/head.js +++ b/devtools/client/debugger/test/mochitest/head.js @@ -1190,3 +1190,28 @@ function afterDispatch(store, type) { }); }); } + +// Return a promise with a reference to jsterm, opening the split +// console if necessary. This cleans up the split console pref so +// it won't pollute other tests. +function getSplitConsole(toolbox, win) { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); + }); + + if (!win) { + win = toolbox.doc.defaultView; + } + + if (!toolbox.splitConsole) { + EventUtils.synthesizeKey("VK_ESCAPE", {}, win); + } + + return new Promise(resolve => { + toolbox.getPanelWhenReady("webconsole").then(() => { + ok(toolbox.splitConsole, "Split console is shown."); + let jsterm = toolbox.getPanel("webconsole").hud.jsterm; + resolve(jsterm); + }); + }); +} diff --git a/devtools/client/framework/target.js b/devtools/client/framework/target.js index d987f932830f..83356fc02241 100644 --- a/devtools/client/framework/target.js +++ b/devtools/client/framework/target.js @@ -732,8 +732,14 @@ WorkerTarget.prototype = { return this._workerClient.url; }, + get isWorkerTarget() { + return true; + }, + get form() { - return {}; + return { + consoleActor: this._workerClient.consoleActor + }; }, get activeTab() { diff --git a/devtools/client/webconsole/webconsole.js b/devtools/client/webconsole/webconsole.js index 2b6b71290db6..d33e5691544d 100644 --- a/devtools/client/webconsole/webconsole.js +++ b/devtools/client/webconsole/webconsole.js @@ -5033,13 +5033,17 @@ WebConsoleConnectionProxy.prototype = { let client = this.client = this.target.client; - client.addListener("logMessage", this._onLogMessage); - client.addListener("pageError", this._onPageError); - client.addListener("consoleAPICall", this._onConsoleAPICall); - client.addListener("fileActivity", this._onFileActivity); - client.addListener("reflowActivity", this._onReflowActivity); - client.addListener("serverLogCall", this._onServerLogCall); - client.addListener("lastPrivateContextExited", this._onLastPrivateContextExited); + if (this.target.isWorkerTarget) { + // XXXworkers: Not Console API yet inside of workers (Bug 1209353). + } else { + client.addListener("logMessage", this._onLogMessage); + client.addListener("pageError", this._onPageError); + client.addListener("consoleAPICall", this._onConsoleAPICall); + client.addListener("fileActivity", this._onFileActivity); + client.addListener("reflowActivity", this._onReflowActivity); + client.addListener("serverLogCall", this._onServerLogCall); + client.addListener("lastPrivateContextExited", this._onLastPrivateContextExited); + } this.target.on("will-navigate", this._onTabNavigated); this.target.on("navigate", this._onTabNavigated); diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index 26302c610cb9..2d5e6a407d43 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -6,35 +6,18 @@ "use strict"; +const Services = require("Services"); const { Cc, Ci, Cu } = require("chrome"); const { DebuggerServer, ActorPool } = require("devtools/server/main"); const { EnvironmentActor, ThreadActor } = require("devtools/server/actors/script"); const { ObjectActor, LongStringActor, createValueGrip, stringIsLong } = require("devtools/server/actors/object"); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Services", - "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyGetter(this, "NetworkMonitor", () => { - return require("devtools/shared/webconsole/network-monitor") - .NetworkMonitor; -}); -XPCOMUtils.defineLazyGetter(this, "NetworkMonitorChild", () => { - return require("devtools/shared/webconsole/network-monitor") - .NetworkMonitorChild; -}); -XPCOMUtils.defineLazyGetter(this, "ConsoleProgressListener", () => { - return require("devtools/shared/webconsole/network-monitor") - .ConsoleProgressListener; -}); -XPCOMUtils.defineLazyGetter(this, "events", () => { - return require("sdk/event/core"); -}); -XPCOMUtils.defineLazyGetter(this, "ServerLoggingListener", () => { - return require("devtools/shared/webconsole/server-logger") - .ServerLoggingListener; -}); +loader.lazyRequireGetter(this, "NetworkMonitor", "devtools/shared/webconsole/network-monitor", true); +loader.lazyRequireGetter(this, "NetworkMonitorChild", "devtools/shared/webconsole/network-monitor", true); +loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/shared/webconsole/network-monitor", true); +loader.lazyRequireGetter(this, "events", "sdk/event/core"); +loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true); for (let name of ["WebConsoleUtils", "ConsoleServiceListener", "ConsoleAPIListener", "addWebConsoleCommands", "JSPropertyProvider", @@ -44,7 +27,11 @@ for (let name of ["WebConsoleUtils", "ConsoleServiceListener", if (prop == "WebConsoleUtils") { prop = "Utils"; } - return require("devtools/shared/webconsole/utils")[prop]; + if (isWorker) { + return require("devtools/shared/webconsole/worker-utils")[prop]; + } else { + return require("devtools/shared/webconsole/utils")[prop]; + } }.bind(null, name), configurable: true, enumerable: true @@ -556,6 +543,11 @@ WebConsoleActor.prototype = */ onStartListeners: function WCA_onStartListeners(aRequest) { + // XXXworkers: Not handling the Console API yet for workers (Bug 1209353). + if (isWorker) { + aRequest.listeners = []; + } + let startedListeners = []; let window = !this.parentActor.isRootActor ? this.window : null; let appId = null; @@ -849,8 +841,12 @@ WebConsoleActor.prototype = } else if ("throw" in evalResult) { let error = evalResult.throw; errorGrip = this.createValueGrip(error); - errorMessage = error && (typeof error === "object") - ? error.unsafeDereference().toString() + // XXXworkers: Calling unsafeDereference() returns an object with no + // toString method in workers. See Bug 1215120. + let unsafeDereference = error && (typeof error === "object") && + error.unsafeDereference(); + errorMessage = unsafeDereference && unsafeDereference.toString + ? unsafeDereference.toString() : "" + error; } } @@ -899,8 +895,8 @@ WebConsoleActor.prototype = environment = frame.environment; } else { - Cu.reportError("Web Console Actor: the frame actor was not found: " + - frameActorId); + DevToolsUtils.reportException("onAutocomplete", + Error("The frame actor was not found: " + frameActorId)); } } // This is the general case (non-paused debugger) @@ -1043,9 +1039,13 @@ WebConsoleActor.prototype = } for (let name in helpers.sandbox) { let desc = Object.getOwnPropertyDescriptor(helpers.sandbox, name); - maybeExport(desc, 'get'); - maybeExport(desc, 'set'); - maybeExport(desc, 'value'); + + // Workers don't have access to Cu so won't be able to exportFunction. + if (!isWorker) { + maybeExport(desc, 'get'); + maybeExport(desc, 'set'); + maybeExport(desc, 'value'); + } if (desc.value) { // Make sure the helpers can be used during eval. desc.value = aDebuggerGlobal.makeDebuggeeValue(desc.value); @@ -1138,8 +1138,8 @@ WebConsoleActor.prototype = frame = frameActor.frame; } else { - Cu.reportError("Web Console Actor: the frame actor was not found: " + - aOptions.frameActor); + DevToolsUtils.reportException("evalWithDebugger", + Error("The frame actor was not found: " + aOptions.frameActor)); } } diff --git a/devtools/server/actors/worker.js b/devtools/server/actors/worker.js index 5af4c897e8f3..05b339ab292d 100644 --- a/devtools/server/actors/worker.js +++ b/devtools/server/actors/worker.js @@ -42,6 +42,7 @@ WorkerActor.prototype = { form: function () { return { actor: this.actorID, + consoleActor: this._consoleActor, url: this._dbg.url, type: this._dbg.type }; @@ -87,13 +88,15 @@ WorkerActor.prototype = { return DebuggerServer.connectToWorker( this.conn, this._dbg, this.actorID, request.options - ).then(({ threadActor, transport }) => { + ).then(({ threadActor, transport, consoleActor }) => { this._threadActor = threadActor; this._transport = transport; + this._consoleActor = consoleActor; return { type: "connected", - threadActor: this._threadActor + threadActor: this._threadActor, + consoleActor: this._consoleActor }; }, (error) => { return { error: error.toString() }; diff --git a/devtools/server/main.js b/devtools/server/main.js index d6fbf0a7b28a..8ef42ab64c32 100644 --- a/devtools/server/main.js +++ b/devtools/server/main.js @@ -833,7 +833,7 @@ var DebuggerServer = { // Steps 3-5 are performed on the worker thread (see worker.js). - // Step 6: Wait for a response from the worker debugger. + // Step 6: Wait for a connection response from the worker debugger. let listener = { onClose: () => { aDbg.removeListener(listener); @@ -843,19 +843,12 @@ var DebuggerServer = { onMessage: (message) => { let packet = JSON.parse(message); - if (packet.type !== "message" || packet.id !== aId) { - return; - } - - message = packet.message; - if (message.error) { - reject(error); - } - - if (message.type !== "paused") { + if (packet.type !== "connected" || packet.id !== aId) { return; } + // The initial connection packet has been received, don't + // need to listen any longer aDbg.removeListener(listener); // Step 7: Create a transport for the connection to the worker. @@ -887,7 +880,8 @@ var DebuggerServer = { aConnection.setForwarding(aId, transport); resolve({ - threadActor: message.from, + threadActor: packet.threadActor, + consoleActor: packet.consoleActor, transport: transport }); } diff --git a/devtools/server/worker.js b/devtools/server/worker.js index 499ffa579528..5b24a129e620 100644 --- a/devtools/server/worker.js +++ b/devtools/server/worker.js @@ -24,6 +24,7 @@ loadSubScript("resource://devtools/shared/worker/loader.js"); var Promise = worker.require("promise"); var { ActorPool } = worker.require("devtools/server/actors/common"); var { ThreadActor } = worker.require("devtools/server/actors/script"); +var { WebConsoleActor } = worker.require("devtools/server/actors/webconsole"); var { TabSources } = worker.require("devtools/server/actors/utils/TabSources"); var makeDebugger = worker.require("devtools/server/actors/utils/make-debugger"); var { DebuggerServer } = worker.require("devtools/server/main"); @@ -54,7 +55,7 @@ this.addEventListener("message", function (event) { let sources = null; - let actor = new ThreadActor({ + let parent = { makeDebugger: makeDebugger.bind(null, { findDebuggees: () => { return [this.global]; @@ -67,21 +68,28 @@ this.addEventListener("message", function (event) { get sources() { if (sources === null) { - sources = new TabSources(actor); + sources = new TabSources(threadActor); } return sources; - } - }, global); + }, - pool.addActor(actor); + window: global + }; - // Step 5: Attach to the thread actor. - // - // This will cause a packet to be sent over the connection to the parent. - // Because this connection uses WorkerDebuggerTransport internally, this - // packet will be sent using WorkerDebuggerGlobalScope.postMessage, causing - // an onMessage event to be fired on the WorkerDebugger in the main thread. - actor.onAttach({}); + let threadActor = new ThreadActor(parent, global); + pool.addActor(threadActor); + + let consoleActor = new WebConsoleActor(connection, parent); + pool.addActor(consoleActor); + + // Step 5: Send a response packet to the parent to notify + // it that a connection has been established. + postMessage(JSON.stringify({ + type: "connected", + id: packet.id, + threadActor: threadActor.actorID, + consoleActor: consoleActor.actorID, + })); break; case "disconnect": diff --git a/devtools/shared/client/main.js b/devtools/shared/client/main.js index 173b980ae14f..420777f55fc2 100644 --- a/devtools/shared/client/main.js +++ b/devtools/shared/client/main.js @@ -1391,20 +1391,36 @@ WorkerClient.prototype = { DevToolsUtils.executeSoon(() => aOnResponse({ type: "connected", threadActor: this.thread._actor, + consoleActor: this.consoleActor, }, this.thread)); return; } + // The connect call on server doesn't attach the thread as of version 44. this.request({ to: this._actor, type: "connect", options: aOptions, - }, (aResponse) => { - if (!aResponse.error) { - this.thread = new ThreadClient(this, aResponse.threadActor); - this.client.registerClient(this.thread); + }, (connectReponse) => { + if (connectReponse.error) { + aOnResponse(connectReponse, null); + return; } - aOnResponse(aResponse, this.thread); + + this.request({ + to: connectReponse.threadActor, + type: "attach" + }, (attachResponse) => { + if (attachResponse.error) { + aOnResponse(attachResponse, null); + } + + this.thread = new ThreadClient(this, connectReponse.threadActor); + this.consoleActor = connectReponse.consoleActor; + this.client.registerClient(this.thread); + + aOnResponse(connectReponse, this.thread); + }); }); }, diff --git a/devtools/shared/webconsole/client.js b/devtools/shared/webconsole/client.js index 39d148a96d02..bdfd289741cf 100644 --- a/devtools/shared/webconsole/client.js +++ b/devtools/shared/webconsole/client.js @@ -296,6 +296,13 @@ WebConsoleClient.prototype = { * Handler for the actors's unsolicited evaluationResult packet. */ onEvaluationResult: function(aNotification, aPacket) { + // The client on the main thread can receive notification packets from + // multiple webconsole actors: the one on the main thread and the ones + // on worker threads. So make sure we should be handling this request. + if (aPacket.from !== this._actor) { + return; + } + // Find the associated callback based on this ID, and fire it. // In a sync evaluation, this would have already been called in // direct response to the client.request function. diff --git a/devtools/shared/webconsole/moz.build b/devtools/shared/webconsole/moz.build index e068645865ca..d7d1908bf9dd 100644 --- a/devtools/shared/webconsole/moz.build +++ b/devtools/shared/webconsole/moz.build @@ -15,4 +15,5 @@ DevToolsModules( 'server-logger-monitor.js', 'server-logger.js', 'utils.js', + 'worker-utils.js', ) diff --git a/devtools/shared/webconsole/worker-utils.js b/devtools/shared/webconsole/worker-utils.js new file mode 100644 index 000000000000..5a3880c32341 --- /dev/null +++ b/devtools/shared/webconsole/worker-utils.js @@ -0,0 +1,13 @@ +// XXXworkers This file is loaded on the server side for worker debugging. +// Since the server is running in the worker thread, it doesn't +// have access to Services / Components. This functionality +// is stubbed out to prevent errors, and will need to implemented +// for Bug 1209353. + +exports.Utils = { l10n: function() {} }; +exports.ConsoleServiceListener = function() {}; +exports.ConsoleAPIListener = function() {}; +exports.addWebConsoleCommands = function() {}; +exports.JSPropertyProvider = function() {}; +exports.ConsoleReflowListener = function() {}; +exports.CONSOLE_WORKER_IDS = []; diff --git a/devtools/shared/worker/loader.js b/devtools/shared/worker/loader.js index e61c00b3ed0b..9c6b67cf627c 100644 --- a/devtools/shared/worker/loader.js +++ b/devtools/shared/worker/loader.js @@ -442,8 +442,12 @@ var { let scope = this; let xpcInspector = { + get eventLoopNestLevel() { + return requestors.length; + }, + get lastNestRequestor() { - return requestors.length === 0 ? null : requestors[0]; + return requestors.length === 0 ? null : requestors[requestors.length - 1]; }, enterNestedEventLoop: function (requestor) {