From: Matthias Schmidt Date: Tue, 5 Jan 2021 17:43:33 +0000 (+0100) Subject: Convert `Media/Manager/Select` to TypeScript X-Git-Tag: 5.4.0_Alpha_1~461^2~6 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=6f03b3c693991d6da6a4b516d28c1cf062235cc6;p=GitHub%2FWoltLab%2FWCF.git Convert `Media/Manager/Select` to TypeScript --- diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Select.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Select.js index c1a4ae2316..ddb676de9e 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Select.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Select.js @@ -1,192 +1,158 @@ /** * Provides the media manager dialog for selecting media for input elements. * - * @author Matthias Schmidt - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Media/Manager/Select + * @author Matthias Schmidt + * @copyright 2001-2021 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Media/Manager/Select */ -define(['Core', 'Dom/Traverse', 'Dom/Util', 'Language', 'ObjectMap', 'Ui/Dialog', 'WoltLabSuite/Core/FileUtil', 'WoltLabSuite/Core/Media/Manager/Base'], function (Core, DomTraverse, DomUtil, Language, ObjectMap, UiDialog, FileUtil, MediaManagerBase) { +define(["require", "exports", "tslib", "./Base", "../../Core", "../../Dom/Traverse", "../../FileUtil", "../../Language", "../../Ui/Dialog"], function (require, exports, tslib_1, Base_1, Core, DomTraverse, FileUtil, Language, UiDialog) { "use strict"; - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function () { }; - Fake.prototype = { - _addButtonEventListeners: function () { }, - _chooseMedia: function () { }, - _click: function () { }, - getMode: function () { }, - setupMediaElement: function () { }, - _removeMedia: function () { }, - _clipboardAction: function () { }, - _dialogClose: function () { }, - _dialogInit: function () { }, - _dialogSetup: function () { }, - _dialogShow: function () { }, - _editMedia: function () { }, - _editorClose: function () { }, - _editorSuccess: function () { }, - _removeClipboardCheckboxes: function () { }, - _setMedia: function () { }, - addMedia: function () { }, - getDialog: function () { }, - getOption: function () { }, - removeMedia: function () { }, - resetMedia: function () { }, - setMedia: function () { } - }; - return Fake; - } - /** - * @constructor - */ - function MediaManagerSelect(options) { - MediaManagerBase.call(this, options); - this._activeButton = null; - this._buttons = elByClass(this._options.buttonClass || 'jsMediaSelectButton'); - this._storeElements = new ObjectMap(); - for (var i = 0, length = this._buttons.length; i < length; i++) { - var button = this._buttons[i]; - // only consider buttons with a proper store specified - var store = elData(button, 'store'); - if (store) { - var storeElement = elById(store); - if (storeElement && storeElement.tagName === 'INPUT') { - this._buttons[i].addEventListener('click', this._click.bind(this)); - this._storeElements.set(button, storeElement); - // add remove button - var removeButton = elCreate('p'); - removeButton.className = 'button'; - DomUtil.insertAfter(removeButton, button); - var icon = elCreate('span'); - icon.className = 'icon icon16 fa-times'; - removeButton.appendChild(icon); - if (!storeElement.value) - elHide(removeButton); - removeButton.addEventListener('click', this._removeMedia.bind(this)); + Base_1 = tslib_1.__importDefault(Base_1); + Core = tslib_1.__importStar(Core); + DomTraverse = tslib_1.__importStar(DomTraverse); + FileUtil = tslib_1.__importStar(FileUtil); + Language = tslib_1.__importStar(Language); + UiDialog = tslib_1.__importStar(UiDialog); + class MediaManagerSelect extends Base_1.default { + constructor(options) { + super(options); + this._activeButton = null; + this._storeElements = new WeakMap(); + this._buttons = document.getElementsByClassName(this._options.buttonClass || "jsMediaSelectButton"); + Array.from(this._buttons).forEach((button) => { + // only consider buttons with a proper store specified + const store = button.dataset.store; + if (store) { + const storeElement = document.getElementById(store); + if (storeElement && storeElement.tagName === "INPUT") { + button.addEventListener("click", this._click.bind(this)); + this._storeElements.set(button, storeElement); + // add remove button + const removeButton = document.createElement("p"); + removeButton.className = "button"; + button.insertAdjacentElement("afterend", removeButton); + const icon = document.createElement("span"); + icon.className = "icon icon16 fa-times"; + removeButton.appendChild(icon); + if (!storeElement.value) { + removeButton.style.display = "none"; + } + removeButton.addEventListener("click", (ev) => this._removeMedia(ev)); + } } - } + }); } - } - Core.inherit(MediaManagerSelect, MediaManagerBase, { - /** - * @see WoltLabSuite/Core/Media/Manager/Base#_addButtonEventListeners - */ - _addButtonEventListeners: function () { - MediaManagerSelect._super.prototype._addButtonEventListeners.call(this); + _addButtonEventListeners() { + super._addButtonEventListeners(); if (!this._mediaManagerMediaList) return; - var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI'); - for (var i = 0, length = listItems.length; i < length; i++) { - var listItem = listItems[i]; - var chooseIcon = elByClass('jsMediaSelectButton', listItem)[0]; + DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI").forEach((listItem) => { + const chooseIcon = listItem.querySelector(".jsMediaSelectButton"); if (chooseIcon) { - chooseIcon.classList.remove('jsMediaSelectButton'); - chooseIcon.addEventListener('click', this._chooseMedia.bind(this)); + chooseIcon.classList.remove("jsMediaSelectButton"); + chooseIcon.addEventListener("click", (ev) => this._chooseMedia(ev)); } - } - }, + }); + } /** * Handles clicking on a media choose icon. - * - * @param {Event} event click event */ - _chooseMedia: function (event) { + _chooseMedia(event) { if (this._activeButton === null) { throw new Error("Media cannot be chosen if no button is active."); } - var media = this._media.get(~~elData(event.currentTarget, 'object-id')); + const target = event.currentTarget; + const media = this._media.get(~~target.dataset.objectId); // save selected media in store element - var input = elById(elData(this._activeButton, 'store')); + const input = document.getElementById(this._activeButton.dataset.store); input.value = media.mediaID; - Core.triggerEvent(input, 'change'); + Core.triggerEvent(input, "change"); // display selected media - var display = elData(this._activeButton, 'display'); + const display = this._activeButton.dataset.display; if (display) { - var displayElement = elById(display); + const displayElement = document.getElementById(display); if (displayElement) { if (media.isImage) { - displayElement.innerHTML = '' + (media.altText && media.altText[LANGUAGE_ID] ? media.altText[LANGUAGE_ID] : '') + ''; + const thumbnailLink = media.smallThumbnailLink ? media.smallThumbnailLink : media.link; + const altText = media.altText && media.altText[window.LANGUAGE_ID] ? media.altText[window.LANGUAGE_ID] : ""; + displayElement.innerHTML = `${altText}`; } else { - var fileIcon = FileUtil.getIconNameByFilename(media.filename); + let fileIcon = FileUtil.getIconNameByFilename(media.filename); if (fileIcon) { - fileIcon = '-' + fileIcon; + fileIcon = "-" + fileIcon; } - displayElement.innerHTML = '
' - + '' - + '
' - + '

' + media.filename + '

' - + '

' + media.formattedFilesize + '

' - + '
' - + '
'; + displayElement.innerHTML = ` +
+ +
+

${media.filename}

+

${media.formattedFilesize}

+
+
`; } } } // show remove button - elShow(this._activeButton.nextElementSibling); + this._activeButton.nextElementSibling.style.removeProperty("display"); UiDialog.close(this); - }, - /** - * @see WoltLabSuite/Core/Media/Manager/Base#_click - */ - _click: function (event) { + } + _click(event) { event.preventDefault(); this._activeButton = event.currentTarget; - MediaManagerSelect._super.prototype._click.call(this, event); - if (!this._mediaManagerMediaList) + super._click(event); + if (!this._mediaManagerMediaList) { return; - var storeElement = this._storeElements.get(this._activeButton); - var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI'), listItem; - for (var i = 0, length = listItems.length; i < length; i++) { - listItem = listItems[i]; - if (storeElement.value && storeElement.value == elData(listItem, 'object-id')) { - listItem.classList.add('jsSelected'); + } + const storeElement = this._storeElements.get(this._activeButton); + DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI").forEach((listItem) => { + if (storeElement.value && storeElement.value == listItem.dataset.objectId) { + listItem.classList.add("jsSelected"); } else { - listItem.classList.remove('jsSelected'); + listItem.classList.remove("jsSelected"); } - } - }, - /** - * @see WoltLabSuite/Core/Media/Manager/Base#getMode - */ - getMode: function () { - return 'select'; - }, - /** - * @see WoltLabSuite/Core/Media/Manager/Base#setupMediaElement - */ - setupMediaElement: function (media, mediaElement) { - MediaManagerSelect._super.prototype.setupMediaElement.call(this, media, mediaElement); + }); + } + getMode() { + return "select"; + } + setupMediaElement(media, mediaElement) { + super.setupMediaElement(media, mediaElement); // add media insertion icon - var buttons = elBySel('nav.buttonGroupNavigation > ul', mediaElement); - var listItem = elCreate('li'); - listItem.className = 'jsMediaSelectButton'; - elData(listItem, 'object-id', media.mediaID); + const buttons = mediaElement.querySelector("nav.buttonGroupNavigation > ul"); + const listItem = document.createElement("li"); + listItem.className = "jsMediaSelectButton"; + listItem.dataset.objectId = media.mediaID; buttons.appendChild(listItem); - listItem.innerHTML = ' '; - }, + listItem.innerHTML = + ' "; + } /** * Handles clicking on the remove button. - * - * @param {Event} event click event */ - _removeMedia: function (event) { + _removeMedia(event) { event.preventDefault(); - var removeButton = event.currentTarget; - elHide(removeButton); - var button = removeButton.previousElementSibling; - var input = elById(elData(button, 'store')); - input.value = ''; - Core.triggerEvent(input, 'change'); - var display = elData(button, 'display'); + const removeButton = event.currentTarget; + const button = removeButton.previousElementSibling; + removeButton.remove(); + const input = document.getElementById(button.dataset.store); + input.value = ""; + Core.triggerEvent(input, "change"); + const display = button.dataset.display; if (display) { - var displayElement = elById(display); + const displayElement = document.getElementById(display); if (displayElement) { - displayElement.innerHTML = ''; + displayElement.innerHTML = ""; } } } - }); + } + Core.enableLegacyInheritance(MediaManagerSelect); return MediaManagerSelect; }); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.js deleted file mode 100644 index d0f397e033..0000000000 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.js +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Provides the media manager dialog for selecting media for input elements. - * - * @author Matthias Schmidt - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Media/Manager/Select - */ -define(['Core', 'Dom/Traverse', 'Dom/Util', 'Language', 'ObjectMap', 'Ui/Dialog', 'WoltLabSuite/Core/FileUtil', 'WoltLabSuite/Core/Media/Manager/Base'], - function(Core, DomTraverse, DomUtil, Language, ObjectMap, UiDialog, FileUtil, MediaManagerBase) { - "use strict"; - - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function() {}; - Fake.prototype = { - _addButtonEventListeners: function() {}, - _chooseMedia: function() {}, - _click: function() {}, - getMode: function() {}, - setupMediaElement: function() {}, - _removeMedia: function() {}, - _clipboardAction: function() {}, - _dialogClose: function() {}, - _dialogInit: function() {}, - _dialogSetup: function() {}, - _dialogShow: function() {}, - _editMedia: function() {}, - _editorClose: function() {}, - _editorSuccess: function() {}, - _removeClipboardCheckboxes: function() {}, - _setMedia: function() {}, - addMedia: function() {}, - getDialog: function() {}, - getOption: function() {}, - removeMedia: function() {}, - resetMedia: function() {}, - setMedia: function() {} - }; - return Fake; - } - - /** - * @constructor - */ - function MediaManagerSelect(options) { - MediaManagerBase.call(this, options); - - this._activeButton = null; - this._buttons = elByClass(this._options.buttonClass || 'jsMediaSelectButton'); - this._storeElements = new ObjectMap(); - - for (var i = 0, length = this._buttons.length; i < length; i++) { - var button = this._buttons[i]; - - // only consider buttons with a proper store specified - var store = elData(button, 'store'); - if (store) { - var storeElement = elById(store); - if (storeElement && storeElement.tagName === 'INPUT') { - this._buttons[i].addEventListener('click', this._click.bind(this)); - - this._storeElements.set(button, storeElement); - - // add remove button - var removeButton = elCreate('p'); - removeButton.className = 'button'; - DomUtil.insertAfter(removeButton, button); - - var icon = elCreate('span'); - icon.className = 'icon icon16 fa-times'; - removeButton.appendChild(icon); - - if (!storeElement.value) elHide(removeButton); - removeButton.addEventListener('click', this._removeMedia.bind(this)); - } - } - } - } - Core.inherit(MediaManagerSelect, MediaManagerBase, { - /** - * @see WoltLabSuite/Core/Media/Manager/Base#_addButtonEventListeners - */ - _addButtonEventListeners: function() { - MediaManagerSelect._super.prototype._addButtonEventListeners.call(this); - - if (!this._mediaManagerMediaList) return; - - var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI'); - for (var i = 0, length = listItems.length; i < length; i++) { - var listItem = listItems[i]; - - var chooseIcon = elByClass('jsMediaSelectButton', listItem)[0]; - if (chooseIcon) { - chooseIcon.classList.remove('jsMediaSelectButton'); - chooseIcon.addEventListener('click', this._chooseMedia.bind(this)); - } - } - }, - - /** - * Handles clicking on a media choose icon. - * - * @param {Event} event click event - */ - _chooseMedia: function(event) { - if (this._activeButton === null) { - throw new Error("Media cannot be chosen if no button is active."); - } - - var media = this._media.get(~~elData(event.currentTarget, 'object-id')); - - // save selected media in store element - var input = elById(elData(this._activeButton, 'store')); - input.value = media.mediaID; - Core.triggerEvent(input, 'change'); - - // display selected media - var display = elData(this._activeButton, 'display'); - if (display) { - var displayElement = elById(display); - if (displayElement) { - if (media.isImage) { - displayElement.innerHTML = '' + (media.altText && media.altText[LANGUAGE_ID] ? media.altText[LANGUAGE_ID] : '') + ''; - } - else { - var fileIcon = FileUtil.getIconNameByFilename(media.filename); - if (fileIcon) { - fileIcon = '-' + fileIcon; - } - - displayElement.innerHTML = '
' - + '' - + '
' - + '

' + media.filename + '

' - + '

' + media.formattedFilesize + '

' - + '
' - + '
'; - } - } - } - - // show remove button - elShow(this._activeButton.nextElementSibling); - - UiDialog.close(this); - }, - - /** - * @see WoltLabSuite/Core/Media/Manager/Base#_click - */ - _click: function(event) { - event.preventDefault(); - this._activeButton = event.currentTarget; - - MediaManagerSelect._super.prototype._click.call(this, event); - - if (!this._mediaManagerMediaList) return; - - var storeElement = this._storeElements.get(this._activeButton); - var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI'), listItem; - for (var i = 0, length = listItems.length; i < length; i++) { - listItem = listItems[i]; - if (storeElement.value && storeElement.value == elData(listItem, 'object-id')) { - listItem.classList.add('jsSelected'); - } - else { - listItem.classList.remove('jsSelected'); - } - } - }, - - /** - * @see WoltLabSuite/Core/Media/Manager/Base#getMode - */ - getMode: function() { - return 'select'; - }, - - /** - * @see WoltLabSuite/Core/Media/Manager/Base#setupMediaElement - */ - setupMediaElement: function(media, mediaElement) { - MediaManagerSelect._super.prototype.setupMediaElement.call(this, media, mediaElement); - - // add media insertion icon - var buttons = elBySel('nav.buttonGroupNavigation > ul', mediaElement); - - var listItem = elCreate('li'); - listItem.className = 'jsMediaSelectButton'; - elData(listItem, 'object-id', media.mediaID); - buttons.appendChild(listItem); - - listItem.innerHTML = ' '; - }, - - /** - * Handles clicking on the remove button. - * - * @param {Event} event click event - */ - _removeMedia: function(event) { - event.preventDefault(); - - var removeButton = event.currentTarget; - elHide(removeButton); - - var button = removeButton.previousElementSibling; - var input = elById(elData(button, 'store')); - input.value = ''; - Core.triggerEvent(input, 'change'); - var display = elData(button, 'display'); - if (display) { - var displayElement = elById(display); - if (displayElement) { - displayElement.innerHTML = ''; - } - } - } - }); - - return MediaManagerSelect; -}); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.ts new file mode 100644 index 0000000000..9b73f15022 --- /dev/null +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Media/Manager/Select.ts @@ -0,0 +1,191 @@ +/** + * Provides the media manager dialog for selecting media for input elements. + * + * @author Matthias Schmidt + * @copyright 2001-2021 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Media/Manager/Select + */ + +import MediaManager from "./Base"; +import * as Core from "../../Core"; +import { Media, MediaManagerSelectOptions } from "../Data"; +import * as DomTraverse from "../../Dom/Traverse"; +import * as FileUtil from "../../FileUtil"; +import * as Language from "../../Language"; +import * as UiDialog from "../../Ui/Dialog"; + +class MediaManagerSelect extends MediaManager { + protected _activeButton: HTMLElement | null = null; + protected readonly _buttons: HTMLCollectionOf; + protected readonly _storeElements = new WeakMap(); + + constructor(options: Partial) { + super(options); + + this._buttons = document.getElementsByClassName( + this._options.buttonClass || "jsMediaSelectButton", + ) as HTMLCollectionOf; + Array.from(this._buttons).forEach((button) => { + // only consider buttons with a proper store specified + const store = button.dataset.store; + if (store) { + const storeElement = document.getElementById(store) as HTMLInputElement; + if (storeElement && storeElement.tagName === "INPUT") { + button.addEventListener("click", this._click.bind(this)); + + this._storeElements.set(button, storeElement); + + // add remove button + const removeButton = document.createElement("p"); + removeButton.className = "button"; + button.insertAdjacentElement("afterend", removeButton); + + const icon = document.createElement("span"); + icon.className = "icon icon16 fa-times"; + removeButton.appendChild(icon); + + if (!storeElement.value) { + removeButton.style.display = "none"; + } + removeButton.addEventListener("click", (ev) => this._removeMedia(ev)); + } + } + }); + } + + protected _addButtonEventListeners(): void { + super._addButtonEventListeners(); + + if (!this._mediaManagerMediaList) return; + + DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI").forEach((listItem) => { + const chooseIcon = listItem.querySelector(".jsMediaSelectButton"); + if (chooseIcon) { + chooseIcon.classList.remove("jsMediaSelectButton"); + chooseIcon.addEventListener("click", (ev: MouseEvent) => this._chooseMedia(ev)); + } + }); + } + + /** + * Handles clicking on a media choose icon. + */ + protected _chooseMedia(event: MouseEvent): void { + if (this._activeButton === null) { + throw new Error("Media cannot be chosen if no button is active."); + } + + const target = event.currentTarget as HTMLElement; + + const media = this._media.get(~~target.dataset.objectId!)!; + + // save selected media in store element + const input = document.getElementById(this._activeButton.dataset.store!) as HTMLInputElement; + input.value = (media.mediaID as unknown) as string; + Core.triggerEvent(input, "change"); + + // display selected media + const display = this._activeButton.dataset.display; + if (display) { + const displayElement = document.getElementById(display); + if (displayElement) { + if (media.isImage) { + const thumbnailLink: string = media.smallThumbnailLink ? media.smallThumbnailLink : media.link; + const altText: string = + media.altText && media.altText[window.LANGUAGE_ID] ? media.altText[window.LANGUAGE_ID] : ""; + displayElement.innerHTML = `${altText}`; + } else { + let fileIcon = FileUtil.getIconNameByFilename(media.filename); + if (fileIcon) { + fileIcon = "-" + fileIcon; + } + + displayElement.innerHTML = ` +
+ +
+

${media.filename}

+

${media.formattedFilesize}

+
+
`; + } + } + } + + // show remove button + (this._activeButton.nextElementSibling as HTMLElement).style.removeProperty("display"); + + UiDialog.close(this); + } + + protected _click(event: MouseEvent): void { + event.preventDefault(); + this._activeButton = event.currentTarget as HTMLInputElement; + + super._click(event); + + if (!this._mediaManagerMediaList) { + return; + } + + const storeElement = this._storeElements.get(this._activeButton)!; + DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI").forEach((listItem) => { + if (storeElement.value && storeElement.value == listItem.dataset.objectId) { + listItem.classList.add("jsSelected"); + } else { + listItem.classList.remove("jsSelected"); + } + }); + } + + public getMode(): string { + return "select"; + } + + public setupMediaElement(media: Media, mediaElement: HTMLElement): void { + super.setupMediaElement(media, mediaElement); + + // add media insertion icon + const buttons = mediaElement.querySelector("nav.buttonGroupNavigation > ul") as HTMLUListElement; + + const listItem = document.createElement("li"); + listItem.className = "jsMediaSelectButton"; + listItem.dataset.objectId = (media.mediaID as unknown) as string; + buttons.appendChild(listItem); + + listItem.innerHTML = + ' "; + } + + /** + * Handles clicking on the remove button. + */ + protected _removeMedia(event: MouseEvent): void { + event.preventDefault(); + + const removeButton = event.currentTarget as HTMLSpanElement; + const button = removeButton.previousElementSibling as HTMLElement; + + removeButton.remove(); + + const input = document.getElementById(button.dataset.store!) as HTMLInputElement; + input.value = ""; + Core.triggerEvent(input, "change"); + const display = button.dataset.display; + if (display) { + const displayElement = document.getElementById(display); + if (displayElement) { + displayElement.innerHTML = ""; + } + } + } +} + +Core.enableLegacyInheritance(MediaManagerSelect); + +export = MediaManagerSelect;