From 92c53944491edde4edfc3dec1dbdf7862bb96d6b Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Wed, 18 May 2016 09:04:30 +0100 Subject: [PATCH] Fix drag-n-drop files from Chrome's download bar closes #6850 - HTML5 drag-n-drop has some weird inconsistencies around the `dragOver` event where it defaults the "drop" behaviour to nothing so you need to cancel the defaults and override - http://stackoverflow.com/questions/19526430/drag-and-drop-file-uploads-from-chrome-downloads-bar --- ghost/admin/app/components/gh-file-uploader.js | 11 +++++++++++ ghost/admin/app/components/gh-image-uploader.js | 10 ++++++++++ .../integration/components/gh-file-uploader-test.js | 7 ++++++- .../integration/components/gh-image-uploader-test.js | 11 ++++++++--- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ghost/admin/app/components/gh-file-uploader.js b/ghost/admin/app/components/gh-file-uploader.js index 8e82b7e97e..f17feb3e5b 100644 --- a/ghost/admin/app/components/gh-file-uploader.js +++ b/ghost/admin/app/components/gh-file-uploader.js @@ -55,7 +55,18 @@ export default Component.extend({ }), dragOver(event) { + if (!event.dataTransfer) { + return; + } + + // this is needed to work around inconsistencies with dropping files + // from Chrome's downloads bar + let eA = event.dataTransfer.effectAllowed; + event.dataTransfer.dropEffect = (eA === 'move' || eA === 'linkMove') ? 'move' : 'copy'; + + event.stopPropagation(); event.preventDefault(); + this.set('dragClass', '--drag-over'); }, diff --git a/ghost/admin/app/components/gh-image-uploader.js b/ghost/admin/app/components/gh-image-uploader.js index 34d29a2153..1141b38fc4 100644 --- a/ghost/admin/app/components/gh-image-uploader.js +++ b/ghost/admin/app/components/gh-image-uploader.js @@ -72,6 +72,16 @@ export default Component.extend({ dragOver(event) { let showUploadForm = this.get('showUploadForm'); + if (!event.dataTransfer) { + return; + } + + // this is needed to work around inconsistencies with dropping files + // from Chrome's downloads bar + let eA = event.dataTransfer.effectAllowed; + event.dataTransfer.dropEffect = (eA === 'move' || eA === 'linkMove') ? 'move' : 'copy'; + + event.stopPropagation(); event.preventDefault(); if (showUploadForm) { diff --git a/ghost/admin/tests/integration/components/gh-file-uploader-test.js b/ghost/admin/tests/integration/components/gh-file-uploader-test.js index b4bece16c6..c5f30cb24c 100644 --- a/ghost/admin/tests/integration/components/gh-file-uploader-test.js +++ b/ghost/admin/tests/integration/components/gh-file-uploader-test.js @@ -78,7 +78,12 @@ describeComponent( this.render(hbs`{{gh-file-uploader}}`); run(() => { - this.$('.gh-image-uploader').trigger('dragover'); + let dragover = Ember.$.Event('dragover', { + dataTransfer: { + files: [] + } + }); + this.$('.gh-image-uploader').trigger(dragover); }); expect(this.$('.gh-image-uploader').hasClass('--drag-over'), 'has drag-over class').to.be.true; diff --git a/ghost/admin/tests/integration/components/gh-image-uploader-test.js b/ghost/admin/tests/integration/components/gh-image-uploader-test.js index 6a90907bbe..ea3513d3d6 100644 --- a/ghost/admin/tests/integration/components/gh-image-uploader-test.js +++ b/ghost/admin/tests/integration/components/gh-image-uploader-test.js @@ -120,7 +120,7 @@ describeComponent( expect(formChanged.secondCall.args[0]).to.equal('upload'); }); - describe('file uploads', function () { + describe('file upload form', function () { it('renders form with supplied text', function () { this.render(hbs`{{gh-image-uploader image=image text="text test"}}`); expect(this.$('.description').text().trim()).to.equal('text test'); @@ -161,7 +161,12 @@ describeComponent( this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`); run(() => { - this.$('.gh-image-uploader').trigger('dragover'); + let dragover = Ember.$.Event('dragover', { + dataTransfer: { + files: [] + } + }); + this.$('.gh-image-uploader').trigger(dragover); }); expect(this.$('.gh-image-uploader').hasClass('--drag-over'), 'has drag-over class').to.be.true; @@ -174,7 +179,7 @@ describeComponent( }); }); - describe('URL input', function () { + describe('URL input form', function () { beforeEach(function () { this.set('configService.fileStorage', false); });