From: Matthias Schmidt Date: Tue, 5 Jan 2021 17:41:29 +0000 (+0100) Subject: Convert `Media/Editor` to TypeScript X-Git-Tag: 5.4.0_Alpha_1~461^2~12 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=ace789ac13624e2d488dabd6b0a65aaf5e369580;p=GitHub%2FWoltLab%2FWCF.git Convert `Media/Editor` to TypeScript --- diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Editor.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Editor.js index 3e66db4418..7e79945d19 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Editor.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Editor.js @@ -1,190 +1,169 @@ /** * Handles editing media files via dialog. * - * @author Matthias Schmidt - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Media/Editor + * @author Matthias Schmidt + * @copyright 2001-2021 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Media/Editor */ -define([ - 'Ajax', - 'Core', - 'Dictionary', - 'Dom/ChangeListener', - 'Dom/Traverse', - 'Dom/Util', - 'Language', - 'Ui/Dialog', - 'Ui/Notification', - 'WoltLabSuite/Core/Language/Chooser', - 'WoltLabSuite/Core/Language/Input', - 'EventKey', - 'WoltLabSuite/Core/Media/Replace' -], function (Ajax, Core, Dictionary, DomChangeListener, DomTraverse, DomUtil, Language, UiDialog, UiNotification, LanguageChooser, LanguageInput, EventKey, MediaReplace) { +define(["require", "exports", "tslib", "../Core", "../Ui/Notification", "../Ui/Dialog", "../Language/Chooser", "../Language/Input", "../Dom/Util", "../Dom/Traverse", "../Dom/Change/Listener", "../Language", "../Ajax", "./Replace"], function (require, exports, tslib_1, Core, UiNotification, UiDialog, LanguageChooser, LanguageInput, DomUtil, DomTraverse, Listener_1, Language, Ajax, Replace_1) { "use strict"; - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function () { }; - Fake.prototype = { - _ajaxSetup: function () { }, - _ajaxSuccess: function () { }, - _close: function () { }, - _keyPress: function () { }, - _saveData: function () { }, - _updateLanguageFields: function () { }, - edit: function () { } - }; - return Fake; - } - /** - * @constructor - */ - function MediaEditor(callbackObject) { - this._callbackObject = callbackObject || {}; - if (this._callbackObject._editorClose && typeof this._callbackObject._editorClose !== 'function') { - throw new TypeError("Callback object has no function '_editorClose'."); - } - if (this._callbackObject._editorSuccess && typeof this._callbackObject._editorSuccess !== 'function') { - throw new TypeError("Callback object has no function '_editorSuccess'."); + Core = tslib_1.__importStar(Core); + UiNotification = tslib_1.__importStar(UiNotification); + UiDialog = tslib_1.__importStar(UiDialog); + LanguageChooser = tslib_1.__importStar(LanguageChooser); + LanguageInput = tslib_1.__importStar(LanguageInput); + DomUtil = tslib_1.__importStar(DomUtil); + DomTraverse = tslib_1.__importStar(DomTraverse); + Listener_1 = tslib_1.__importDefault(Listener_1); + Language = tslib_1.__importStar(Language); + Ajax = tslib_1.__importStar(Ajax); + Replace_1 = tslib_1.__importDefault(Replace_1); + class MediaEditor { + constructor(callbackObject) { + this._availableLanguageCount = 1; + this._categoryIds = []; + this._dialogs = new Map(); + this._media = null; + this._oldCategoryId = 0; + this._callbackObject = callbackObject || {}; + if (this._callbackObject._editorClose && typeof this._callbackObject._editorClose !== "function") { + throw new TypeError("Callback object has no function '_editorClose'."); + } + if (this._callbackObject._editorSuccess && typeof this._callbackObject._editorSuccess !== "function") { + throw new TypeError("Callback object has no function '_editorSuccess'."); + } } - this._media = null; - this._availableLanguageCount = 1; - this._categoryIds = []; - this._oldCategoryId = 0; - this._dialogs = new Dictionary(); - } - MediaEditor.prototype = { - /** - * Returns the data for Ajax to setup the Ajax/Request object. - * - * @return {object} setup data for Ajax/Request object - */ - _ajaxSetup: function () { + _ajaxSetup() { return { data: { - actionName: 'update', - className: 'wcf\\data\\media\\MediaAction' - } + actionName: "update", + className: "wcf\\data\\media\\MediaAction", + }, }; - }, - /** - * Handles successful AJAX requests. - * - * @param {object} data response data - */ - _ajaxSuccess: function (data) { + } + _ajaxSuccess() { UiNotification.show(); if (this._callbackObject._editorSuccess) { this._callbackObject._editorSuccess(this._media, this._oldCategoryId); this._oldCategoryId = 0; } - UiDialog.close('mediaEditor_' + this._media.mediaID); + UiDialog.close(`mediaEditor_${this._media.mediaID}`); this._media = null; - }, + } /** * Is called if an editor is manually closed by the user. */ - _close: function () { + _close() { this._media = null; if (this._callbackObject._editorClose) { this._callbackObject._editorClose(); } - }, + } /** * Initializes the editor dialog. * - * @param {HTMLElement} content - * @param {object} data - * @since 5.3 + * @since 5.3 */ - _initEditor: function (content, data) { + _initEditor(content, data) { this._availableLanguageCount = ~~data.returnValues.availableLanguageCount; this._categoryIds = data.returnValues.categoryIDs.map(function (number) { return ~~number; }); - var didLoadMediaData = false; if (data.returnValues.mediaData) { this._media = data.returnValues.mediaData; - didLoadMediaData = true; } // make sure that the language chooser is initialized first - setTimeout(function () { + setTimeout(() => { if (this._availableLanguageCount > 1) { - LanguageChooser.setLanguageId('mediaEditor_' + this._media.mediaID + '_languageID', this._media.languageID || LANGUAGE_ID); + LanguageChooser.setLanguageId(`mediaEditor_${this._media.mediaID}_languageID`, this._media.languageID || window.LANGUAGE_ID); } if (this._categoryIds.length) { - elBySel('select[name=categoryID]', content).value = ~~this._media.categoryID; + const categoryID = content.querySelector("select[name=categoryID]"); + categoryID.value = this._media.categoryID; } - var title = elBySel('input[name=title]', content); - var altText = elBySel('input[name=altText]', content); - var caption = elBySel('textarea[name=caption]', content); + const title = content.querySelector("input[name=title]"); + const altText = content.querySelector("input[name=altText]"); + const caption = content.querySelector("textarea[name=caption]"); + const mediaId = this._media.mediaID; if (this._availableLanguageCount > 1 && this._media.isMultilingual) { - if (elById('altText_' + this._media.mediaID)) - LanguageInput.setValues('altText_' + this._media.mediaID, Dictionary.fromObject(this._media.altText || {})); - if (elById('caption_' + this._media.mediaID)) - LanguageInput.setValues('caption_' + this._media.mediaID, Dictionary.fromObject(this._media.caption || {})); - LanguageInput.setValues('title_' + this._media.mediaID, Dictionary.fromObject(this._media.title || {})); + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.setValues(`altText_${this._media.mediaID}`, (this._media.altText || {})); + } + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.setValues(`caption_${this._media.mediaID}`, (this._media.caption || {})); + } + LanguageInput.setValues(`title_${this._media.mediaID}`, (this._media.title || {})); } else { - title.value = this._media.title ? this._media.title[this._media.languageID || LANGUAGE_ID] : ''; - if (altText) - altText.value = this._media.altText ? this._media.altText[this._media.languageID || LANGUAGE_ID] : ''; - if (caption) - caption.value = this._media.caption ? this._media.caption[this._media.languageID || LANGUAGE_ID] : ''; + title.value = this._media.title ? this._media.title[this._media.languageID || window.LANGUAGE_ID] : ""; + if (altText) { + altText.value = this._media.altText + ? this._media.altText[this._media.languageID || window.LANGUAGE_ID] + : ""; + } + if (caption) { + caption.value = this._media.caption + ? this._media.caption[this._media.languageID || window.LANGUAGE_ID] + : ""; + } } if (this._availableLanguageCount > 1) { - var isMultilingual = elBySel('input[name=isMultilingual]', content); - isMultilingual.addEventListener('change', this._updateLanguageFields.bind(this)); + const isMultilingual = content.querySelector("input[name=isMultilingual]"); + isMultilingual.addEventListener("change", (ev) => this._updateLanguageFields(ev)); this._updateLanguageFields(null, isMultilingual); } - var keyPress = this._keyPress.bind(this); - if (altText) - altText.addEventListener('keypress', keyPress); - title.addEventListener('keypress', keyPress); - elBySel('button[data-type=submit]', content).addEventListener('click', this._saveData.bind(this)); + if (altText) { + altText.addEventListener("keypress", (ev) => this._keyPress(ev)); + } + title.addEventListener("keypress", (ev) => this._keyPress(ev)); + content.querySelector("button[data-type=submit]").addEventListener("click", () => this._saveData()); // remove focus from input elements and scroll dialog to top document.activeElement.blur(); - elById('mediaEditor_' + this._media.mediaID).parentNode.scrollTop = 0; + document.getElementById(`mediaEditor_${this._media.mediaID}`).parentNode.scrollTop = 0; // Initialize button to replace media file. - var uploadButton = elByClass('mediaManagerMediaReplaceButton', content)[0]; - var target = elByClass('mediaThumbnail', content)[0]; + const uploadButton = content.querySelector(".mediaManagerMediaReplaceButton"); + let target = content.querySelector(".mediaThumbnail"); if (!target) { - target = elCreate('div'); + target = document.createElement("div"); content.appendChild(target); } - new MediaReplace(this._media.mediaID, DomUtil.identify(uploadButton), + new Replace_1.default(~~this._media.mediaID, DomUtil.identify(uploadButton), // Pass an anonymous element for non-images which is required internally // but not needed in this case. DomUtil.identify(target), { - mediaEditor: this + mediaEditor: this, }); - DomChangeListener.trigger(); - }.bind(this), 200); - }, + Listener_1.default.trigger(); + }, 200); + } /** * Handles the `[ENTER]` key to submit the form. - * - * @param {object} event event object */ - _keyPress: function (event) { - if (EventKey.Enter(event)) { + _keyPress(event) { + if (event.key === "Enter") { event.preventDefault(); this._saveData(); } - }, + } /** * Saves the data of the currently edited media. */ - _saveData: function () { - var content = UiDialog.getDialog('mediaEditor_' + this._media.mediaID).content; - var categoryId = elBySel('select[name=categoryID]', content); - var altText = elBySel('input[name=altText]', content); - var caption = elBySel('textarea[name=caption]', content); - var captionEnableHtml = elBySel('input[name=captionEnableHtml]', content); - var title = elBySel('input[name=title]', content); - var hasError = false; - var altTextError = (altText ? DomTraverse.childByClass(altText.parentNode.parentNode, 'innerError') : false); - var captionError = (caption ? DomTraverse.childByClass(caption.parentNode.parentNode, 'innerError') : false); - var titleError = DomTraverse.childByClass(title.parentNode.parentNode, 'innerError'); + _saveData() { + const content = UiDialog.getDialog(`mediaEditor_${this._media.mediaID}`).content; + const categoryId = content.querySelector("select[name=categoryID]"); + const altText = content.querySelector("input[name=altText]"); + const caption = content.querySelector("textarea[name=caption]"); + const captionEnableHtml = content.querySelector("input[name=captionEnableHtml]"); + const title = content.querySelector("input[name=title]"); + let hasError = false; + const altTextError = altText + ? DomTraverse.childByClass(altText.parentNode.parentNode, "innerError") + : false; + const captionError = caption + ? DomTraverse.childByClass(caption.parentNode.parentNode, "innerError") + : false; + const titleError = DomTraverse.childByClass(title.parentNode.parentNode, "innerError"); // category this._oldCategoryId = this._media.categoryID; if (this._categoryIds.length) { @@ -196,80 +175,91 @@ define([ } // language and multilingualism if (this._availableLanguageCount > 1) { - this._media.isMultilingual = ~~elBySel('input[name=isMultilingual]', content).checked; - this._media.languageID = this._media.isMultilingual ? null : LanguageChooser.getLanguageId('mediaEditor_' + this._media.mediaID + '_languageID'); + const isMultilingual = content.querySelector("input[name=isMultilingual]"); + this._media.isMultilingual = ~~isMultilingual.checked; + this._media.languageID = this._media.isMultilingual + ? null + : LanguageChooser.getLanguageId(`mediaEditor_${this._media.mediaID}_languageID`); } else { - this._media.languageID = LANGUAGE_ID; + this._media.languageID = window.LANGUAGE_ID; } // altText, caption and title this._media.altText = {}; this._media.caption = {}; this._media.title = {}; if (this._availableLanguageCount > 1 && this._media.isMultilingual) { - if (elById('altText_' + this._media.mediaID) && !LanguageInput.validate('altText_' + this._media.mediaID, true)) { + if (altText && !LanguageInput.validate(altText.id, true)) { hasError = true; if (!altTextError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); altText.parentNode.parentNode.appendChild(error); } } - if (elById('caption_' + this._media.mediaID) && !LanguageInput.validate('caption_' + this._media.mediaID, true)) { + if (caption && !LanguageInput.validate(caption.id, true)) { hasError = true; if (!captionError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); caption.parentNode.parentNode.appendChild(error); } } - if (!LanguageInput.validate('title_' + this._media.mediaID, true)) { + if (!LanguageInput.validate(title.id, true)) { hasError = true; if (!titleError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); title.parentNode.parentNode.appendChild(error); } } - this._media.altText = (elById('altText_' + this._media.mediaID) ? LanguageInput.getValues('altText_' + this._media.mediaID).toObject() : ''); - this._media.caption = (elById('caption_' + this._media.mediaID) ? LanguageInput.getValues('caption_' + this._media.mediaID).toObject() : ''); - this._media.title = LanguageInput.getValues('title_' + this._media.mediaID).toObject(); + this._media.altText = altText ? this.mapToI18nValues(LanguageInput.getValues(altText.id)) : ""; + this._media.caption = caption ? this.mapToI18nValues(LanguageInput.getValues(caption.id)) : ""; + this._media.title = this.mapToI18nValues(LanguageInput.getValues(title.id)); } else { - this._media.altText[this._media.languageID] = (altText ? altText.value : ''); - this._media.caption[this._media.languageID] = (caption ? caption.value : ''); + this._media.altText[this._media.languageID] = altText ? altText.value : ""; + this._media.caption[this._media.languageID] = caption ? caption.value : ""; this._media.title[this._media.languageID] = title.value; } // captionEnableHtml - if (captionEnableHtml) + if (captionEnableHtml) { this._media.captionEnableHtml = ~~captionEnableHtml.checked; - else + } + else { this._media.captionEnableHtml = 0; - var aclValues = { - allowAll: ~~elById('mediaEditor_' + this._media.mediaID + '_aclAllowAll').checked, + } + const aclValues = { + allowAll: ~~document.getElementById(`mediaEditor_${this._media.mediaID}_aclAllowAll`) + .checked, group: [], - user: [] + user: [], }; - var aclGroups = elBySelAll('input[name="mediaEditor_' + this._media.mediaID + 'aclValues[group][]"]', content); - for (var i = 0, length = aclGroups.length; i < length; i++) { - aclValues.group.push(~~aclGroups[i].value); - } - var aclUsers = elBySelAll('input[name="mediaEditor_' + this._media.mediaID + 'aclValues[user][]"]', content); - for (var i = 0, length = aclUsers.length; i < length; i++) { - aclValues.user.push(~~aclUsers[i].value); - } + content + .querySelectorAll(`input[name="mediaEditor_${this._media.mediaID}_aclValues[group][]"]`) + .forEach((aclGroup) => { + aclValues.group.push(~~aclGroup.value); + }); + content + .querySelectorAll(`input[name="mediaEditor_${this._media.mediaID}_aclValues[user][]"]`) + .forEach((aclUser) => { + aclValues.user.push(~~aclUser.value); + }); if (!hasError) { - if (altTextError) - elRemove(altTextError); - if (captionError) - elRemove(captionError); - if (titleError) - elRemove(titleError); + if (altTextError) { + altTextError.remove(); + } + if (captionError) { + captionError.remove(); + } + if (titleError) { + titleError.remove(); + } Ajax.api(this, { - actionName: 'update', + actionName: "update", objectIDs: [this._media.mediaID], parameters: { aclValues: aclValues, @@ -279,88 +269,102 @@ define([ captionEnableHtml: this._media.captionEnableHtml, categoryID: this._media.categoryID, isMultilingual: this._media.isMultilingual, - languageID: this._media.languageID + languageID: this._media.languageID, }, - title: this._media.title - } + title: this._media.title, + }, }); } - }, + } + mapToI18nValues(values) { + const obj = {}; + values.forEach((value, key) => (obj[key] = value)); + return obj; + } /** - * Updates language-related input fields depending on whether multilingualism - * is enabled. + * Updates language-related input fields depending on whether multilingualis is enabled. */ - _updateLanguageFields: function (event, element) { - if (event) + _updateLanguageFields(event, element) { + if (event) { element = event.currentTarget; - var languageChooserContainer = elById('mediaEditor_' + this._media.mediaID + '_languageIDContainer').parentNode; + } + const mediaId = this._media.mediaID; + const languageChooserContainer = document.getElementById(`mediaEditor_${mediaId}_languageIDContainer`) + .parentNode; if (element.checked) { - LanguageInput.enable('title_' + this._media.mediaID); - if (elById('caption_' + this._media.mediaID)) - LanguageInput.enable('caption_' + this._media.mediaID); - if (elById('altText_' + this._media.mediaID)) - LanguageInput.enable('altText_' + this._media.mediaID); - elHide(languageChooserContainer); + LanguageInput.enable(`title_${mediaId}`); + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.enable(`caption_${mediaId}`); + } + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.enable(`altText_${mediaId}`); + } + languageChooserContainer.style.display = "none"; } else { - LanguageInput.disable('title_' + this._media.mediaID); - if (elById('caption_' + this._media.mediaID)) - LanguageInput.disable('caption_' + this._media.mediaID); - if (elById('altText_' + this._media.mediaID)) - LanguageInput.disable('altText_' + this._media.mediaID); - elShow(languageChooserContainer); + LanguageInput.disable(`title_${mediaId}`); + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.disable(`caption_${mediaId}`); + } + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.disable(`altText_${mediaId}`); + } + languageChooserContainer.style.display = "block"; } - }, + } /** - * Edits the media with the given data. - * - * @param {object|integer} media data of the edited media or media id for which the data will be loaded + * Edits the media with the given data or id. */ - edit: function (media) { - if (typeof media !== 'object') { + edit(editedMedia) { + let media; + let mediaId = 0; + if (typeof editedMedia === "object") { + media = editedMedia; + mediaId = media.mediaID; + } + else { media = { - mediaID: ~~media + mediaID: editedMedia, }; + mediaId = editedMedia; } if (this._media !== null) { - throw new Error("Cannot edit media with id '" + media.mediaID + "' while editing media with id '" + this._media.mediaID + "'"); + throw new Error(`Cannot edit media with id ${mediaId} while editing media with id '${this._media.mediaID}'.`); } this._media = media; - if (!this._dialogs.has('mediaEditor_' + media.mediaID)) { - this._dialogs.set('mediaEditor_' + media.mediaID, { - _dialogSetup: function () { + if (!this._dialogs.has(`mediaEditor_${mediaId}`)) { + this._dialogs.set(`mediaEditor_${mediaId}`, { + _dialogSetup: () => { return { - id: 'mediaEditor_' + media.mediaID, + id: `mediaEditor_${mediaId}`, options: { backdropCloseOnClick: false, onClose: this._close.bind(this), - title: Language.get('wcf.media.edit') + title: Language.get("wcf.media.edit"), }, source: { after: this._initEditor.bind(this), data: { - actionName: 'getEditorDialog', - className: 'wcf\\data\\media\\MediaAction', - objectIDs: [media.mediaID] - } - } + actionName: "getEditorDialog", + className: "wcf\\data\\media\\MediaAction", + objectIDs: [mediaId], + }, + }, }; - }.bind(this) + }, }); } - UiDialog.open(this._dialogs.get('mediaEditor_' + media.mediaID)); - }, + UiDialog.open(this._dialogs.get(`mediaEditor_${mediaId}`)); + } /** * Updates the data of the currently edited media file. - * - * @param {object} data - * @since 5.3 */ - updateData: function (data) { + updateData(media) { if (this._callbackObject._editorSuccess) { - this._callbackObject._editorSuccess(data); + this._callbackObject._editorSuccess(media); } } - }; + } + Core.enableLegacyInheritance(MediaEditor); return MediaEditor; }); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.js deleted file mode 100644 index b771353049..0000000000 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.js +++ /dev/null @@ -1,425 +0,0 @@ -/** - * Handles editing media files via dialog. - * - * @author Matthias Schmidt - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Media/Editor - */ -define( - [ - 'Ajax', - 'Core', - 'Dictionary', - 'Dom/ChangeListener', - 'Dom/Traverse', - 'Dom/Util', - 'Language', - 'Ui/Dialog', - 'Ui/Notification', - 'WoltLabSuite/Core/Language/Chooser', - 'WoltLabSuite/Core/Language/Input', - 'EventKey', - 'WoltLabSuite/Core/Media/Replace' - ], - function( - Ajax, - Core, - Dictionary, - DomChangeListener, - DomTraverse, - DomUtil, - Language, - UiDialog, - UiNotification, - LanguageChooser, - LanguageInput, - EventKey, - MediaReplace - ) -{ - "use strict"; - - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function() {}; - Fake.prototype = { - _ajaxSetup: function() {}, - _ajaxSuccess: function() {}, - _close: function() {}, - _keyPress: function() {}, - _saveData: function() {}, - _updateLanguageFields: function() {}, - edit: function() {} - }; - return Fake; - } - - /** - * @constructor - */ - function MediaEditor(callbackObject) { - this._callbackObject = callbackObject || {}; - - if (this._callbackObject._editorClose && typeof this._callbackObject._editorClose !== 'function') { - throw new TypeError("Callback object has no function '_editorClose'."); - } - if (this._callbackObject._editorSuccess && typeof this._callbackObject._editorSuccess !== 'function') { - throw new TypeError("Callback object has no function '_editorSuccess'."); - } - - this._media = null; - this._availableLanguageCount = 1; - this._categoryIds = []; - this._oldCategoryId = 0; - - this._dialogs = new Dictionary(); - } - MediaEditor.prototype = { - /** - * Returns the data for Ajax to setup the Ajax/Request object. - * - * @return {object} setup data for Ajax/Request object - */ - _ajaxSetup: function() { - return { - data: { - actionName: 'update', - className: 'wcf\\data\\media\\MediaAction' - } - }; - }, - - /** - * Handles successful AJAX requests. - * - * @param {object} data response data - */ - _ajaxSuccess: function(data) { - UiNotification.show(); - - if (this._callbackObject._editorSuccess) { - this._callbackObject._editorSuccess(this._media, this._oldCategoryId); - this._oldCategoryId = 0; - } - - UiDialog.close('mediaEditor_' + this._media.mediaID); - - this._media = null; - }, - - /** - * Is called if an editor is manually closed by the user. - */ - _close: function() { - this._media = null; - - if (this._callbackObject._editorClose) { - this._callbackObject._editorClose(); - } - }, - - /** - * Initializes the editor dialog. - * - * @param {HTMLElement} content - * @param {object} data - * @since 5.3 - */ - _initEditor: function(content, data) { - this._availableLanguageCount = ~~data.returnValues.availableLanguageCount; - this._categoryIds = data.returnValues.categoryIDs.map(function(number) { - return ~~number; - }); - - var didLoadMediaData = false; - if (data.returnValues.mediaData) { - this._media = data.returnValues.mediaData; - - didLoadMediaData = true; - } - - // make sure that the language chooser is initialized first - setTimeout(function() { - if (this._availableLanguageCount > 1) { - LanguageChooser.setLanguageId('mediaEditor_' + this._media.mediaID + '_languageID', this._media.languageID || LANGUAGE_ID); - } - - if (this._categoryIds.length) { - elBySel('select[name=categoryID]', content).value = ~~this._media.categoryID; - } - - var title = elBySel('input[name=title]', content); - var altText = elBySel('input[name=altText]', content); - var caption = elBySel('textarea[name=caption]', content); - - if (this._availableLanguageCount > 1 && this._media.isMultilingual) { - if (elById('altText_' + this._media.mediaID)) LanguageInput.setValues('altText_' + this._media.mediaID, Dictionary.fromObject(this._media.altText || { })); - if (elById('caption_' + this._media.mediaID)) LanguageInput.setValues('caption_' + this._media.mediaID, Dictionary.fromObject(this._media.caption || { })); - LanguageInput.setValues('title_' + this._media.mediaID, Dictionary.fromObject(this._media.title || { })); - } - else { - title.value = this._media.title ? this._media.title[this._media.languageID || LANGUAGE_ID] : ''; - if (altText) altText.value = this._media.altText ? this._media.altText[this._media.languageID || LANGUAGE_ID] : ''; - if (caption) caption.value = this._media.caption ? this._media.caption[this._media.languageID || LANGUAGE_ID] : ''; - } - - if (this._availableLanguageCount > 1) { - var isMultilingual = elBySel('input[name=isMultilingual]', content); - isMultilingual.addEventListener('change', this._updateLanguageFields.bind(this)); - - this._updateLanguageFields(null, isMultilingual); - } - - var keyPress = this._keyPress.bind(this); - if (altText) altText.addEventListener('keypress', keyPress); - title.addEventListener('keypress', keyPress); - - elBySel('button[data-type=submit]', content).addEventListener('click', this._saveData.bind(this)); - - // remove focus from input elements and scroll dialog to top - document.activeElement.blur(); - elById('mediaEditor_' + this._media.mediaID).parentNode.scrollTop = 0; - - // Initialize button to replace media file. - var uploadButton = elByClass('mediaManagerMediaReplaceButton', content)[0]; - var target = elByClass('mediaThumbnail', content)[0]; - if (!target) { - target = elCreate('div'); - content.appendChild(target); - } - new MediaReplace( - this._media.mediaID, - DomUtil.identify(uploadButton), - // Pass an anonymous element for non-images which is required internally - // but not needed in this case. - DomUtil.identify(target), - { - mediaEditor: this - } - ); - - DomChangeListener.trigger(); - }.bind(this), 200); - }, - - /** - * Handles the `[ENTER]` key to submit the form. - * - * @param {object} event event object - */ - _keyPress: function(event) { - if (EventKey.Enter(event)) { - event.preventDefault(); - - this._saveData(); - } - }, - - /** - * Saves the data of the currently edited media. - */ - _saveData: function() { - var content = UiDialog.getDialog('mediaEditor_' + this._media.mediaID).content; - - var categoryId = elBySel('select[name=categoryID]', content); - var altText = elBySel('input[name=altText]', content); - var caption = elBySel('textarea[name=caption]', content); - var captionEnableHtml = elBySel('input[name=captionEnableHtml]', content); - var title = elBySel('input[name=title]', content); - - var hasError = false; - var altTextError = (altText ? DomTraverse.childByClass(altText.parentNode.parentNode, 'innerError') : false); - var captionError = (caption ? DomTraverse.childByClass(caption.parentNode.parentNode, 'innerError') : false); - var titleError = DomTraverse.childByClass(title.parentNode.parentNode, 'innerError'); - - // category - this._oldCategoryId = this._media.categoryID; - if (this._categoryIds.length) { - this._media.categoryID = ~~categoryId.value; - - // if the selected category id not valid (manipulated DOM), ignore - if (this._categoryIds.indexOf(this._media.categoryID) === -1) { - this._media.categoryID = 0; - } - } - - // language and multilingualism - if (this._availableLanguageCount > 1) { - this._media.isMultilingual = ~~elBySel('input[name=isMultilingual]', content).checked; - this._media.languageID = this._media.isMultilingual ? null : LanguageChooser.getLanguageId('mediaEditor_' + this._media.mediaID + '_languageID'); - } - else { - this._media.languageID = LANGUAGE_ID; - } - - // altText, caption and title - this._media.altText = {}; - this._media.caption = {}; - this._media.title = {}; - if (this._availableLanguageCount > 1 && this._media.isMultilingual) { - if (elById('altText_' + this._media.mediaID) && !LanguageInput.validate('altText_' + this._media.mediaID, true)) { - hasError = true; - if (!altTextError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); - altText.parentNode.parentNode.appendChild(error); - } - } - if (elById('caption_' + this._media.mediaID) && !LanguageInput.validate('caption_' + this._media.mediaID, true)) { - hasError = true; - if (!captionError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); - caption.parentNode.parentNode.appendChild(error); - } - } - if (!LanguageInput.validate('title_' + this._media.mediaID, true)) { - hasError = true; - if (!titleError) { - var error = elCreate('small'); - error.className = 'innerError'; - error.textContent = Language.get('wcf.global.form.error.multilingual'); - title.parentNode.parentNode.appendChild(error); - } - } - - this._media.altText = (elById('altText_' + this._media.mediaID) ? LanguageInput.getValues('altText_' + this._media.mediaID).toObject() : ''); - this._media.caption = (elById('caption_' + this._media.mediaID) ? LanguageInput.getValues('caption_' + this._media.mediaID).toObject() : ''); - this._media.title = LanguageInput.getValues('title_' + this._media.mediaID).toObject(); - } - else { - this._media.altText[this._media.languageID] = (altText ? altText.value : ''); - this._media.caption[this._media.languageID] = (caption ? caption.value : ''); - this._media.title[this._media.languageID] = title.value; - } - - // captionEnableHtml - if (captionEnableHtml) this._media.captionEnableHtml = ~~captionEnableHtml.checked; - else this._media.captionEnableHtml = 0; - - var aclValues = { - allowAll: ~~elById('mediaEditor_' + this._media.mediaID + '_aclAllowAll').checked, - group: [], - user: [] - }; - - var aclGroups = elBySelAll('input[name="mediaEditor_' + this._media.mediaID + 'aclValues[group][]"]', content); - for (var i = 0, length = aclGroups.length; i < length; i++) { - aclValues.group.push(~~aclGroups[i].value); - } - - var aclUsers = elBySelAll('input[name="mediaEditor_' + this._media.mediaID + 'aclValues[user][]"]', content); - for (var i = 0, length = aclUsers.length; i < length; i++) { - aclValues.user.push(~~aclUsers[i].value); - } - - if (!hasError) { - if (altTextError) elRemove(altTextError); - if (captionError) elRemove(captionError); - if (titleError) elRemove(titleError); - - Ajax.api(this, { - actionName: 'update', - objectIDs: [ this._media.mediaID ], - parameters: { - aclValues: aclValues, - altText: this._media.altText, - caption: this._media.caption, - data: { - captionEnableHtml: this._media.captionEnableHtml, - categoryID: this._media.categoryID, - isMultilingual: this._media.isMultilingual, - languageID: this._media.languageID - }, - title: this._media.title - } - }); - } - }, - - /** - * Updates language-related input fields depending on whether multilingualism - * is enabled. - */ - _updateLanguageFields: function(event, element) { - if (event) element = event.currentTarget; - - var languageChooserContainer = elById('mediaEditor_' + this._media.mediaID + '_languageIDContainer').parentNode; - - if (element.checked) { - LanguageInput.enable('title_' + this._media.mediaID); - if (elById('caption_' + this._media.mediaID)) LanguageInput.enable('caption_' + this._media.mediaID); - if (elById('altText_' + this._media.mediaID)) LanguageInput.enable('altText_' + this._media.mediaID); - - elHide(languageChooserContainer); - } - else { - LanguageInput.disable('title_' + this._media.mediaID); - if (elById('caption_' + this._media.mediaID)) LanguageInput.disable('caption_' + this._media.mediaID); - if (elById('altText_' + this._media.mediaID)) LanguageInput.disable('altText_' + this._media.mediaID); - - elShow(languageChooserContainer); - } - }, - - /** - * Edits the media with the given data. - * - * @param {object|integer} media data of the edited media or media id for which the data will be loaded - */ - edit: function(media) { - if (typeof media !== 'object') { - media = { - mediaID: ~~media - }; - } - - if (this._media !== null) { - throw new Error("Cannot edit media with id '" + media.mediaID + "' while editing media with id '" + this._media.mediaID + "'"); - } - - this._media = media; - - if (!this._dialogs.has('mediaEditor_' + media.mediaID)) { - this._dialogs.set('mediaEditor_' + media.mediaID, { - _dialogSetup: function() { - return { - id: 'mediaEditor_' + media.mediaID, - options: { - backdropCloseOnClick: false, - onClose: this._close.bind(this), - title: Language.get('wcf.media.edit') - }, - source: { - after: this._initEditor.bind(this), - data: { - actionName: 'getEditorDialog', - className: 'wcf\\data\\media\\MediaAction', - objectIDs: [media.mediaID] - } - } - }; - }.bind(this) - }); - } - - UiDialog.open(this._dialogs.get('mediaEditor_' + media.mediaID)); - }, - - /** - * Updates the data of the currently edited media file. - * - * @param {object} data - * @since 5.3 - */ - updateData: function(data) { - if (this._callbackObject._editorSuccess) { - this._callbackObject._editorSuccess(data); - } - } - }; - - return MediaEditor; -}); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.ts new file mode 100644 index 0000000000..25f4f0e3f6 --- /dev/null +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Editor.ts @@ -0,0 +1,438 @@ +/** + * Handles editing media files via dialog. + * + * @author Matthias Schmidt + * @copyright 2001-2021 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Media/Editor + */ + +import * as Core from "../Core"; +import { Media, MediaEditorCallbackObject } from "./Data"; +import { AjaxCallbackObject, AjaxCallbackSetup } from "../Ajax/Data"; +import * as UiNotification from "../Ui/Notification"; +import * as UiDialog from "../Ui/Dialog"; +import { DialogCallbackObject } from "../Ui/Dialog/Data"; +import * as LanguageChooser from "../Language/Chooser"; +import * as LanguageInput from "../Language/Input"; +import * as DomUtil from "../Dom/Util"; +import * as DomTraverse from "../Dom/Traverse"; +import DomChangeListener from "../Dom/Change/Listener"; +import * as Language from "../Language"; +import * as Ajax from "../Ajax"; +import MediaReplace from "./Replace"; +import { I18nValues } from "../Language/Input"; + +type InitEditorData = { + returnValues: { + availableLanguageCount: number; + categoryIDs: number[]; + mediaData?: Media; + }; +}; + +class MediaEditor implements AjaxCallbackObject { + protected _availableLanguageCount = 1; + protected _categoryIds: number[] = []; + protected _dialogs = new Map(); + protected readonly _callbackObject: MediaEditorCallbackObject; + protected _media: Media | null = null; + protected _oldCategoryId = 0; + + constructor(callbackObject: MediaEditorCallbackObject) { + this._callbackObject = callbackObject || {}; + + if (this._callbackObject._editorClose && typeof this._callbackObject._editorClose !== "function") { + throw new TypeError("Callback object has no function '_editorClose'."); + } + if (this._callbackObject._editorSuccess && typeof this._callbackObject._editorSuccess !== "function") { + throw new TypeError("Callback object has no function '_editorSuccess'."); + } + } + + public _ajaxSetup(): ReturnType { + return { + data: { + actionName: "update", + className: "wcf\\data\\media\\MediaAction", + }, + }; + } + + public _ajaxSuccess(): void { + UiNotification.show(); + + if (this._callbackObject._editorSuccess) { + this._callbackObject._editorSuccess(this._media, this._oldCategoryId); + this._oldCategoryId = 0; + } + + UiDialog.close(`mediaEditor_${this._media!.mediaID}`); + + this._media = null; + } + + /** + * Is called if an editor is manually closed by the user. + */ + protected _close(): void { + this._media = null; + + if (this._callbackObject._editorClose) { + this._callbackObject._editorClose(); + } + } + + /** + * Initializes the editor dialog. + * + * @since 5.3 + */ + protected _initEditor(content: HTMLElement, data: InitEditorData): void { + this._availableLanguageCount = ~~data.returnValues.availableLanguageCount; + this._categoryIds = data.returnValues.categoryIDs.map(function (number) { + return ~~number; + }); + + if (data.returnValues.mediaData) { + this._media = data.returnValues.mediaData; + } + + // make sure that the language chooser is initialized first + setTimeout(() => { + if (this._availableLanguageCount > 1) { + LanguageChooser.setLanguageId( + `mediaEditor_${this._media!.mediaID}_languageID`, + this._media!.languageID || window.LANGUAGE_ID, + ); + } + + if (this._categoryIds.length) { + const categoryID = content.querySelector("select[name=categoryID]") as HTMLSelectElement; + categoryID.value = (this._media!.categoryID as unknown) as string; + } + + const title = content.querySelector("input[name=title]") as HTMLInputElement; + const altText = content.querySelector("input[name=altText]") as HTMLInputElement; + const caption = content.querySelector("textarea[name=caption]") as HTMLInputElement; + const mediaId = this._media!.mediaID; + + if (this._availableLanguageCount > 1 && this._media!.isMultilingual) { + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.setValues(`altText_${this._media!.mediaID}`, (this._media!.altText || {}) as I18nValues); + } + + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.setValues(`caption_${this._media!.mediaID}`, (this._media!.caption || {}) as I18nValues); + } + + LanguageInput.setValues(`title_${this._media!.mediaID}`, (this._media!.title || {}) as I18nValues); + } else { + title.value = this._media!.title ? this._media!.title[this._media!.languageID || window.LANGUAGE_ID] : ""; + if (altText) { + altText.value = this._media!.altText + ? this._media!.altText[this._media!.languageID || window.LANGUAGE_ID] + : ""; + } + if (caption) { + caption.value = this._media!.caption + ? this._media!.caption[this._media!.languageID || window.LANGUAGE_ID] + : ""; + } + } + + if (this._availableLanguageCount > 1) { + const isMultilingual = content.querySelector("input[name=isMultilingual]") as HTMLInputElement; + isMultilingual.addEventListener("change", (ev) => this._updateLanguageFields(ev)); + + this._updateLanguageFields(null, isMultilingual); + } + + if (altText) { + altText.addEventListener("keypress", (ev) => this._keyPress(ev)); + } + title.addEventListener("keypress", (ev) => this._keyPress(ev)); + + content.querySelector("button[data-type=submit]")!.addEventListener("click", () => this._saveData()); + + // remove focus from input elements and scroll dialog to top + (document.activeElement! as HTMLElement).blur(); + (document.getElementById(`mediaEditor_${this._media!.mediaID}`)!.parentNode as HTMLElement).scrollTop = 0; + + // Initialize button to replace media file. + const uploadButton = content.querySelector(".mediaManagerMediaReplaceButton")!; + let target = content.querySelector(".mediaThumbnail"); + if (!target) { + target = document.createElement("div"); + content.appendChild(target); + } + new MediaReplace( + ~~this._media!.mediaID, + DomUtil.identify(uploadButton), + // Pass an anonymous element for non-images which is required internally + // but not needed in this case. + DomUtil.identify(target), + { + mediaEditor: this, + }, + ); + + DomChangeListener.trigger(); + }, 200); + } + + /** + * Handles the `[ENTER]` key to submit the form. + */ + protected _keyPress(event: KeyboardEvent): void { + if (event.key === "Enter") { + event.preventDefault(); + + this._saveData(); + } + } + + /** + * Saves the data of the currently edited media. + */ + protected _saveData(): void { + const content = UiDialog.getDialog(`mediaEditor_${this._media!.mediaID}`)!.content; + + const categoryId = content.querySelector("select[name=categoryID]") as HTMLSelectElement; + const altText = content.querySelector("input[name=altText]") as HTMLInputElement; + const caption = content.querySelector("textarea[name=caption]") as HTMLTextAreaElement; + const captionEnableHtml = content.querySelector("input[name=captionEnableHtml]") as HTMLInputElement; + const title = content.querySelector("input[name=title]") as HTMLInputElement; + + let hasError = false; + const altTextError = altText + ? DomTraverse.childByClass(altText.parentNode!.parentNode as HTMLElement, "innerError") + : false; + const captionError = caption + ? DomTraverse.childByClass(caption.parentNode!.parentNode as HTMLElement, "innerError") + : false; + const titleError = DomTraverse.childByClass(title.parentNode!.parentNode as HTMLElement, "innerError"); + + // category + this._oldCategoryId = this._media!.categoryID; + if (this._categoryIds.length) { + this._media!.categoryID = ~~categoryId!.value; + + // if the selected category id not valid (manipulated DOM), ignore + if (this._categoryIds.indexOf(this._media!.categoryID) === -1) { + this._media!.categoryID = 0; + } + } + + // language and multilingualism + if (this._availableLanguageCount > 1) { + const isMultilingual = content.querySelector("input[name=isMultilingual]") as HTMLInputElement; + this._media!.isMultilingual = ~~isMultilingual.checked; + this._media!.languageID = this._media!.isMultilingual + ? null + : LanguageChooser.getLanguageId(`mediaEditor_${this._media!.mediaID}_languageID`); + } else { + this._media!.languageID = window.LANGUAGE_ID; + } + + // altText, caption and title + this._media!.altText = {}; + this._media!.caption = {}; + this._media!.title = {}; + if (this._availableLanguageCount > 1 && this._media!.isMultilingual) { + if (altText && !LanguageInput.validate(altText.id, true)) { + hasError = true; + if (!altTextError) { + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); + altText.parentNode!.parentNode!.appendChild(error); + } + } + if (caption && !LanguageInput.validate(caption.id, true)) { + hasError = true; + if (!captionError) { + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); + caption.parentNode!.parentNode!.appendChild(error); + } + } + if (!LanguageInput.validate(title.id, true)) { + hasError = true; + if (!titleError) { + const error = document.createElement("small"); + error.className = "innerError"; + error.textContent = Language.get("wcf.global.form.error.multilingual"); + title.parentNode!.parentNode!.appendChild(error); + } + } + + this._media!.altText = altText ? this.mapToI18nValues(LanguageInput.getValues(altText.id)) : ""; + this._media!.caption = caption ? this.mapToI18nValues(LanguageInput.getValues(caption.id)) : ""; + this._media!.title = this.mapToI18nValues(LanguageInput.getValues(title.id)); + } else { + this._media!.altText[this._media!.languageID!] = altText ? altText.value : ""; + this._media!.caption[this._media!.languageID!] = caption ? caption.value : ""; + this._media!.title[this._media!.languageID!] = title.value; + } + + // captionEnableHtml + if (captionEnableHtml) { + this._media!.captionEnableHtml = ~~captionEnableHtml.checked; + } else { + this._media!.captionEnableHtml = 0; + } + + const aclValues = { + allowAll: ~~(document.getElementById(`mediaEditor_${this._media!.mediaID}_aclAllowAll`)! as HTMLInputElement) + .checked, + group: [] as number[], + user: [] as number[], + }; + + content + .querySelectorAll(`input[name="mediaEditor_${this._media!.mediaID}_aclValues[group][]"]`) + .forEach((aclGroup: HTMLInputElement) => { + aclValues.group.push(~~aclGroup.value); + }); + + content + .querySelectorAll(`input[name="mediaEditor_${this._media!.mediaID}_aclValues[user][]"]`) + .forEach((aclUser: HTMLInputElement) => { + aclValues.user.push(~~aclUser.value); + }); + + if (!hasError) { + if (altTextError) { + altTextError.remove(); + } + if (captionError) { + captionError.remove(); + } + if (titleError) { + titleError.remove(); + } + + Ajax.api(this, { + actionName: "update", + objectIDs: [this._media!.mediaID], + parameters: { + aclValues: aclValues, + altText: this._media!.altText, + caption: this._media!.caption, + data: { + captionEnableHtml: this._media!.captionEnableHtml, + categoryID: this._media!.categoryID, + isMultilingual: this._media!.isMultilingual, + languageID: this._media!.languageID, + }, + title: this._media!.title, + }, + }); + } + } + + private mapToI18nValues(values: Map): I18nValues { + const obj = {}; + values.forEach((value, key) => (obj[key] = value)); + + return obj; + } + + /** + * Updates language-related input fields depending on whether multilingualis is enabled. + */ + protected _updateLanguageFields(event: Event | null, element?: HTMLInputElement): void { + if (event) { + element = event.currentTarget as HTMLInputElement; + } + + const mediaId = this._media!.mediaID; + const languageChooserContainer = document.getElementById(`mediaEditor_${mediaId}_languageIDContainer`)! + .parentNode! as HTMLElement; + + if (element!.checked) { + LanguageInput.enable(`title_${mediaId}`); + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.enable(`caption_${mediaId}`); + } + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.enable(`altText_${mediaId}`); + } + + languageChooserContainer.style.display = "none"; + } else { + LanguageInput.disable(`title_${mediaId}`); + if (document.getElementById(`caption_${mediaId}`)) { + LanguageInput.disable(`caption_${mediaId}`); + } + if (document.getElementById(`altText_${mediaId}`)) { + LanguageInput.disable(`altText_${mediaId}`); + } + + languageChooserContainer.style.display = "block"; + } + } + + /** + * Edits the media with the given data or id. + */ + public edit(editedMedia: Media | number): void { + let media: Media; + let mediaId = 0; + if (typeof editedMedia === "object") { + media = editedMedia; + mediaId = media.mediaID; + } else { + media = { + mediaID: editedMedia, + } as Media; + mediaId = editedMedia; + } + + if (this._media !== null) { + throw new Error(`Cannot edit media with id ${mediaId} while editing media with id '${this._media.mediaID}'.`); + } + + this._media = media; + + if (!this._dialogs.has(`mediaEditor_${mediaId}`)) { + this._dialogs.set(`mediaEditor_${mediaId}`, { + _dialogSetup: () => { + return { + id: `mediaEditor_${mediaId}`, + options: { + backdropCloseOnClick: false, + onClose: this._close.bind(this), + title: Language.get("wcf.media.edit"), + }, + source: { + after: this._initEditor.bind(this), + data: { + actionName: "getEditorDialog", + className: "wcf\\data\\media\\MediaAction", + objectIDs: [mediaId], + }, + }, + }; + }, + }); + } + + UiDialog.open(this._dialogs.get(`mediaEditor_${mediaId}`)!); + } + + /** + * Updates the data of the currently edited media file. + */ + public updateData(media: Media): void { + if (this._callbackObject._editorSuccess) { + this._callbackObject._editorSuccess(media); + } + } +} + +Core.enableLegacyInheritance(MediaEditor); + +export = MediaEditor;