OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> | 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> |
4 * Copyright (C) 2009 Joseph Pecoraro | 4 * Copyright (C) 2009 Joseph Pecoraro |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * | 9 * |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 this._eventSupport = new WebInspector.Object(); | 64 this._eventSupport = new WebInspector.Object(); |
65 | 65 |
66 this._visible = false; | 66 this._visible = false; |
67 | 67 |
68 this.element.addEventListener("contextmenu", this._contextMenuEventFired.bin
d(this), true); | 68 this.element.addEventListener("contextmenu", this._contextMenuEventFired.bin
d(this), true); |
69 this._contextMenuCallback = contextMenuCallback; | 69 this._contextMenuCallback = contextMenuCallback; |
70 this._setPseudoClassCallback = setPseudoClassCallback; | 70 this._setPseudoClassCallback = setPseudoClassCallback; |
71 this._createNodeDecorators(); | 71 this._createNodeDecorators(); |
72 } | 72 } |
73 | 73 |
| 74 /** @typedef {{node: !WebInspector.DOMNode, isCut: boolean}} */ |
| 75 WebInspector.ElementsTreeOutline.ClipboardData; |
| 76 |
74 /** | 77 /** |
75 * @enum {string} | 78 * @enum {string} |
76 */ | 79 */ |
77 WebInspector.ElementsTreeOutline.Events = { | 80 WebInspector.ElementsTreeOutline.Events = { |
78 SelectedNodeChanged: "SelectedNodeChanged", | 81 SelectedNodeChanged: "SelectedNodeChanged", |
79 ElementsTreeUpdated: "ElementsTreeUpdated" | 82 ElementsTreeUpdated: "ElementsTreeUpdated" |
80 } | 83 } |
81 | 84 |
82 /** | 85 /** |
83 * @const | 86 * @const |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 wireToDOMModel: function() | 140 wireToDOMModel: function() |
138 { | 141 { |
139 this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this._t
arget.domModel, this); | 142 this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this._t
arget.domModel, this); |
140 }, | 143 }, |
141 | 144 |
142 unwireFromDOMModel: function() | 145 unwireFromDOMModel: function() |
143 { | 146 { |
144 if (this._elementsTreeUpdater) | 147 if (this._elementsTreeUpdater) |
145 this._elementsTreeUpdater.dispose(); | 148 this._elementsTreeUpdater.dispose(); |
146 }, | 149 }, |
| 150 |
| 151 /** |
| 152 * @param {?WebInspector.ElementsTreeOutline.ClipboardData} data |
| 153 */ |
| 154 _setClipboardData: function(data) |
| 155 { |
| 156 if (this._clipboardNodeData) { |
| 157 var treeElement = this.findTreeElement(this._clipboardNodeData.node)
; |
| 158 if (treeElement) |
| 159 treeElement.setInClipboard(false); |
| 160 delete this._clipboardNodeData; |
| 161 } |
| 162 |
| 163 if (data) { |
| 164 var treeElement = this.findTreeElement(data.node); |
| 165 if (treeElement) |
| 166 treeElement.setInClipboard(true); |
| 167 this._clipboardNodeData = data; |
| 168 } |
| 169 }, |
| 170 |
| 171 /** |
| 172 * @param {!WebInspector.DOMNode} removedNode |
| 173 */ |
| 174 _resetClipboardIfNeeded: function(removedNode) |
| 175 { |
| 176 if (this._clipboardNodeData && this._clipboardNodeData.node === removedN
ode) |
| 177 this._setClipboardData(null); |
| 178 }, |
| 179 |
| 180 /** |
| 181 * @param {boolean} isCut |
| 182 * @param {!Event} event |
| 183 */ |
| 184 handleCopyOrCutKeyboardEvent: function(isCut, event) |
| 185 { |
| 186 this._setClipboardData(null); |
| 187 |
| 188 // Do not interfere with text editing. |
| 189 var currentFocusElement = WebInspector.currentFocusElement(); |
| 190 if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElemen
t)) |
| 191 return; |
| 192 |
| 193 var targetNode = this.selectedDOMNode(); |
| 194 if (!targetNode) |
| 195 return; |
| 196 |
| 197 event.clipboardData.clearData(); |
| 198 event.preventDefault(); |
| 199 |
| 200 this._performCopyOrCut(isCut, targetNode); |
| 201 }, |
| 202 |
| 203 /** |
| 204 * @param {boolean} isCut |
| 205 * @param {?WebInspector.DOMNode} node |
| 206 */ |
| 207 _performCopyOrCut: function(isCut, node) |
| 208 { |
| 209 if (isCut && (node.isShadowRoot() || node.ancestorUserAgentShadowRoot())
) |
| 210 return; |
| 211 |
| 212 node.copyNode(); |
| 213 this._setClipboardData({ node: node, isCut: isCut }); |
| 214 }, |
| 215 |
| 216 /** |
| 217 * @param {!WebInspector.DOMNode} targetNode |
| 218 * @return {boolean} |
| 219 */ |
| 220 _canPaste: function(targetNode) |
| 221 { |
| 222 if (targetNode.isShadowRoot() || targetNode.ancestorUserAgentShadowRoot(
)) |
| 223 return false; |
| 224 |
| 225 if (!this._clipboardNodeData) |
| 226 return false; |
| 227 |
| 228 var node = this._clipboardNodeData.node; |
| 229 if (this._clipboardNodeData.isCut && (node === targetNode || node.isAnce
stor(targetNode))) |
| 230 return false; |
| 231 |
| 232 if (targetNode.target() !== node.target()) |
| 233 return false; |
| 234 return true; |
| 235 }, |
| 236 |
| 237 /** |
| 238 * @param {!WebInspector.DOMNode} targetNode |
| 239 */ |
| 240 _pasteNode: function(targetNode) |
| 241 { |
| 242 if (this._canPaste(targetNode)) |
| 243 this._performPaste(targetNode); |
| 244 }, |
| 245 |
| 246 /** |
| 247 * @param {!Event} event |
| 248 */ |
| 249 handlePasteKeyboardEvent: function(event) |
| 250 { |
| 251 // Do not interfere with text editing. |
| 252 var currentFocusElement = WebInspector.currentFocusElement(); |
| 253 if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElemen
t)) |
| 254 return; |
| 255 |
| 256 var targetNode = this.selectedDOMNode(); |
| 257 if (!targetNode || !this._canPaste(targetNode)) |
| 258 return; |
| 259 |
| 260 event.preventDefault(); |
| 261 this._performPaste(targetNode); |
| 262 }, |
| 263 |
| 264 /** |
| 265 * @param {!WebInspector.DOMNode} targetNode |
| 266 */ |
| 267 _performPaste: function(targetNode) |
| 268 { |
| 269 if (this._clipboardNodeData.isCut) { |
| 270 this._clipboardNodeData.node.moveTo(targetNode, null, expandCallback
.bind(this)); |
| 271 this._setClipboardData(null); |
| 272 } else { |
| 273 this._clipboardNodeData.node.copyTo(targetNode, null, expandCallback
.bind(this)); |
| 274 } |
| 275 |
| 276 /** |
| 277 * @param {?Protocol.Error} error |
| 278 * @param {!DOMAgent.NodeId} nodeId |
| 279 * @this {WebInspector.ElementsTreeOutline} |
| 280 */ |
| 281 function expandCallback(error, nodeId) |
| 282 { |
| 283 if (error) |
| 284 return; |
| 285 var pastedNode = this._domModel.nodeForId(nodeId); |
| 286 if (!pastedNode) |
| 287 return; |
| 288 this.selectDOMNode(pastedNode); |
| 289 } |
| 290 }, |
| 291 |
147 /** | 292 /** |
148 * @param {boolean} visible | 293 * @param {boolean} visible |
149 */ | 294 */ |
150 setVisible: function(visible) | 295 setVisible: function(visible) |
151 { | 296 { |
152 this._visible = visible; | 297 this._visible = visible; |
153 if (!this._visible) | 298 if (!this._visible) |
154 return; | 299 return; |
155 | 300 |
156 this._updateModifiedNodes(); | 301 this._updateModifiedNodes(); |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html
-comment"); | 751 var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html
-comment"); |
607 contextMenu.appendApplicableItems(event.target); | 752 contextMenu.appendApplicableItems(event.target); |
608 if (textNode) { | 753 if (textNode) { |
609 contextMenu.appendSeparator(); | 754 contextMenu.appendSeparator(); |
610 treeElement._populateTextContextMenu(contextMenu, textNode); | 755 treeElement._populateTextContextMenu(contextMenu, textNode); |
611 } else if (isTag) { | 756 } else if (isTag) { |
612 contextMenu.appendSeparator(); | 757 contextMenu.appendSeparator(); |
613 treeElement._populateTagContextMenu(contextMenu, event); | 758 treeElement._populateTagContextMenu(contextMenu, event); |
614 } else if (commentNode) { | 759 } else if (commentNode) { |
615 contextMenu.appendSeparator(); | 760 contextMenu.appendSeparator(); |
616 treeElement._populateNodeContextMenu(contextMenu, textNode); | 761 treeElement._populateNodeContextMenu(contextMenu); |
617 } else if (isPseudoElement) { | 762 } else if (isPseudoElement) { |
618 treeElement._populateScrollIntoView(contextMenu); | 763 treeElement._populateScrollIntoView(contextMenu); |
619 } else if (treeElement._node.isShadowRoot()) { | 764 } else if (treeElement._node.isShadowRoot()) { |
620 this.treeOutline._populateContextMenu(contextMenu, treeElement._node
); | 765 this.treeOutline._populateContextMenu(contextMenu, treeElement._node
); |
621 } | 766 } |
622 }, | 767 }, |
623 | 768 |
624 _updateModifiedNodes: function() | 769 _updateModifiedNodes: function() |
625 { | 770 { |
626 if (this._elementsTreeUpdater) | 771 if (this._elementsTreeUpdater) |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 // Preserve the semantic of node by following the order of updates for h
ide and show. | 1058 // Preserve the semantic of node by following the order of updates for h
ide and show. |
914 if (show) { | 1059 if (show) { |
915 for (var i = 0, size = this._highlightResult.length; i < size; ++i) | 1060 for (var i = 0, size = this._highlightResult.length; i < size; ++i) |
916 updateEntryShow(this._highlightResult[i]); | 1061 updateEntryShow(this._highlightResult[i]); |
917 } else { | 1062 } else { |
918 for (var i = (this._highlightResult.length - 1); i >= 0; --i) | 1063 for (var i = (this._highlightResult.length - 1); i >= 0; --i) |
919 updateEntryHide(this._highlightResult[i]); | 1064 updateEntryHide(this._highlightResult[i]); |
920 } | 1065 } |
921 }, | 1066 }, |
922 | 1067 |
| 1068 /** |
| 1069 * @param {boolean} inClipboard |
| 1070 */ |
| 1071 setInClipboard: function(inClipboard) |
| 1072 { |
| 1073 if (this._inClipboard === inClipboard) |
| 1074 return; |
| 1075 this._inClipboard = inClipboard; |
| 1076 this.listItemElement.classList.toggle("in-clipboard", inClipboard); |
| 1077 }, |
| 1078 |
923 get hovered() | 1079 get hovered() |
924 { | 1080 { |
925 return this._hovered; | 1081 return this._hovered; |
926 }, | 1082 }, |
927 | 1083 |
928 set hovered(x) | 1084 set hovered(x) |
929 { | 1085 { |
930 if (this._hovered === x) | 1086 if (this._hovered === x) |
931 return; | 1087 return; |
932 | 1088 |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 }, | 1602 }, |
1447 | 1603 |
1448 _populateNodeContextMenu: function(contextMenu) | 1604 _populateNodeContextMenu: function(contextMenu) |
1449 { | 1605 { |
1450 // Add free-form node-related actions. | 1606 // Add free-form node-related actions. |
1451 var openTagElement = this.treeOutline.getCachedTreeElement(this.represen
tedObject) || this; | 1607 var openTagElement = this.treeOutline.getCachedTreeElement(this.represen
tedObject) || this; |
1452 var isEditable = this.hasEditableNode(); | 1608 var isEditable = this.hasEditableNode(); |
1453 if (isEditable && !this._editing) | 1609 if (isEditable && !this._editing) |
1454 contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTa
gElement._editAsHTML.bind(openTagElement)); | 1610 contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTa
gElement._editAsHTML.bind(openTagElement)); |
1455 var isShadowRoot = this.representedObject.isShadowRoot(); | 1611 var isShadowRoot = this.representedObject.isShadowRoot(); |
1456 if (!isShadowRoot) | |
1457 contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._
copyHTML.bind(this)); | |
1458 | 1612 |
1459 // Place it here so that all "Copy"-ing items stick together. | 1613 // Place it here so that all "Copy"-ing items stick together. |
1460 if (this.representedObject.nodeType() === Node.ELEMENT_NODE) | 1614 if (this.representedObject.nodeType() === Node.ELEMENT_NODE) |
1461 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa
seMenuTitles() ? "Copy CSS path" : "Copy CSS Path"), this._copyCSSPath.bind(this
)); | 1615 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa
seMenuTitles() ? "Copy CSS path" : "Copy CSS Path"), this._copyCSSPath.bind(this
)); |
1462 if (!isShadowRoot) | 1616 if (!isShadowRoot) |
1463 contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._co
pyXPath.bind(this)); | 1617 contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._co
pyXPath.bind(this)); |
| 1618 if (!isShadowRoot) { |
| 1619 var treeOutline = this.treeOutline; |
| 1620 contextMenu.appendItem(WebInspector.UIString("Copy"), treeOutline._p
erformCopyOrCut.bind(treeOutline, false, this.representedObject)); |
| 1621 contextMenu.appendItem(WebInspector.UIString("Cut"), treeOutline._pe
rformCopyOrCut.bind(treeOutline, true, this.representedObject), !this.hasEditabl
eNode()); |
| 1622 contextMenu.appendItem(WebInspector.UIString("Paste"), treeOutline._
pasteNode.bind(treeOutline, this.representedObject), !treeOutline._canPaste(this
.representedObject)); |
| 1623 } |
| 1624 |
1464 if (isEditable) | 1625 if (isEditable) |
1465 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa
seMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); | 1626 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa
seMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); |
1466 }, | 1627 }, |
1467 | 1628 |
1468 _startEditing: function() | 1629 _startEditing: function() |
1469 { | 1630 { |
1470 if (this.treeOutline.selectedDOMNode() !== this._node) | 1631 if (this.treeOutline.selectedDOMNode() !== this._node) |
1471 return; | 1632 return; |
1472 | 1633 |
1473 var listItem = this._listItemNode; | 1634 var listItem = this._listItemNode; |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2340 */ | 2501 */ |
2341 function commitChange(initialValue, value) | 2502 function commitChange(initialValue, value) |
2342 { | 2503 { |
2343 if (initialValue !== value) | 2504 if (initialValue !== value) |
2344 node.setOuterHTML(value, selectNode); | 2505 node.setOuterHTML(value, selectNode); |
2345 } | 2506 } |
2346 | 2507 |
2347 node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); | 2508 node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); |
2348 }, | 2509 }, |
2349 | 2510 |
2350 _copyHTML: function() | |
2351 { | |
2352 this._node.copyNode(); | |
2353 }, | |
2354 | |
2355 _copyCSSPath: function() | 2511 _copyCSSPath: function() |
2356 { | 2512 { |
2357 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath
(this._node, true)); | 2513 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath
(this._node, true)); |
2358 }, | 2514 }, |
2359 | 2515 |
2360 _copyXPath: function() | 2516 _copyXPath: function() |
2361 { | 2517 { |
2362 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(t
his._node, true)); | 2518 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(t
his._node, true)); |
2363 }, | 2519 }, |
2364 | 2520 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 this._nodeModified(event.data, true); | 2700 this._nodeModified(event.data, true); |
2545 }, | 2701 }, |
2546 | 2702 |
2547 _nodeInserted: function(event) | 2703 _nodeInserted: function(event) |
2548 { | 2704 { |
2549 this._nodeModified(event.data, false, event.data.parentNode); | 2705 this._nodeModified(event.data, false, event.data.parentNode); |
2550 }, | 2706 }, |
2551 | 2707 |
2552 _nodeRemoved: function(event) | 2708 _nodeRemoved: function(event) |
2553 { | 2709 { |
| 2710 this._treeOutline._resetClipboardIfNeeded(event.data.node); |
2554 this._nodeModified(event.data.node, false, event.data.parent); | 2711 this._nodeModified(event.data.node, false, event.data.parent); |
2555 }, | 2712 }, |
2556 | 2713 |
2557 _childNodeCountUpdated: function(event) | 2714 _childNodeCountUpdated: function(event) |
2558 { | 2715 { |
2559 var treeElement = this._treeOutline.findTreeElement(event.data); | 2716 var treeElement = this._treeOutline.findTreeElement(event.data); |
2560 if (treeElement) { | 2717 if (treeElement) { |
2561 var oldHasChildren = treeElement.hasChildren; | 2718 var oldHasChildren = treeElement.hasChildren; |
2562 treeElement._updateHasChildren(); | 2719 treeElement._updateHasChildren(); |
2563 if (treeElement.hasChildren !== oldHasChildren) | 2720 if (treeElement.hasChildren !== oldHasChildren) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2628 | 2785 |
2629 this._treeOutline._fireElementsTreeUpdated(nodes); | 2786 this._treeOutline._fireElementsTreeUpdated(nodes); |
2630 }, | 2787 }, |
2631 | 2788 |
2632 _reset: function() | 2789 _reset: function() |
2633 { | 2790 { |
2634 this._treeOutline.rootDOMNode = null; | 2791 this._treeOutline.rootDOMNode = null; |
2635 this._treeOutline.selectDOMNode(null, false); | 2792 this._treeOutline.selectDOMNode(null, false); |
2636 this._domModel.hideDOMNodeHighlight(); | 2793 this._domModel.hideDOMNodeHighlight(); |
2637 this._recentlyModifiedNodes.clear(); | 2794 this._recentlyModifiedNodes.clear(); |
| 2795 delete this._treeOutline._clipboardNodeData; |
2638 } | 2796 } |
2639 } | 2797 } |
2640 | 2798 |
2641 /** | 2799 /** |
2642 * @constructor | 2800 * @constructor |
2643 * @param {boolean} isUpdated | 2801 * @param {boolean} isUpdated |
2644 * @param {!WebInspector.DOMNode=} parent | 2802 * @param {!WebInspector.DOMNode=} parent |
2645 */ | 2803 */ |
2646 WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent) | 2804 WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent) |
2647 { | 2805 { |
(...skipping 23 matching lines...) Expand all Loading... |
2671 var treeOutline = new WebInspector.ElementsTreeOutline(node.target(), fa
lse, false); | 2829 var treeOutline = new WebInspector.ElementsTreeOutline(node.target(), fa
lse, false); |
2672 treeOutline.rootDOMNode = node; | 2830 treeOutline.rootDOMNode = node; |
2673 treeOutline.element.classList.add("outline-disclosure"); | 2831 treeOutline.element.classList.add("outline-disclosure"); |
2674 if (!treeOutline.children[0].hasChildren) | 2832 if (!treeOutline.children[0].hasChildren) |
2675 treeOutline.element.classList.add("single-node"); | 2833 treeOutline.element.classList.add("single-node"); |
2676 treeOutline.setVisible(true); | 2834 treeOutline.setVisible(true); |
2677 treeOutline.element.treeElementForTest = treeOutline.children[0]; | 2835 treeOutline.element.treeElementForTest = treeOutline.children[0]; |
2678 return treeOutline.element; | 2836 return treeOutline.element; |
2679 } | 2837 } |
2680 } | 2838 } |
OLD | NEW |