From b3ed915db26c8f7dce2a95581a83dafbf4ce18d0 Mon Sep 17 00:00:00 2001 From: Alan Dipert Date: Thu, 4 Oct 2018 09:50:29 -0700 Subject: [PATCH] Fixes #2142 DnD file upload on Firefox 57+ - Firefox 57+ appears not to fire a change event when the `files` field is modified, which prevented uploads from occuring. This commit triggers a change event manually and doesn't impact the functioning of other browsers. - Namespaced events were used improperly in existing code which resulted in "jank" on Firefox. Namespaces shouldn't have been attached to events generated by the browser. - The "drop" and "dragleave" handlers are now separate. This fixes a problem on Firefox where the drop event wasn't reliably changing the state of the input so it no longer glowed. --- srcjs/input_binding_fileinput.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/srcjs/input_binding_fileinput.js b/srcjs/input_binding_fileinput.js index 8aaf8c20a..fc7033790 100644 --- a/srcjs/input_binding_fileinput.js +++ b/srcjs/input_binding_fileinput.js @@ -322,7 +322,7 @@ $.extend(fileInputBinding, { // Attach a dragenter handler to $el and all of its children. When the first // child is entered, trigger a draghoverstart event. - $el.on("dragenter.dragHover", e => { + $el.on("dragenter", e => { if (collection.length === 0) { $el.trigger("draghoverstart" + ns, e.originalEvent); } @@ -332,9 +332,15 @@ $.extend(fileInputBinding, { collection = collection.add(e.originalEvent.target); }); - // Attach dragleave and drop handlers to $el and its children. Whenever a + // If a drop happens, clear the collection and trigger a draghoverend. + $el.on("drop", e => { + collection = $(); + $el.trigger("draghoverend" + ns, e.originalEvent); + }); + + // Attach dragleave to $el and its children. Whenever a // child fires either of these events, remove it from the collection. - $el.on("dragleave.dragHover drop.dragHover", e => { + $el.on("dragleave", e => { collection = collection.not(e.originalEvent.target); // When the collection has no elements, all of the children have been // removed, and produce draghoverend event. @@ -402,6 +408,11 @@ $.extend(fileInputBinding, { // (Chrome, Safari) $el.val(""); el.files = e.originalEvent.dataTransfer.files; + // Recent versions of Firefox (57+, or "Quantum" and beyond) don't seem to + // automatically trigger a change event, so we trigger one manually here. + // On browsers that do trigger change, this operation appears to be + // idempotent, as el.files doesn't change between events. + $el.trigger("change"); } }, _activeClass: "shiny-file-input-active", @@ -488,7 +499,7 @@ $.extend(fileInputBinding, { this._enableDraghover($zone, ".zone"); } - $el.on("change.fileInputBinding", uploadFiles); + $el.on("change", uploadFiles); }, unsubscribe: function(el) {