diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css index b5f9530e0d..5f013b2dd6 100644 --- a/src/wp-admin/css/edit.css +++ b/src/wp-admin/css/edit.css @@ -593,7 +593,52 @@ span.wp-media-buttons-icon:before { } .edit-form-section { - margin-bottom: 20px; + margin-bottom: 20px; + position: relative; +} + +.uploader-editor { + background: rgba( 150, 150, 150, 0.9 ); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 250000; + display: none; + text-align: center; +} + +.uploader-editor-content { + border: 1px dashed #fff; + position: absolute; + top: 10px; + left: 10px; + right: 10px; + bottom: 10px; + pointer-events: none; +} + +#poststuff .uploader-editor-content h3 { + margin: -0.5em 0 0; + position: absolute; + top: 50%; + left: 0; + right: 0; + transform: translateY( -50% ); + font-size: 40px; + color: #fff; + padding: 0; + display: none; + pointer-events: none; +} + +.uploader-editor.droppable { + background: rgba( 0, 86, 132, 0.9 ); +} + +#poststuff .uploader-editor.droppable h3 { + display: block; } /* TinyMCE */ diff --git a/src/wp-includes/js/media-editor.js b/src/wp-includes/js/media-editor.js index 31491321c8..76befb34b4 100644 --- a/src/wp-includes/js/media-editor.js +++ b/src/wp-includes/js/media-editor.js @@ -1030,6 +1030,9 @@ wp.media.editor.open( editor, options ); }); + + // Initialize and render the Editor drag-and-drop uploader. + new wp.media.view.EditorUploader().render(); } }; diff --git a/src/wp-includes/js/media-views.js b/src/wp-includes/js/media-views.js index e3ce54ec83..35b999bee9 100644 --- a/src/wp-includes/js/media-views.js +++ b/src/wp-includes/js/media-views.js @@ -2781,6 +2781,12 @@ dropzone = this.uploader.dropzone; dropzone.on( 'dropzone:enter', _.bind( this.show, this ) ); dropzone.on( 'dropzone:leave', _.bind( this.hide, this ) ); + + $( this.uploader ).on( 'uploader:ready', _.bind( this._ready, this ) ); + }, + + _ready: function() { + this.controller.trigger( 'uploader:ready' ); }, show: function() { @@ -2806,6 +2812,103 @@ } }); + /** + * wp.media.view.EditorUploader + * + * @constructor + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ + media.view.EditorUploader = media.View.extend({ + tagName: 'div', + className: 'uploader-editor', + template: media.template( 'uploader-editor' ), + + events: { + 'drop': 'drop', + 'dragover': 'dropzoneDragover', + 'dragleave': 'dropzoneDragleave', + }, + + initialize: function() { + this.files = []; + this.$document = $(document); + this.$document.on( 'dragover', _.bind( this.containerDragover, this ) ); + this.$document.on( 'dragleave', _.bind( this.containerDragleave, this ) ); + return this; + }, + + refresh: function() { + // Hide the dropzone only if dragging has left the screen. + return this.$el.toggle( this.overContainer || this.overDropzone ); + }, + + render: function() { + media.View.prototype.render.apply( this, arguments ); + $( '.edit-form-section' ).append( this.$el ); + return this; + }, + + drop: function( event ) { + this.files = event.originalEvent.dataTransfer.files; + if ( this.files.length < 1 ) + return; + + this.containerDragleave(); + this.dropzoneDragleave(); + + if ( ! this.workflow ) { + this.workflow = wp.media.editor.open( 'content', { + frame: 'post', + state: 'insert', + title: wp.media.view.l10n.addMedia, + multiple: true + }); + this.workflow.on( 'uploader:ready', this.addFiles, this ); + } else { + this.workflow.state().reset(); + this.addFiles.apply( this ); + this.workflow.open(); + } + + return false; + }, + + addFiles: function() { + if ( this.files.length ) { + this.workflow.uploader.uploader.uploader.addFile( _.toArray( this.files ) ); + this.files = []; + } + return this; + }, + + containerDragover: function() { + this.overContainer = true; + this.refresh(); + }, + + containerDragleave: function() { + this.overContainer = false; + + // Throttle dragleave because it's called when bouncing from some elements to others. + _.delay( _.bind( this.refresh, this ), 50 ); + }, + + dropzoneDragover: function() { + this.$el.addClass( 'droppable' ); + this.overDropzone = true; + _.defer( _.bind( this.refresh, this ) ); + return false; + }, + + dropzoneDragleave: function() { + this.$el.removeClass( 'droppable' ); + this.overDropzone = false; + this.refresh(); + } + }); + /** * wp.media.view.UploaderInline * diff --git a/src/wp-includes/js/plupload/wp-plupload.js b/src/wp-includes/js/plupload/wp-plupload.js index 4b853441ce..d8476caffd 100644 --- a/src/wp-includes/js/plupload/wp-plupload.js +++ b/src/wp-includes/js/plupload/wp-plupload.js @@ -149,6 +149,8 @@ window.wp = window.wp || {}; dropzone.trigger('dropzone:leave').removeClass('drag-over'); }, 0 ); }); + + $(self).trigger( 'uploader:ready' ); }); this.uploader.init(); diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 91216ed1d8..63bb8b0dd4 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -41,6 +41,12 @@ function wp_print_media_templates() { + +