зеркало из https://github.com/mozilla/gecko-dev.git
Bug 701419 - Add a "Copy Unique Selector" option in the inspected element's menu and the corresponding test. f=paul r=jwalker
This commit is contained in:
Родитель
789442d7d4
Коммит
a9ab361602
|
@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
Cu.import("resource:///modules/devtools/EventEmitter.jsm");
|
||||
Cu.import("resource:///modules/devtools/CssLogic.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MarkupView",
|
||||
"resource:///modules/devtools/MarkupView.jsm");
|
||||
|
@ -645,6 +646,21 @@ InspectorPanel.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy a unique selector of the selected Node to the clipboard.
|
||||
*/
|
||||
copyUniqueSelector: function InspectorPanel_copyUniqueSelector()
|
||||
{
|
||||
if (!this.selection.isNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let toCopy = CssLogic.findCssSelector(this.selection.node);
|
||||
if (toCopy) {
|
||||
clipboardHelper.copyString(toCopy);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the selected node.
|
||||
*/
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
label="&inspectorHTMLCopyOuter.label;"
|
||||
accesskey="&inspectorHTMLCopyOuter.accesskey;"
|
||||
oncommand="inspector.copyOuterHTML()"/>
|
||||
<menuitem id="node-menu-copyuniqueselector"
|
||||
label="&inspectorCopyUniqueSelector.label;"
|
||||
accesskey="&inspectorCopyUniqueSelector.accesskey;"
|
||||
oncommand="inspector.copyUniqueSelector()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="node-menu-delete"
|
||||
label="&inspectorHTMLDelete.label;"
|
||||
|
|
|
@ -56,6 +56,15 @@ function test() {
|
|||
|
||||
waitForClipboard("<p>This is some example text</p>",
|
||||
function() { copyOuter.doCommand(); },
|
||||
testCopyUniqueSelectorMenu, testCopyUniqueSelectorMenu);
|
||||
}
|
||||
|
||||
function testCopyUniqueSelectorMenu() {
|
||||
let copyUniqueSelector = inspector.panelDoc.getElementById("node-menu-copyuniqueselector");
|
||||
ok(copyUniqueSelector, "the popup menu has a copy unique selector menu item");
|
||||
|
||||
waitForClipboard("body > div:nth-child(1) > p:nth-child(2)",
|
||||
function() { copyUniqueSelector.doCommand(); },
|
||||
testDeleteNode, testDeleteNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -821,6 +821,80 @@ CssLogic.shortSource = function CssLogic_shortSource(aSheet)
|
|||
return dataUrl ? dataUrl[1] : aSheet.href;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the position of [element] in [nodeList].
|
||||
* @returns an index of the match, or -1 if there is no match
|
||||
*/
|
||||
function positionInNodeList(element, nodeList) {
|
||||
for (var i = 0; i < nodeList.length; i++) {
|
||||
if (element === nodeList[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a unique CSS selector for a given element
|
||||
* @returns a string such that ele.ownerDocument.querySelector(reply) === ele
|
||||
* and ele.ownerDocument.querySelectorAll(reply).length === 1
|
||||
*/
|
||||
CssLogic.findCssSelector = function CssLogic_findCssSelector(ele) {
|
||||
var document = ele.ownerDocument;
|
||||
if (ele.id && document.getElementById(ele.id) === ele) {
|
||||
return '#' + ele.id;
|
||||
}
|
||||
|
||||
// Inherently unique by tag name
|
||||
var tagName = ele.tagName.toLowerCase();
|
||||
if (tagName === 'html') {
|
||||
return 'html';
|
||||
}
|
||||
if (tagName === 'head') {
|
||||
return 'head';
|
||||
}
|
||||
if (tagName === 'body') {
|
||||
return 'body';
|
||||
}
|
||||
|
||||
if (ele.parentNode == null) {
|
||||
console.log('danger: ' + tagName);
|
||||
}
|
||||
|
||||
// We might be able to find a unique class name
|
||||
var selector, index, matches;
|
||||
if (ele.classList.length > 0) {
|
||||
for (var i = 0; i < ele.classList.length; i++) {
|
||||
// Is this className unique by itself?
|
||||
selector = '.' + ele.classList.item(i);
|
||||
matches = document.querySelectorAll(selector);
|
||||
if (matches.length === 1) {
|
||||
return selector;
|
||||
}
|
||||
// Maybe it's unique with a tag name?
|
||||
selector = tagName + selector;
|
||||
matches = document.querySelectorAll(selector);
|
||||
if (matches.length === 1) {
|
||||
return selector;
|
||||
}
|
||||
// Maybe it's unique using a tag name and nth-child
|
||||
index = positionInNodeList(ele, ele.parentNode.children) + 1;
|
||||
selector = selector + ':nth-child(' + index + ')';
|
||||
matches = document.querySelectorAll(selector);
|
||||
if (matches.length === 1) {
|
||||
return selector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// So we can be unique w.r.t. our parent, and use recursion
|
||||
index = positionInNodeList(ele, ele.parentNode.children) + 1;
|
||||
selector = CssLogic_findCssSelector(ele.parentNode) + ' > ' +
|
||||
tagName + ':nth-child(' + index + ')';
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
/**
|
||||
* A safe way to access cached bits of information about a stylesheet.
|
||||
*
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
<!ENTITY inspectorHTMLCopyOuter.label "Copy Outer HTML">
|
||||
<!ENTITY inspectorHTMLCopyOuter.accesskey "O">
|
||||
|
||||
<!ENTITY inspectorCopyUniqueSelector.label "Copy Unique Selector">
|
||||
<!ENTITY inspectorCopyUniqueSelector.accesskey "U">
|
||||
|
||||
<!ENTITY inspectorHTMLDelete.label "Delete Node">
|
||||
<!ENTITY inspectorHTMLDelete.accesskey "D">
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче