Chromium Code Reviews| Index: Source/devtools/front_end/DOMAgent.js |
| diff --git a/Source/devtools/front_end/DOMAgent.js b/Source/devtools/front_end/DOMAgent.js |
| index 45467bc785d2b124fa86413c1df121a4feaaf940..e514613674bae9b2f99c2ae9eb220c4c2d357018 100644 |
| --- a/Source/devtools/front_end/DOMAgent.js |
| +++ b/Source/devtools/front_end/DOMAgent.js |
| @@ -119,13 +119,13 @@ WebInspector.DOMNode.PseudoElementNames = { |
| * @param {string} value |
| * @param {boolean} optimized |
| */ |
| -WebInspector.DOMNode.XPathStep = function(value, optimized) |
| +WebInspector.DOMNode.PathStep = function(value, optimized) |
| { |
| this.value = value; |
| this.optimized = optimized; |
| } |
| -WebInspector.DOMNode.XPathStep.prototype = { |
| +WebInspector.DOMNode.PathStep.prototype = { |
| toString: function() |
| { |
| return this.value; |
| @@ -416,6 +416,14 @@ WebInspector.DOMNode.prototype = { |
| /** |
| * @param {boolean} optimized |
| */ |
| + copyCSSPath: function(optimized) |
| + { |
| + InspectorFrontendHost.copyText(this.cssPath(optimized)); |
| + }, |
| + |
| + /** |
| + * @param {boolean} optimized |
| + */ |
| copyXPath: function(optimized) |
| { |
| InspectorFrontendHost.copyText(this.xPath(optimized)); |
| @@ -671,6 +679,95 @@ WebInspector.DOMNode.prototype = { |
| * @param {boolean} optimized |
| * @return {string} |
| */ |
| + cssPath: function(optimized) |
| + { |
| + if (this._nodeType !== Node.ELEMENT_NODE) |
| + return ""; |
| + |
| + var steps = []; |
| + var contextNode = this; |
| + while (contextNode) { |
| + var step = contextNode._cssPathValue(optimized); |
| + if (!step) |
| + break; // Error - bail out early. |
| + steps.push(step); |
| + if (step.optimized) |
| + break; |
| + contextNode = contextNode.parentNode; |
| + } |
| + |
| + steps.reverse(); |
| + return steps.join(" > "); |
| + }, |
| + |
| + /** |
| + * @param {boolean} optimized |
| + * @return {WebInspector.DOMNode.PathStep} |
| + */ |
| + _cssPathValue: function(optimized) |
| + { |
| + if (this._nodeType !== Node.ELEMENT_NODE) |
| + return null; |
| + if (optimized) { |
| + if (this.getAttribute("id")) |
| + return new WebInspector.DOMNode.PathStep("#" + this.getAttribute("id"), true); |
| + var nodeNameLower = this._nodeName.toLowerCase(); |
| + if (nodeNameLower === "body" || nodeNameLower === "head" || nodeNameLower === "html") |
| + return new WebInspector.DOMNode.PathStep(this.nodeNameInCorrectCase(), true); |
| + } |
| + var ownValue = this.nodeNameInCorrectCase(); |
| + var parent = this.parentNode; |
| + if (!parent || parent._nodeType === Node.DOCUMENT_NODE) |
| + return new WebInspector.DOMNode.PathStep(ownValue, true); |
| + |
| + var nodeName = this.nodeNameInCorrectCase(); |
|
aandrey
2013/11/18 13:43:51
move above and get rid of ownValue
apavlov
2013/11/18 15:03:59
Done.
|
| + var uniqueClassNamesArray = (this.getAttribute("class") || "").split(/\s+/g); |
|
aandrey
2013/11/18 13:43:51
this array is not unique, and can contain empty st
apavlov
2013/11/18 15:03:59
It is not unique, but it cannot contain empty stri
aandrey
2013/11/18 15:15:56
FYI.
a = document.createElement("div");
a.classNa
|
| + var uniqueClassNamesLeft = uniqueClassNamesArray.length; |
| + var uniqueClassNames = uniqueClassNamesArray.keySet(); |
| + var needsClassNames; |
|
aandrey
2013/11/18 13:43:51
plz init (with "false" I believe?)
apavlov
2013/11/18 15:03:59
Done.
|
| + var needsNthChild; |
|
aandrey
2013/11/18 13:43:51
ditto
apavlov
2013/11/18 15:03:59
Done.
|
| + var ownIndex = -1; |
| + var siblings = parent.children(); |
| + for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) { |
| + var sibling = siblings[i]; |
| + if (sibling === this) { |
| + ownIndex = i; |
| + continue; |
| + } |
| + if (sibling.nodeNameInCorrectCase() !== nodeName) |
| + continue; |
| + if (!uniqueClassNamesLeft) { |
| + needsNthChild = true; |
| + continue; |
| + } |
| + |
| + needsClassNames = true; |
| + var siblingClasses = (sibling.getAttribute("class") || "").split(/\s+/g).keySet(); |
|
aandrey
2013/11/18 13:43:51
code dup, plz extract
apavlov
2013/11/18 15:03:59
Done.
|
| + for (var siblingClass in siblingClasses) { |
| + if (!uniqueClassNames.hasOwnProperty(siblingClass)) |
| + continue; |
| + delete uniqueClassNames[siblingClass]; |
| + if (!--uniqueClassNamesLeft) { |
|
aandrey
2013/11/18 13:43:51
Did you mean uniqueClassNamesLeft to be initialize
apavlov
2013/11/18 15:03:59
Yep. Fixed
|
| + needsNthChild = true; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + var result = nodeName; |
| + if (needsClassNames && uniqueClassNamesLeft) { |
| + for (var className in uniqueClassNames) |
| + result += "." + className; |
| + } |
| + if (needsNthChild) |
| + result += ":nth-child(" + (ownIndex + 1) + ")"; |
| + return new WebInspector.DOMNode.PathStep(result, false); |
| + }, |
| + |
| + /** |
| + * @param {boolean} optimized |
| + * @return {string} |
| + */ |
| xPath: function(optimized) |
| { |
| if (this._nodeType === Node.DOCUMENT_NODE) |
| @@ -694,7 +791,7 @@ WebInspector.DOMNode.prototype = { |
| /** |
| * @param {boolean} optimized |
| - * @return {WebInspector.DOMNode.XPathStep} |
| + * @return {WebInspector.DOMNode.PathStep} |
| */ |
| _xPathValue: function(optimized) |
| { |
| @@ -706,7 +803,7 @@ WebInspector.DOMNode.prototype = { |
| switch (this._nodeType) { |
| case Node.ELEMENT_NODE: |
| if (optimized && this.getAttribute("id")) |
| - return new WebInspector.DOMNode.XPathStep("//*[@id=\"" + this.getAttribute("id") + "\"]", true); |
| + return new WebInspector.DOMNode.PathStep("//*[@id=\"" + this.getAttribute("id") + "\"]", true); |
| ownValue = this._localName; |
| break; |
| case Node.ATTRIBUTE_NODE: |
| @@ -733,7 +830,7 @@ WebInspector.DOMNode.prototype = { |
| if (ownIndex > 0) |
| ownValue += "[" + ownIndex + "]"; |
| - return new WebInspector.DOMNode.XPathStep(ownValue, this._nodeType === Node.DOCUMENT_NODE); |
| + return new WebInspector.DOMNode.PathStep(ownValue, this._nodeType === Node.DOCUMENT_NODE); |
| }, |
| /** |