Chromium Code Reviews| Index: Source/devtools/front_end/elements/ElementsTreeOutline.js |
| diff --git a/Source/devtools/front_end/elements/ElementsTreeOutline.js b/Source/devtools/front_end/elements/ElementsTreeOutline.js |
| index 9cc824b7538c809813e0b79de20e8689cc68ab22..da0e35fe3c09ecad6e84fca93f78225ef5ebac92 100644 |
| --- a/Source/devtools/front_end/elements/ElementsTreeOutline.js |
| +++ b/Source/devtools/front_end/elements/ElementsTreeOutline.js |
| @@ -71,6 +71,9 @@ WebInspector.ElementsTreeOutline = function(target, omitRootDOMNode, selectEnabl |
| this._createNodeDecorators(); |
| } |
| +/** @typedef {{node: !WebInspector.DOMNode, isCut: boolean}} */ |
| +WebInspector.ElementsTreeOutline.ClipboardData; |
| + |
| /** |
| * @enum {string} |
| */ |
| @@ -144,6 +147,132 @@ WebInspector.ElementsTreeOutline.prototype = { |
| if (this._elementsTreeUpdater) |
| this._elementsTreeUpdater.dispose(); |
| }, |
| + |
| + /** |
| + * @param {?WebInspector.ElementsTreeOutline.ClipboardData} data |
| + */ |
| + _setClipboardData: function(data) |
| + { |
| + if (this._clipboardNodeData) { |
| + var treeElement = this.findTreeElement(this._clipboardNodeData.node); |
| + if (treeElement) |
| + treeElement.setInClipboard(false); |
| + delete this._clipboardNodeData; |
| + } |
| + |
| + if (data) { |
| + var treeElement = this.findTreeElement(data.node); |
| + if (treeElement) |
| + treeElement.setInClipboard(true); |
| + this._clipboardNodeData = data; |
| + } |
| + }, |
| + |
| + _cutNode: function() |
| + { |
| + this.handleCopyOrCutEvent(true); |
| + }, |
| + |
| + _copyNode: function() |
| + { |
| + this.handleCopyOrCutEvent(false); |
| + }, |
| + |
| + _pasteNode: function() |
| + { |
| + this.handlePasteEvent(); |
| + }, |
| + |
| + /** |
| + * @param {boolean} isCut |
| + * @param {!Event=} event |
| + */ |
| + handleCopyOrCutEvent: function(isCut, event) |
| + { |
| + this._setClipboardData(null); |
| + var currentFocusElement = WebInspector.currentFocusElement(); |
| + if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElement)) |
| + return; |
| + |
| + // Don't prevent the normal copy if the user has a selection. |
| + if (!window.getSelection().isCollapsed) |
| + return; |
| + |
| + var selectedNode = this.selectedDOMNode(); |
| + if (!selectedNode) |
| + return; |
| + |
| + if (event) { |
| + event.clipboardData.clearData(); |
| + event.preventDefault(); |
| + } |
| + selectedNode.copyNode(); |
| + this._setClipboardData({node: selectedNode, isCut: isCut}); |
| + }, |
| + |
| + /** |
| + * @return {boolean} |
| + */ |
| + _canPaste: function() |
| + { |
| + if (!this._clipboardNodeData) |
| + return false; |
| + |
| + // Don't prevent the normal copy if the user has a selection. |
| + if (!window.getSelection().isCollapsed) |
| + return false; |
| + |
| + var currentFocusElement = WebInspector.currentFocusElement(); |
| + if (currentFocusElement && WebInspector.isBeingEdited(currentFocusElement)) |
| + return false; |
| + |
| + var targetNode = this.selectedDOMNode(); |
| + if (!targetNode) |
| + return false; |
| + |
| + var node = this._clipboardNodeData.node; |
| + if (this._clipboardNodeData.isCut && (node === targetNode || node.isAncestor(targetNode))) |
|
aandrey
2014/07/25 13:32:54
node.isSelfOrAncestor(targetNode)
apavlov
2014/07/25 15:04:47
This works for ordinary DOM Node's, not our WI.DOM
|
| + return false; |
| + |
| + if (targetNode.target() !== node.target()) |
| + return false; |
| + return true; |
| + }, |
| + |
| + /** |
| + * @param {!Event=} event |
| + */ |
| + handlePasteEvent: function(event) |
| + { |
| + if (!this._canPaste()) |
| + return; |
| + |
| + if (this._clipboardNodeData.isCut) { |
| + this._clipboardNodeData.node.moveTo(this.selectedDOMNode(), null, expandCallback.bind(this)); |
| + this._setClipboardData(null); |
| + } else { |
| + this._clipboardNodeData.node.copyTo(this.selectedDOMNode(), null, expandCallback.bind(this)); |
| + } |
| + |
| + if (event) |
| + event.preventDefault(); |
| + |
| + /** |
| + * @param {?Protocol.Error} error |
| + * @param {!DOMAgent.NodeId} nodeId |
| + * @this {WebInspector.ElementsTreeOutline} |
| + */ |
| + function expandCallback(error, nodeId) |
| + { |
| + if (error) |
| + return; |
| + var pastedNode = this._domModel.nodeForId(nodeId); |
| + if (!pastedNode) |
| + return; |
| + this.selectDOMNode(pastedNode); |
| + } |
| + }, |
| + |
| /** |
| * @param {boolean} visible |
| */ |
| @@ -350,6 +479,8 @@ WebInspector.ElementsTreeOutline.prototype = { |
| if (this._suppressRevealAndSelect) |
| return; |
| + this._updateModifiedNodes(); |
| + |
| if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootDOMNode) |
| node = this.rootDOMNode.firstChild; |
| if (!node) |
| @@ -920,6 +1051,17 @@ WebInspector.ElementsTreeElement.prototype = { |
| } |
| }, |
| + /** |
| + * @param {boolean} inClipboard |
| + */ |
| + setInClipboard: function(inClipboard) |
| + { |
| + if (this._inClipboard === inClipboard) |
| + return; |
| + this._inClipboard = inClipboard; |
| + this.listItemElement.classList.toggle("in-clipboard", inClipboard); |
| + }, |
| + |
| get hovered() |
| { |
| return this._hovered; |
| @@ -1453,14 +1595,20 @@ WebInspector.ElementsTreeElement.prototype = { |
| if (isEditable && !this._editing) |
| contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTagElement._editAsHTML.bind(openTagElement)); |
| var isShadowRoot = this.representedObject.isShadowRoot(); |
| - if (!isShadowRoot) |
| - contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this)); |
| // Place it here so that all "Copy"-ing items stick together. |
| if (this.representedObject.nodeType() === Node.ELEMENT_NODE) |
| contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy CSS path" : "Copy CSS Path"), this._copyCSSPath.bind(this)); |
| if (!isShadowRoot) |
| contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this)); |
| + if (!isShadowRoot) { |
| + var treeOutline = this.treeOutline; |
| + contextMenu.appendItem(WebInspector.UIString("Copy"), treeOutline._copyNode.bind(treeOutline)); |
|
aandrey
2014/07/25 13:32:54
This callbacks should always work regardless of th
apavlov
2014/07/25 15:04:47
Done
|
| + contextMenu.appendItem(WebInspector.UIString("Cut"), treeOutline._cutNode.bind(treeOutline)); |
| + if (treeOutline._canPaste()) |
| + contextMenu.appendItem(WebInspector.UIString("Paste"), treeOutline._pasteNode.bind(treeOutline)); |
|
aandrey
2014/07/25 13:32:54
maybe always append this option, but make disabled
apavlov
2014/07/25 15:04:47
Done.
|
| + } |
| + |
| if (isEditable) |
| contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); |
| }, |
| @@ -2347,11 +2495,6 @@ WebInspector.ElementsTreeElement.prototype = { |
| node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); |
| }, |
| - _copyHTML: function() |
| - { |
| - this._node.copyNode(); |
| - }, |
| - |
| _copyCSSPath: function() |
| { |
| InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.cssPath(this._node, true)); |
| @@ -2635,6 +2778,7 @@ WebInspector.ElementsTreeUpdater.prototype = { |
| this._treeOutline.selectDOMNode(null, false); |
| this._domModel.hideDOMNodeHighlight(); |
| this._recentlyModifiedNodes.clear(); |
| + delete this._treeOutline._clipboardNodeData; |
| } |
| } |