Add Drag&Drop and Copy&Paste support for media
authorMatthias Schmidt <gravatronics@live.com>
Sun, 26 Mar 2017 11:29:25 +0000 (13:29 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 26 Mar 2017 11:29:25 +0000 (13:29 +0200)
See #2199

com.woltlab.wcf/templates/wysiwyg.tpl
wcfsetup/install/files/acp/templates/wysiwyg.tpl
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDragAndDrop.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Editor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js

index f77d6b7a6cbf01ee6594dd0f4d9528b5e87bec5f..5314a1b989178f5e82dcefa6ec844e198fd69dd7 100644 (file)
                                        buttonMobile: buttonMobile,
                                        customButtons: customButtons,
                                        highlighters: highlighters,
+                                       media: {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}true{else}false{/if},
                                        mediaUrl: '{link controller='Media' id=-123456789 thumbnail='void' forceFrontend=true}{/link}'
                                }
                        };
index f77d6b7a6cbf01ee6594dd0f4d9528b5e87bec5f..5314a1b989178f5e82dcefa6ec844e198fd69dd7 100644 (file)
                                        buttonMobile: buttonMobile,
                                        customButtons: customButtons,
                                        highlighters: highlighters,
+                                       media: {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}true{else}false{/if},
                                        mediaUrl: '{link controller='Media' id=-123456789 thumbnail='void' forceFrontend=true}{/link}'
                                }
                        };
