Bug 1326753 - Fix inspect node from browser context menu against elements in iframes. r=pbro
authorAlexandre Poirot <poirot.alex@gmail.com>
Wed, 18 Jan 2017 22:08:10 +0100
changeset 377309 2b174f46eb04be4bb428dbf21c82e03efdb5bb91
parent 377308 7400d6afc2d2190e9276647a944f35008dfdf267
child 377310 0cfe2272eecbf0e06349986e5df7873bf5da65df
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1326753
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1326753 - Fix inspect node from browser context menu against elements in iframes. r=pbro MozReview-Commit-ID: C4dvnISlneS
devtools/client/framework/devtools-browser.js
devtools/client/inspector/test/browser.ini
devtools/client/inspector/test/browser_inspector_inspect_node_contextmenu.js
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -290,30 +290,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
@@ -115,16 +115,17 @@ skip-if = (os == 'linux' && bits == 32 &
 [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
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_inspector_keyboard-shortcuts.js]
 [browser_inspector_menu-01-sensitivity.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
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");
+}