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); |
}, |
/** |