index 0410d7da9d5f71c73fbe2d3cadd75d0530feb563..4ca802aace51fdba57ca039341ea8676c0b99d22 100644 (file)
@@ -3,7 +3,7 @@ $.Redactor.prototype.WoltLabDragAndDrop = function() {
        
        return {
                init: function() {
-                       if (!this.opts.woltlab.attachments) {
+                       if (!this.opts.woltlab.attachments && !this.opts.woltlab.media) {
                                return;
                        }
                        
index 623a0ebd0b653524c5d723ee7548a54c2617b97e..cbace8624afc91dd94a0a02cd9607094b1191b3f 100644 (file)
@@ -40,6 +40,7 @@ define(
                this._mediaCache = null;
                this._mediaManagerMediaList = null;
                this._search = null;
+               this._upload = null;
                this._forceClipboard = false;
                this._hadInitiallyMarkedItems = false;
                
@@ -184,7 +185,7 @@ define(
                                
                                if (Permission.get('admin.content.cms.canManageMedia')) {
                                        var uploadButton = elByClass('mediaManagerMediaUploadButton', UiDialog.getDialog(this).dialog)[0];
-                                       new MediaUpload(DomUtil.identify(uploadButton), DomUtil.identify(this._mediaManagerMediaList), {
+                                       this._upload = new MediaUpload(DomUtil.identify(uploadButton), DomUtil.identify(this._mediaManagerMediaList), {
                                                mediaManager: this
                                        });
                                        
index 75806ad3a622a69f0c4f77674e0f4a82b3ae4d87..17c662505aac4d21a036315bd19abd53d32f18ce 100644 (file)
@@ -6,8 +6,8 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLabSuite/Core/Media/Manager/Editor
  */
-define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabSuite/Core/Controller/Clipboard', 'WoltLabSuite/Core/Media/Manager/Base'],
-       function(Core, Dictionary, DomTraverse, Language, UiDialog, ControllerClipboard, MediaManagerBase) {
+define(['Core', 'Dictionary', 'Dom/Traverse', 'EventHandler', 'Language', 'Permission', 'Ui/Dialog', 'WoltLabSuite/Core/Controller/Clipboard', 'WoltLabSuite/Core/Media/Manager/Base'],
+       function(Core, Dictionary, DomTraverse, EventHandler, Language, Permission, UiDialog, ControllerClipboard, MediaManagerBase) {
        "use strict";
        
        /**
@@ -29,6 +29,22 @@ define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabS
                }
                this._mediaToInsert = new Dictionary();
                this._mediaToInsertByClipboard = false;
+               this._uploadData = null;
+               this._uploadId = null;
+               
+               if (this._options.editor && !this._options.editor.opts.woltlab.attachments) {
+                       var editorId = elData(this._options.editor.$editor[0], 'element-id');
+                       
+                       var uuid1 = EventHandler.add('com.woltlab.wcf.redactor2', 'dragAndDrop_' + editorId, this._editorUpload.bind(this));
+                       var uuid2 = EventHandler.add('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + editorId, this._editorUpload.bind(this));
+                       
+                       EventHandler.add('com.woltlab.wcf.redactor2', 'destory_' + editorId, function() {
+                               EventHandler.remove('com.woltlab.wcf.redactor2', 'dragAndDrop_' + editorId, uuid1);
+                               EventHandler.remove('com.woltlab.wcf.redactor2', 'dragAndDrop_' + editorId, uuid2);
+                       });
+                       
+                       EventHandler.add('com.woltlab.wcf.media.upload', 'success', this._mediaUploaded.bind(this));
+               }
        }
        Core.inherit(MediaManagerEditor, MediaManagerBase, {
                /**
@@ -139,6 +155,36 @@ define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabS
                        }
                },
                
+               /**
+                * @see WoltLabSuite/Core/Media/Manager/Base#_dialogShow
+                */
+               _dialogShow: function() {
+                       MediaManagerEditor._super.prototype._dialogShow.call(this);
+                       
+                       // check if data needs to be uploaded
+                       if (this._uploadData) {
+                               if (this._uploadData.file) {
+                                       this._upload.uploadFile(this._uploadData.file);
+                               }
+                               else {
+                                       this._uploadId = this._upload.uploadBlob(this._uploadData.blob);
+                               }
+                               
+                               this._uploadData = null;
+                       }
+               },
+               
+               /**
+                * Handles pasting and dragging and dropping files into the editor. 
+                * 
+                * @param       {object}        data    data of the uploaded file
+                */
+               _editorUpload: function(data) {
+                       this._uploadData = data;
+                       
+                       UiDialog.open(this);
+               },
+               
                /**
                 * Returns the id of the insert dialog based on the media files to be inserted.
                 * 
@@ -187,8 +233,11 @@ define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabS
                 * 
                 * @param       {Event?}        event
                 * @param       {string?}       thumbnailSize
+                * @param       {boolean?}      closeEditor
                 */
-               _insertMedia: function(event, thumbnailSize) {
+               _insertMedia: function(event, thumbnailSize, closeEditor) {
+                       if (closeEditor === undefined) closeEditor = true;
+                       
                        var insertType = 'separate';
                        
                        // update insert options with selected values if method is called by clicking on 'insert' button
@@ -231,7 +280,9 @@ define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabS
                        this._mediaToInsertByClipboard = false;
                        
                        // close manager dialog
-                       UiDialog.close(this);
+                       if (closeEditor) {
+                               UiDialog.close(this);
+                       }
                },
                
                /**
@@ -290,6 +341,22 @@ define(['Core', 'Dictionary', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLabS
                        }
                },
                
+               /**
+                * Is called after media files are successfully uploaded to insert copied media.
+                * 
+                * @param       {object}        data            upload data
+                */
+               _mediaUploaded: function(data) {
+                       if (this._uploadId !== null && this._upload === data.upload) {
+                               if (this._uploadId === data.uploadId || (Array.isArray(this._uploadId) && this._uploadId.indexOf(data.uploadId) !== -1)) {
+                                       this._mediaToInsert = Dictionary.fromObject(data.media);
+                                       this._insertMedia(null, 'medium', false);
+                                       
+                                       this._uploadId = null;
+                               }
+                       }
+               },
+               
                /**
                 * Handles clicking on the insert button.
                 * 
index 7fefec0cb46b8b33beeb30d222d1a68e66635e8f..ffad7d0ad21e09994d201618b1d99eb29a6bb0da 100644 (file)
@@ -160,7 +160,8 @@ define(
                        EventHandler.fire('com.woltlab.wcf.media.upload', 'success', {
                                files: files,
                                media: data.returnValues.media,
-                               upload: this
+                               upload: this,
+                               uploadId: uploadId
                        });
                },
                
index bc3a5116440f977c574bb733582bb39576f10233..fb044bb4f5046d9f7d1b838aad6bdd05f620eecb 100644 (file)
@@ -337,6 +337,26 @@ define(['AjaxRequest', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util', 'Do
                        request.sendRequest();
                        
                        return uploadId;
+               },
+               
+               /**
+                * Uploads the given file blob.
+                * 
+                * @param       {Blob}          blob            file blob
+                * @return      {int}           identifier for the uploaded file
+                */
+               uploadBlob: function(blob) {
+                       return this._upload(null, null, blob);
+               },
+               
+               /**
+                * Uploads the given file.
+                *
+                * @param       {File}          file            uploaded file
+                * @return      {int}           identifier(s) for the uploaded file
+                */
+               uploadFile: function(file) {
+                       return this._upload(null, file);
                }
        };