EventHandler.add("com.woltlab.wcf.media.upload", "removedErroneousUploadRow", () => deleteCallback());
// eslint-disable-next-line
//@ts-ignore
- var deleteAction = new WCF.Action.Delete("wcf\\data\\media\\MediaAction", ".jsMediaRow");
+ const deleteAction = new WCF.Action.Delete("wcf\\data\\media\\MediaAction", ".jsMediaRow");
deleteAction.setCallback(deleteCallback);
addButtonEventListeners();
DomChangeListener.add("WoltLabSuite/Core/Controller/Media/List", () => addButtonEventListeners());
* Is triggered after media files have been deleted using the delete icon.
*/
function deleteCallback(objectIds) {
- var tableRowCount = _tableBody.getElementsByTagName("tr").length;
+ const tableRowCount = _tableBody.getElementsByTagName("tr").length;
if (objectIds === undefined) {
if (!tableRowCount) {
window.location.reload();
window.location.reload();
}
else {
- Clipboard.reload.bind(Clipboard);
+ Clipboard.reload();
}
}
/**
*/
function openEditorAfterUpload(data) {
if (data.upload === _upload && !data.isMultiFileUpload && !_upload.hasPendingUploads()) {
- var keys = Object.keys(data.media);
+ const keys = Object.keys(data.media);
if (keys.length) {
_mediaEditor.edit(data.media[keys[0]]);
}
/**
* Formats the given filesize.
*/
- function formatFilesize(byte, precision) {
- if (precision === undefined) {
- precision = 2;
- }
+ function formatFilesize(byte, precision = 2) {
let symbol = "Byte";
if (byte >= 1000) {
byte /= 1000;
*/
_initEditor(content, data) {
this._availableLanguageCount = ~~data.returnValues.availableLanguageCount;
- this._categoryIds = data.returnValues.categoryIDs.map(function (number) {
- return ~~number;
- });
+ this._categoryIds = data.returnValues.categoryIDs.map((number) => number);
if (data.returnValues.mediaData) {
this._media = data.returnValues.mediaData;
}
}
if (this._categoryIds.length) {
const categoryID = content.querySelector("select[name=categoryID]");
- categoryID.value = this._media.categoryID;
+ if (this._media.categoryID) {
+ categoryID.value = this._media.categoryID.toString();
+ }
+ else {
+ categoryID.value = "0";
+ }
}
const title = content.querySelector("input[name=title]");
const altText = content.querySelector("input[name=altText]");
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");
+ const altTextError = altText ? DomTraverse.childByClass(altText.parentNode, "innerError") : false;
+ const captionError = caption ? DomTraverse.childByClass(caption.parentNode, "innerError") : false;
+ const titleError = DomTraverse.childByClass(title.parentNode, "innerError");
// category
this._oldCategoryId = this._media.categoryID;
if (this._categoryIds.length) {
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);
+ DomUtil.innerError(altText, Language.get("wcf.global.form.error.multilingual"));
}
}
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);
+ DomUtil.innerError(caption, Language.get("wcf.global.form.error.multilingual"));
}
}
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);
+ DomUtil.innerError(title, Language.get("wcf.global.form.error.multilingual"));
}
}
this._media.altText = altText ? this.mapToI18nValues(LanguageInput.getValues(altText.id)) : "";
const aclValues = {
allowAll: ~~document.getElementById(`mediaEditor_${this._media.mediaID}_aclAllowAll`)
.checked,
- group: [],
- user: [],
+ group: Array.from(content.querySelectorAll(`input[name="mediaEditor_${this._media.mediaID}_aclValues[group][]"]`)).map((aclGroup) => ~~aclGroup.value),
+ user: Array.from(content.querySelectorAll(`input[name="mediaEditor_${this._media.mediaID}_aclValues[user][]"]`)).map((aclUser) => ~~aclUser.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) {
altTextError.remove();
if (document.getElementById(`altText_${mediaId}`)) {
LanguageInput.enable(`altText_${mediaId}`);
}
- languageChooserContainer.style.display = "none";
+ DomUtil.hide(languageChooserContainer);
}
else {
LanguageInput.disable(`title_${mediaId}`);
if (document.getElementById(`altText_${mediaId}`)) {
LanguageInput.disable(`altText_${mediaId}`);
}
- languageChooserContainer.style.display = "block";
+ DomUtil.show(languageChooserContainer);
}
}
/**
id: `mediaEditor_${mediaId}`,
options: {
backdropCloseOnClick: false,
- onClose: this._close.bind(this),
+ onClose: () => this._close(),
title: Language.get("wcf.media.edit"),
},
source: {
- after: this._initEditor.bind(this),
+ after: (content, responseData) => this._initEditor(content, responseData),
data: {
actionName: "getEditorDialog",
className: "wcf\\data\\media\\MediaAction",
constructor(options) {
this._forceClipboard = false;
this._hadInitiallyMarkedItems = false;
- this._id = `mediaManager${mediaManagerCounter++}`;
this._listItems = new Map();
this._media = new Map();
this._mediaEditor = null;
imagesOnly: false,
minSearchLength: 3,
}, options);
+ this._id = `mediaManager${mediaManagerCounter++}`;
if (Permission.get("admin.content.cms.canManageMedia")) {
this._mediaEditor = new Editor_1.default(this);
}
this._mediaManagerMediaList = dialog.querySelector(".mediaManagerMediaList");
this._mediaCategorySelect = dialog.querySelector(".mediaManagerCategoryList > select");
if (this._mediaCategorySelect) {
- this._mediaCategorySelect.addEventListener("change", this._categoryChange.bind(this));
+ this._mediaCategorySelect.addEventListener("change", () => this._categoryChange());
}
// store list items locally
const listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI");
DomUtil.replaceElement(UiDialog.getDialog(this).content.querySelector(".jsPagination"), newPagination);
this._pagination = new Pagination_1.default(newPagination, {
activePage: pageNo,
- callbackSwitch: this._search.search.bind(this._search),
+ callbackSwitch: (pageNo) => this._search.search(pageNo),
maxPage: pageCount,
});
}
else if (this._pagination) {
- this._pagination.getElement().style.display = "none";
+ DomUtil.hide(this._pagination.getElement());
}
}
/**
* Sets the displayed media (after a search).
*/
_setMedia(media) {
- this._media = new Map();
- Object.entries(media).forEach(([mediaId, media]) => {
- this._media.set(~~mediaId, media);
- });
+ this._media = new Map(Object.entries(media).map(([mediaId, media]) => [~~mediaId, media]));
let info = DomTraverse.nextByClass(this._mediaManagerMediaList, "info");
if (this._media.size) {
if (info) {
- info.style.display = "none";
+ DomUtil.hide(info);
}
}
else {
info.className = "info";
info.textContent = Language.get("wcf.media.search.noResults");
}
- info.style.display = "block";
+ DomUtil.show(info);
DomUtil.insertAfter(info, this._mediaManagerMediaList);
}
DomTraverse.childrenByTag(this._mediaManagerMediaList, "LI").forEach((listItem) => {
if (!this._media.has(~~listItem.dataset.objectId)) {
- listItem.style.display = "none";
+ DomUtil.hide(listItem);
}
else {
- listItem.style.display = "block";
+ DomUtil.show(listItem);
}
});
DomChangeListener.trigger();
const checkbox = document.createElement("input");
checkbox.className = "jsClipboardItem";
checkbox.type = "checkbox";
- checkbox.dataset.objectId = media.mediaID;
+ checkbox.dataset.objectId = media.mediaID.toString();
label.appendChild(checkbox);
if (Permission.get("admin.content.cms.canManageMedia")) {
const editButton = document.createElement("li");
editButton.className = "jsMediaEditButton";
- editButton.dataset.objectId = media.mediaID;
+ editButton.dataset.objectId = media.mediaID.toString();
buttons.appendChild(editButton);
editButton.innerHTML = `
<a>
</a>`;
const deleteButton = document.createElement("li");
deleteButton.className = "jsDeleteButton";
- deleteButton.dataset.objectId = media.mediaID;
+ deleteButton.dataset.objectId = media.mediaID.toString();
// use temporary title to not unescape html in filename
const uuid = Core.getUuid();
deleteButton.dataset.confirmMessageHtml = StringUtil.unescapeHTML(Language.get("wcf.media.delete.confirmMessage", {
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLabSuite/Core/Media/Manager/Editor
*/
-define(["require", "exports", "tslib", "./Base", "../../Core", "../../Event/Handler", "../../Dom/Traverse", "../../Language", "../../Ui/Dialog", "../../Controller/Clipboard"], function (require, exports, tslib_1, Base_1, Core, EventHandler, DomTraverse, Language, UiDialog, Clipboard) {
+define(["require", "exports", "tslib", "./Base", "../../Core", "../../Event/Handler", "../../Dom/Traverse", "../../Language", "../../Ui/Dialog", "../../Controller/Clipboard", "../../Dom/Util"], function (require, exports, tslib_1, Base_1, Core, EventHandler, DomTraverse, Language, UiDialog, Clipboard, Util_1) {
"use strict";
Base_1 = tslib_1.__importDefault(Base_1);
Core = tslib_1.__importStar(Core);
Language = tslib_1.__importStar(Language);
UiDialog = tslib_1.__importStar(UiDialog);
Clipboard = tslib_1.__importStar(Clipboard);
+ Util_1 = tslib_1.__importDefault(Util_1);
class MediaManagerEditor extends Base_1.default {
constructor(options) {
options = Core.extend({
return {
id: this._getInsertDialogId(),
options: {
- onClose: this._editorClose.bind(this),
+ onClose: () => this._editorClose(),
onSetup: (content) => {
content.querySelector(".buttonPrimary").addEventListener("click", (ev) => this._insertMedia(ev));
- content.querySelector(".thumbnailSizeSelection").style.display = "block";
+ Util_1.default.show(content.querySelector(".thumbnailSizeSelection"));
},
title: Language.get("wcf.media.insert"),
},
_getThumbnailSizes() {
return ["small", "medium", "large"]
.map((size) => {
- let supportSize = true;
- this._mediaToInsert.forEach(function (media) {
- if (!media[size + "ThumbnailType"]) {
- supportSize = false;
- }
+ const supportSize = Array.from(this._mediaToInsert).every(([_mediaId, media]) => {
+ return media[size + "ThumbnailType"] !== null;
});
if (supportSize) {
return size;
}
}
if (this._mediaToInsertByClipboard) {
- const mediaIds = [];
- this._mediaToInsert.forEach(function (media) {
- mediaIds.push(~~media.mediaID);
- });
- Clipboard.unmark("com.woltlab.wcf.media", mediaIds);
+ Clipboard.unmark("com.woltlab.wcf.media", Array.from(this._mediaToInsert.keys()));
}
this._mediaToInsert = new Map();
this._mediaToInsertByClipboard = false;
this._mediaToInsert = new Map();
this._mediaToInsertByClipboard = insertedByClipboard || false;
// open the insert dialog if all media files are images
- let imagesOnly = true, media;
- for (let i = 0, length = mediaIds.length; i < length; i++) {
- media = this._media.get(mediaIds[i]);
+ let imagesOnly = true;
+ mediaIds.forEach((mediaId) => {
+ const media = this._media.get(mediaId);
this._mediaToInsert.set(media.mediaID, media);
if (!media.isImage) {
imagesOnly = false;
}
- }
+ });
if (imagesOnly) {
const thumbnailSizes = this._getThumbnailSizes();
if (thumbnailSizes.length) {
const buttons = mediaElement.querySelector("nav.buttonGroupNavigation > ul");
const listItem = document.createElement("li");
listItem.className = "jsMediaInsertButton";
- listItem.dataset.objectId = media.mediaID;
+ listItem.dataset.objectId = media.mediaID.toString();
buttons.appendChild(listItem);
listItem.innerHTML = `
<a>
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLabSuite/Core/Media/Manager/Search
*/
-define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Language", "../../Ajax", "../../Core"], function (require, exports, tslib_1, DomTraverse, Language, Ajax, Core) {
+define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Language", "../../Ajax", "../../Core", "../../Dom/Util"], function (require, exports, tslib_1, DomTraverse, Language, Ajax, Core, Util_1) {
"use strict";
DomTraverse = tslib_1.__importStar(DomTraverse);
Language = tslib_1.__importStar(Language);
Ajax = tslib_1.__importStar(Ajax);
Core = tslib_1.__importStar(Core);
+ Util_1 = tslib_1.__importDefault(Util_1);
class MediaManagerSearch {
constructor(mediaManager) {
this._searchMode = false;
_hideStringThresholdError() {
const innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, "innerInfo");
if (innerInfo) {
- innerInfo.style.display = "none";
+ Util_1.default.hide(innerInfo);
}
}
/**
_showStringThresholdError() {
let innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, "innerInfo");
if (innerInfo) {
- innerInfo.style.display = "block";
+ Util_1.default.show(innerInfo);
}
else {
innerInfo = document.createElement("p");
* Hides the media search.
*/
hideSearch() {
- this._searchContainer.style.display = "none";
+ Util_1.default.hide(this._searchContainer);
}
/**
* Resets the media search.
* Shows the media search.
*/
showSearch() {
- this._searchContainer.style.display = "block";
+ Util_1.default.show(this._searchContainer);
}
/**
* Sends an AJAX request to fetch search results.
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLabSuite/Core/Media/Manager/Select
*/
-define(["require", "exports", "tslib", "./Base", "../../Core", "../../Dom/Traverse", "../../FileUtil", "../../Language", "../../Ui/Dialog"], function (require, exports, tslib_1, Base_1, Core, DomTraverse, FileUtil, Language, UiDialog) {
+define(["require", "exports", "tslib", "./Base", "../../Core", "../../Dom/Traverse", "../../FileUtil", "../../Language", "../../Ui/Dialog", "../../Dom/Util"], function (require, exports, tslib_1, Base_1, Core, DomTraverse, FileUtil, Language, UiDialog, Util_1) {
"use strict";
Base_1 = tslib_1.__importDefault(Base_1);
Core = tslib_1.__importStar(Core);
FileUtil = tslib_1.__importStar(FileUtil);
Language = tslib_1.__importStar(Language);
UiDialog = tslib_1.__importStar(UiDialog);
+ Util_1 = tslib_1.__importDefault(Util_1);
class MediaManagerSelect extends Base_1.default {
constructor(options) {
super(options);
if (store) {
const storeElement = document.getElementById(store);
if (storeElement && storeElement.tagName === "INPUT") {
- button.addEventListener("click", this._click.bind(this));
+ button.addEventListener("click", (ev) => this._click(ev));
this._storeElements.set(button, storeElement);
// add remove button
const removeButton = document.createElement("p");
icon.className = "icon icon16 fa-times";
removeButton.appendChild(icon);
if (!storeElement.value) {
- removeButton.style.display = "none";
+ Util_1.default.hide(removeButton);
}
removeButton.addEventListener("click", (ev) => this._removeMedia(ev));
}
const media = this._media.get(~~target.dataset.objectId);
// save selected media in store element
const input = document.getElementById(this._activeButton.dataset.store);
- input.value = media.mediaID;
+ input.value = media.mediaID.toString();
Core.triggerEvent(input, "change");
// display selected media
const display = this._activeButton.dataset.display;
const buttons = mediaElement.querySelector("nav.buttonGroupNavigation > ul");
const listItem = document.createElement("li");
listItem.className = "jsMediaSelectButton";
- listItem.dataset.objectId = media.mediaID;
+ listItem.dataset.objectId = media.mediaID.toString();
buttons.appendChild(listItem);
listItem.innerHTML =
'<a><span class="icon icon16 fa-check jsTooltip" title="' +
*/
define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", "../Dom/Traverse", "../Language", "../User", "../Date/Util", "../FileUtil", "../Dom/Change/Listener", "../Event/Handler"], function (require, exports, tslib_1, Upload_1, Core, DomUtil, DomTraverse, Language, User_1, DateUtil, FileUtil, DomChangeListener, EventHandler) {
"use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.MediaUpload = void 0;
Upload_1 = tslib_1.__importDefault(Upload_1);
Core = tslib_1.__importStar(Core);
DomUtil = tslib_1.__importStar(DomUtil);
}
Array.from(fileElement.getElementsByTagName("TD")).forEach((cell) => {
if (cell.classList.contains("columnMark")) {
- cell.querySelectorAll("[data-object-id]").forEach((el) => (el.style.display = "none"));
+ cell.querySelectorAll("[data-object-id]").forEach((el) => DomUtil.hide(el));
}
else if (cell.classList.contains("columnIcon")) {
- cell.querySelectorAll("[data-object-id]").forEach((el) => (el.style.display = "none"));
+ cell.querySelectorAll("[data-object-id]").forEach((el) => DomUtil.hide(el));
cell.querySelector(".mediaEditButton").classList.add("jsMediaEditButton");
cell.querySelector(".jsDeleteButton").dataset.confirmMessageHtml = Language.get("wcf.media.delete.confirmMessage", {
title: file.name,
if (media) {
// update object id
file.querySelectorAll("[data-object-id]").forEach((el) => {
- el.dataset.objectId = media.mediaID;
+ el.dataset.objectId = media.mediaID.toString();
el.style.removeProperty("display");
});
- file.querySelector(".columnMediaID").textContent = media.mediaID;
+ file.querySelector(".columnMediaID").textContent = media.mediaID.toString();
// update icon
this._replaceFileIcon(file.querySelector(".fa-spinner"), media, 48);
}
}
const fileIcon = file.querySelector(".fa-spinner");
fileIcon.classList.remove("fa-spinner");
- fileIcon.classList.add("fa-remove");
- fileIcon.classList.add("pointer");
- fileIcon.classList.add("jsTooltip");
+ fileIcon.classList.add("fa-remove", "pointer", "jsTooltip");
fileIcon.title = Language.get("wcf.global.button.delete");
fileIcon.addEventListener("click", (event) => {
const target = event.currentTarget;
- target.parentNode.parentNode.parentNode.remove();
+ target.closest(".mediaFile").remove();
EventHandler.fire("com.woltlab.wcf.media.upload", "removedErroneousUploadRow");
});
file.classList.add("uploadFailed");
const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "SPAN");
this._replaceFileIcon(fileIcon, media, 144);
file.className = "jsClipboardObject mediaFile";
- file.dataset.objectId = media.mediaID;
+ file.dataset.objectId = media.mediaID.toString();
if (this._mediaManager) {
this._mediaManager.setupMediaElement(media, file);
this._mediaManager.addMedia(media, file);
}
const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "SPAN");
fileIcon.classList.remove("fa-spinner");
- fileIcon.classList.add("fa-remove");
- fileIcon.classList.add("pointer");
- file.classList.add("uploadFailed");
- file.classList.add("jsTooltip");
+ fileIcon.classList.add("fa-remove", "pointer");
+ file.classList.add("uploadFailed", "jsTooltip");
file.title = Language.get("wcf.global.button.delete");
file.addEventListener("click", () => file.remove());
const title = DomTraverse.childByClass(DomTraverse.childByClass(file, "mediaInformation"), "mediaTitle");
});
}
}
- exports.MediaUpload = MediaUpload;
Core.enableLegacyInheritance(MediaUpload);
- exports.default = MediaUpload;
+ return MediaUpload;
});
const _tableBody = document.getElementById("mediaListTableBody")!;
let _upload: MediaListUpload;
-type MediaListOptions = {
+interface MediaListOptions {
categoryId?: number;
hasMarkedItems?: boolean;
-};
+}
export function init(options: MediaListOptions): void {
options = options || {};
// eslint-disable-next-line
//@ts-ignore
- var deleteAction = new WCF.Action.Delete("wcf\\data\\media\\MediaAction", ".jsMediaRow");
+ const deleteAction = new WCF.Action.Delete("wcf\\data\\media\\MediaAction", ".jsMediaRow");
deleteAction.setCallback(deleteCallback);
addButtonEventListeners();
* Is triggered after media files have been deleted using the delete icon.
*/
function deleteCallback(objectIds?: number[]): void {
- var tableRowCount = _tableBody.getElementsByTagName("tr").length;
+ const tableRowCount = _tableBody.getElementsByTagName("tr").length;
if (objectIds === undefined) {
if (!tableRowCount) {
window.location.reload();
// table is empty, reload page
window.location.reload();
} else {
- Clipboard.reload.bind(Clipboard);
+ Clipboard.reload();
}
}
*/
function openEditorAfterUpload(data: MediaUploadSuccessEventData) {
if (data.upload === _upload && !data.isMultiFileUpload && !_upload.hasPendingUploads()) {
- var keys = Object.keys(data.media);
+ const keys = Object.keys(data.media);
if (keys.length) {
_mediaEditor.edit(data.media[keys[0]]);
*/
function clipboardDeleteMedia(mediaIds: number[]) {
Array.from(document.getElementsByClassName("jsMediaRow")).forEach((media) => {
- const mediaID = ~~media.querySelector<HTMLElement>(".jsClipboardItem")!.dataset.objectId!;
+ const mediaID = ~~(media.querySelector(".jsClipboardItem") as HTMLElement).dataset.objectId!;
if (mediaIds.indexOf(mediaID) !== -1) {
media.remove();
/**
* Formats the given filesize.
*/
-export function formatFilesize(byte: number, precision?: number): string {
- if (precision === undefined) {
- precision = 2;
- }
-
+export function formatFilesize(byte: number, precision = 2): string {
let symbol = "Byte";
if (byte >= 1000) {
byte /= 1000;
let clipboardObjectIds: number[] = [];
-type ClipboardActionData = {
+interface ClipboardActionData {
data: {
- actionName: string;
+ actionName: "com.woltlab.wcf.media.delete" | "com.woltlab.wcf.media.insert" | "com.woltlab.wcf.media.setCategory";
parameters: {
objectIDs: number[];
};
};
responseData: null;
-};
+}
/**
* Handles successful clipboard actions.
import MediaReplace from "./Replace";
import { I18nValues } from "../Language/Input";
-type InitEditorData = {
+interface InitEditorData {
returnValues: {
availableLanguageCount: number;
categoryIDs: number[];
mediaData?: Media;
};
-};
+}
class MediaEditor implements AjaxCallbackObject {
protected _availableLanguageCount = 1;
*/
protected _initEditor(content: HTMLElement, data: InitEditorData): void {
this._availableLanguageCount = ~~data.returnValues.availableLanguageCount;
- this._categoryIds = data.returnValues.categoryIDs.map(function (number) {
- return ~~number;
- });
+ this._categoryIds = data.returnValues.categoryIDs.map((number) => number);
if (data.returnValues.mediaData) {
this._media = data.returnValues.mediaData;
if (this._categoryIds.length) {
const categoryID = content.querySelector("select[name=categoryID]") as HTMLSelectElement;
- categoryID.value = (this._media!.categoryID as unknown) as string;
+ if (this._media!.categoryID) {
+ categoryID.value = this._media!.categoryID.toString();
+ } else {
+ categoryID.value = "0";
+ }
}
const title = content.querySelector("input[name=title]") 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");
+ const altTextError = altText ? DomTraverse.childByClass(altText.parentNode! as HTMLElement, "innerError") : false;
+ const captionError = caption ? DomTraverse.childByClass(caption.parentNode! as HTMLElement, "innerError") : false;
+ const titleError = DomTraverse.childByClass(title.parentNode! as HTMLElement, "innerError");
// category
this._oldCategoryId = this._media!.categoryID;
if (this._categoryIds.length) {
- this._media!.categoryID = ~~categoryId!.value;
+ this._media!.categoryID = ~~categoryId.value;
// if the selected category id not valid (manipulated DOM), ignore
if (this._categoryIds.indexOf(this._media!.categoryID) === -1) {
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);
+ DomUtil.innerError(altText, Language.get("wcf.global.form.error.multilingual"));
}
}
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);
+ DomUtil.innerError(caption, Language.get("wcf.global.form.error.multilingual"));
}
}
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);
+ DomUtil.innerError(title, Language.get("wcf.global.form.error.multilingual"));
}
}
const aclValues = {
allowAll: ~~(document.getElementById(`mediaEditor_${this._media!.mediaID}_aclAllowAll`)! as HTMLInputElement)
.checked,
- group: [] as number[],
- user: [] as number[],
+ group: Array.from(
+ content.querySelectorAll(`input[name="mediaEditor_${this._media!.mediaID}_aclValues[group][]"]`),
+ ).map((aclGroup: HTMLInputElement) => ~~aclGroup.value),
+ user: Array.from(
+ content.querySelectorAll(`input[name="mediaEditor_${this._media!.mediaID}_aclValues[user][]"]`),
+ ).map((aclUser: HTMLInputElement) => ~~aclUser.value),
};
- 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();
LanguageInput.enable(`altText_${mediaId}`);
}
- languageChooserContainer.style.display = "none";
+ DomUtil.hide(languageChooserContainer);
} else {
LanguageInput.disable(`title_${mediaId}`);
if (document.getElementById(`caption_${mediaId}`)) {
LanguageInput.disable(`altText_${mediaId}`);
}
- languageChooserContainer.style.display = "block";
+ DomUtil.show(languageChooserContainer);
}
}
id: `mediaEditor_${mediaId}`,
options: {
backdropCloseOnClick: false,
- onClose: this._close.bind(this),
+ onClose: () => this._close(),
title: Language.get("wcf.media.edit"),
},
source: {
- after: this._initEditor.bind(this),
+ after: (content: HTMLElement, responseData: InitEditorData) => this._initEditor(content, responseData),
data: {
actionName: "getEditorDialog",
className: "wcf\\data\\media\\MediaAction",
let mediaManagerCounter = 0;
-type DialogInitAjaxResponseData = {
+interface DialogInitAjaxResponseData {
returnValues: {
hasMarkedItems: number;
media: object;
pageCount: number;
};
-};
+}
-type SetMediaAdditionalData = {
+interface SetMediaAdditionalData {
pageCount: number;
pageNo: number;
-};
+}
abstract class MediaManager<TOptions extends MediaManagerOptions = MediaManagerOptions>
implements DialogCallbackObject, MediaEditorCallbackObject {
protected _forceClipboard = false;
protected _hadInitiallyMarkedItems = false;
- protected readonly _id = `mediaManager${mediaManagerCounter++}`;
+ protected readonly _id;
protected readonly _listItems = new Map<number, HTMLLIElement>();
protected _media = new Map<number, Media>();
protected _mediaCategorySelect: HTMLSelectElement | null;
options,
) as TOptions;
+ this._id = `mediaManager${mediaManagerCounter++}`;
+
if (Permission.get("admin.content.cms.canManageMedia")) {
this._mediaEditor = new MediaEditor(this);
}
const editIcon = listItem.querySelector(".jsMediaEditButton");
if (editIcon) {
editIcon.classList.remove("jsMediaEditButton");
- editIcon.addEventListener("click", (ev: MouseEvent) => this._editMedia(ev));
+ editIcon.addEventListener("click", (ev) => this._editMedia(ev));
}
});
}
/**
* Handles clicks on the media manager button.
*/
- protected _click(event: MouseEvent): void {
+ protected _click(event: Event): void {
event.preventDefault();
UiDialog.open(this);
this._mediaCategorySelect = dialog.querySelector(".mediaManagerCategoryList > select");
if (this._mediaCategorySelect) {
- this._mediaCategorySelect.addEventListener("change", this._categoryChange.bind(this));
+ this._mediaCategorySelect.addEventListener("change", () => this._categoryChange());
}
// store list items locally
/**
* Opens the media editor for a media file.
*/
- protected _editMedia(event: MouseEvent): void {
+ protected _editMedia(event: Event): void {
if (!Permission.get("admin.content.cms.canManageMedia")) {
throw new Error("You are not allowed to edit media files.");
}
this._pagination = new UiPagination(newPagination, {
activePage: pageNo,
- callbackSwitch: this._search!.search.bind(this._search),
+ callbackSwitch: (pageNo: number) => this._search!.search(pageNo),
maxPage: pageCount,
});
} else if (this._pagination) {
- this._pagination.getElement().style.display = "none";
+ DomUtil.hide(this._pagination.getElement());
}
}
* Sets the displayed media (after a search).
*/
_setMedia(media: object): void {
- this._media = new Map<number, Media>();
- Object.entries(media).forEach(([mediaId, media]) => {
- this._media.set(~~mediaId, media);
- });
+ this._media = new Map<number, Media>(Object.entries(media).map(([mediaId, media]) => [~~mediaId, media]));
let info = DomTraverse.nextByClass(this._mediaManagerMediaList!, "info") as HTMLElement;
if (this._media.size) {
if (info) {
- info.style.display = "none";
+ DomUtil.hide(info);
}
} else {
if (info === null) {
info.textContent = Language.get("wcf.media.search.noResults");
}
- info.style.display = "block";
+ DomUtil.show(info);
DomUtil.insertAfter(info, this._mediaManagerMediaList!);
}
DomTraverse.childrenByTag(this._mediaManagerMediaList!, "LI").forEach((listItem) => {
if (!this._media.has(~~listItem.dataset.objectId!)) {
- listItem.style.display = "none";
+ DomUtil.hide(listItem);
} else {
- listItem.style.display = "block";
+ DomUtil.show(listItem);
}
});
const checkbox = document.createElement("input");
checkbox.className = "jsClipboardItem";
checkbox.type = "checkbox";
- checkbox.dataset.objectId = (media.mediaID as unknown) as string;
+ checkbox.dataset.objectId = media.mediaID.toString();
label.appendChild(checkbox);
if (Permission.get("admin.content.cms.canManageMedia")) {
const editButton = document.createElement("li");
editButton.className = "jsMediaEditButton";
- editButton.dataset.objectId = (media.mediaID as unknown) as string;
+ editButton.dataset.objectId = media.mediaID.toString();
buttons.appendChild(editButton);
editButton.innerHTML = `
const deleteButton = document.createElement("li");
deleteButton.className = "jsDeleteButton";
- deleteButton.dataset.objectId = (media.mediaID as unknown) as string;
+ deleteButton.dataset.objectId = media.mediaID.toString();
// use temporary title to not unescape html in filename
const uuid = Core.getUuid();
import * as UiDialog from "../../Ui/Dialog";
import * as Clipboard from "../../Controller/Clipboard";
import { OnDropPayload } from "../../Ui/Redactor/DragAndDrop";
+import DomUtil from "../../Dom/Util";
type PasteFromClipboard = {
blob: Blob;
const insertIcon = listItem.querySelector(".jsMediaInsertButton");
if (insertIcon) {
insertIcon.classList.remove("jsMediaInsertButton");
- insertIcon.addEventListener("click", (ev: MouseEvent) => this._openInsertDialog(ev));
+ insertIcon.addEventListener("click", (ev) => this._openInsertDialog(ev));
}
});
}
return {
id: this._getInsertDialogId(),
options: {
- onClose: this._editorClose.bind(this),
+ onClose: () => this._editorClose(),
onSetup: (content) => {
content.querySelector(".buttonPrimary")!.addEventListener("click", (ev) => this._insertMedia(ev));
- (content.querySelector(".thumbnailSizeSelection") as HTMLElement).style.display = "block";
+ DomUtil.show(content.querySelector(".thumbnailSizeSelection") as HTMLElement);
},
title: Language.get("wcf.media.insert"),
},
});
}
- protected _click(event: MouseEvent): void {
+ protected _click(event: Event): void {
this._activeButton = event.currentTarget;
super._click(event);
protected _getThumbnailSizes(): string[] {
return ["small", "medium", "large"]
.map((size) => {
- let supportSize = true;
- this._mediaToInsert.forEach(function (media) {
- if (!media[size + "ThumbnailType"]) {
- supportSize = false;
- }
+ const supportSize = Array.from(this._mediaToInsert).every(([_mediaId, media]) => {
+ return media[size + "ThumbnailType"] !== null;
});
if (supportSize) {
}
if (this._mediaToInsertByClipboard) {
- const mediaIds: number[] = [];
- this._mediaToInsert.forEach(function (media) {
- mediaIds.push(~~media.mediaID);
- });
-
- Clipboard.unmark("com.woltlab.wcf.media", mediaIds);
+ Clipboard.unmark("com.woltlab.wcf.media", Array.from(this._mediaToInsert.keys()));
}
this._mediaToInsert = new Map<number, Media>();
/**
* Handles clicking on the insert button.
*/
- protected _openInsertDialog(event: MouseEvent): void {
+ protected _openInsertDialog(event: Event): void {
const target = event.currentTarget as HTMLElement;
this.insertMedia([~~target.dataset.objectId!]);
this._mediaToInsertByClipboard = insertedByClipboard || false;
// open the insert dialog if all media files are images
- let imagesOnly = true,
- media;
- for (let i = 0, length = mediaIds.length; i < length; i++) {
- media = this._media.get(mediaIds[i]);
+ let imagesOnly = true;
+ mediaIds.forEach((mediaId) => {
+ const media = this._media.get(mediaId)!;
this._mediaToInsert.set(media.mediaID, media);
if (!media.isImage) {
imagesOnly = false;
}
- }
+ });
if (imagesOnly) {
const thumbnailSizes = this._getThumbnailSizes();
const listItem = document.createElement("li");
listItem.className = "jsMediaInsertButton";
- listItem.dataset.objectId = (media.mediaID as unknown) as string;
+ listItem.dataset.objectId = media.mediaID.toString();
buttons.appendChild(listItem);
listItem.innerHTML = `
import * as Language from "../../Language";
import * as Ajax from "../../Ajax";
import * as Core from "../../Core";
+import DomUtil from "../../Dom/Util";
-type AjaxResponseData = {
+interface AjaxResponseData {
returnValues: {
media?: Media;
pageCount?: number;
pageNo?: number;
template?: string;
};
-};
+}
class MediaManagerSearch implements AjaxCallbackObject {
protected readonly _cancelButton: HTMLSpanElement;
"innerInfo",
) as HTMLElement;
if (innerInfo) {
- innerInfo.style.display = "none";
+ DomUtil.hide(innerInfo);
}
}
"innerInfo",
) as HTMLParagraphElement;
if (innerInfo) {
- innerInfo.style.display = "block";
+ DomUtil.show(innerInfo);
} else {
innerInfo = document.createElement("p");
innerInfo.className = "innerInfo";
* Hides the media search.
*/
public hideSearch(): void {
- this._searchContainer.style.display = "none";
+ DomUtil.hide(this._searchContainer);
}
/**
* Shows the media search.
*/
public showSearch(): void {
- this._searchContainer.style.display = "block";
+ DomUtil.show(this._searchContainer);
}
/**
import * as FileUtil from "../../FileUtil";
import * as Language from "../../Language";
import * as UiDialog from "../../Ui/Dialog";
+import DomUtil from "../../Dom/Util";
class MediaManagerSelect extends MediaManager<MediaManagerSelectOptions> {
protected _activeButton: HTMLElement | null = null;
if (store) {
const storeElement = document.getElementById(store) as HTMLInputElement;
if (storeElement && storeElement.tagName === "INPUT") {
- button.addEventListener("click", this._click.bind(this));
+ button.addEventListener("click", (ev) => this._click(ev));
this._storeElements.set(button, storeElement);
removeButton.appendChild(icon);
if (!storeElement.value) {
- removeButton.style.display = "none";
+ DomUtil.hide(removeButton);
}
removeButton.addEventListener("click", (ev) => this._removeMedia(ev));
}
const chooseIcon = listItem.querySelector(".jsMediaSelectButton");
if (chooseIcon) {
chooseIcon.classList.remove("jsMediaSelectButton");
- chooseIcon.addEventListener("click", (ev: MouseEvent) => this._chooseMedia(ev));
+ chooseIcon.addEventListener("click", (ev) => this._chooseMedia(ev));
}
});
}
/**
* Handles clicking on a media choose icon.
*/
- protected _chooseMedia(event: MouseEvent): void {
+ protected _chooseMedia(event: Event): void {
if (this._activeButton === null) {
throw new Error("Media cannot be chosen if no button is active.");
}
// save selected media in store element
const input = document.getElementById(this._activeButton.dataset.store!) as HTMLInputElement;
- input.value = (media.mediaID as unknown) as string;
+ input.value = media.mediaID.toString();
Core.triggerEvent(input, "change");
// display selected media
UiDialog.close(this);
}
- protected _click(event: MouseEvent): void {
+ protected _click(event: Event): void {
event.preventDefault();
this._activeButton = event.currentTarget as HTMLInputElement;
const listItem = document.createElement("li");
listItem.className = "jsMediaSelectButton";
- listItem.dataset.objectId = (media.mediaID as unknown) as string;
+ listItem.dataset.objectId = media.mediaID.toString();
buttons.appendChild(listItem);
listItem.innerHTML =
/**
* Handles clicking on the remove button.
*/
- protected _removeMedia(event: MouseEvent): void {
+ protected _removeMedia(event: Event): void {
event.preventDefault();
const removeButton = event.currentTarget as HTMLSpanElement;
import * as EventHandler from "../Event/Handler";
import MediaManager from "./Manager/Base";
-export class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> extends Upload<TOptions> {
+class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> extends Upload<TOptions> {
protected _categoryId: number | null = null;
protected readonly _elementTagSize: number;
protected readonly _mediaManager: MediaManager | null;
Array.from(fileElement.getElementsByTagName("TD")).forEach((cell: HTMLTableDataCellElement) => {
if (cell.classList.contains("columnMark")) {
- cell.querySelectorAll("[data-object-id]").forEach((el: HTMLElement) => (el.style.display = "none"));
+ cell.querySelectorAll("[data-object-id]").forEach((el: HTMLElement) => DomUtil.hide(el));
} else if (cell.classList.contains("columnIcon")) {
- cell.querySelectorAll("[data-object-id]").forEach((el: HTMLElement) => (el.style.display = "none"));
+ cell.querySelectorAll("[data-object-id]").forEach((el: HTMLElement) => DomUtil.hide(el));
cell.querySelector(".mediaEditButton")!.classList.add("jsMediaEditButton");
(cell.querySelector(".jsDeleteButton") as HTMLElement).dataset.confirmMessageHtml = Language.get(
if (media) {
// update object id
file.querySelectorAll("[data-object-id]").forEach((el: HTMLElement) => {
- el.dataset.objectId = (media.mediaID as unknown) as string;
+ el.dataset.objectId = media.mediaID.toString();
el.style.removeProperty("display");
});
- file.querySelector(".columnMediaID")!.textContent = (media.mediaID as unknown) as string;
+ file.querySelector(".columnMediaID")!.textContent = media.mediaID.toString();
// update icon
this._replaceFileIcon(file.querySelector(".fa-spinner") as HTMLSpanElement, media, 48);
const fileIcon = file.querySelector(".fa-spinner") as HTMLSpanElement;
fileIcon.classList.remove("fa-spinner");
- fileIcon.classList.add("fa-remove");
- fileIcon.classList.add("pointer");
- fileIcon.classList.add("jsTooltip");
+ fileIcon.classList.add("fa-remove", "pointer", "jsTooltip");
fileIcon.title = Language.get("wcf.global.button.delete");
fileIcon.addEventListener("click", (event) => {
const target = event.currentTarget as HTMLSpanElement;
- (target.parentNode!.parentNode!.parentNode! as HTMLElement).remove();
+ target.closest(".mediaFile")!.remove();
EventHandler.fire("com.woltlab.wcf.media.upload", "removedErroneousUploadRow");
});
this._replaceFileIcon(fileIcon, media, 144);
file.className = "jsClipboardObject mediaFile";
- file.dataset.objectId = (media.mediaID as unknown) as string;
+ file.dataset.objectId = media.mediaID.toString();
if (this._mediaManager) {
this._mediaManager.setupMediaElement(media, file);
const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail")!, "SPAN")!;
fileIcon.classList.remove("fa-spinner");
- fileIcon.classList.add("fa-remove");
- fileIcon.classList.add("pointer");
+ fileIcon.classList.add("fa-remove", "pointer");
- file.classList.add("uploadFailed");
- file.classList.add("jsTooltip");
+ file.classList.add("uploadFailed", "jsTooltip");
file.title = Language.get("wcf.global.button.delete");
file.addEventListener("click", () => file.remove());
Core.enableLegacyInheritance(MediaUpload);
-export default MediaUpload;
+export = MediaUpload;