Skip to content

Commit

Permalink
Use XPath to select elements (#1056)
Browse files Browse the repository at this point in the history
This renames the `inspectDOMElement` API to `inspectDOMNode`, and
changes the argument from a CSS selector to an XPath selector.

The problem with CSS selectors are that they only support selecting
elements, whereas XPath allows us to select any arbitrary DOM node,
including text nodes, comments etc.

This commit sets a better foundation for supporting things other
than classic components. Since Glimmer components, route templates,
"tagless" classic components etc have "outer HTML" semantics, they
don't necessarily have a single element. Going forward, we will
likely want to select the first node in a component's "bounds",
which could be an arbitrary DOM node (i.e. may or may not be an
element node, so CSS selectors are not sufficient).
  • Loading branch information
chancancode authored and RobbieTheWagner committed Nov 5, 2019
1 parent 0058477 commit 3357dff
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 16 deletions.
10 changes: 5 additions & 5 deletions app/adapters/web-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ export default BasicAdapter.extend({
},

/**
* Open the devtools "Elements" tab and select a specific DOM element.
* Open the devtools "Elements" tab and select a specific DOM node.
*
* @method inspectDOMElement
* @param {String} selector jQuery selector
* @method inspectDOMNode
* @param {String} selector XPath selector
*/
inspectDOMElement(selector) {
chrome.devtools.inspectedWindow.eval(`inspect($('${selector}')[0])`);
inspectDOMNode(selector) {
chrome.devtools.inspectedWindow.eval(`inspect($x('${selector}')[0])`);
},

/**
Expand Down
8 changes: 4 additions & 4 deletions app/routes/component-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default TabRoute.extend({
this.port.on('view:viewTree', this, this.setViewTree);
this.port.on('view:stopInspecting', this, this.stopInspecting);
this.port.on('view:startInspecting', this, this.startInspecting);
this.port.on('view:inspectDOMElement', this, this.inspectDOMElement);
this.port.on('view:inspectDOMNode', this, this.inspectDOMNode);

this.set('controller.viewTreeLoaded', false);
this.port.send('view:setOptions', { options: this.get('controller.options') });
Expand All @@ -27,7 +27,7 @@ export default TabRoute.extend({
this.port.off('view:viewTree', this, this.setViewTree);
this.port.off('view:stopInspecting', this, this.stopInspecting);
this.port.off('view:startInspecting', this, this.startInspecting);
this.port.off('view:inspectDOMElement', this, this.inspectDOMElement);
this.port.off('view:inspectDOMNode', this, this.inspectDOMNode);
},

setViewTree(options) {
Expand Down Expand Up @@ -57,8 +57,8 @@ export default TabRoute.extend({
this.set('controller.inspectingViews', false);
},

inspectDOMElement({ elementSelector }) {
this.get('port.adapter').inspectDOMElement(elementSelector);
inspectDOMNode({ selector }) {
this.get('port.adapter').inspectDOMNode(selector);
},

actions: {
Expand Down
4 changes: 2 additions & 2 deletions ember_debug/adapters/web-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export default BasicAdapter.extend({
*/
inspectElement(elem) {
/* inspect(elem); */
this.get('namespace.port').send('view:inspectDOMElement', {
elementSelector: `#${elem.getAttribute('id')}`
this.get('namespace.port').send('view:inspectDOMNode', {
selector: `//*[@id="${elem.getAttribute('id')}"]`
});
},

Expand Down
6 changes: 4 additions & 2 deletions skeletons/firefox/lib/devtools-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ exports.openDevTool = function(toolId) {
return gDevToolsBrowser.selectToolCommand(gBrowser, toolId);
};

exports.inspectDOMElement = function(target, selector, toolId) {
exports.inspectDOMNode = function(target, selector, toolId) {
return gDevTools.showToolbox(target, "inspector").then(toolbox => {
let sel = toolbox.getCurrentPanel().selection;
sel.setNode(sel.document.querySelector(selector), toolId);
let doc = sel.document;
let result = doc.evaluate(selector, doc, null, 9 /* FIRST_ORDERED_NODE_TYPE */);
sel.setNode(result.singleNodeValue, toolId);
});
};

Expand Down
6 changes: 3 additions & 3 deletions skeletons/firefox/lib/tomster-devtool-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const logError = curry(function log(msg, e) {
console.error("ember-extensions: " + msg, e);
});

const { openDevTool, inspectDOMElement, openSource,
const { openDevTool, inspectDOMNode, openSource,
evaluateFileOnTargetWindow } = require("./devtools-utils");

var Promise = require("sdk/core/promise.js");
Expand Down Expand Up @@ -133,9 +133,9 @@ let EmberInspector = Class({

log("_handleTargetTabMessage", msg);

if (msg.type === "view:devtools:inspectDOMElement") {
if (msg.type === "view:devtools:inspectDOMNode") {
// polyfill missing inspect function in content-script
inspectDOMElement(this.toolbox._target, msg.elementSelector,
inspectDOMNode(this.toolbox._target, msg.selector,
exports.devtoolTabDefinition.id);
} else {
// route to devtool panel
Expand Down

0 comments on commit 3357dff

Please sign in to comment.