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} node | |
173 */ | |
174 _cutNode: function(node) | |
aandrey
2014/07/25 15:44:27
remove this in favor of .bind(..., true)?
apavlov
2014/07/25 16:09:56
Done.
| |
175 { | |
176 this._performCopyOrCut(true, node); | |
177 }, | |
178 | |
179 /** | |
180 * @param {!WebInspector.DOMNode} node | |
181 */ | |
182 _copyNode: function(node) | |
aandrey
2014/07/25 15:44:27
ditto
apavlov
2014/07/25 16:09:56
Done.
| |
183 { | |
184 this._performCopyOrCut(false, node); | |
185 }, | |
186 | |
187 /** | |
188 * @param {boolean} isCut | |
189 * @param {!Event} event | |
190 */ | |
191 handleCopyOrCutKeyboardEvent: function(isCut, event) | |
192 { | |
193 this._setClipboardData(null); | |
aandrey
2014/07/25 15:44:26
should it be after all the returns?
apavlov
2014/07/25 16:09:57
Nope. We don't want users to go dizzy about having
| |
194 | |
195 // Do not interfere with text editing. | |
196 var currentFocusElement = WebInspector.currentFocusElement(); | |
197 if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElemen t)) | |
198 return; | |
199 | |
200 var targetNode = this.selectedDOMNode(); | |
201 if (!targetNode) | |
202 return; | |
203 | |
204 if (isCut && (targetNode.isShadowRoot() || targetNode.ancestorUserAgentS hadowRoot())) | |
205 return; | |
206 | |
207 event.clipboardData.clearData(); | |
208 event.preventDefault(); | |
209 this._performCopyOrCut(isCut, targetNode); | |
210 }, | |
211 | |
212 /** | |
213 * @param {boolean} isCut | |
214 * @param {?WebInspector.DOMNode} node | |
215 */ | |
216 _performCopyOrCut: function(isCut, node) | |
217 { | |
218 node.copyNode(); | |
219 this._setClipboardData({node: node, isCut: isCut}); | |
aandrey
2014/07/25 15:44:27
nit: spaces after { and before }
apavlov
2014/07/25 16:09:57
Done.
| |
220 }, | |
221 | |
222 /** | |
223 * @param {!WebInspector.DOMNode} targetNode | |
224 * @return {boolean} | |
225 */ | |
226 _canPaste: function(targetNode) | |
227 { | |
228 if (targetNode.isShadowRoot() || targetNode.ancestorUserAgentShadowRoot( )) | |
229 return false; | |
230 | |
231 if (!this._clipboardNodeData) | |
232 return false; | |
233 | |
234 var node = this._clipboardNodeData.node; | |
235 if (this._clipboardNodeData.isCut && (node === targetNode || node.isAnce stor(targetNode))) | |
236 return false; | |
237 | |
238 if (targetNode.target() !== node.target()) | |
239 return false; | |
240 return true; | |
241 }, | |
242 | |
243 /** | |
244 * @param {!WebInspector.DOMNode} targetNode | |
245 */ | |
246 _pasteNode: function(targetNode) | |
aandrey
2014/07/25 15:44:26
remove this (looks like the code would be a lot si
apavlov
2014/07/25 16:09:57
Done.
| |
247 { | |
248 this._performPaste(targetNode); | |
249 }, | |
250 | |
251 /** | |
252 * @param {!Event} event | |
253 */ | |
254 handlePasteKeyboardEvent: function(event) | |
255 { | |
256 // Do not interfere with text editing. | |
257 var currentFocusElement = WebInspector.currentFocusElement(); | |
258 if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElemen t)) | |
259 return; | |
260 | |
261 var targetNode = this.selectedDOMNode(); | |
262 if (!targetNode || !this._canPaste(targetNode)) | |
263 return; | |
264 | |
265 event.preventDefault(); | |
aandrey
2014/07/25 15:44:27
maybe event.consume(false); ?
apavlov
2014/07/25 16:09:57
true, since we need to preventDefault(). Done.
| |
266 this._performPaste(targetNode); | |
267 }, | |
268 | |
269 /** | |
270 * @param {!WebInspector.DOMNode} targetNode | |
271 */ | |
272 _performPaste: function(targetNode) | |
273 { | |
274 if (this._clipboardNodeData.isCut) { | |
275 this._clipboardNodeData.node.moveTo(targetNode, null, expandCallback .bind(this)); | |
276 this._setClipboardData(null); | |
277 } else { | |
278 this._clipboardNodeData.node.copyTo(targetNode, null, expandCallback .bind(this)); | |
279 } | |
280 | |
281 /** | |
282 * @param {?Protocol.Error} error | |
283 * @param {!DOMAgent.NodeId} nodeId | |
284 * @this {WebInspector.ElementsTreeOutline} | |
285 */ | |
286 function expandCallback(error, nodeId) | |
287 { | |
288 if (error) | |
289 return; | |
290 var pastedNode = this._domModel.nodeForId(nodeId); | |
291 if (!pastedNode) | |
292 return; | |
293 this.selectDOMNode(pastedNode); | |
294 } | |
295 }, | |
296 | |
147 /** | 297 /** |
148 * @param {boolean} visible | 298 * @param {boolean} visible |
149 */ | 299 */ |
150 setVisible: function(visible) | 300 setVisible: function(visible) |
151 { | 301 { |
152 this._visible = visible; | 302 this._visible = visible; |
153 if (!this._visible) | 303 if (!this._visible) |
154 return; | 304 return; |
155 | 305 |
156 this._updateModifiedNodes(); | 306 this._updateModifiedNodes(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 | 493 |
344 /** | 494 /** |
345 * @param {?WebInspector.DOMNode} node | 495 * @param {?WebInspector.DOMNode} node |
346 * @param {boolean} omitFocus | 496 * @param {boolean} omitFocus |
347 */ | 497 */ |
348 _revealAndSelectNode: function(node, omitFocus) | 498 _revealAndSelectNode: function(node, omitFocus) |
349 { | 499 { |
350 if (this._suppressRevealAndSelect) | 500 if (this._suppressRevealAndSelect) |
351 return; | 501 return; |
352 | 502 |
503 this._updateModifiedNodes(); | |
504 | |
353 if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootD OMNode) | 505 if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootD OMNode) |
354 node = this.rootDOMNode.firstChild; | 506 node = this.rootDOMNode.firstChild; |
355 if (!node) | 507 if (!node) |
356 return; | 508 return; |
357 var treeElement = this.createTreeElementFor(node); | 509 var treeElement = this.createTreeElementFor(node); |
358 if (!treeElement) | 510 if (!treeElement) |
359 return; | 511 return; |
360 | 512 |
361 treeElement.revealAndSelect(omitFocus); | 513 treeElement.revealAndSelect(omitFocus); |
362 }, | 514 }, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html -comment"); | 758 var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html -comment"); |
607 contextMenu.appendApplicableItems(event.target); | 759 contextMenu.appendApplicableItems(event.target); |
608 if (textNode) { | 760 if (textNode) { |
609 contextMenu.appendSeparator(); | 761 contextMenu.appendSeparator(); |
610 treeElement._populateTextContextMenu(contextMenu, textNode); | 762 treeElement._populateTextContextMenu(contextMenu, textNode); |
611 } else if (isTag) { | 763 } else if (isTag) { |
612 contextMenu.appendSeparator(); | 764 contextMenu.appendSeparator(); |
613 treeElement._populateTagContextMenu(contextMenu, event); | 765 treeElement._populateTagContextMenu(contextMenu, event); |
614 } else if (commentNode) { | 766 } else if (commentNode) { |
615 contextMenu.appendSeparator(); | 767 contextMenu.appendSeparator(); |
616 treeElement._populateNodeContextMenu(contextMenu, textNode); | 768 treeElement._populateNodeContextMenu(contextMenu); |
617 } else if (isPseudoElement) { | 769 } else if (isPseudoElement) { |
618 treeElement._populateScrollIntoView(contextMenu); | 770 treeElement._populateScrollIntoView(contextMenu); |
619 } else if (treeElement._node.isShadowRoot()) { | 771 } else if (treeElement._node.isShadowRoot()) { |
620 this.treeOutline._populateContextMenu(contextMenu, treeElement._node ); | 772 this.treeOutline._populateContextMenu(contextMenu, treeElement._node ); |
621 } | 773 } |
622 }, | 774 }, |
623 | 775 |
624 _updateModifiedNodes: function() | 776 _updateModifiedNodes: function() |
625 { | 777 { |
626 if (this._elementsTreeUpdater) | 778 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. | 1065 // Preserve the semantic of node by following the order of updates for h ide and show. |
914 if (show) { | 1066 if (show) { |
915 for (var i = 0, size = this._highlightResult.length; i < size; ++i) | 1067 for (var i = 0, size = this._highlightResult.length; i < size; ++i) |
916 updateEntryShow(this._highlightResult[i]); | 1068 updateEntryShow(this._highlightResult[i]); |
917 } else { | 1069 } else { |
918 for (var i = (this._highlightResult.length - 1); i >= 0; --i) | 1070 for (var i = (this._highlightResult.length - 1); i >= 0; --i) |
919 updateEntryHide(this._highlightResult[i]); | 1071 updateEntryHide(this._highlightResult[i]); |
920 } | 1072 } |
921 }, | 1073 }, |
922 | 1074 |
1075 /** | |
1076 * @param {boolean} inClipboard | |
1077 */ | |
1078 setInClipboard: function(inClipboard) | |
1079 { | |
1080 if (this._inClipboard === inClipboard) | |
1081 return; | |
1082 this._inClipboard = inClipboard; | |
1083 this.listItemElement.classList.toggle("in-clipboard", inClipboard); | |
1084 }, | |
1085 | |
923 get hovered() | 1086 get hovered() |
924 { | 1087 { |
925 return this._hovered; | 1088 return this._hovered; |
926 }, | 1089 }, |
927 | 1090 |
928 set hovered(x) | 1091 set hovered(x) |
929 { | 1092 { |
930 if (this._hovered === x) | 1093 if (this._hovered === x) |
931 return; | 1094 return; |
932 | 1095 |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1446 }, | 1609 }, |
1447 | 1610 |
1448 _populateNodeContextMenu: function(contextMenu) | 1611 _populateNodeContextMenu: function(contextMenu) |
1449 { | 1612 { |
1450 // Add free-form node-related actions. | 1613 // Add free-form node-related actions. |
1451 var openTagElement = this.treeOutline.getCachedTreeElement(this.represen tedObject) || this; | 1614 var openTagElement = this.treeOutline.getCachedTreeElement(this.represen tedObject) || this; |
1452 var isEditable = this.hasEditableNode(); | 1615 var isEditable = this.hasEditableNode(); |
1453 if (isEditable && !this._editing) | 1616 if (isEditable && !this._editing) |
1454 contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTa gElement._editAsHTML.bind(openTagElement)); | 1617 contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTa gElement._editAsHTML.bind(openTagElement)); |
1455 var isShadowRoot = this.representedObject.isShadowRoot(); | 1618 var isShadowRoot = this.representedObject.isShadowRoot(); |
1456 if (!isShadowRoot) | |
1457 contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._ copyHTML.bind(this)); | |
1458 | 1619 |
1459 // Place it here so that all "Copy"-ing items stick together. | 1620 // Place it here so that all "Copy"-ing items stick together. |
1460 if (this.representedObject.nodeType() === Node.ELEMENT_NODE) | 1621 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 )); | 1622 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa seMenuTitles() ? "Copy CSS path" : "Copy CSS Path"), this._copyCSSPath.bind(this )); |
1462 if (!isShadowRoot) | 1623 if (!isShadowRoot) |
1463 contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._co pyXPath.bind(this)); | 1624 contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._co pyXPath.bind(this)); |
1625 if (!isShadowRoot) { | |
1626 var treeOutline = this.treeOutline; | |
1627 contextMenu.appendItem(WebInspector.UIString("Copy"), treeOutline._c opyNode.bind(treeOutline, this.representedObject)); | |
1628 contextMenu.appendItem(WebInspector.UIString("Cut"), treeOutline._cu tNode.bind(treeOutline, this.representedObject), !this.hasEditableNode()); | |
1629 contextMenu.appendItem(WebInspector.UIString("Paste"), treeOutline._ pasteNode.bind(treeOutline, this.representedObject), !treeOutline._canPaste(this .representedObject)); | |
1630 } | |
1631 | |
1464 if (isEditable) | 1632 if (isEditable) |
1465 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa seMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); | 1633 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCa seMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); |
1466 }, | 1634 }, |
1467 | 1635 |
1468 _startEditing: function() | 1636 _startEditing: function() |
1469 { | 1637 { |
1470 if (this.treeOutline.selectedDOMNode() !== this._node) | 1638 if (this.treeOutline.selectedDOMNode() !== this._node) |
1471 return; | 1639 return; |
1472 | 1640 |
1473 var listItem = this._listItemNode; | 1641 var listItem = this._listItemNode; |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2340 */ | 2508 */ |
2341 function commitChange(initialValue, value) | 2509 function commitChange(initialValue, value) |
2342 { | 2510 { |
2343 if (initialValue !== value) | 2511 if (initialValue !== value) |
2344 node.setOuterHTML(value, selectNode); | 2512 node.setOuterHTML(value, selectNode); |
2345 } | 2513 } |
2346 | 2514 |
2347 node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); | 2515 node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); |
2348 }, | 2516 }, |
2349 | 2517 |
2350 _copyHTML: function() | |
2351 { | |
2352 this._node.copyNode(); | |
2353 }, | |
2354 | |
2355 _copyCSSPath: function() | 2518 _copyCSSPath: function() |
2356 { | 2519 { |
2357 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath (this._node, true)); | 2520 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath (this._node, true)); |
2358 }, | 2521 }, |
2359 | 2522 |
2360 _copyXPath: function() | 2523 _copyXPath: function() |
2361 { | 2524 { |
2362 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(t his._node, true)); | 2525 InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(t his._node, true)); |
2363 }, | 2526 }, |
2364 | 2527 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2628 | 2791 |
2629 this._treeOutline._fireElementsTreeUpdated(nodes); | 2792 this._treeOutline._fireElementsTreeUpdated(nodes); |
2630 }, | 2793 }, |
2631 | 2794 |
2632 _reset: function() | 2795 _reset: function() |
2633 { | 2796 { |
2634 this._treeOutline.rootDOMNode = null; | 2797 this._treeOutline.rootDOMNode = null; |
2635 this._treeOutline.selectDOMNode(null, false); | 2798 this._treeOutline.selectDOMNode(null, false); |
2636 this._domModel.hideDOMNodeHighlight(); | 2799 this._domModel.hideDOMNodeHighlight(); |
2637 this._recentlyModifiedNodes.clear(); | 2800 this._recentlyModifiedNodes.clear(); |
2801 delete this._treeOutline._clipboardNodeData; | |
2638 } | 2802 } |
2639 } | 2803 } |
2640 | 2804 |
2641 /** | 2805 /** |
2642 * @constructor | 2806 * @constructor |
2643 * @param {boolean} isUpdated | 2807 * @param {boolean} isUpdated |
2644 * @param {!WebInspector.DOMNode=} parent | 2808 * @param {!WebInspector.DOMNode=} parent |
2645 */ | 2809 */ |
2646 WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent) | 2810 WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent) |
2647 { | 2811 { |
(...skipping 23 matching lines...) Expand all Loading... | |
2671 var treeOutline = new WebInspector.ElementsTreeOutline(node.target(), fa lse, false); | 2835 var treeOutline = new WebInspector.ElementsTreeOutline(node.target(), fa lse, false); |
2672 treeOutline.rootDOMNode = node; | 2836 treeOutline.rootDOMNode = node; |
2673 treeOutline.element.classList.add("outline-disclosure"); | 2837 treeOutline.element.classList.add("outline-disclosure"); |
2674 if (!treeOutline.children[0].hasChildren) | 2838 if (!treeOutline.children[0].hasChildren) |
2675 treeOutline.element.classList.add("single-node"); | 2839 treeOutline.element.classList.add("single-node"); |
2676 treeOutline.setVisible(true); | 2840 treeOutline.setVisible(true); |
2677 treeOutline.element.treeElementForTest = treeOutline.children[0]; | 2841 treeOutline.element.treeElementForTest = treeOutline.children[0]; |
2678 return treeOutline.element; | 2842 return treeOutline.element; |
2679 } | 2843 } |
2680 } | 2844 } |
OLD | NEW |