Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Joseph Pecoraro | 3 * Copyright (C) 2009 Joseph Pecoraro |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 WebInspector.DOMNode.PseudoElementNames = { | 112 WebInspector.DOMNode.PseudoElementNames = { |
| 113 Before: "before", | 113 Before: "before", |
| 114 After: "after" | 114 After: "after" |
| 115 } | 115 } |
| 116 | 116 |
| 117 /** | 117 /** |
| 118 * @constructor | 118 * @constructor |
| 119 * @param {string} value | 119 * @param {string} value |
| 120 * @param {boolean} optimized | 120 * @param {boolean} optimized |
| 121 */ | 121 */ |
| 122 WebInspector.DOMNode.XPathStep = function(value, optimized) | 122 WebInspector.DOMNode.PathStep = function(value, optimized) |
| 123 { | 123 { |
| 124 this.value = value; | 124 this.value = value; |
| 125 this.optimized = optimized; | 125 this.optimized = optimized; |
| 126 } | 126 } |
| 127 | 127 |
| 128 WebInspector.DOMNode.XPathStep.prototype = { | 128 WebInspector.DOMNode.PathStep.prototype = { |
| 129 toString: function() | 129 toString: function() |
| 130 { | 130 { |
| 131 return this.value; | 131 return this.value; |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 | 134 |
| 135 WebInspector.DOMNode.prototype = { | 135 WebInspector.DOMNode.prototype = { |
| 136 /** | 136 /** |
| 137 * @return {Array.<WebInspector.DOMNode>} | 137 * @return {Array.<WebInspector.DOMNode>} |
| 138 */ | 138 */ |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 { | 409 { |
| 410 if (!error) | 410 if (!error) |
| 411 InspectorFrontendHost.copyText(text); | 411 InspectorFrontendHost.copyText(text); |
| 412 } | 412 } |
| 413 DOMAgent.getOuterHTML(this.id, copy); | 413 DOMAgent.getOuterHTML(this.id, copy); |
| 414 }, | 414 }, |
| 415 | 415 |
| 416 /** | 416 /** |
| 417 * @param {boolean} optimized | 417 * @param {boolean} optimized |
| 418 */ | 418 */ |
| 419 copyCSSPath: function(optimized) | |
| 420 { | |
| 421 InspectorFrontendHost.copyText(this.cssPath(optimized)); | |
| 422 }, | |
| 423 | |
| 424 /** | |
| 425 * @param {boolean} optimized | |
| 426 */ | |
| 419 copyXPath: function(optimized) | 427 copyXPath: function(optimized) |
| 420 { | 428 { |
| 421 InspectorFrontendHost.copyText(this.xPath(optimized)); | 429 InspectorFrontendHost.copyText(this.xPath(optimized)); |
| 422 }, | 430 }, |
| 423 | 431 |
| 424 /** | 432 /** |
| 425 * @param {string} objectGroupId | 433 * @param {string} objectGroupId |
| 426 * @param {function(?Protocol.Error)=} callback | 434 * @param {function(?Protocol.Error)=} callback |
| 427 */ | 435 */ |
| 428 eventListeners: function(objectGroupId, callback) | 436 eventListeners: function(objectGroupId, callback) |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 */ | 672 */ |
| 665 isXMLNode: function() | 673 isXMLNode: function() |
| 666 { | 674 { |
| 667 return !!this.ownerDocument && !!this.ownerDocument.xmlVersion; | 675 return !!this.ownerDocument && !!this.ownerDocument.xmlVersion; |
| 668 }, | 676 }, |
| 669 | 677 |
| 670 /** | 678 /** |
| 671 * @param {boolean} optimized | 679 * @param {boolean} optimized |
| 672 * @return {string} | 680 * @return {string} |
| 673 */ | 681 */ |
| 682 cssPath: function(optimized) | |
| 683 { | |
| 684 if (this._nodeType !== Node.ELEMENT_NODE) | |
| 685 return ""; | |
| 686 | |
| 687 var steps = []; | |
| 688 var contextNode = this; | |
| 689 while (contextNode) { | |
| 690 var step = contextNode._cssPathValue(optimized); | |
| 691 if (!step) | |
| 692 break; // Error - bail out early. | |
| 693 steps.push(step); | |
| 694 if (step.optimized) | |
| 695 break; | |
| 696 contextNode = contextNode.parentNode; | |
| 697 } | |
| 698 | |
| 699 steps.reverse(); | |
| 700 return steps.join(" > "); | |
| 701 }, | |
| 702 | |
| 703 /** | |
| 704 * @param {boolean} optimized | |
| 705 * @return {WebInspector.DOMNode.PathStep} | |
| 706 */ | |
| 707 _cssPathValue: function(optimized) | |
| 708 { | |
| 709 if (this._nodeType !== Node.ELEMENT_NODE) | |
| 710 return null; | |
| 711 if (optimized) { | |
| 712 if (this.getAttribute("id")) | |
| 713 return new WebInspector.DOMNode.PathStep("#" + this.getAttribute ("id"), true); | |
|
aandrey
2013/11/18 16:27:22
"id" can contain spaces. can it be written properl
| |
| 714 var nodeNameLower = this._nodeName.toLowerCase(); | |
| 715 if (nodeNameLower === "body" || nodeNameLower === "head" || nodeName Lower === "html") | |
| 716 return new WebInspector.DOMNode.PathStep(this.nodeNameInCorrectC ase(), true); | |
| 717 } | |
| 718 var nodeName = this.nodeNameInCorrectCase(); | |
| 719 var parent = this.parentNode; | |
| 720 if (!parent || parent._nodeType === Node.DOCUMENT_NODE) | |
| 721 return new WebInspector.DOMNode.PathStep(nodeName, true); | |
| 722 | |
| 723 /** | |
| 724 * @param {WebInspector.DOMNode} node | |
| 725 * @return {Object.<string, boolean>} | |
| 726 */ | |
| 727 function elementClassNames(node) | |
| 728 { | |
| 729 var classAttribute = node.getAttribute("class"); | |
| 730 if (!classAttribute) | |
| 731 return {}; | |
| 732 | |
| 733 return classAttribute.split(/\s+/g).filter(function(name) { | |
|
aandrey
2013/11/18 16:27:22
.filter(Boolean).keySet();
| |
| 734 return !!name; | |
| 735 }).keySet(); | |
| 736 } | |
| 737 | |
| 738 var uniqueClassNames = elementClassNames(this); | |
| 739 var uniqueClassNamesLeft = 0; | |
| 740 for (var name in uniqueClassNames) | |
| 741 ++uniqueClassNamesLeft; | |
| 742 var needsClassNames = false; | |
| 743 var needsNthChild = false; | |
| 744 var ownIndex = -1; | |
| 745 var siblings = parent.children(); | |
| 746 for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.leng th; ++i) { | |
| 747 var sibling = siblings[i]; | |
| 748 if (sibling === this) { | |
| 749 ownIndex = i; | |
| 750 continue; | |
| 751 } | |
| 752 if (sibling.nodeNameInCorrectCase() !== nodeName) | |
| 753 continue; | |
| 754 if (!uniqueClassNamesLeft) { | |
| 755 needsNthChild = true; | |
| 756 continue; | |
| 757 } | |
| 758 | |
| 759 needsClassNames = true; | |
| 760 var siblingClassNames = elementClassNames(sibling); | |
| 761 for (var siblingClass in siblingClassNames) { | |
| 762 if (!uniqueClassNames.hasOwnProperty(siblingClass)) | |
| 763 continue; | |
| 764 delete uniqueClassNames[siblingClass]; | |
| 765 if (!--uniqueClassNamesLeft) { | |
| 766 needsNthChild = true; | |
| 767 break; | |
| 768 } | |
| 769 } | |
| 770 } | |
| 771 | |
| 772 var result = nodeName; | |
| 773 if (needsClassNames && uniqueClassNamesLeft) { | |
| 774 for (var className in uniqueClassNames) | |
| 775 result += "." + className; | |
| 776 } | |
| 777 if (needsNthChild) | |
| 778 result += ":nth-child(" + (ownIndex + 1) + ")"; | |
| 779 return new WebInspector.DOMNode.PathStep(result, false); | |
| 780 }, | |
| 781 | |
| 782 /** | |
| 783 * @param {boolean} optimized | |
| 784 * @return {string} | |
| 785 */ | |
| 674 xPath: function(optimized) | 786 xPath: function(optimized) |
| 675 { | 787 { |
| 676 if (this._nodeType === Node.DOCUMENT_NODE) | 788 if (this._nodeType === Node.DOCUMENT_NODE) |
| 677 return "/"; | 789 return "/"; |
| 678 | 790 |
| 679 var steps = []; | 791 var steps = []; |
| 680 var contextNode = this; | 792 var contextNode = this; |
| 681 while (contextNode) { | 793 while (contextNode) { |
| 682 var step = contextNode._xPathValue(optimized); | 794 var step = contextNode._xPathValue(optimized); |
| 683 if (!step) | 795 if (!step) |
| 684 break; // Error - bail out early. | 796 break; // Error - bail out early. |
| 685 steps.push(step); | 797 steps.push(step); |
| 686 if (step.optimized) | 798 if (step.optimized) |
| 687 break; | 799 break; |
| 688 contextNode = contextNode.parentNode; | 800 contextNode = contextNode.parentNode; |
| 689 } | 801 } |
| 690 | 802 |
| 691 steps.reverse(); | 803 steps.reverse(); |
| 692 return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/") ; | 804 return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/") ; |
| 693 }, | 805 }, |
| 694 | 806 |
| 695 /** | 807 /** |
| 696 * @param {boolean} optimized | 808 * @param {boolean} optimized |
| 697 * @return {WebInspector.DOMNode.XPathStep} | 809 * @return {WebInspector.DOMNode.PathStep} |
| 698 */ | 810 */ |
| 699 _xPathValue: function(optimized) | 811 _xPathValue: function(optimized) |
| 700 { | 812 { |
| 701 var ownValue; | 813 var ownValue; |
| 702 var ownIndex = this._xPathIndex(); | 814 var ownIndex = this._xPathIndex(); |
| 703 if (ownIndex === -1) | 815 if (ownIndex === -1) |
| 704 return null; // Error. | 816 return null; // Error. |
| 705 | 817 |
| 706 switch (this._nodeType) { | 818 switch (this._nodeType) { |
| 707 case Node.ELEMENT_NODE: | 819 case Node.ELEMENT_NODE: |
| 708 if (optimized && this.getAttribute("id")) | 820 if (optimized && this.getAttribute("id")) |
| 709 return new WebInspector.DOMNode.XPathStep("//*[@id=\"" + this.ge tAttribute("id") + "\"]", true); | 821 return new WebInspector.DOMNode.PathStep("//*[@id=\"" + this.get Attribute("id") + "\"]", true); |
| 710 ownValue = this._localName; | 822 ownValue = this._localName; |
| 711 break; | 823 break; |
| 712 case Node.ATTRIBUTE_NODE: | 824 case Node.ATTRIBUTE_NODE: |
| 713 ownValue = "@" + this._nodeName; | 825 ownValue = "@" + this._nodeName; |
| 714 break; | 826 break; |
| 715 case Node.TEXT_NODE: | 827 case Node.TEXT_NODE: |
| 716 case Node.CDATA_SECTION_NODE: | 828 case Node.CDATA_SECTION_NODE: |
| 717 ownValue = "text()"; | 829 ownValue = "text()"; |
| 718 break; | 830 break; |
| 719 case Node.PROCESSING_INSTRUCTION_NODE: | 831 case Node.PROCESSING_INSTRUCTION_NODE: |
| 720 ownValue = "processing-instruction()"; | 832 ownValue = "processing-instruction()"; |
| 721 break; | 833 break; |
| 722 case Node.COMMENT_NODE: | 834 case Node.COMMENT_NODE: |
| 723 ownValue = "comment()"; | 835 ownValue = "comment()"; |
| 724 break; | 836 break; |
| 725 case Node.DOCUMENT_NODE: | 837 case Node.DOCUMENT_NODE: |
| 726 ownValue = ""; | 838 ownValue = ""; |
| 727 break; | 839 break; |
| 728 default: | 840 default: |
| 729 ownValue = ""; | 841 ownValue = ""; |
| 730 break; | 842 break; |
| 731 } | 843 } |
| 732 | 844 |
| 733 if (ownIndex > 0) | 845 if (ownIndex > 0) |
| 734 ownValue += "[" + ownIndex + "]"; | 846 ownValue += "[" + ownIndex + "]"; |
| 735 | 847 |
| 736 return new WebInspector.DOMNode.XPathStep(ownValue, this._nodeType === N ode.DOCUMENT_NODE); | 848 return new WebInspector.DOMNode.PathStep(ownValue, this._nodeType === No de.DOCUMENT_NODE); |
| 737 }, | 849 }, |
| 738 | 850 |
| 739 /** | 851 /** |
| 740 * @return {number} | 852 * @return {number} |
| 741 */ | 853 */ |
| 742 _xPathIndex: function() | 854 _xPathIndex: function() |
| 743 { | 855 { |
| 744 // Returns -1 in case of error, 0 if no siblings matching the same expre ssion, <XPath index among the same expression-matching sibling nodes> otherwise. | 856 // Returns -1 in case of error, 0 if no siblings matching the same expre ssion, <XPath index among the same expression-matching sibling nodes> otherwise. |
| 745 function areNodesSimilar(left, right) | 857 function areNodesSimilar(left, right) |
| 746 { | 858 { |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1735 setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback) | 1847 setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback) |
| 1736 { | 1848 { |
| 1737 DOMAgent.setInspectModeEnabled(enabled, inspectShadowDOM, config, callba ck); | 1849 DOMAgent.setInspectModeEnabled(enabled, inspectShadowDOM, config, callba ck); |
| 1738 } | 1850 } |
| 1739 } | 1851 } |
| 1740 | 1852 |
| 1741 /** | 1853 /** |
| 1742 * @type {?WebInspector.DOMAgent} | 1854 * @type {?WebInspector.DOMAgent} |
| 1743 */ | 1855 */ |
| 1744 WebInspector.domAgent = null; | 1856 WebInspector.domAgent = null; |
| OLD | NEW |