From 473583922ef15371a3106e414e2aa1247311138f Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 14 Sep 2013 21:32:53 +0400 Subject: [PATCH] counting dragLeave/Enter events is not reliable --- lib/ace/mouse/dragdrop_handler.js | 34 ++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/ace/mouse/dragdrop_handler.js b/lib/ace/mouse/dragdrop_handler.js index e3788ded..846b1a27 100644 --- a/lib/ace/mouse/dragdrop_handler.js +++ b/lib/ace/mouse/dragdrop_handler.js @@ -60,7 +60,7 @@ function DragdropHandler(mouseHandler) { var mouseTarget = editor.container; var dragSelectionMarker, x, y; var timerId, range; - var dragCursor, counter = 0; + var dragCursor, dragLeaveT = null; var dragOperation; this.onDragStart = function(e) { @@ -105,9 +105,11 @@ function DragdropHandler(mouseHandler) { this.onDragEnter = function(e) { if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; + if (dragLeaveT) { + dragLeaveT = null; + } if (!dragSelectionMarker) addDragMarker(); - counter++; // dataTransfer object does not save dropEffect across events on IE, so we store it in dragOperation e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); return event.preventDefault(e); @@ -116,10 +118,12 @@ function DragdropHandler(mouseHandler) { this.onDragOver = function(e) { if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; + if (dragLeaveT) { + dragLeaveT = null; + } // Opera doesn't trigger dragenter event on drag start if (!dragSelectionMarker) { addDragMarker(); - counter++; } if (onMouseMoveTimer !== null) onMouseMoveTimer = null; @@ -131,13 +135,23 @@ function DragdropHandler(mouseHandler) { }; this.onDragLeave = function(e) { - counter--; - if (counter <= 0 && dragSelectionMarker) { - clearDragMarker(); - dragOperation = null; - return event.preventDefault(e); + if (!dragLeaveT && dragSelectionMarker) { + dragLeaveT = Date.now(); + dragLeaveTimer = setTimeout(onDragLeaveInternal, 100); } }; + var dragLeaveTimer = null; + function onDragLeaveInternal() { + dragLeaveTimer = null; + if (!dragLeaveT) return; + var dt = Date.now() - dragLeaveT; + if (dt <= 80) { + dragLeaveTimer = setTimeout(onDragLeaveInternal, 100 - dt); + } else { + clearDragMarker(); + dragLeaveT = dragOperation = null; + } + } this.onDrop = function(e) { if (!dragSelectionMarker) @@ -217,7 +231,7 @@ function DragdropHandler(mouseHandler) { editor.clearSelection(); clearInterval(timerId); timerId = setInterval(onDragInterval, 20); - counter = 0; + dragLeaveT = null; event.addListener(document, "mousemove", onMouseMove); } @@ -229,7 +243,7 @@ function DragdropHandler(mouseHandler) { editor.selection.fromOrientedRange(range); editor.$blockScrolling -= 1; range = null; - counter = 0; + dragLeaveT = null; event.removeListener(document, "mousemove", onMouseMove); }