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 |