From 74ab68872f3cd14f57e1e44882766cdcc19a0fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 8 Jun 2018 11:10:46 +0200 Subject: [PATCH 1/5] Remove duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "disableDropState" was set as the event handler in 8d4e5747f386a0, but the duplicated code was accidentally added back in 786e858d23c4a4. Signed-off-by: Daniel Calviño Sánchez --- apps/files/js/file-upload.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 824f6a1fd5..dfa460c914 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -1164,12 +1164,7 @@ OC.Uploader.prototype = _.extend({ filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept'); } }); - fileupload.on('fileuploaddragleave fileuploaddrop', function (){ - $('#app-content').removeClass('file-drag'); - $('.dropping-to-dir').removeClass('dropping-to-dir'); - $('.dir-drop').removeClass('dir-drop'); - $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); - }); + fileupload.on('fileuploaddragleave fileuploaddrop', disableDropState); fileupload.on('fileuploadchunksend', function(e, data) { // modify the request to adjust it to our own chunking From bb64b6f87c18e0b708619758abe28f3cfe8f3f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 8 Jun 2018 13:16:28 +0200 Subject: [PATCH 2/5] Add callback to clean up after misbehaved drag and drop events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The jQuery Plugin triggers the "dragover" callback when the browser triggers the "dragover" event and the types in their DataTransfer include a "Files" item. It also triggers the "drop" callback when the browser triggers the "drop" event and the list of files in its DataTransfer is not empty. Unfortunately some browsers may trigger "dragover" events with a DataTransfer that includes a "Files" item and then trigger a "drop" event with an empty list of files. When that happens the actions performed in the "dragXXX" callbacks could be left hanging if they were expected to be finished in the "drop" callback (for example, if the drop zone was highlighted during the drag to be then restored when the file was finally dropped). This commit adds the "dropnofiles" callback to be able to handle those situations. Signed-off-by: Daniel Calviño Sánchez --- apps/files/js/jquery.fileupload.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/files/js/jquery.fileupload.js b/apps/files/js/jquery.fileupload.js index 622161ede9..ea8529f322 100644 --- a/apps/files/js/jquery.fileupload.js +++ b/apps/files/js/jquery.fileupload.js @@ -258,6 +258,9 @@ // Callback for drop events of the dropZone(s): // drop: function (e, data) {}, // .bind('fileuploaddrop', func); + // Callback for drop events of the dropZone(s) when there are no files: + // dropnofiles: function (e) {}, // .bind('fileuploaddropnofiles', func); + // Callback for dragover events of the dropZone(s): // dragover: function (e) {}, // .bind('fileuploaddragover', func); @@ -1275,6 +1278,15 @@ that._onAdd(e, data); } }); + } else { + // "dropnofiles" is triggered to allow proper cleanup of the + // drag and drop operation, as some browsers trigger "drop" + // events that have no files even if the "DataTransfer.types" of + // the "dragover" event included a "Files" item. + this._trigger( + 'dropnofiles', + $.Event('drop', {delegatedEvent: e}) + ); } }, From d8251344c1677ee3e6a60695291304c844c66377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 8 Jun 2018 13:40:48 +0200 Subject: [PATCH 3/5] Use "dropnofiles" callback to disable the drop state in the UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a file is dragged from the desktop to the file list the file list is highlighted, and when the file is finally dropped or the drag operation is cancelled the highlighting is removed. In some cases, due to a wrong implementation, a browser may end a file drag with a drop with no files (for example, when a folder or text is dragged), which would cause the highlight to not be removed. Now those cases are handled with the "dropnofiles" callback, which restores the UI and also shows a message to the user. The error message is just a generic one, as in some cases it is not even possible to know whether the problem came from a text drag or a folder drag, and whether the problem appears or not depends on the browser, version and even operating system. Signed-off-by: Daniel Calviño Sánchez --- apps/files/js/file-upload.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index dfa460c914..4244bd673d 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -1166,6 +1166,16 @@ OC.Uploader.prototype = _.extend({ }); fileupload.on('fileuploaddragleave fileuploaddrop', disableDropState); + // In some browsers the "drop" event can be triggered with no + // files even if the "dragover" event seemed to suggest that a + // file was being dragged (and thus caused "fileuploaddragover" + // to be triggered). + fileupload.on('fileuploaddropnofiles', function() { + disableDropState(); + + OC.Notification.show(t('files', 'Uploading that item is not supported'), {type: 'error'}); + }); + fileupload.on('fileuploadchunksend', function(e, data) { // modify the request to adjust it to our own chunking var upload = self.getUpload(data); From 463d92c339a9e87032e07342bbeb9198f4d8c804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 8 Jun 2018 19:07:19 +0200 Subject: [PATCH 4/5] Remove no longer needed special handling for Firefox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The highlighting was removed in Firefox when the cursor was no longer moving to handle the behaviour of reporting a file drag and then providing no files in the drop event. That behaviour (which was only present in Firefox 48 and 49) is already handled with the "dropnofiles" callback, so that special handling is no longer needed. Signed-off-by: Daniel Calviño Sánchez --- apps/files/js/file-upload.js | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 4244bd673d..dc412c10d7 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -1131,23 +1131,8 @@ OC.Uploader.prototype = _.extend({ self.log('progress handle fileuploadfail', e, data); self.trigger('fail', e, data); }); - var disableDropState = function() { - $('#app-content').removeClass('file-drag'); - $('.dropping-to-dir').removeClass('dropping-to-dir'); - $('.dir-drop').removeClass('dir-drop'); - $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); - }; - var disableClassOnFirefox = _.debounce(function() { - disableDropState(); - }, 100); fileupload.on('fileuploaddragover', function(e){ $('#app-content').addClass('file-drag'); - // dropping a folder in firefox doesn't cause a drop event - // this is simulated by simply invoke disabling all classes - // once no dragover event isn't noticed anymore - if (/Firefox/i.test(navigator.userAgent)) { - disableClassOnFirefox(); - } $('#emptycontent .icon-folder').addClass('icon-filetype-folder-drag-accept'); var filerow = $(e.delegatedEvent.target).closest('tr'); @@ -1164,6 +1149,14 @@ OC.Uploader.prototype = _.extend({ filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept'); } }); + + var disableDropState = function() { + $('#app-content').removeClass('file-drag'); + $('.dropping-to-dir').removeClass('dropping-to-dir'); + $('.dir-drop').removeClass('dir-drop'); + $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); + }; + fileupload.on('fileuploaddragleave fileuploaddrop', disableDropState); // In some browsers the "drop" event can be triggered with no From 4eafae4178fcbd99627d9e9625b0b1f1ebe46dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 8 Jun 2018 20:37:43 +0200 Subject: [PATCH 5/5] Do not show an error message when draging and dropping text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the browser reports a drag of items other than files (for example, text) and then triggers a drop event with no files no error message should be shown to the user, as in that case there would be no highlight of the drop zone and no indication that the drop would be valid (except for the mouse cursor); the error message should be shown only when the drop event with no files follows a file drag. Signed-off-by: Daniel Calviño Sánchez --- apps/files/js/file-upload.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index dc412c10d7..fac086c3da 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -1041,6 +1041,8 @@ OC.Uploader.prototype = _.extend({ //remaining time var lastUpdate, lastSize, bufferSize, buffer, bufferIndex, bufferIndex2, bufferTotal; + var dragging = false; + // add progress handlers fileupload.on('fileuploadadd', function(e, data) { self.log('progress handle fileuploadadd', e, data); @@ -1148,6 +1150,8 @@ OC.Uploader.prototype = _.extend({ filerow.addClass('dropping-to-dir'); filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept'); } + + dragging = true; }); var disableDropState = function() { @@ -1155,6 +1159,8 @@ OC.Uploader.prototype = _.extend({ $('.dropping-to-dir').removeClass('dropping-to-dir'); $('.dir-drop').removeClass('dir-drop'); $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); + + dragging = false; }; fileupload.on('fileuploaddragleave fileuploaddrop', disableDropState); @@ -1164,6 +1170,10 @@ OC.Uploader.prototype = _.extend({ // file was being dragged (and thus caused "fileuploaddragover" // to be triggered). fileupload.on('fileuploaddropnofiles', function() { + if (!dragging) { + return; + } + disableDropState(); OC.Notification.show(t('files', 'Uploading that item is not supported'), {type: 'error'});