Bug 1326753 - Fix inspect node from browser context menu against elements in iframes. r=pbro
MozReview-Commit-ID: C4dvnISlneS
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -235,30 +235,53 @@ var gDevToolsBrowser = exports.gDevTools
win.focus();
} else {
Services.ww.openWindow(null, "chrome://webide/content/", "webide", "chrome,centerscreen,resizable", null);
}
},
inspectNode: function (tab, node) {
let target = TargetFactory.forTab(tab);
- let selector = findCssSelector(node);
+
+ // Generate a cross iframes query selector
+ let selectors = [];
+ while(node) {
+ selectors.push(findCssSelector(node));
+ node = node.ownerDocument.defaultView.frameElement;
+ }
return gDevTools.showToolbox(target, "inspector").then(toolbox => {
let inspector = toolbox.getCurrentPanel();
// new-node-front tells us when the node has been selected, whether the
// browser is remote or not.
let onNewNode = inspector.selection.once("new-node-front");
- inspector.walker.getRootNode().then(rootNode => {
- return inspector.walker.querySelector(rootNode, selector);
- }).then(node => {
- inspector.selection.setNodeFront(node, "browser-context-menu");
- });
+ // Evaluate the cross iframes query selectors
+ function querySelectors(nodeFront) {
+ let selector = selectors.pop();
+ if (!selector) {
+ return Promise.resolve(nodeFront);
+ }
+ return inspector.walker.querySelector(nodeFront, selector)
+ .then(node => {
+ if (selectors.length > 0) {
+ return inspector.walker.children(node).then(({ nodes }) => {
+ return nodes[0]; // This is the NodeFront for the document node inside the iframe
+ });
+ }
+ return node;
+ }).then(querySelectors);
+ }
+ inspector.walker.getRootNode()
+ .then(querySelectors)
+ .then(node => {
+ // Select the final node
+ inspector.selection.setNodeFront(node, "browser-context-menu");
+ });
return onNewNode.then(() => {
// Now that the node has been selected, wait until the inspector is
// fully updated.
return inspector.once("inspector-updated");
});
});
},
--- a/devtools/client/inspector/test/browser.ini
+++ b/devtools/client/inspector/test/browser.ini
@@ -114,16 +114,17 @@ subsuite = clipboard
[browser_inspector_iframe-navigation.js]
[browser_inspector_infobar_01.js]
[browser_inspector_infobar_02.js]
[browser_inspector_infobar_03.js]
[browser_inspector_infobar_textnode.js]
[browser_inspector_initialization.js]
skip-if = (e10s && debug) # Bug 1250058 - Docshell leak on debug e10s
[browser_inspector_inspect-object-element.js]
+[browser_inspector_inspect_node_contextmenu.js]
[browser_inspector_invalidate.js]
[browser_inspector_keyboard-shortcuts-copy-outerhtml.js]
subsuite = clipboard
[browser_inspector_keyboard-shortcuts.js]
[browser_inspector_menu-01-sensitivity.js]
subsuite = clipboard
[browser_inspector_menu-02-copy-items.js]
subsuite = clipboard
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_inspect_node_contextmenu.js
@@ -0,0 +1,38 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* globals getTestActorWithoutToolbox */
+"use strict";
+
+// Tests for inspect node in browser context menu
+
+const FRAME_URI = "data:text/html;charset=utf-8," +
+ encodeURI(`<div id="in-frame">div in the iframe</div>`);
+const HTML = `
+ <div id="salutation">Salution in top document</div>
+ <iframe src="${FRAME_URI}"></iframe>
+`;
+
+const TEST_URI = "data:text/html;charset=utf-8," + encodeURI(HTML);
+
+add_task(function* () {
+ let tab = yield addTab(TEST_URI);
+ let testActor = yield getTestActorWithoutToolbox(tab);
+
+ yield testContextMenuWithinIframe(testActor);
+});
+
+function* testContextMenuWithinIframe(testActor) {
+ info("Opening inspector via 'Inspect Element' context menu item within an iframe");
+ let selector = ["iframe", "#in-frame"];
+ yield clickOnInspectMenuItem(testActor, selector);
+
+ info("Checking inspector state.");
+ let inspector = getActiveInspector();
+ let nodeFront = yield getNodeFrontInFrame("#in-frame", "iframe", inspector);
+
+ is(inspector.selection.nodeFront, nodeFront,
+ "Right node is selected in the markup view");
+}