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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 WebInspector.DOMNode.PseudoElementNames = { | 113 WebInspector.DOMNode.PseudoElementNames = { |
| 114 Before: "before", | 114 Before: "before", |
| 115 After: "after" | 115 After: "after" |
| 116 } | 116 } |
| 117 | 117 |
| 118 WebInspector.DOMNode.ShadowRootTypes = { | 118 WebInspector.DOMNode.ShadowRootTypes = { |
| 119 UserAgent: "user-agent", | 119 UserAgent: "user-agent", |
| 120 Author: "author" | 120 Author: "author" |
| 121 } | 121 } |
| 122 | 122 |
| 123 /** | |
| 124 * @constructor | |
| 125 * @param {string} value | |
| 126 * @param {boolean} optimized | |
| 127 */ | |
| 128 WebInspector.DOMNode.XPathStep = function(value, optimized) | |
| 129 { | |
| 130 this.value = value; | |
| 131 this.optimized = optimized; | |
| 132 } | |
| 133 | |
| 134 WebInspector.DOMNode.XPathStep.prototype = { | |
| 135 toString: function() | |
| 136 { | |
| 137 return this.value; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 WebInspector.DOMNode.prototype = { | 123 WebInspector.DOMNode.prototype = { |
| 142 /** | 124 /** |
| 143 * @return {Array.<WebInspector.DOMNode>} | 125 * @return {Array.<WebInspector.DOMNode>} |
| 144 */ | 126 */ |
| 145 children: function() | 127 children: function() |
| 146 { | 128 { |
| 147 return this._children ? this._children.slice() : null; | 129 return this._children ? this._children.slice() : null; |
| 148 }, | 130 }, |
| 149 | 131 |
| 150 /** | 132 /** |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 { | 405 { |
| 424 if (!error) | 406 if (!error) |
| 425 InspectorFrontendHost.copyText(text); | 407 InspectorFrontendHost.copyText(text); |
| 426 } | 408 } |
| 427 DOMAgent.getOuterHTML(this.id, copy); | 409 DOMAgent.getOuterHTML(this.id, copy); |
| 428 }, | 410 }, |
| 429 | 411 |
| 430 /** | 412 /** |
| 431 * @param {boolean} optimized | 413 * @param {boolean} optimized |
| 432 */ | 414 */ |
| 415 copyCSSPath: function(optimized) | |
| 416 { | |
| 417 InspectorFrontendHost.copyText(this.cssPath(optimized)); | |
| 418 }, | |
| 419 | |
| 420 /** | |
| 421 * @param {boolean} optimized | |
| 422 */ | |
| 433 copyXPath: function(optimized) | 423 copyXPath: function(optimized) |
| 434 { | 424 { |
| 435 InspectorFrontendHost.copyText(this.xPath(optimized)); | 425 InspectorFrontendHost.copyText(this.xPath(optimized)); |
| 436 }, | 426 }, |
| 437 | 427 |
| 438 /** | 428 /** |
| 439 * @param {string} objectGroupId | 429 * @param {string} objectGroupId |
| 440 * @param {function(?Protocol.Error)=} callback | 430 * @param {function(?Protocol.Error)=} callback |
| 441 */ | 431 */ |
| 442 eventListeners: function(objectGroupId, callback) | 432 eventListeners: function(objectGroupId, callback) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 459 return path.join(","); | 449 return path.join(","); |
| 460 }, | 450 }, |
| 461 | 451 |
| 462 /** | 452 /** |
| 463 * @param {boolean} justSelector | 453 * @param {boolean} justSelector |
| 464 * @return {string} | 454 * @return {string} |
| 465 */ | 455 */ |
| 466 appropriateSelectorFor: function(justSelector) | 456 appropriateSelectorFor: function(justSelector) |
| 467 { | 457 { |
| 468 var lowerCaseName = this.localName() || this.nodeName().toLowerCase(); | 458 var lowerCaseName = this.localName() || this.nodeName().toLowerCase(); |
| 469 | 459 if (this._nodeType !== Node.ELEMENT_NODE) |
| 470 var id = this.getAttribute("id"); | 460 return lowerCaseName; |
| 471 if (id) { | |
| 472 var selector = "#" + id; | |
| 473 return (justSelector ? selector : lowerCaseName + selector); | |
| 474 } | |
| 475 | |
| 476 var className = this.getAttribute("class"); | |
| 477 if (className) { | |
| 478 var selector = "." + className.trim().replace(/\s+/g, "."); | |
| 479 return (justSelector ? selector : lowerCaseName + selector); | |
| 480 } | |
| 481 | |
| 482 if (lowerCaseName === "input" && this.getAttribute("type")) | 461 if (lowerCaseName === "input" && this.getAttribute("type")) |
| 483 return lowerCaseName + "[type=\"" + this.getAttribute("type") + "\"] "; | 462 return lowerCaseName + "[type=\"" + this.getAttribute("type") + "\"] "; |
| 484 | 463 |
| 485 return lowerCaseName; | 464 return this.cssPath(justSelector); |
| 486 }, | 465 }, |
| 487 | 466 |
| 488 /** | 467 /** |
| 489 * @param {WebInspector.DOMNode} node | 468 * @param {WebInspector.DOMNode} node |
| 490 * @return {boolean} | 469 * @return {boolean} |
| 491 */ | 470 */ |
| 492 isAncestor: function(node) | 471 isAncestor: function(node) |
| 493 { | 472 { |
| 494 if (!node) | 473 if (!node) |
| 495 return false; | 474 return false; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 */ | 657 */ |
| 679 isXMLNode: function() | 658 isXMLNode: function() |
| 680 { | 659 { |
| 681 return !!this.ownerDocument && !!this.ownerDocument.xmlVersion; | 660 return !!this.ownerDocument && !!this.ownerDocument.xmlVersion; |
| 682 }, | 661 }, |
| 683 | 662 |
| 684 /** | 663 /** |
| 685 * @param {boolean} optimized | 664 * @param {boolean} optimized |
| 686 * @return {string} | 665 * @return {string} |
| 687 */ | 666 */ |
| 667 cssPath: function(optimized) | |
| 668 { | |
| 669 if (this._nodeType !== Node.ELEMENT_NODE) | |
| 670 return ""; | |
| 671 | |
| 672 var steps = []; | |
| 673 var contextNode = this; | |
| 674 while (contextNode) { | |
| 675 var step = WebInspector.DOMPresentationUtils.cssPathValue(contextNod e, optimized); | |
|
aandrey
2013/11/21 10:17:34
there is a dependency problem: "sdk" module (conta
| |
| 676 if (!step) | |
| 677 break; // Error - bail out early. | |
| 678 steps.push(step); | |
| 679 if (step.optimized) | |
| 680 break; | |
| 681 contextNode = contextNode.parentNode; | |
| 682 } | |
| 683 | |
| 684 steps.reverse(); | |
| 685 return steps.join(" > "); | |
| 686 }, | |
| 687 | |
| 688 /** | |
| 689 * @param {boolean} optimized | |
| 690 * @return {WebInspector.DOMNodePathStep} | |
| 691 */ | |
| 692 _cssPathValue: function(optimized) | |
|
aandrey
2013/11/21 10:17:34
remove this method
| |
| 693 { | |
| 694 if (this._nodeType !== Node.ELEMENT_NODE) | |
| 695 return null; | |
| 696 if (optimized) { | |
| 697 var id = this.getAttribute("id"); | |
| 698 if (id) | |
| 699 return new WebInspector.DOMNodePathStep(idSelector(id), true); | |
| 700 var nodeNameLower = this._nodeName.toLowerCase(); | |
| 701 if (nodeNameLower === "body" || nodeNameLower === "head" || nodeName Lower === "html") | |
| 702 return new WebInspector.DOMNodePathStep(this.nodeNameInCorrectCa se(), true); | |
| 703 } | |
| 704 var nodeName = this.nodeNameInCorrectCase(); | |
| 705 var parent = this.parentNode; | |
| 706 if (!parent || parent._nodeType === Node.DOCUMENT_NODE) | |
| 707 return new WebInspector.DOMNodePathStep(nodeName, true); | |
| 708 | |
| 709 /** | |
| 710 * @param {WebInspector.DOMNode} node | |
| 711 * @return {Array.<string>} | |
| 712 */ | |
| 713 function elementClassNames(node) | |
| 714 { | |
| 715 var classAttribute = node.getAttribute("class"); | |
| 716 if (!classAttribute) | |
| 717 return []; | |
| 718 | |
| 719 return classAttribute.split(/\s+/g).filter(Boolean); | |
| 720 } | |
| 721 | |
| 722 /** | |
| 723 * @param {string} id | |
| 724 * @return {string} | |
| 725 */ | |
| 726 function idSelector(id) | |
| 727 { | |
| 728 return "#" + escapeIdentifierIfNeeded(id); | |
| 729 } | |
| 730 | |
| 731 /** | |
| 732 * @param {string} ident | |
| 733 * @return {string} | |
| 734 */ | |
| 735 function escapeIdentifierIfNeeded(ident) | |
| 736 { | |
| 737 if (isCSSIdentifier(ident)) | |
| 738 return ident; | |
| 739 var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident); | |
| 740 var lastIndex = ident.length - 1; | |
| 741 return ident.replace(/./g, function(c, i) { | |
| 742 return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? escapeAsciiChar(c, i === lastIndex) : c; | |
| 743 }); | |
| 744 } | |
| 745 | |
| 746 /** | |
| 747 * @param {string} c | |
| 748 * @param {boolean} isLast | |
| 749 * @return {string} | |
| 750 */ | |
| 751 function escapeAsciiChar(c, isLast) | |
| 752 { | |
| 753 return "\\" + toHexByte(c) + (isLast ? "" : " "); | |
| 754 } | |
| 755 | |
| 756 /** | |
| 757 * @param {string} c | |
| 758 */ | |
| 759 function toHexByte(c) | |
| 760 { | |
| 761 var hexByte = c.charCodeAt(0).toString(16); | |
| 762 if (hexByte.length === 1) | |
| 763 hexByte = "0" + hexByte; | |
| 764 return hexByte; | |
| 765 } | |
| 766 | |
| 767 /** | |
| 768 * @param {string} c | |
| 769 * @return {boolean} | |
| 770 */ | |
| 771 function isCSSIdentChar(c) | |
| 772 { | |
| 773 if (/[a-zA-Z0-9_-]/.test(c)) | |
| 774 return true; | |
| 775 return c.charCodeAt(0) >= 0xA0; | |
| 776 } | |
| 777 | |
| 778 /** | |
| 779 * @param {string} value | |
| 780 * @return {boolean} | |
| 781 */ | |
| 782 function isCSSIdentifier(value) | |
| 783 { | |
| 784 return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value); | |
| 785 } | |
| 786 | |
| 787 var uniqueClassNamesArray = elementClassNames(this); | |
| 788 var needsClassNames = false; | |
| 789 var needsNthChild = false; | |
| 790 var ownIndex = -1; | |
| 791 var siblings = parent.children(); | |
| 792 for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.leng th; ++i) { | |
| 793 var sibling = siblings[i]; | |
| 794 if (sibling === this) { | |
| 795 ownIndex = i; | |
| 796 continue; | |
| 797 } | |
| 798 if (needsNthChild) | |
| 799 continue; | |
| 800 if (sibling.nodeNameInCorrectCase() !== nodeName) | |
| 801 continue; | |
| 802 | |
| 803 needsClassNames = true; | |
| 804 var ownClassNames = uniqueClassNamesArray.keySet(); | |
| 805 var ownClassNameCount = 0; | |
| 806 for (var name in ownClassNames) | |
| 807 ++ownClassNameCount; | |
| 808 if (ownClassNameCount === 0) { | |
| 809 needsNthChild = true; | |
| 810 continue; | |
| 811 } | |
| 812 var siblingClassNames = elementClassNames(sibling).keySet(); | |
| 813 for (var siblingClass in siblingClassNames) { | |
| 814 if (!ownClassNames.hasOwnProperty(siblingClass)) | |
| 815 continue; | |
| 816 delete ownClassNames[siblingClass]; | |
| 817 if (!--ownClassNameCount) { | |
| 818 needsNthChild = true; | |
| 819 break; | |
| 820 } | |
| 821 } | |
| 822 } | |
| 823 | |
| 824 var result = nodeName; | |
| 825 if (needsNthChild) { | |
| 826 result += ":nth-child(" + (ownIndex + 1) + ")"; | |
| 827 } else if (needsClassNames) { | |
| 828 for (var name in uniqueClassNamesArray.keySet()) | |
| 829 result += "." + escapeIdentifierIfNeeded(name); | |
| 830 } | |
| 831 return new WebInspector.DOMNodePathStep(result, false); | |
| 832 }, | |
| 833 | |
| 834 /** | |
| 835 * @param {boolean} optimized | |
| 836 * @return {string} | |
| 837 */ | |
| 688 xPath: function(optimized) | 838 xPath: function(optimized) |
| 689 { | 839 { |
| 690 if (this._nodeType === Node.DOCUMENT_NODE) | 840 if (this._nodeType === Node.DOCUMENT_NODE) |
| 691 return "/"; | 841 return "/"; |
| 692 | 842 |
| 693 var steps = []; | 843 var steps = []; |
| 694 var contextNode = this; | 844 var contextNode = this; |
| 695 while (contextNode) { | 845 while (contextNode) { |
| 696 var step = contextNode._xPathValue(optimized); | 846 var step = contextNode._xPathValue(optimized); |
| 697 if (!step) | 847 if (!step) |
| 698 break; // Error - bail out early. | 848 break; // Error - bail out early. |
| 699 steps.push(step); | 849 steps.push(step); |
| 700 if (step.optimized) | 850 if (step.optimized) |
| 701 break; | 851 break; |
| 702 contextNode = contextNode.parentNode; | 852 contextNode = contextNode.parentNode; |
| 703 } | 853 } |
| 704 | 854 |
| 705 steps.reverse(); | 855 steps.reverse(); |
| 706 return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/") ; | 856 return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/") ; |
| 707 }, | 857 }, |
| 708 | 858 |
| 709 /** | 859 /** |
| 710 * @param {boolean} optimized | 860 * @param {boolean} optimized |
| 711 * @return {WebInspector.DOMNode.XPathStep} | 861 * @return {WebInspector.DOMNodePathStep} |
| 712 */ | 862 */ |
| 713 _xPathValue: function(optimized) | 863 _xPathValue: function(optimized) |
| 714 { | 864 { |
| 715 var ownValue; | 865 var ownValue; |
| 716 var ownIndex = this._xPathIndex(); | 866 var ownIndex = this._xPathIndex(); |
| 717 if (ownIndex === -1) | 867 if (ownIndex === -1) |
| 718 return null; // Error. | 868 return null; // Error. |
| 719 | 869 |
| 720 switch (this._nodeType) { | 870 switch (this._nodeType) { |
| 721 case Node.ELEMENT_NODE: | 871 case Node.ELEMENT_NODE: |
| 722 if (optimized && this.getAttribute("id")) | 872 if (optimized && this.getAttribute("id")) |
| 723 return new WebInspector.DOMNode.XPathStep("//*[@id=\"" + this.ge tAttribute("id") + "\"]", true); | 873 return new WebInspector.DOMNodePathStep("//*[@id=\"" + this.getA ttribute("id") + "\"]", true); |
| 724 ownValue = this._localName; | 874 ownValue = this._localName; |
| 725 break; | 875 break; |
| 726 case Node.ATTRIBUTE_NODE: | 876 case Node.ATTRIBUTE_NODE: |
| 727 ownValue = "@" + this._nodeName; | 877 ownValue = "@" + this._nodeName; |
| 728 break; | 878 break; |
| 729 case Node.TEXT_NODE: | 879 case Node.TEXT_NODE: |
| 730 case Node.CDATA_SECTION_NODE: | 880 case Node.CDATA_SECTION_NODE: |
| 731 ownValue = "text()"; | 881 ownValue = "text()"; |
| 732 break; | 882 break; |
| 733 case Node.PROCESSING_INSTRUCTION_NODE: | 883 case Node.PROCESSING_INSTRUCTION_NODE: |
| 734 ownValue = "processing-instruction()"; | 884 ownValue = "processing-instruction()"; |
| 735 break; | 885 break; |
| 736 case Node.COMMENT_NODE: | 886 case Node.COMMENT_NODE: |
| 737 ownValue = "comment()"; | 887 ownValue = "comment()"; |
| 738 break; | 888 break; |
| 739 case Node.DOCUMENT_NODE: | 889 case Node.DOCUMENT_NODE: |
| 740 ownValue = ""; | 890 ownValue = ""; |
| 741 break; | 891 break; |
| 742 default: | 892 default: |
| 743 ownValue = ""; | 893 ownValue = ""; |
| 744 break; | 894 break; |
| 745 } | 895 } |
| 746 | 896 |
| 747 if (ownIndex > 0) | 897 if (ownIndex > 0) |
| 748 ownValue += "[" + ownIndex + "]"; | 898 ownValue += "[" + ownIndex + "]"; |
| 749 | 899 |
| 750 return new WebInspector.DOMNode.XPathStep(ownValue, this._nodeType === N ode.DOCUMENT_NODE); | 900 return new WebInspector.DOMNodePathStep(ownValue, this._nodeType === Nod e.DOCUMENT_NODE); |
| 751 }, | 901 }, |
| 752 | 902 |
| 753 /** | 903 /** |
| 754 * @return {number} | 904 * @return {number} |
| 755 */ | 905 */ |
| 756 _xPathIndex: function() | 906 _xPathIndex: function() |
| 757 { | 907 { |
| 758 // 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. | 908 // 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. |
| 759 function areNodesSimilar(left, right) | 909 function areNodesSimilar(left, right) |
| 760 { | 910 { |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1749 setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback) | 1899 setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback) |
| 1750 { | 1900 { |
| 1751 DOMAgent.setInspectModeEnabled(enabled, inspectShadowDOM, config, callba ck); | 1901 DOMAgent.setInspectModeEnabled(enabled, inspectShadowDOM, config, callba ck); |
| 1752 } | 1902 } |
| 1753 } | 1903 } |
| 1754 | 1904 |
| 1755 /** | 1905 /** |
| 1756 * @type {?WebInspector.DOMAgent} | 1906 * @type {?WebInspector.DOMAgent} |
| 1757 */ | 1907 */ |
| 1758 WebInspector.domAgent = null; | 1908 WebInspector.domAgent = null; |
| OLD | NEW |