From 1fe49e0c395d6cc7a5d11a3936c7ca3d4c1a468c Mon Sep 17 00:00:00 2001 From: jos Date: Wed, 30 Dec 2015 22:20:15 +0100 Subject: [PATCH] Fixed not being able to select a single node --- HISTORY.md | 2 +- src/js/Node.js | 55 ++++++++++++++++++++--------------------- src/js/treemode.js | 61 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 68629b8..3c4f09d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,7 +6,7 @@ https://github.com/josdejong/jsoneditor ## not yet released, version 5.0.0 - Implemented selection of multiple nodes, allowing to move/duplicate/remove - multiple nodes at once. + multiple nodes at once (See #106). - Implemented a new option `escapeUnicode`, which will show the hexadecimal unicode instead of the character itself. (See #93 and #230). - Implemented method `getMode`. diff --git a/src/js/Node.js b/src/js/Node.js index 5722e10..0120af0 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -1434,6 +1434,11 @@ Node.onDragEnd = function (nodes, event) { var firstIndex = parent.childs.indexOf(firstNode); var beforeNode = parent.childs[firstIndex + nodes.length] || parent.append; + // set focus to the context menu button of the first node + if (nodes[0]) { + nodes[0].dom.menu.focus(); + } + var params = { nodes: nodes, oldSelection: editor.drag.oldSelection, @@ -1954,37 +1959,31 @@ Node.prototype.onEvent = function (event) { // focus // when clicked in whitespace left or right from the field or value, set focus var domTree = dom.tree; - if (target == domTree.parentNode) { - switch (type) { - case 'click': - var left = (event.offsetX != undefined) ? - (event.offsetX < (this.getLevel() + 1) * 24) : - (event.pageX < util.getAbsoluteLeft(dom.tdSeparator));// for FF - if (left || expandable) { - // node is expandable when it is an object or array - if (domField) { - util.setEndOfContentEditable(domField); - domField.focus(); - } - } - else { - if (domValue) { - util.setEndOfContentEditable(domValue); - domValue.focus(); - } - } - break; + if (target == domTree.parentNode && + type == 'click' && !event.hasMoved) { + var left = (event.offsetX != undefined) ? + (event.offsetX < (this.getLevel() + 1) * 24) : + (event.pageX < util.getAbsoluteLeft(dom.tdSeparator));// for FF + if (left || expandable) { + // node is expandable when it is an object or array + if (domField) { + util.setEndOfContentEditable(domField); + domField.focus(); + } + } + else { + if (domValue) { + util.setEndOfContentEditable(domValue); + domValue.focus(); + } } } if ((target == dom.tdExpand && !expandable) || target == dom.tdField || - target == dom.tdSeparator) { - switch (type) { - case 'click': - if (domField) { - util.setEndOfContentEditable(domField); - domField.focus(); - } - break; + target == dom.tdSeparator && + type == 'click' && !event.hasMoved) { + if (domField) { + util.setEndOfContentEditable(domField); + domField.focus(); } } diff --git a/src/js/treemode.js b/src/js/treemode.js index fb8db82..6d9ca75 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -641,19 +641,28 @@ treemode._onEvent = function (event) { domFocus = event.target; } + if (event.type == 'mousedown') { + this._startDragDistance(event); + } + if (event.type == 'mousemove' || event.type == 'mouseup' || event.type == 'click') { + this._updateDragDistance(event); + } + var node = Node.getNodeFromTarget(event.target); if (node && node.selected) { - if (event.type == 'click' && event.target == node.dom.menu) { - this.showContextMenu(event.target); - - // stop propagation - return; - } - if (event.type == 'click') { + if (event.target == node.dom.menu) { + this.showContextMenu(event.target); + + // stop propagation (else we will open the context menu of a single node) + return; + } + // deselect a multi selection - this.deselect(); + if (!event.hasMoved) { + this.deselect(); + } } if (event.type == 'mousedown') { @@ -681,6 +690,30 @@ treemode._onEvent = function (event) { } }; +treemode._startDragDistance = function (event) { + this.dragDistanceEvent = { + initialTarget: event.target, + initialPageX: event.pageX, + initialPageY: event.pageY, + dragDistance: 0, + hasMoved: false + }; +}; + +treemode._updateDragDistance = function (event) { + var diffX = event.pageX - this.dragDistanceEvent.initialPageX; + var diffY = event.pageY - this.dragDistanceEvent.initialPageY; + + this.dragDistanceEvent.dragDistance = Math.sqrt(diffX * diffX + diffY * diffY); + this.dragDistanceEvent.hasMoved = + this.dragDistanceEvent.hasMoved || this.dragDistanceEvent.dragDistance > 10; + + event.dragDistance = this.dragDistanceEvent.dragDistance; + event.hasMoved = this.dragDistanceEvent.hasMoved; + + return event.dragDistance; +}; + /** * Start multi selection of nodes by dragging the mouse * @param event @@ -695,6 +728,8 @@ treemode._onMultiSelectStart = function (event) { nodes: [] }; + this._startDragDistance(event); + var editor = this; if (!this.mousemove) { this.mousemove = util.addEventListener(window, 'mousemove', function (event) { @@ -717,6 +752,11 @@ treemode._onMultiSelectStart = function (event) { treemode._onMultiSelect = function (event) { event.preventDefault(); + this._updateDragDistance(event); + if (!event.hasMoved) { + return; + } + var node = Node.getNodeFromTarget(event.target); if (node) { @@ -745,8 +785,9 @@ treemode._onMultiSelect = function (event) { * @private */ treemode._onMultiSelectEnd = function (event) { - if (this.multiselection.end) { - this.multiselection.end.dom.menu.focus(); + // set focus to the context menu button of the first node + if (this.multiselection.nodes[0]) { + this.multiselection.nodes[0].dom.menu.focus(); } this.multiselection.start = null;