diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index d2f1cbf5c314..471b67328f94 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -3389,23 +3389,21 @@ Toolbox.prototype = { objectActor.preview && objectActor.preview.nodeType === domNodeConstants.ELEMENT_NODE ) { - // Open the inspector and select the DOM Element. - await this.loadTool("inspector"); - const inspector = this.getPanel("inspector"); - const nodeFound = await inspector.inspectNodeActor( - objectActor.actor, - inspectFromAnnotation - ); - if (nodeFound) { - await this.selectTool("inspector"); - } - } else if ( - objectActor.type !== "null" && - objectActor.type !== "undefined" - ) { + return this.viewElementInInspector(objectActor, inspectFromAnnotation); + } + + if (objectActor.class == "Function") { + const { url, line } = objectActor.location; + return this.viewSourceInDebugger(url, line); + } + + if (objectActor.type !== "null" && objectActor.type !== "undefined") { // Open then split console and inspect the object in the variables view, // when the objectActor doesn't represent an undefined or null value. - await this.openSplitConsole(); + if (this.currentToolId != "webconsole") { + await this.openSplitConsole(); + } + const panel = this.getPanel("webconsole"); panel.hud.ui.inspectObjectActor(objectActor); } @@ -3795,6 +3793,19 @@ Toolbox.prototype = { ); }, + viewElementInInspector: async function(objectActor, inspectFromAnnotation) { + // Open the inspector and select the DOM Element. + await this.loadTool("inspector"); + const inspector = this.getPanel("inspector"); + const nodeFound = await inspector.inspectNodeActor( + objectActor.actor, + inspectFromAnnotation + ); + if (nodeFound) { + await this.selectTool("inspector"); + } + }, + /** * Opens source in debugger. Falls back to plain "view-source:". * @see devtools/client/shared/source-utils.js diff --git a/devtools/client/webconsole/test/browser/browser.ini b/devtools/client/webconsole/test/browser/browser.ini index 83e75081fa3d..3318ad94f5d3 100644 --- a/devtools/client/webconsole/test/browser/browser.ini +++ b/devtools/client/webconsole/test/browser/browser.ini @@ -130,6 +130,8 @@ support-files = test-non-javascript-mime-worker.html test-primitive-stacktrace.html test-reopen-closed-tab.html + test-simple-function.html + test-simple-function.js test-sourcemap-error-01.html test-sourcemap-error-01.js test-sourcemap-error-02.html diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_inspect.js b/devtools/client/webconsole/test/browser/browser_jsterm_inspect.js index 8ee4a33c3dd6..92fe9c649ce8 100644 --- a/devtools/client/webconsole/test/browser/browser_jsterm_inspect.js +++ b/devtools/client/webconsole/test/browser/browser_jsterm_inspect.js @@ -5,21 +5,75 @@ "use strict"; -const TEST_URI = "data:text/html;charset=utf8,
test inspect() command"; +const TEST_URI = + "https://example.com/browser/devtools/client/webconsole/test/browser/" + + "test-simple-function.html"; add_task(async function() { - const hud = await openNewTabAndConsole(TEST_URI); + let hud = await openNewTabAndConsole(TEST_URI); + const toolbox = gDevTools.getToolbox(hud.target); + await testInspectingElement(hud, toolbox); + await testInspectingFunction(hud, toolbox); + + hud = await openNewTabAndConsole(TEST_URI); + await testInspectingWindow(hud); + await testInspectIngPrimitive(hud); +}); + +async function testInspectingElement(hud, toolbox) { + info("Test `inspect(el)`"); + execute(hud, "inspect(document.querySelector('p'))"); + await waitForSelectedElementInInspector(toolbox, "p"); + ok(true, "inspected element is now selected in the inspector"); +} + +async function testInspectingFunction(hud, toolbox) { + info("Test `inspect(test)`"); + execute(hud, "inspect(test)"); + + await waitFor(() => { + const dbg = toolbox.getPanel("jsdebugger"); + if (!dbg) { + return false; + } + + const selectedLocation = dbg._selectors.getSelectedLocation( + dbg._getState() + ); + + if (!selectedLocation) { + return false; + } + + return ( + selectedLocation.sourceId.includes("test-simple-function.js") && + selectedLocation.line == 3 + ); + }); + + ok(true, "inspected function is now selected in the debugger"); +} + +async function testInspectingWindow(hud) { info("Test `inspect(window)`"); // Add a global value so we can check it later. execute(hud, "testProp = 'testValue'"); execute(hud, "inspect(window)"); - const inspectWindowNode = await waitFor(() => - findInspectResultMessage(hud.ui.outputNode, 1) - ); + const objectInspectors = await waitFor(() => { + const message = findInspectResultMessage(hud.ui.outputNode, 1); + if (!message) { + return false; + } + + const treeEls = message.querySelectorAll(".tree"); + if (treeEls.length == 0) { + return false; + } + return [...treeEls]; + }); - const objectInspectors = [...inspectWindowNode.querySelectorAll(".tree")]; is( objectInspectors.length, 1, @@ -55,8 +109,9 @@ add_task(async function() { '"testValue"', "The testProp property value is displayed as expected" ); +} - /* Check that a primitive value can be inspected, too */ +async function testInspectIngPrimitive(hud) { info("Test `inspect(1)`"); execute(hud, "inspect(1)"); @@ -68,8 +123,24 @@ add_task(async function() { 1, "The primitive is displayed as expected" ); -}); +} function findInspectResultMessage(node, index) { return node.querySelectorAll(".message.result")[index]; } + +async function waitForSelectedElementInInspector(toolbox, displayName) { + return waitFor(() => { + const inspector = toolbox.getPanel("inspector"); + if (!inspector) { + return false; + } + + const selection = inspector.selection; + return ( + selection && + selection.nodeFront && + selection.nodeFront.displayName == displayName + ); + }); +} diff --git a/devtools/client/webconsole/test/browser/test-simple-function.html b/devtools/client/webconsole/test/browser/test-simple-function.html new file mode 100644 index 000000000000..1c328fbb5ff2 --- /dev/null +++ b/devtools/client/webconsole/test/browser/test-simple-function.html @@ -0,0 +1,9 @@ + + +
+ + + +Test inspecting an element
+ + diff --git a/devtools/client/webconsole/test/browser/test-simple-function.js b/devtools/client/webconsole/test/browser/test-simple-function.js new file mode 100644 index 000000000000..770a19bc99cd --- /dev/null +++ b/devtools/client/webconsole/test/browser/test-simple-function.js @@ -0,0 +1,5 @@ +"use strict"; + +window.test = function() { + console.log("simple function"); +}; diff --git a/devtools/client/webconsole/webconsole-wrapper.js b/devtools/client/webconsole/webconsole-wrapper.js index e709cfbfd10b..1221b52b9cf7 100644 --- a/devtools/client/webconsole/webconsole-wrapper.js +++ b/devtools/client/webconsole/webconsole-wrapper.js @@ -235,7 +235,13 @@ class WebConsoleWrapper { }, getMappedExpression: this.hud.getMappedExpression.bind(this.hud), getPanelWindow: () => webConsoleUI.window, - inspectObjectActor: webConsoleUI.inspectObjectActor.bind(webConsoleUI), + inspectObjectActor: objectActor => { + if (this.toolbox) { + this.toolbox.inspectObjectActor(objectActor); + } else { + webConsoleUI.inspectObjectActor(objectActor); + } + }, }; // Set `openContextMenu` this way so, `serviceContainer` variable