Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1595)

Unified Diff: Source/devtools/front_end/elements/ElementsTreeOutline.js

Issue 397303002: DevTools: [Elements] Implement shortcut-based node cut-copy-pasting (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Make DOMAgent.copyTo hidden Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}
}

Powered by Google App Engine
This is Rietveld 408576698