From: Matthias Schmidt Date: Sun, 26 Mar 2017 11:29:25 +0000 (+0200) Subject: Add Drag&Drop and Copy&Paste support for media X-Git-Tag: 3.1.0_Alpha_1~543 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2413a6e5c11d0154439de61ab85d80cf9ab6fad8;p=GitHub%2FWoltLab%2FWCF.git Add Drag&Drop and Copy&Paste support for media See #2199 --- diff --git a/com.woltlab.wcf/templates/wysiwyg.tpl b/com.woltlab.wcf/templates/wysiwyg.tpl index f77d6b7a6c..5314a1b989 100644 --- a/com.woltlab.wcf/templates/wysiwyg.tpl +++ b/com.woltlab.wcf/templates/wysiwyg.tpl @@ -228,6 +228,7 @@ 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}' } }; diff --git a/wcfsetup/install/files/acp/templates/wysiwyg.tpl b/wcfsetup/install/files/acp/templates/wysiwyg.tpl index f77d6b7a6c..5314a1b989 100644 --- a/wcfsetup/install/files/acp/templates/wysiwyg.tpl +++ b/wcfsetup/install/files/acp/templates/wysiwyg.tpl @@ -228,6 +228,7 @@ 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}' } }; diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDragAndDrop.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDragAndDrop.js index 0410d7da9d..4ca802aace 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDragAndDrop.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDragAndDrop.js @@ -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; } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js index 623a0ebd0b..cbace8624a 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js @@ -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 }); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Editor.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Editor.js index 75806ad3a6..17c662505a 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Editor.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Editor.js @@ -6,8 +6,8 @@ * @license GNU Lesser General Public License * @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. * diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js index 7fefec0cb4..ffad7d0ad2 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js @@ -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 }); }, diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js index bc3a511644..fb044bb4f5 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js @@ -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); } };