From 665fa1717489e35e40b09c7179f8d4a46bc68225 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 30 Oct 2020 15:36:13 +0100 Subject: [PATCH] Resolve errors found by ESLint --- .../js/WoltLabSuite/Core/Ajax/Request.js | 66 ++-- .../files/js/WoltLabSuite/Core/ColorUtil.js | 5 +- .../files/js/WoltLabSuite/Core/Core.js | 55 ++- .../files/js/WoltLabSuite/Core/Date/Picker.js | 43 ++- .../files/js/WoltLabSuite/Core/Devtools.js | 19 +- .../files/js/WoltLabSuite/Core/Dictionary.js | 8 +- .../files/js/WoltLabSuite/Core/Dom/Util.js | 37 +- .../files/js/WoltLabSuite/Core/I18n/Plural.js | 267 ++++++++----- .../js/WoltLabSuite/Core/Image/Resizer.js | 25 +- .../files/js/WoltLabSuite/Core/NumberUtil.js | 6 +- .../files/js/WoltLabSuite/Core/Permission.js | 6 +- .../files/js/WoltLabSuite/Core/StringUtil.js | 2 +- .../files/js/WoltLabSuite/Core/Template.js | 3 +- .../js/WoltLabSuite/Core/Timer/Repeating.js | 2 +- .../js/WoltLabSuite/Core/Ui/Alignment.js | 103 +++-- .../files/js/WoltLabSuite/Core/Ui/Dialog.js | 14 +- .../WoltLabSuite/Core/Ui/Dropdown/Reusable.js | 2 +- .../WoltLabSuite/Core/Ui/Dropdown/Simple.js | 2 +- .../WoltLabSuite/Core/Ui/Page/Header/Fixed.js | 2 +- .../WoltLabSuite/Core/Ui/Page/Header/Menu.js | 2 +- .../Core/Ui/Page/Menu/Abstract.js | 5 +- .../files/js/WoltLabSuite/Core/Ui/Screen.js | 4 +- .../js/WoltLabSuite/Core/Ui/Search/Page.js | 4 +- .../js/WoltLabSuite/Core/Ui/Suggestion.js | 4 +- .../files/js/WoltLabSuite/Core/Ui/TabMenu.js | 4 +- .../js/WoltLabSuite/Core/Ui/TabMenu/Simple.js | 14 +- .../WoltLabSuite/Core/Ui/User/Trophy/List.js | 4 +- .../ts/WoltLabSuite/Core/Ajax/Request.ts | 87 +++-- .../files/ts/WoltLabSuite/Core/ColorUtil.ts | 6 +- .../files/ts/WoltLabSuite/Core/Core.ts | 58 ++- .../files/ts/WoltLabSuite/Core/Date/Picker.ts | 50 ++- .../files/ts/WoltLabSuite/Core/Devtools.ts | 23 +- .../files/ts/WoltLabSuite/Core/Dictionary.ts | 8 +- .../files/ts/WoltLabSuite/Core/Dom/Util.ts | 38 +- .../files/ts/WoltLabSuite/Core/I18n/Plural.ts | 351 +++++++++++++----- .../ts/WoltLabSuite/Core/Image/Resizer.ts | 34 +- .../files/ts/WoltLabSuite/Core/NumberUtil.ts | 6 +- .../files/ts/WoltLabSuite/Core/Permission.ts | 6 +- .../files/ts/WoltLabSuite/Core/StringUtil.ts | 2 +- .../files/ts/WoltLabSuite/Core/Template.ts | 3 +- .../ts/WoltLabSuite/Core/Timer/Repeating.ts | 2 +- .../ts/WoltLabSuite/Core/Ui/Alignment.ts | 139 ++++--- .../files/ts/WoltLabSuite/Core/Ui/Dialog.ts | 14 +- .../WoltLabSuite/Core/Ui/Dropdown/Reusable.ts | 2 +- .../WoltLabSuite/Core/Ui/Dropdown/Simple.ts | 2 +- .../WoltLabSuite/Core/Ui/Page/Header/Fixed.ts | 2 +- .../WoltLabSuite/Core/Ui/Page/Header/Menu.ts | 2 +- .../Core/Ui/Page/Menu/Abstract.ts | 11 +- .../files/ts/WoltLabSuite/Core/Ui/Screen.ts | 4 +- .../ts/WoltLabSuite/Core/Ui/Search/Page.ts | 4 +- .../ts/WoltLabSuite/Core/Ui/Suggestion.ts | 17 +- .../files/ts/WoltLabSuite/Core/Ui/TabMenu.ts | 14 +- .../ts/WoltLabSuite/Core/Ui/TabMenu/Simple.ts | 14 +- .../WoltLabSuite/Core/Ui/User/Trophy/List.ts | 4 +- 54 files changed, 950 insertions(+), 661 deletions(-) diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js index 3ee58dde0f..7a0462a915 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js @@ -60,16 +60,21 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis this._data = this._options.data; } if (this._options.callbackObject) { - if (typeof this._options.callbackObject._ajaxFailure === "function") + if (typeof this._options.callbackObject._ajaxFailure === "function") { this._options.failure = this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxFinalize === "function") + } + if (typeof this._options.callbackObject._ajaxFinalize === "function") { this._options.finalize = this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxSuccess === "function") + } + if (typeof this._options.callbackObject._ajaxSuccess === "function") { this._options.success = this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxProgress === "function") + } + if (typeof this._options.callbackObject._ajaxProgress === "function") { this._options.progress = this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxUploadProgress === "function") + } + if (typeof this._options.callbackObject._ajaxUploadProgress === "function") { this._options.uploadProgress = this._options.callbackObject._ajaxUploadProgress.bind(this._options.callbackObject); + } } if (!_didInit) { _didInit = true; @@ -100,26 +105,26 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis if (this._options.withCredentials) { this._xhr.withCredentials = true; } - const self = this; const options = Core.clone(this._options); - this._xhr.onload = function () { - if (this.readyState === XMLHttpRequest.DONE) { - if ((this.status >= 200 && this.status < 300) || this.status === 304) { - if (options.responseType && this.getResponseHeader("Content-Type").indexOf(options.responseType) !== 0) { + this._xhr.onload = () => { + const xhr = this._xhr; + if (xhr.readyState === XMLHttpRequest.DONE) { + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { + if (options.responseType && xhr.getResponseHeader("Content-Type").indexOf(options.responseType) !== 0) { // request succeeded but invalid response type - self._failure(this, options); + this._failure(xhr, options); } else { - self._success(this, options); + this._success(xhr, options); } } else { - self._failure(this, options); + this._failure(xhr, options); } } }; - this._xhr.onerror = function () { - self._failure(this, options); + this._xhr.onerror = () => { + this._failure(this._xhr, options); }; if (this._options.progress) { this._xhr.onprogress = this._options.progress; @@ -161,7 +166,7 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis * Returns an option by key or undefined. */ getOption(key) { - if (this._options.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(this._options, key)) { return this._options[key]; } return null; @@ -199,7 +204,7 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis } // force-invoke the background queue if (data && data.forceBackgroundQueuePerform) { - new Promise((resolve_1, reject_1) => { require(["../BackgroundQueue"], resolve_1, reject_1); }).then(tslib_1.__importStar).then((backgroundQueue) => backgroundQueue.invoke()); + void new Promise((resolve_1, reject_1) => { require(["../BackgroundQueue"], resolve_1, reject_1); }).then(tslib_1.__importStar).then((backgroundQueue) => backgroundQueue.invoke()); } } options.success(data, xhr.responseText, xhr, options.data); @@ -231,7 +236,7 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis if (options.ignoreError !== true && showError) { const html = this.getErrorHtml(data, xhr); if (html) { - new Promise((resolve_2, reject_2) => { require(["../Ui/Dialog"], resolve_2, reject_2); }).then(tslib_1.__importStar).then((UiDialog) => { + void new Promise((resolve_2, reject_2) => { require(["../Ui/Dialog"], resolve_2, reject_2); }).then(tslib_1.__importStar).then((UiDialog) => { UiDialog.openStatic(Util_1.default.getUniqueId(), html, { title: Language.get("wcf.global.error.title"), }); @@ -248,30 +253,33 @@ define(["require", "exports", "tslib", "./Status", "../Core", "../Dom/Change/Lis let message; if (data !== null) { if (data.returnValues && data.returnValues.description) { - details += "

Description:

" + data.returnValues.description + "

"; + details += `

Description:

${data.returnValues.description}

`; } if (data.file && data.line) { - details += "

File:

" + data.file + " in line " + data.line + "

"; + details += `

File:

${data.file} in line ${data.line}

`; + } + if (data.stacktrace) { + details += `

Stacktrace:

${data.stacktrace}

`; + } + else if (data.exceptionID) { + details += `

Exception ID: ${data.exceptionID}

`; } - if (data.stacktrace) - details += "

Stacktrace:

" + data.stacktrace + "

"; - else if (data.exceptionID) - details += "

Exception ID: " + data.exceptionID + "

"; message = data.message; - data.previous.forEach(function (previous) { - details += "

" + previous.message + "

"; - details += "

Stacktrace

" + previous.stacktrace + "

"; + data.previous.forEach((previous) => { + details += `

${previous.message}

`; + details += `

Stacktrace

${previous.stacktrace}

`; }); } else { message = xhr.responseText; } if (!message || message === "undefined") { - if (!window.ENABLE_DEBUG_MODE) + if (!window.ENABLE_DEBUG_MODE) { return null; + } message = "XMLHttpRequest failed without a responseText. Check your browser console."; } - return '

' + message + "

" + details + "
"; + return `

${message}

${details}
`; } /** * Finalizes a request. diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js b/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js index 34fedc4e7c..8ed83736fa 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js @@ -106,11 +106,10 @@ define(["require", "exports"], function (require, exports) { else { s = diff / max; } - const v = max; return { h: Math.round(h), s: Math.round(s * 100), - v: Math.round(v * 100), + v: Math.round(max * 100), }; } exports.rgbToHsv = rgbToHsv; @@ -152,7 +151,7 @@ define(["require", "exports"], function (require, exports) { function rgbToHex(r, g, b) { const charList = "0123456789ABCDEF"; if (g === undefined) { - if (r.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)) { + if (/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/.exec(r.toString())) { r = +RegExp.$1; g = +RegExp.$2; b = +RegExp.$3; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js index d1c1f5f0e0..bd232bd328 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js @@ -46,8 +46,9 @@ define(["require", "exports"], function (require, exports) { for (let i = 0, length = parts.length; i < length; i++) { const part = parts[i].trim(); if (part.length) { - if (controller.length) + if (controller.length) { controller += "-"; + } controller += part.toLowerCase(); } } @@ -67,24 +68,23 @@ define(["require", "exports"], function (require, exports) { const newObj = clone(out); for (let i = 0, length = args.length; i < length; i++) { const obj = args[i]; - if (!obj) + if (!obj) { continue; - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - if (!Array.isArray(obj[key]) && typeof obj[key] === "object") { - if (isPlainObject(obj[key])) { - // object literals have the prototype of Object which in return has no parent prototype - newObj[key] = extend(out[key], obj[key]); - } - else { - newObj[key] = obj[key]; - } + } + Object.keys(obj).forEach((key) => { + if (!Array.isArray(obj[key]) && typeof obj[key] === "object") { + if (isPlainObject(obj[key])) { + // object literals have the prototype of Object which in return has no parent prototype + newObj[key] = extend(out[key], obj[key]); } else { newObj[key] = obj[key]; } } - } + else { + newObj[key] = obj[key]; + } + }); } return newObj; } @@ -134,7 +134,7 @@ define(["require", "exports"], function (require, exports) { * Returns true if `obj` is an object literal. */ function isPlainObject(obj) { - if (typeof obj !== "object" || obj === null || obj.nodeType) { + if (typeof obj !== "object" || obj === null) { return false; } return Object.getPrototypeOf(obj) === Object.prototype; @@ -164,18 +164,16 @@ define(["require", "exports"], function (require, exports) { */ function serialize(obj, prefix) { const parameters = []; - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - const parameterKey = prefix ? prefix + "[" + key + "]" : key; - const value = obj[key]; - if (typeof value === "object") { - parameters.push(serialize(value, parameterKey)); - } - else { - parameters.push(encodeURIComponent(parameterKey) + "=" + encodeURIComponent(value)); - } + Object.keys(obj).forEach((key) => { + const parameterKey = prefix ? prefix + "[" + key + "]" : key; + const value = obj[key]; + if (typeof value === "object") { + parameters.push(serialize(value, parameterKey)); } - } + else { + parameters.push(encodeURIComponent(parameterKey) + "=" + encodeURIComponent(value)); + } + }); return parameters.join("&"); } exports.serialize = serialize; @@ -215,11 +213,10 @@ define(["require", "exports"], function (require, exports) { }) { let timeoutId; return function (...args) { - const context = this; - const doLater = function () { + const doLater = () => { timeoutId = undefined; if (!options.isImmediate) { - func.apply(context, args); + func.apply(this, args); } }; const shouldCallNow = options.isImmediate && timeoutId === undefined; @@ -228,7 +225,7 @@ define(["require", "exports"], function (require, exports) { } timeoutId = setTimeout(doLater, waitMilliseconds); if (shouldCallNow) { - func.apply(context, args); + func.apply(this, args); } }; } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Date/Picker.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Date/Picker.js index b819a43ac2..7c8458a8a5 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Date/Picker.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Date/Picker.js @@ -68,7 +68,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste let months = ""; const monthNames = Language.get("__monthsShort"); for (let i = 0; i < 12; i++) { - months += '"; + months += ``; } _dateMonth.innerHTML = months; _dateYear = document.createElement("select"); @@ -95,8 +95,9 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste const weekdays = Language.get("__daysShort"); for (let i = 0; i < 7; i++) { let day = i + _firstDayOfWeek; - if (day > 6) + if (day > 6) { day -= 7; + } const span = document.createElement("span"); span.textContent = weekdays[day]; item.appendChild(span); @@ -124,7 +125,8 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste let tmp = ""; for (let i = 0; i < 24; i++) { date.setHours(i); - tmp += '"; + const value = DateUtil.format(date, timeFormat); + tmp += ``; } _dateHour.innerHTML = tmp; _dateTime.appendChild(_dateHour); @@ -136,7 +138,8 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste _dateMinute.addEventListener("change", formatValue); tmp = ""; for (let i = 0; i < 60; i++) { - tmp += '"; + const value = i < 10 ? "0" + i.toString() : i; + tmp += ``; } _dateMinute.innerHTML = tmp; _dateTime.appendChild(_dateMinute); @@ -149,20 +152,20 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste function initDateRange(element, now, isMinDate) { const name = isMinDate ? "minDate" : "maxDate"; let value = (element.dataset[name] || "").trim(); - if (value.match(/^(\d{4})-(\d{2})-(\d{2})$/)) { + if (/^(\d{4})-(\d{2})-(\d{2})$/.exec(value)) { // YYYY-mm-dd value = new Date(value).getTime().toString(); } else if (value === "now") { value = now.getTime().toString(); } - else if (value.match(/^\d{1,3}$/)) { + else if (/^\d{1,3}$/.exec(value)) { // relative time span in years const date = new Date(now.getTime()); date.setFullYear(date.getFullYear() + ~~value * (isMinDate ? -1 : 1)); value = date.getTime().toString(); } - else if (value.match(/^datePicker-(.+)$/)) { + else if (/^datePicker-(.+)$/.exec(value)) { // element id, e.g. `datePicker-someOtherElement` value = RegExp.$1; if (document.getElementById(value) === null) { @@ -181,8 +184,9 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste * Sets up callbacks and event listeners. */ function setup() { - if (_didInit) + if (_didInit) { return; + } _didInit = true; _firstDayOfWeek = parseInt(Language.get("wcf.date.firstDayOfTheWeek"), 10); Listener_1.default.add("WoltLabSuite/Core/Date/Picker", () => DatePicker.init()); @@ -190,7 +194,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste } function getDateValue(attributeName) { let date = _input.dataset[attributeName] || ""; - if (date.match(/^datePicker-(.+)$/)) { + if (/^datePicker-(.+)$/.exec(date)) { const referenceElement = document.getElementById(RegExp.$1); if (referenceElement === null) { throw new Error(`Unable to find an element with the id '${RegExp.$1}'.`); @@ -309,7 +313,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste // create options for month and year let years = ""; for (let i = _minDate.getFullYear(), last = _maxDate.getFullYear(); i <= last; i++) { - years += '"; + years += ``; } _dateYear.innerHTML = years; _dateYear.value = year.toString(); @@ -344,7 +348,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste year = parseInt(_dateGrid.dataset.year, 10); } // check if current selection exceeds min/max date - let date = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-" + ("0" + day.toString()).slice(-2)); + let date = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-" + ("0" + day.toString()).slice(-2)); if (date < _minDate) { year = _minDate.getFullYear(); month = _minDate.getMonth(); @@ -361,7 +365,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste _dateYear.value = year.toString(); rebuildMonths = true; } - date = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + date = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); // shift until first displayed day equals first day of week while (date.getDay() !== _firstDayOfWeek) { date.setDate(date.getDate() - 1); @@ -380,10 +384,12 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste cell.textContent = date.getDate().toString(); selectable = date.getMonth() === month; if (selectable) { - if (date < comparableMinDate) + if (date < comparableMinDate) { selectable = false; - else if (date > _maxDate) + } + else if (date > _maxDate) { selectable = false; + } } cell.classList[selectable ? "remove" : "add"]("otherMonth"); if (selectable) { @@ -415,10 +421,10 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste (year === _minDate.getFullYear() && +currentMonth.value < _minDate.getMonth()) || (year === _maxDate.getFullYear() && +currentMonth.value > _maxDate.getMonth()); } - const nextMonth = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + const nextMonth = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); nextMonth.setMonth(nextMonth.getMonth() + 1); _dateMonthNext.classList[nextMonth < _maxDate ? "add" : "remove"]("active"); - const previousMonth = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + const previousMonth = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); previousMonth.setDate(previousMonth.getDate() - 1); _dateMonthPrevious.classList[previousMonth > _minDate ? "add" : "remove"]("active"); } @@ -575,7 +581,7 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste if (isBirthday) { element.dataset.minDate = "120"; // do not use 'now' here, all though it makes sense, it causes bad UX - element.dataset.maxDate = new Date().getFullYear() + "-12-31"; + element.dataset.maxDate = new Date().getFullYear().toString() + "-12-31"; } else { if (element.min) { @@ -642,8 +648,9 @@ define(["require", "exports", "tslib", "../Core", "./Util", "../Dom/Change/Liste const button = document.createElement("a"); button.className = "inputSuffix button"; button.addEventListener("click", this.clear.bind(this, element)); - if (isEmpty) + if (isEmpty) { button.style.setProperty("visibility", "hidden", ""); + } container.appendChild(button); icon = document.createElement("span"); icon.className = "icon icon16 fa-times"; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools.js index d8d04ecb37..1e38812b41 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools.js @@ -25,14 +25,11 @@ define(["require", "exports"], function (require, exports) { help() { window.console.log(""); window.console.log("%cAvailable commands:", "text-decoration: underline"); - const commands = []; - for (const cmd in Devtools) { - if (cmd !== "_internal_" && Devtools.hasOwnProperty(cmd)) { - commands.push(cmd); - } - } - commands.sort().forEach(function (cmd) { - window.console.log("\tDevtools." + cmd + "()"); + Object.keys(Devtools) + .filter((cmd) => cmd !== "_internal_") + .sort() + .forEach((cmd) => { + window.console.log(`\tDevtools.${cmd}()`); }); window.console.log(""); }, @@ -69,10 +66,12 @@ define(["require", "exports"], function (require, exports) { catch (e) { // Ignore JSON parsing failure. } - if (!_settings.editorAutosave) + if (!_settings.editorAutosave) { Devtools.toggleEditorAutosave(true); - if (_settings.eventLogging) + } + if (_settings.eventLogging) { Devtools.toggleEventLogging(true); + } } window.console.log("Settings are saved per browser session, enter `Devtools.help()` to learn more."); window.console.log(""); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js index 701cdd6429..819ffb74ff 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js @@ -77,11 +77,9 @@ define(["require", "exports"], function (require, exports) { */ static fromObject(object) { const result = new Dictionary(); - for (const key in object) { - if (object.hasOwnProperty(key)) { - result.set(key, object[key]); - } - } + Object.keys(object).forEach((key) => { + result.set(key, object[key]); + }); return result; } get size() { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js index b6798a91a5..fed4dc3d1c 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js @@ -54,7 +54,7 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo getUniqueId() { let elementId; do { - elementId = "wcf" + _idCounter++; + elementId = `wcf${_idCounter++}`; } while (document.getElementById(elementId) !== null); return elementId; }, @@ -135,24 +135,22 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo */ setStyles(element, styles) { let important = false; - for (const property in styles) { - if (styles.hasOwnProperty(property)) { - if (/ !important$/.test(styles[property])) { - important = true; - styles[property] = styles[property].replace(/ !important$/, ""); - } - else { - important = false; - } - // for a set style property with priority = important, some browsers are - // not able to overwrite it with a property != important; removing the - // property first solves this issue - if (element.style.getPropertyPriority(property) === "important" && !important) { - element.style.removeProperty(property); - } - element.style.setProperty(property, styles[property], important ? "important" : ""); + Object.keys(styles).forEach((property) => { + if (/ !important$/.test(styles[property])) { + important = true; + styles[property] = styles[property].replace(/ !important$/, ""); } - } + else { + important = false; + } + // for a set style property with priority = important, some browsers are + // not able to overwrite it with a property != important; removing the + // property first solves this issue + if (element.style.getPropertyPriority(property) === "important" && !important) { + element.style.removeProperty(property); + } + element.style.setProperty(property, styles[property], important ? "important" : ""); + }); }, /** * Returns a style property value as integer. @@ -246,8 +244,9 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo */ getDataAttributes(element, prefix, camelCaseName, idToUpperCase) { prefix = prefix || ""; - if (prefix.indexOf("data-") !== 0) + if (prefix.indexOf("data-") !== 0) { prefix = "data-" + prefix; + } camelCaseName = camelCaseName === true; idToUpperCase = idToUpperCase === true; const attributes = {}; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js b/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js index 4fc431a55b..042ba9f01a 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js @@ -50,10 +50,11 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo value = value.length; } // handle numeric attributes - for (const key in parameters) { - if (parameters.hasOwnProperty(key) && key.toString() === (~~key).toString() && key == value) { - return parameters[key]; - } + const numericAttribute = Object.keys(parameters).find((key) => { + return key.toString() === (~~key).toString() && key == value; + }); + if (numericAttribute) { + return numericAttribute; } let category = Plural.getCategory(value); if (!parameters[category]) { @@ -84,61 +85,75 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Afrikaans af(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Amharic am(n) { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) + if (n == 1 || i === 0) { return PLURAL_ONE; + } }, // Arabic ar(n) { - if (n == 0) + if (n == 0) { return PLURAL_ZERO; - if (n == 1) + } + if (n == 1) { return PLURAL_ONE; - if (n == 2) + } + if (n == 2) { return PLURAL_TWO; + } const mod100 = n % 100; - if (mod100 >= 3 && mod100 <= 10) + if (mod100 >= 3 && mod100 <= 10) { return PLURAL_FEW; - if (mod100 >= 11 && mod100 <= 99) + } + if (mod100 >= 11 && mod100 <= 99) { return PLURAL_MANY; + } }, // Assamese as(n) { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) + if (n == 1 || i === 0) { return PLURAL_ONE; + } }, // Azerbaijani az(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Belarusian be(n) { const mod10 = n % 10; const mod100 = n % 100; - if (mod10 == 1 && mod100 != 11) + if (mod10 == 1 && mod100 != 11) { return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) + } + if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { return PLURAL_FEW; - if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) + } + if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) { return PLURAL_MANY; + } }, // Bulgarian bg(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Bengali bn(n) { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) + if (n == 1 || i === 0) { return PLURAL_ONE; + } }, // Tibetan bo(_n) { @@ -152,44 +167,56 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo const mod100 = n % 100; const fMod10 = f % 10; const fMod100 = f % 100; - if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) + if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) { return PLURAL_ONE; + } if ((v == 0 && mod10 >= 2 && mod10 <= 4 && mod100 >= 12 && mod100 <= 14) || - (fMod10 >= 2 && fMod10 <= 4 && fMod100 >= 12 && fMod100 <= 14)) + (fMod10 >= 2 && fMod10 <= 4 && fMod100 >= 12 && fMod100 <= 14)) { return PLURAL_FEW; + } }, // Czech cs(n) { const v = Plural.getV(n); - if (n == 1 && v === 0) + if (n == 1 && v === 0) { return PLURAL_ONE; - if (n >= 2 && n <= 4 && v === 0) + } + if (n >= 2 && n <= 4 && v === 0) { return PLURAL_FEW; - if (v === 0) + } + if (v === 0) { return PLURAL_MANY; + } }, // Welsh cy(n) { - if (n == 0) + if (n == 0) { return PLURAL_ZERO; - if (n == 1) + } + if (n == 1) { return PLURAL_ONE; - if (n == 2) + } + if (n == 2) { return PLURAL_TWO; - if (n == 3) + } + if (n == 3) { return PLURAL_FEW; - if (n == 6) + } + if (n == 6) { return PLURAL_MANY; + } }, // Danish da(n) { - if (n > 0 && n < 2) + if (n > 0 && n < 2) { return PLURAL_ONE; + } }, // Greek el(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Catalan (ca) // German (de) @@ -202,59 +229,73 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo // Swahili (sw) // Urdu (ur) en(n) { - if (n == 1 && Plural.getV(n) === 0) + if (n == 1 && Plural.getV(n) === 0) { return PLURAL_ONE; + } }, // Spanish es(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Basque eu(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Persian fa(n) { - if (n >= 0 && n <= 1) + if (n >= 0 && n <= 1) { return PLURAL_ONE; + } }, // French fr(n) { - if (n >= 0 && n < 2) + if (n >= 0 && n < 2) { return PLURAL_ONE; + } }, // Irish ga(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; - if (n == 2) + } + if (n == 2) { return PLURAL_TWO; - if (n == 3 || n == 4 || n == 5 || n == 6) + } + if (n == 3 || n == 4 || n == 5 || n == 6) { return PLURAL_FEW; - if (n == 7 || n == 8 || n == 9 || n == 10) + } + if (n == 7 || n == 8 || n == 9 || n == 10) { return PLURAL_MANY; + } }, // Gujarati gu(n) { - if (n >= 0 && n <= 1) + if (n >= 0 && n <= 1) { return PLURAL_ONE; + } }, // Hebrew he(n) { const v = Plural.getV(n); - if (n == 1 && v === 0) + if (n == 1 && v === 0) { return PLURAL_ONE; - if (n == 2 && v === 0) + } + if (n == 2 && v === 0) { return PLURAL_TWO; - if (n > 10 && v === 0 && n % 10 == 0) + } + if (n > 10 && v === 0 && n % 10 == 0) { return PLURAL_MANY; + } }, // Hindi hi(n) { - if (n >= 0 && n <= 1) + if (n >= 0 && n <= 1) { return PLURAL_ONE; + } }, // Croatian hr(n) { @@ -263,13 +304,15 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Hungarian hu(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Armenian hy(n) { - if (n >= 0 && n < 2) + if (n >= 0 && n < 2) { return PLURAL_ONE; + } }, // Indonesian id(_n) { @@ -278,8 +321,9 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo // Icelandic is(n) { const f = Plural.getF(n); - if ((f === 0 && n % 10 === 1 && !(n % 100 === 11)) || !(f === 0)) + if ((f === 0 && n % 10 === 1 && !(n % 100 === 11)) || !(f === 0)) { return PLURAL_ONE; + } }, // Japanese ja(_n) { @@ -291,13 +335,15 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Georgian ka(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Kazakh kk(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Khmer km(_n) { @@ -305,8 +351,9 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Kannada kn(n) { - if (n >= 0 && n <= 1) + if (n >= 0 && n <= 1) { return PLURAL_ONE; + } }, // Korean ko(_n) { @@ -314,18 +361,21 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Kurdish ku(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Kyrgyz ky(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Luxembourgish lb(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Lao lo(_n) { @@ -335,12 +385,15 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo lt(n) { const mod10 = n % 10; const mod100 = n % 100; - if (mod10 == 1 && !(mod100 >= 11 && mod100 <= 19)) + if (mod10 == 1 && !(mod100 >= 11 && mod100 <= 19)) { return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 9 && !(mod100 >= 11 && mod100 <= 19)) + } + if (mod10 >= 2 && mod10 <= 9 && !(mod100 >= 11 && mod100 <= 19)) { return PLURAL_FEW; - if (Plural.getF(n) != 0) + } + if (Plural.getF(n) != 0) { return PLURAL_MANY; + } }, // Latvian lv(n) { @@ -350,10 +403,12 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo const f = Plural.getF(n); const fMod10 = f % 10; const fMod100 = f % 100; - if (mod10 == 0 || (mod100 >= 11 && mod100 <= 19) || (v == 2 && fMod100 >= 11 && fMod100 <= 19)) + if (mod10 == 0 || (mod100 >= 11 && mod100 <= 19) || (v == 2 && fMod100 >= 11 && fMod100 <= 19)) { return PLURAL_ZERO; - if ((mod10 == 1 && mod100 != 11) || (v == 2 && fMod10 == 1 && fMod100 != 11) || (v != 2 && fMod10 == 1)) + } + if ((mod10 == 1 && mod100 != 11) || (v == 2 && fMod10 == 1 && fMod100 != 11) || (v != 2 && fMod10 == 1)) { return PLURAL_ONE; + } }, // Macedonian mk(n) { @@ -361,18 +416,21 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Malayalam ml(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Mongolian mn(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Marathi mr(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Malay ms(_n) { @@ -381,12 +439,15 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo // Maltese mt(n) { const mod100 = n % 100; - if (n == 1) + if (n == 1) { return PLURAL_ONE; - if (n == 0 || (mod100 >= 2 && mod100 <= 10)) + } + if (n == 0 || (mod100 >= 2 && mod100 <= 10)) { return PLURAL_FEW; - if (mod100 >= 11 && mod100 <= 19) + } + if (mod100 >= 11 && mod100 <= 19) { return PLURAL_MANY; + } }, // Burmese my(_n) { @@ -394,78 +455,94 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Norwegian no(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Nepali ne(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Odia or(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Punjabi pa(n) { - if (n == 1 || n == 0) + if (n == 1 || n == 0) { return PLURAL_ONE; + } }, // Polish pl(n) { const v = Plural.getV(n); const mod10 = n % 10; const mod100 = n % 100; - if (n == 1 && v == 0) + if (n == 1 && v == 0) { return PLURAL_ONE; - if (v == 0 && mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) + } + if (v == 0 && mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { return PLURAL_FEW; + } if (v == 0 && - ((n != 1 && mod10 >= 0 && mod10 <= 1) || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 12 && mod100 <= 14))) + ((n != 1 && mod10 >= 0 && mod10 <= 1) || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 12 && mod100 <= 14))) { return PLURAL_MANY; + } }, // Pashto ps(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Portuguese pt(n) { - if (n >= 0 && n < 2) + if (n >= 0 && n < 2) { return PLURAL_ONE; + } }, // Romanian ro(n) { const v = Plural.getV(n); const mod100 = n % 100; - if (n == 1 && v === 0) + if (n == 1 && v === 0) { return PLURAL_ONE; - if (v != 0 || n == 0 || (mod100 >= 2 && mod100 <= 19)) + } + if (v != 0 || n == 0 || (mod100 >= 2 && mod100 <= 19)) { return PLURAL_FEW; + } }, // Russian ru(n) { const mod10 = n % 10; const mod100 = n % 100; if (Plural.getV(n) == 0) { - if (mod10 == 1 && mod100 != 11) + if (mod10 == 1 && mod100 != 11) { return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) + } + if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { return PLURAL_FEW; - if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) + } + if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) { return PLURAL_MANY; + } } }, // Sindhi sd(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Sinhala si(n) { - if (n == 0 || n == 1 || (Math.floor(n) == 0 && Plural.getF(n) == 1)) + if (n == 0 || n == 1 || (Math.floor(n) == 0 && Plural.getF(n) == 1)) { return PLURAL_ONE; + } }, // Slovak sk(n) { @@ -476,17 +553,21 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo sl(n) { const v = Plural.getV(n); const mod100 = n % 100; - if (v == 0 && mod100 == 1) + if (v == 0 && mod100 == 1) { return PLURAL_ONE; - if (v == 0 && mod100 == 2) + } + if (v == 0 && mod100 == 2) { return PLURAL_TWO; - if ((v == 0 && (mod100 == 3 || mod100 == 4)) || v != 0) + } + if ((v == 0 && (mod100 == 3 || mod100 == 4)) || v != 0) { return PLURAL_FEW; + } }, // Albanian sq(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Serbian sr(n) { @@ -495,13 +576,15 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Tamil ta(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Telugu te(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Tajik tg(_n) { @@ -513,18 +596,21 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Turkmen tk(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Turkish tr(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Uyghur ug(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Ukrainian uk(n) { @@ -533,8 +619,9 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo }, // Uzbek uz(n) { - if (n == 1) + if (n == 1) { return PLURAL_ONE; + } }, // Vietnamese vi(_n) { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js index 9b9443c841..f55116ca96 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js @@ -1,10 +1,10 @@ /** * This module allows resizing and conversion of HTMLImageElements to Blob and File objects * - * @author Tim Duesterhus, Maximilian Mader - * @copyright 2001-2020 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Image/Resizer + * @author Tim Duesterhus, Maximilian Mader + * @copyright 2001-2020 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Image/Resizer */ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], function (require, exports, tslib_1, FileUtil, ExifUtil, pica_1) { "use strict"; @@ -27,8 +27,9 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun * Sets the default maximum width for this instance */ setMaxWidth(value) { - if (value == null) + if (value == null) { value = DEFAULT_WIDTH; + } this.maxWidth = value; return this; } @@ -36,8 +37,9 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun * Sets the default maximum height for this instance */ setMaxHeight(value) { - if (value == null) + if (value == null) { value = DEFAULT_HEIGHT; + } this.maxHeight = value; return this; } @@ -45,8 +47,9 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun * Sets the default quality for this instance */ setQuality(value) { - if (value == null) + if (value == null) { value = DEFAULT_QUALITY; + } this.quality = value; return this; } @@ -54,8 +57,9 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun * Sets the default file type for this instance */ setFileType(value) { - if (value == null) + if (value == null) { value = DEFAULT_FILETYPE; + } this.fileType = value; return this; } @@ -63,7 +67,7 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun * Converts the given object of exif data and image data into a File. */ async saveFile(data, fileName, fileType = this.fileType, quality = this.quality) { - const basename = fileName.match(/(.+)(\..+?)$/); + const basename = /(.+)(\..+?)$/.exec(fileName); let blob = await pica.toBlob(data.image, fileType, quality); if (fileType === "image/jpeg" && typeof data.exif !== "undefined") { blob = await ExifUtil.setExifData(blob, data.exif); @@ -108,8 +112,9 @@ define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], fun const canvas = document.createElement("canvas"); if (window.createImageBitmap) { const bitmap = await createImageBitmap(image); - if (bitmap.height != image.height) + if (bitmap.height != image.height) { throw new Error("Chrome Bug #1069965"); + } } // Prevent upscaling const newWidth = Math.min(maxWidth, image.width); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/NumberUtil.js b/wcfsetup/install/files/js/WoltLabSuite/Core/NumberUtil.js index 5f22062429..502e9e833d 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/NumberUtil.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/NumberUtil.js @@ -28,10 +28,12 @@ define(["require", "exports"], function (require, exports) { } // Shift let tmp = value.toString().split("e"); - value = Math.round(+(tmp[0] + "e" + (tmp[1] ? +tmp[1] - exp : -exp))); + let exponent = tmp[1] ? +tmp[1] - exp : -exp; + value = Math.round(+`${tmp[0]}e${exponent}`); // Shift back tmp = value.toString().split("e"); - return +(tmp[0] + "e" + (tmp[1] ? +tmp[1] + exp : exp)); + exponent = tmp[1] ? +tmp[1] + exp : exp; + return +`${tmp[0]}e${exponent}`; } exports.round = round; }); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Permission.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Permission.js index 63b66844f4..b5f78c4ea3 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Permission.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Permission.js @@ -26,11 +26,7 @@ define(["require", "exports"], function (require, exports) { * Adds all the permissions in the given object to the store. */ function addObject(object) { - for (const key in object) { - if (object.hasOwnProperty(key)) { - add(key, object[key]); - } - } + Object.keys(object).forEach((key) => add(key, object[key])); } exports.addObject = addObject; /** diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/StringUtil.js b/wcfsetup/install/files/js/WoltLabSuite/Core/StringUtil.js index e65b732b00..78f7aca3b5 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/StringUtil.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/StringUtil.js @@ -40,7 +40,7 @@ define(["require", "exports", "tslib", "./Language", "./NumberUtil"], function ( * @see https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/regexp.js#L25 */ function escapeRegExp(string) { - return String(string).replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1"); + return String(string).replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1"); } exports.escapeRegExp = escapeRegExp; /** diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Template.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Template.js index 92f9572e8b..f48484edff 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Template.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Template.js @@ -43,6 +43,7 @@ define(["require", "exports", "tslib", "./Template.grammar", "./StringUtil", "./ "v.__wcf = window.WCF; v.__window = window;\n" + "return " + template; + // eslint-disable-next-line @typescript-eslint/no-implied-eval this.fetch = new Function("StringUtil", "Language", "I18nPlural", "v", template).bind(undefined, StringUtil, Language, I18nPlural); } catch (e) { @@ -52,8 +53,6 @@ define(["require", "exports", "tslib", "./Template.grammar", "./StringUtil", "./ } /** * Evaluates the Template using the given parameters. - * - * @param {object} v Parameters to pass to the template. */ fetch(_v) { // this will be replaced in the init function diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Timer/Repeating.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Timer/Repeating.js index 29b695e1c1..f56acd9c95 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Timer/Repeating.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Timer/Repeating.js @@ -19,7 +19,7 @@ define(["require", "exports"], function (require, exports) { throw new TypeError("Expected a valid callback as first argument."); } if (delta < 0 || delta > 86400 * 1000) { - throw new RangeError("Invalid delta " + delta + ". Delta must be in the interval [0, 86400000]."); + throw new RangeError(`Invalid delta ${delta}. Delta must be in the interval [0, 86400000].`); } // curry callback with `this` as the first parameter this._callback = callback.bind(undefined, this); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Alignment.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Alignment.js index 41ddf4b2b8..0ebaf3e897 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Alignment.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Alignment.js @@ -15,61 +15,8 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Dom/Uti DomTraverse = tslib_1.__importStar(DomTraverse); Util_1 = tslib_1.__importDefault(Util_1); Language = tslib_1.__importStar(Language); - /** - * Calculates left/right position and verifies if the element would be still within the page's boundaries. - * - * @param {string} alignment align to this side of the reference element - * @param {Object} elDimensions element dimensions - * @param {Object} refDimensions reference element dimensions - * @param {Object} refOffsets position of reference element relative to the document - * @param {int} windowWidth window width - * @returns {Object} calculation results - */ - function tryAlignmentHorizontal(alignment, elDimensions, refDimensions, refOffsets, windowWidth) { - let left = "auto"; - let right = "auto"; - let result = true; - if (alignment === "left") { - left = refOffsets.left; - if (left + elDimensions.width > windowWidth) { - result = false; - } - } - else if (alignment === "right") { - if (refOffsets.left + refDimensions.width < elDimensions.width) { - result = false; - } - else { - right = windowWidth - (refOffsets.left + refDimensions.width); - if (right < 0) { - result = false; - } - } - } - else { - left = refOffsets.left + refDimensions.width / 2 - elDimensions.width / 2; - left = ~~left; - if (left < 0 || left + elDimensions.width > windowWidth) { - result = false; - } - } - return { - align: alignment, - left: left, - right: right, - result: result, - }; - } /** * Calculates top/bottom position and verifies if the element would be still within the page's boundaries. - * - * @param {string} alignment align to this side of the reference element - * @param {Object} elDimensions element dimensions - * @param {Object} refDimensions reference element dimensions - * @param {Object} refOffsets position of reference element relative to the document - * @param {int} windowHeight window height - * @param {int} verticalOffset desired gap between element and reference element - * @returns {object} calculation results */ function tryAlignmentVertical(alignment, elDimensions, refDimensions, refOffsets, windowHeight, verticalOffset) { let bottom = "auto"; @@ -106,12 +53,46 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Dom/Uti result: result, }; } + /** + * Calculates left/right position and verifies if the element would be still within the page's boundaries. + */ + function tryAlignmentHorizontal(alignment, elDimensions, refDimensions, refOffsets, windowWidth) { + let left = "auto"; + let right = "auto"; + let result = true; + if (alignment === "left") { + left = refOffsets.left; + if (left + elDimensions.width > windowWidth) { + result = false; + } + } + else if (alignment === "right") { + if (refOffsets.left + refDimensions.width < elDimensions.width) { + result = false; + } + else { + right = windowWidth - (refOffsets.left + refDimensions.width); + if (right < 0) { + result = false; + } + } + } + else { + left = refOffsets.left + refDimensions.width / 2 - elDimensions.width / 2; + left = ~~left; + if (left < 0 || left + elDimensions.width > windowWidth) { + result = false; + } + } + return { + align: alignment, + left: left, + right: right, + result: result, + }; + } /** * Sets the alignment for target element relatively to the reference element. - * - * @param {Element} element target element - * @param {Element} referenceElement reference element - * @param {Object} options list of options to alter the behavior */ function set(element, referenceElement, options) { options = Core.extend({ @@ -226,10 +207,10 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Dom/Uti element.classList[left === "auto" ? "add" : "remove"](options.pointerClassNames[1 /* Right */]); } Util_1.default.setStyles(element, { - bottom: bottom === "auto" ? bottom : Math.round(bottom) + "px", - left: left === "auto" ? left : Math.ceil(left) + "px", - right: right === "auto" ? right : Math.floor(right) + "px", - top: top === "auto" ? top : Math.round(top) + "px", + bottom: bottom === "auto" ? bottom : Math.round(bottom).toString() + "px", + left: left === "auto" ? left : Math.ceil(left).toString() + "px", + right: right === "auto" ? right : Math.floor(right).toString() + "px", + top: top === "auto" ? top : Math.round(top).toString() + "px", }); Util_1.default.show(element); element.style.removeProperty("visibility"); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js index b4b22c1dd9..01ed6e661c 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js @@ -154,7 +154,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S setupData.source = html; } else { - new Promise((resolve_1, reject_1) => { require(["../Ajax"], resolve_1, reject_1); }).then(tslib_1.__importStar).then((Ajax) => { + void new Promise((resolve_1, reject_1) => { require(["../Ajax"], resolve_1, reject_1); }).then(tslib_1.__importStar).then((Ajax) => { const source = setupData.source; Ajax.api(this, source.data, (data) => { if (data.returnValues && typeof data.returnValues.template === "string") { @@ -217,7 +217,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S options.backdropCloseOnClick = false; if (options.closeConfirmMessage) { options.onBeforeClose = (id) => { - new Promise((resolve_2, reject_2) => { require(["./Confirmation"], resolve_2, reject_2); }).then(tslib_1.__importStar).then((UiConfirmation) => { + void new Promise((resolve_2, reject_2) => { require(["./Confirmation"], resolve_2, reject_2); }).then(tslib_1.__importStar).then((UiConfirmation) => { UiConfirmation.show({ confirm: this.close.bind(this, id), message: options.closeConfirmMessage || "", @@ -265,7 +265,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S } const data = _dialogs.get(id); if (data === undefined) { - throw new Error("Expected a valid dialog id, '" + id + "' does not match any active dialog."); + throw new Error(`Expected a valid dialog id, '${id}' does not match any active dialog.`); } if (_validCallbacks.indexOf(key) === -1) { throw new Error("Invalid callback identifier, '" + key + "' is not recognized."); @@ -322,7 +322,9 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S contentContainer.addEventListener("wheel", (event) => { let allowScroll = false; let element = event.target; - let clientHeight, scrollHeight, scrollTop; + let clientHeight; + let scrollHeight; + let scrollTop; for (;;) { clientHeight = element.clientHeight; scrollHeight = element.scrollHeight; @@ -524,7 +526,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S // browser the results can vary. By subtracting a single pixel we're // working around fractional values, without visually changing anything. unavailableHeight -= 1; - contentContainer.style.setProperty("margin-bottom", unavailableHeight + "px", ""); + contentContainer.style.setProperty("margin-bottom", `${unavailableHeight}px`, ""); } else { contentContainer.classList.remove("dialogForm"); @@ -532,7 +534,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S } unavailableHeight += Util_1.default.outerHeight(data.header); const maximumHeight = window.innerHeight * (_dialogFullHeight ? 1 : 0.8) - unavailableHeight; - contentContainer.style.setProperty("max-height", ~~maximumHeight + "px", ""); + contentContainer.style.setProperty("max-height", `${~~maximumHeight}px`, ""); // fix for a calculation bug in Chrome causing the scrollbar to overlap the border if (Environment.browser() === "chrome") { if (data.content.scrollHeight > maximumHeight) { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Reusable.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Reusable.js index f23c260f22..679b7a74aa 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Reusable.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Reusable.js @@ -31,7 +31,7 @@ define(["require", "exports", "tslib", "./Simple"], function (require, exports, return; } const ghostElement = document.createElement("div"); - ghostElement.id = "reusableDropdownGhost" + _ghostElementId++; + ghostElement.id = `reusableDropdownGhost${_ghostElementId++}`; Simple_1.default.initFragment(ghostElement, menu); _dropdowns.set(identifier, ghostElement.id); } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js index 06a7bdd8a8..1169bc7528 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js @@ -342,7 +342,7 @@ define(["require", "exports", "tslib", "../../CallbackList", "../../Core", "../. button.addEventListener("keydown", handleKeyDown); _dropdowns.set(containerId, dropdown); _menus.set(containerId, menu); - if (!containerId.match(/^wcf\d+$/)) { + if (!/^wcf\d+$/.test(containerId)) { menu.dataset.source = containerId; } // prevent page scrolling diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Fixed.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Fixed.js index b4fe87d3b3..21c205d5ef 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Fixed.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Fixed.js @@ -68,7 +68,7 @@ define(["require", "exports", "tslib", "../../../Event/Handler", "../../Alignmen horizontal: "right", }); } - _pageHeaderSearch.style.setProperty("top", _pageHeaderPanel.clientHeight + "px", ""); + _pageHeaderSearch.style.setProperty("top", `${_pageHeaderPanel.clientHeight}px`, ""); _searchInput.focus(); window.setTimeout(() => { _searchInput.selectionStart = _searchInput.selectionEnd = _searchInput.value.length; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Menu.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Menu.js index 32c640430f..e3009ab1a7 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Menu.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Header/Menu.js @@ -82,7 +82,7 @@ define(["require", "exports", "tslib", "../../../Environment", "../../../Languag */ function setMarginLeft(offset) { _marginLeft = Math.min(_marginLeft + offset, 0); - _firstElement.style.setProperty("margin-left", _marginLeft + "px", ""); + _firstElement.style.setProperty("margin-left", `${_marginLeft}px`, ""); } /** * Toggles button overlays and rebuilds the list diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js index 7fb7f21b43..74254d5dde 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js @@ -261,8 +261,9 @@ define(["require", "exports", "tslib", "../../../Core", "../../../Environment", position = this.menu.offsetWidth; if (position < 0) position = 0; - this.menu.style.setProperty("transform", "translateX(" + (appearsAt === "left" ? 1 : -1) * (position - this.menu.offsetWidth) + "px)"); - backdrop.style.setProperty(appearsAt, Math.min(this.menu.offsetWidth, position) + "px"); + const offset = (appearsAt === "left" ? 1 : -1) * (position - this.menu.offsetWidth); + this.menu.style.setProperty("transform", `translateX(${offset}px)`); + backdrop.style.setProperty(appearsAt, Math.min(this.menu.offsetWidth, position).toString() + "px"); } }); } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Screen.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Screen.js index e1ebf600b8..7bf7547bce 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Screen.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Screen.js @@ -97,10 +97,10 @@ define(["require", "exports", "tslib", "../Core", "../Environment"], function (r // setting translateY causes Mobile Safari to snap if (Environment.platform() === "ios") { pageContainer.style.setProperty("position", "relative", ""); - pageContainer.style.setProperty("top", "-" + _scrollTop + "px", ""); + pageContainer.style.setProperty("top", `-${_scrollTop}px`, ""); } else { - pageContainer.style.setProperty("margin-top", "-" + _scrollTop + "px", ""); + pageContainer.style.setProperty("margin-top", `-${_scrollTop}px`, ""); } document.documentElement.classList.add("disableScrolling"); } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Page.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Page.js index aac7f6be6f..283cddefb7 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Page.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Page.js @@ -63,12 +63,12 @@ define(["require", "exports", "tslib", "../../Core", "../../Dom/Traverse", "../. if (UiScreen.is("screen-lg")) { dropdownMenu.dataset.dropdownAlignmentHorizontal = "right"; const minWidth = searchInput.clientWidth; - dropdownMenu.style.setProperty("min-width", minWidth + "px", ""); + dropdownMenu.style.setProperty("min-width", `${minWidth}px`, ""); // calculate offset to ignore the width caused by the submit button const parent = searchInput.parentElement; const offsetRight = Util_1.default.offset(parent).left + parent.clientWidth - (Util_1.default.offset(searchInput).left + minWidth); const offsetTop = Util_1.default.styleAsInt(window.getComputedStyle(parent), "padding-bottom"); - dropdownMenu.style.setProperty("transform", "translateX(-" + Math.ceil(offsetRight) + "px) translateY(-" + offsetTop + "px)", ""); + dropdownMenu.style.setProperty("transform", `translateX(-${Math.ceil(offsetRight)}px) translateY(-${offsetTop}px)`, ""); } }, callbackSelect() { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Suggestion.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Suggestion.js index 70f8a6a418..a2444669eb 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Suggestion.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Suggestion.js @@ -173,13 +173,13 @@ define(["require", "exports", "tslib", "../Ajax", "../Core", "./Dropdown/Simple" const anchor = document.createElement("a"); if (item.icon) { anchor.className = "box16"; - anchor.innerHTML = item.icon + " "; + anchor.innerHTML = `${item.icon} `; anchor.children[1].textContent = item.label; } else { anchor.textContent = item.label; } - anchor.dataset.objectId = item.objectID; + anchor.dataset.objectId = item.objectID.toString(); if (item.type) { anchor.dataset.type = item.type; } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu.js index 87f1d703e3..ca177e3882 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu.js @@ -152,11 +152,11 @@ define(["require", "exports", "tslib", "../Dom/Change/Listener", "../Dom/Util", list.classList.add("enableAnimation"); // new value is larger, we're scrolling towards the end if (scrollLeft < left) { - list.firstElementChild.style.setProperty("margin-left", scrollLeft - left + "px", ""); + list.firstElementChild.style.setProperty("margin-left", `${scrollLeft - left}px`, ""); } else { // new value is smaller, we're scrolling towards the start - list.style.setProperty("padding-left", scrollLeft - left + "px", ""); + list.style.setProperty("padding-left", `${scrollLeft - left}px`, ""); } setTimeout(() => { list.classList.remove("enableAnimation"); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu/Simple.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu/Simple.js index ab692257ed..b1eb8f2ac4 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu/Simple.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/TabMenu/Simple.js @@ -204,7 +204,7 @@ define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Dom/Util", " }); } if (!tab) { - throw new Error("Expected a valid tab name, '" + name + "' given (tab menu id: '" + this.container.id + "')."); + throw new Error(`Expected a valid tab name, '${name}' given (tab menu id: '${this.container.id}').`); } } name = (name || tab.dataset.name || ""); @@ -270,13 +270,9 @@ define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Dom/Util", " // update history window.history.replaceState(undefined, "", location); } - // TODO - /* - require(['WoltLabSuite/Core/Ui/TabMenu'], function (UiTabMenu) { - //noinspection JSUnresolvedFunction - UiTabMenu.scrollToTab(tab); + void new Promise((resolve_1, reject_1) => { require(["../TabMenu"], resolve_1, reject_1); }).then(tslib_1.__importStar).then((UiTabMenu) => { + UiTabMenu.scrollToTab(tab); }); - */ } /** * Selects the first visible tab of the tab menu and return `true`. If there is no @@ -331,7 +327,7 @@ define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Dom/Util", " if (!name) { if (tab.childElementCount === 1 && tab.children[0].nodeName === "A") { const link = tab.children[0]; - if (link.href.match(/#([^#]+)$/)) { + if (/#([^#]+)$/.exec(link.href)) { name = RegExp.$1; if (document.getElementById(name) === null) { name = null; @@ -364,7 +360,7 @@ define(["require", "exports", "tslib", "../../Dom/Traverse", "../../Dom/Util", " return this.tabs; } static getIdentifierFromHash() { - if (window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)) { + if (/^#+([^/]+)+(?:\/.+)?/.exec(window.location.hash)) { return RegExp.$1; } return ""; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js index 54694be128..f1a32f61ee 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js @@ -37,7 +37,7 @@ define(["require", "exports", "tslib", "../../../Ajax", "../../../Dom/Change/Lis this.currentPageNo = 0; this.currentUser = 0; this.knownElements = new WeakSet(); - Listener_1.default.add("WoltLabSuite/Core/Ui/User/Trophy/List", this.rebuild.bind(this)); + Listener_1.default.add("WoltLabSuite/Core/Ui/User/Trophy/List", () => this.rebuild()); this.rebuild(); } /** @@ -71,7 +71,7 @@ define(["require", "exports", "tslib", "../../../Ajax", "../../../Dom/Change/Lis if (data) { // validate pageNo if (data.pageCount !== 0 && (this.currentPageNo < 1 || this.currentPageNo > data.pageCount)) { - throw new RangeError("pageNo must be between 1 and " + data.pageCount + " (" + this.currentPageNo + " given)."); + throw new RangeError(`pageNo must be between 1 and ${data.pageCount} (${this.currentPageNo} given).`); } } if (data && data.has(this.currentPageNo)) { diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts index e12e8fca9c..5c800daa9c 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ajax/Request.ts @@ -17,6 +17,23 @@ import DomChangeListener from "../Dom/Change/Listener"; import DomUtil from "../Dom/Util"; import * as Language from "../Language"; +interface PreviousException { + message: string; + stacktrace: string; +} + +interface AjaxResponseException extends ResponseData { + exceptionID?: string; + previous: PreviousException[]; + file?: string; + line?: number; + message: string; + returnValues?: { + description?: string; + }; + stacktrace?: string; +} + let _didInit = false; let _ignoreAllErrors = false; @@ -78,18 +95,23 @@ class AjaxRequest { } if (this._options.callbackObject) { - if (typeof this._options.callbackObject._ajaxFailure === "function") + if (typeof this._options.callbackObject._ajaxFailure === "function") { this._options.failure = this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxFinalize === "function") + } + if (typeof this._options.callbackObject._ajaxFinalize === "function") { this._options.finalize = this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxSuccess === "function") + } + if (typeof this._options.callbackObject._ajaxSuccess === "function") { this._options.success = this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxProgress === "function") + } + if (typeof this._options.callbackObject._ajaxProgress === "function") { this._options.progress = this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject); - if (typeof this._options.callbackObject._ajaxUploadProgress === "function") + } + if (typeof this._options.callbackObject._ajaxUploadProgress === "function") { this._options.uploadProgress = this._options.callbackObject._ajaxUploadProgress.bind( this._options.callbackObject ); + } } if (!_didInit) { @@ -127,24 +149,24 @@ class AjaxRequest { this._xhr.withCredentials = true; } - const self = this; const options = Core.clone(this._options) as RequestOptions; - this._xhr.onload = function () { - if (this.readyState === XMLHttpRequest.DONE) { - if ((this.status >= 200 && this.status < 300) || this.status === 304) { - if (options.responseType && this.getResponseHeader("Content-Type")!.indexOf(options.responseType) !== 0) { + this._xhr.onload = () => { + const xhr = this._xhr!; + if (xhr.readyState === XMLHttpRequest.DONE) { + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { + if (options.responseType && xhr.getResponseHeader("Content-Type")!.indexOf(options.responseType) !== 0) { // request succeeded but invalid response type - self._failure(this, options); + this._failure(xhr, options); } else { - self._success(this, options); + this._success(xhr, options); } } else { - self._failure(this, options); + this._failure(xhr, options); } } }; - this._xhr.onerror = function () { - self._failure(this, options); + this._xhr.onerror = () => { + this._failure(this._xhr!, options); }; if (this._options.progress) { @@ -185,7 +207,7 @@ class AjaxRequest { /** * Sets a specific option. */ - setOption(key: string, value: any): void { + setOption(key: string, value: unknown): void { this._options[key] = value; } @@ -193,7 +215,7 @@ class AjaxRequest { * Returns an option by key or undefined. */ getOption(key: string): unknown | null { - if (this._options.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(this._options, key)) { return this._options[key]; } @@ -238,7 +260,7 @@ class AjaxRequest { // force-invoke the background queue if (data && data.forceBackgroundQueuePerform) { - import("../BackgroundQueue").then((backgroundQueue) => backgroundQueue.invoke()); + void import("../BackgroundQueue").then((backgroundQueue) => backgroundQueue.invoke()); } } @@ -274,10 +296,10 @@ class AjaxRequest { } if (options.ignoreError !== true && showError) { - const html = this.getErrorHtml(data, xhr); + const html = this.getErrorHtml(data as AjaxResponseException, xhr); if (html) { - import("../Ui/Dialog").then((UiDialog) => { + void import("../Ui/Dialog").then((UiDialog) => { UiDialog.openStatic(DomUtil.getUniqueId(), html, { title: Language.get("wcf.global.error.title"), }); @@ -291,39 +313,44 @@ class AjaxRequest { /** * Returns the inner HTML for an error/exception display. */ - getErrorHtml(data: ResponseData | null, xhr: XMLHttpRequest): string | null { + getErrorHtml(data: AjaxResponseException | null, xhr: XMLHttpRequest): string | null { let details = ""; let message: string; if (data !== null) { if (data.returnValues && data.returnValues.description) { - details += "

Description:

" + data.returnValues.description + "

"; + details += `

Description:

${data.returnValues.description}

`; } if (data.file && data.line) { - details += "

File:

" + data.file + " in line " + data.line + "

"; + details += `

File:

${data.file} in line ${data.line}

`; } - if (data.stacktrace) details += "

Stacktrace:

" + data.stacktrace + "

"; - else if (data.exceptionID) details += "

Exception ID: " + data.exceptionID + "

"; + if (data.stacktrace) { + details += `

Stacktrace:

${data.stacktrace}

`; + } else if (data.exceptionID) { + details += `

Exception ID: ${data.exceptionID}

`; + } message = data.message; - data.previous.forEach(function (previous) { - details += "

" + previous.message + "

"; - details += "

Stacktrace

" + previous.stacktrace + "

"; + data.previous.forEach((previous) => { + details += `

${previous.message}

`; + details += `

Stacktrace

${previous.stacktrace}

`; }); } else { message = xhr.responseText; } if (!message || message === "undefined") { - if (!window.ENABLE_DEBUG_MODE) return null; + if (!window.ENABLE_DEBUG_MODE) { + return null; + } message = "XMLHttpRequest failed without a responseText. Check your browser console."; } - return '

' + message + "

" + details + "
"; + return `

${message}

${details}
`; } /** diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil.ts index 2bc772f4de..d58c57ccd9 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil.ts @@ -119,12 +119,10 @@ export function rgbToHsv(r: number, g: number, b: number): HSV { s = diff / max; } - const v = max; - return { h: Math.round(h), s: Math.round(s * 100), - v: Math.round(v * 100), + v: Math.round(max * 100), }; } @@ -169,7 +167,7 @@ export function rgbToHex(r: number, g: number, b: number): string { const charList = "0123456789ABCDEF"; if (g === undefined) { - if (r.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)) { + if (/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/.exec(r.toString())) { r = +RegExp.$1; g = +RegExp.$2; b = +RegExp.$3; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts index ccb355207c..f7d78d149b 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts @@ -50,7 +50,9 @@ export function convertLegacyUrl(url: string): string { for (let i = 0, length = parts.length; i < length; i++) { const part = parts[i].trim(); if (part.length) { - if (controller.length) controller += "-"; + if (controller.length) { + controller += "-"; + } controller += part.toLowerCase(); } } @@ -73,22 +75,22 @@ export function extend(out: object, ...args: object[]): object { for (let i = 0, length = args.length; i < length; i++) { const obj = args[i]; - if (!obj) continue; - - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - if (!Array.isArray(obj[key]) && typeof obj[key] === "object") { - if (isPlainObject(obj[key])) { - // object literals have the prototype of Object which in return has no parent prototype - newObj[key] = extend(out[key], obj[key]); - } else { - newObj[key] = obj[key]; - } + if (!obj) { + continue; + } + + Object.keys(obj).forEach((key) => { + if (!Array.isArray(obj[key]) && typeof obj[key] === "object") { + if (isPlainObject(obj[key])) { + // object literals have the prototype of Object which in return has no parent prototype + newObj[key] = extend(out[key], obj[key]); } else { newObj[key] = obj[key]; } + } else { + newObj[key] = obj[key]; } - } + }); } return newObj; @@ -142,8 +144,8 @@ export function inherit(constructor: new () => any, superConstructor: new () => /** * Returns true if `obj` is an object literal. */ -export function isPlainObject(obj: any): boolean { - if (typeof obj !== "object" || obj === null || obj.nodeType) { +export function isPlainObject(obj: unknown): boolean { + if (typeof obj !== "object" || obj === null) { return false; } @@ -176,18 +178,16 @@ export function getUuid(): string { export function serialize(obj: object, prefix?: string): string { const parameters: string[] = []; - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - const parameterKey = prefix ? prefix + "[" + key + "]" : key; - const value = obj[key]; + Object.keys(obj).forEach((key) => { + const parameterKey = prefix ? prefix + "[" + key + "]" : key; + const value = obj[key]; - if (typeof value === "object") { - parameters.push(serialize(value, parameterKey)); - } else { - parameters.push(encodeURIComponent(parameterKey) + "=" + encodeURIComponent(value)); - } + if (typeof value === "object") { + parameters.push(serialize(value, parameterKey)); + } else { + parameters.push(encodeURIComponent(parameterKey) + "=" + encodeURIComponent(value)); } - } + }); return parameters.join("&"); } @@ -240,12 +240,10 @@ export function debounce( let timeoutId: ReturnType | undefined; return function (this: ThisParameterType, ...args: Parameters) { - const context = this; - - const doLater = function () { + const doLater = () => { timeoutId = undefined; if (!options.isImmediate) { - func.apply(context, args); + func.apply(this, args); } }; @@ -258,7 +256,7 @@ export function debounce( timeoutId = setTimeout(doLater, waitMilliseconds); if (shouldCallNow) { - func.apply(context, args); + func.apply(this, args); } }; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker.ts index 0d5c2cb2d1..35472cdade 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker.ts @@ -77,7 +77,7 @@ function createPicker() { let months = ""; const monthNames = Language.get("__monthsShort"); for (let i = 0; i < 12; i++) { - months += '"; + months += ``; } _dateMonth.innerHTML = months; @@ -109,7 +109,9 @@ function createPicker() { const weekdays = Language.get("__daysShort"); for (let i = 0; i < 7; i++) { let day = i + _firstDayOfWeek; - if (day > 6) day -= 7; + if (day > 6) { + day -= 7; + } const span = document.createElement("span"); span.textContent = weekdays[day]; @@ -144,7 +146,9 @@ function createPicker() { let tmp = ""; for (let i = 0; i < 24; i++) { date.setHours(i); - tmp += '"; + + const value = DateUtil.format(date, timeFormat); + tmp += ``; } _dateHour.innerHTML = tmp; @@ -160,7 +164,8 @@ function createPicker() { tmp = ""; for (let i = 0; i < 60; i++) { - tmp += '"; + const value = i < 10 ? "0" + i.toString() : i; + tmp += ``; } _dateMinute.innerHTML = tmp; @@ -178,18 +183,18 @@ function initDateRange(element: HTMLInputElement, now: Date, isMinDate: boolean) const name = isMinDate ? "minDate" : "maxDate"; let value = (element.dataset[name] || "").trim(); - if (value.match(/^(\d{4})-(\d{2})-(\d{2})$/)) { + if (/^(\d{4})-(\d{2})-(\d{2})$/.exec(value)) { // YYYY-mm-dd value = new Date(value).getTime().toString(); } else if (value === "now") { value = now.getTime().toString(); - } else if (value.match(/^\d{1,3}$/)) { + } else if (/^\d{1,3}$/.exec(value)) { // relative time span in years const date = new Date(now.getTime()); date.setFullYear(date.getFullYear() + ~~value * (isMinDate ? -1 : 1)); value = date.getTime().toString(); - } else if (value.match(/^datePicker-(.+)$/)) { + } else if (/^datePicker-(.+)$/.exec(value)) { // element id, e.g. `datePicker-someOtherElement` value = RegExp.$1; @@ -211,7 +216,9 @@ function initDateRange(element: HTMLInputElement, now: Date, isMinDate: boolean) * Sets up callbacks and event listeners. */ function setup() { - if (_didInit) return; + if (_didInit) { + return; + } _didInit = true; _firstDayOfWeek = parseInt(Language.get("wcf.date.firstDayOfTheWeek"), 10); @@ -222,7 +229,7 @@ function setup() { function getDateValue(attributeName: string): Date { let date = _input!.dataset[attributeName] || ""; - if (date.match(/^datePicker-(.+)$/)) { + if (/^datePicker-(.+)$/.exec(date)) { const referenceElement = document.getElementById(RegExp.$1); if (referenceElement === null) { throw new Error(`Unable to find an element with the id '${RegExp.$1}'.`); @@ -362,7 +369,7 @@ function renderPicker(day: number, month: number, year: number): void { // create options for month and year let years = ""; for (let i = _minDate.getFullYear(), last = _maxDate.getFullYear(); i <= last; i++) { - years += '"; + years += ``; } _dateYear.innerHTML = years; _dateYear.value = year.toString(); @@ -405,7 +412,9 @@ function renderGrid(day?: number, month?: number, year?: number): void { } // check if current selection exceeds min/max date - let date = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-" + ("0" + day.toString()).slice(-2)); + let date = new Date( + year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-" + ("0" + day.toString()).slice(-2) + ); if (date < _minDate) { year = _minDate.getFullYear(); month = _minDate.getMonth(); @@ -426,7 +435,7 @@ function renderGrid(day?: number, month?: number, year?: number): void { rebuildMonths = true; } - date = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + date = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); // shift until first displayed day equals first day of week while (date.getDay() !== _firstDayOfWeek) { @@ -451,8 +460,11 @@ function renderGrid(day?: number, month?: number, year?: number): void { cell.textContent = date.getDate().toString(); selectable = date.getMonth() === month; if (selectable) { - if (date < comparableMinDate) selectable = false; - else if (date > _maxDate) selectable = false; + if (date < comparableMinDate) { + selectable = false; + } else if (date > _maxDate) { + selectable = false; + } } cell.classList[selectable ? "remove" : "add"]("otherMonth"); @@ -493,12 +505,12 @@ function renderGrid(day?: number, month?: number, year?: number): void { (year === _maxDate.getFullYear() && +currentMonth.value > _maxDate.getMonth()); } - const nextMonth = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + const nextMonth = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); nextMonth.setMonth(nextMonth.getMonth() + 1); _dateMonthNext.classList[nextMonth < _maxDate ? "add" : "remove"]("active"); - const previousMonth = new Date(year + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); + const previousMonth = new Date(year.toString() + "-" + ("0" + (month + 1).toString()).slice(-2) + "-01"); previousMonth.setDate(previousMonth.getDate() - 1); _dateMonthPrevious.classList[previousMonth > _minDate ? "add" : "remove"]("active"); @@ -693,7 +705,7 @@ const DatePicker = { element.dataset.minDate = "120"; // do not use 'now' here, all though it makes sense, it causes bad UX - element.dataset.maxDate = new Date().getFullYear() + "-12-31"; + element.dataset.maxDate = new Date().getFullYear().toString() + "-12-31"; } else { if (element.min) { element.dataset.minDate = element.min; @@ -771,7 +783,9 @@ const DatePicker = { const button = document.createElement("a"); button.className = "inputSuffix button"; button.addEventListener("click", this.clear.bind(this, element)); - if (isEmpty) button.style.setProperty("visibility", "hidden", ""); + if (isEmpty) { + button.style.setProperty("visibility", "hidden", ""); + } container.appendChild(button); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools.ts index 62e8b0c685..b001a7507b 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools.ts @@ -27,15 +27,12 @@ const Devtools = { window.console.log(""); window.console.log("%cAvailable commands:", "text-decoration: underline"); - const commands: string[] = []; - for (const cmd in Devtools) { - if (cmd !== "_internal_" && Devtools.hasOwnProperty(cmd)) { - commands.push(cmd); - } - } - commands.sort().forEach(function (cmd) { - window.console.log("\tDevtools." + cmd + "()"); - }); + Object.keys(Devtools) + .filter((cmd) => cmd !== "_internal_") + .sort() + .forEach((cmd) => { + window.console.log(`\tDevtools.${cmd}()`); + }); window.console.log(""); }, @@ -82,8 +79,12 @@ const Devtools = { // Ignore JSON parsing failure. } - if (!_settings.editorAutosave) Devtools.toggleEditorAutosave(true); - if (_settings.eventLogging) Devtools.toggleEventLogging(true); + if (!_settings.editorAutosave) { + Devtools.toggleEditorAutosave(true); + } + if (_settings.eventLogging) { + Devtools.toggleEventLogging(true); + } } window.console.log("Settings are saved per browser session, enter `Devtools.help()` to learn more."); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts index 52f542aea1..1d4806c759 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts @@ -86,11 +86,9 @@ class Dictionary { static fromObject(object: object): Dictionary { const result = new Dictionary(); - for (const key in object) { - if (object.hasOwnProperty(key)) { - result.set(key, object[key]); - } - } + Object.keys(object).forEach((key) => { + result.set(key, object[key]); + }); return result; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts index 36305ba2a9..0949f3b957 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts @@ -63,7 +63,7 @@ const DomUtil = { let elementId: string; do { - elementId = "wcf" + _idCounter++; + elementId = `wcf${_idCounter++}`; } while (document.getElementById(elementId) !== null); return elementId; @@ -161,26 +161,24 @@ const DomUtil = { */ setStyles(element: HTMLElement, styles: CssDeclarations): void { let important = false; - for (const property in styles) { - if (styles.hasOwnProperty(property)) { - if (/ !important$/.test(styles[property])) { - important = true; - - styles[property] = styles[property].replace(/ !important$/, ""); - } else { - important = false; - } + Object.keys(styles).forEach((property) => { + if (/ !important$/.test(styles[property])) { + important = true; - // for a set style property with priority = important, some browsers are - // not able to overwrite it with a property != important; removing the - // property first solves this issue - if (element.style.getPropertyPriority(property) === "important" && !important) { - element.style.removeProperty(property); - } + styles[property] = styles[property].replace(/ !important$/, ""); + } else { + important = false; + } - element.style.setProperty(property, styles[property], important ? "important" : ""); + // for a set style property with priority = important, some browsers are + // not able to overwrite it with a property != important; removing the + // property first solves this issue + if (element.style.getPropertyPriority(property) === "important" && !important) { + element.style.removeProperty(property); } - } + + element.style.setProperty(property, styles[property], important ? "important" : ""); + }); }, /** @@ -295,7 +293,9 @@ const DomUtil = { idToUpperCase?: boolean ): DataAttributes { prefix = prefix || ""; - if (prefix.indexOf("data-") !== 0) prefix = "data-" + prefix; + if (prefix.indexOf("data-") !== 0) { + prefix = "data-" + prefix; + } camelCaseName = camelCaseName === true; idToUpperCase = idToUpperCase === true; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/I18n/Plural.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/I18n/Plural.ts index 71047d61a4..b79bd944ab 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/I18n/Plural.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/I18n/Plural.ts @@ -57,10 +57,12 @@ const Plural = { } // handle numeric attributes - for (const key in parameters) { - if (parameters.hasOwnProperty(key) && key.toString() === (~~key).toString() && key == value) { - return parameters[key]; - } + const numericAttribute = Object.keys(parameters).find((key) => { + return key.toString() === (~~key).toString() && key == value; + }); + + if (numericAttribute) { + return numericAttribute; } let category = Plural.getCategory(value); @@ -98,35 +100,53 @@ const Plural = { // Afrikaans af(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Amharic am(n: number): string | undefined { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) return PLURAL_ONE; + if (n == 1 || i === 0) { + return PLURAL_ONE; + } }, // Arabic ar(n: number): string | undefined { - if (n == 0) return PLURAL_ZERO; - if (n == 1) return PLURAL_ONE; - if (n == 2) return PLURAL_TWO; + if (n == 0) { + return PLURAL_ZERO; + } + if (n == 1) { + return PLURAL_ONE; + } + if (n == 2) { + return PLURAL_TWO; + } const mod100 = n % 100; - if (mod100 >= 3 && mod100 <= 10) return PLURAL_FEW; - if (mod100 >= 11 && mod100 <= 99) return PLURAL_MANY; + if (mod100 >= 3 && mod100 <= 10) { + return PLURAL_FEW; + } + if (mod100 >= 11 && mod100 <= 99) { + return PLURAL_MANY; + } }, // Assamese as(n: number): string | undefined { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) return PLURAL_ONE; + if (n == 1 || i === 0) { + return PLURAL_ONE; + } }, // Azerbaijani az(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Belarusian @@ -134,20 +154,30 @@ const Plural = { const mod10 = n % 10; const mod100 = n % 100; - if (mod10 == 1 && mod100 != 11) return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW; - if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) return PLURAL_MANY; + if (mod10 == 1 && mod100 != 11) { + return PLURAL_ONE; + } + if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { + return PLURAL_FEW; + } + if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) { + return PLURAL_MANY; + } }, // Bulgarian bg(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Bengali bn(n: number): string | undefined { const i = Math.floor(Math.abs(n)); - if (n == 1 || i === 0) return PLURAL_ONE; + if (n == 1 || i === 0) { + return PLURAL_ONE; + } }, // Tibetan @@ -164,40 +194,63 @@ const Plural = { const fMod10 = f % 10; const fMod100 = f % 100; - if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) return PLURAL_ONE; + if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) { + return PLURAL_ONE; + } if ( (v == 0 && mod10 >= 2 && mod10 <= 4 && mod100 >= 12 && mod100 <= 14) || (fMod10 >= 2 && fMod10 <= 4 && fMod100 >= 12 && fMod100 <= 14) - ) + ) { return PLURAL_FEW; + } }, // Czech cs(n: number): string | undefined { const v = Plural.getV(n); - if (n == 1 && v === 0) return PLURAL_ONE; - if (n >= 2 && n <= 4 && v === 0) return PLURAL_FEW; - if (v === 0) return PLURAL_MANY; + if (n == 1 && v === 0) { + return PLURAL_ONE; + } + if (n >= 2 && n <= 4 && v === 0) { + return PLURAL_FEW; + } + if (v === 0) { + return PLURAL_MANY; + } }, // Welsh cy(n: number): string | undefined { - if (n == 0) return PLURAL_ZERO; - if (n == 1) return PLURAL_ONE; - if (n == 2) return PLURAL_TWO; - if (n == 3) return PLURAL_FEW; - if (n == 6) return PLURAL_MANY; + if (n == 0) { + return PLURAL_ZERO; + } + if (n == 1) { + return PLURAL_ONE; + } + if (n == 2) { + return PLURAL_TWO; + } + if (n == 3) { + return PLURAL_FEW; + } + if (n == 6) { + return PLURAL_MANY; + } }, // Danish da(n: number): string | undefined { - if (n > 0 && n < 2) return PLURAL_ONE; + if (n > 0 && n < 2) { + return PLURAL_ONE; + } }, // Greek el(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Catalan (ca) @@ -211,54 +264,82 @@ const Plural = { // Swahili (sw) // Urdu (ur) en(n: number): string | undefined { - if (n == 1 && Plural.getV(n) === 0) return PLURAL_ONE; + if (n == 1 && Plural.getV(n) === 0) { + return PLURAL_ONE; + } }, // Spanish es(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Basque eu(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Persian fa(n: number): string | undefined { - if (n >= 0 && n <= 1) return PLURAL_ONE; + if (n >= 0 && n <= 1) { + return PLURAL_ONE; + } }, // French fr(n: number): string | undefined { - if (n >= 0 && n < 2) return PLURAL_ONE; + if (n >= 0 && n < 2) { + return PLURAL_ONE; + } }, // Irish ga(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; - if (n == 2) return PLURAL_TWO; - if (n == 3 || n == 4 || n == 5 || n == 6) return PLURAL_FEW; - if (n == 7 || n == 8 || n == 9 || n == 10) return PLURAL_MANY; + if (n == 1) { + return PLURAL_ONE; + } + if (n == 2) { + return PLURAL_TWO; + } + if (n == 3 || n == 4 || n == 5 || n == 6) { + return PLURAL_FEW; + } + if (n == 7 || n == 8 || n == 9 || n == 10) { + return PLURAL_MANY; + } }, // Gujarati gu(n: number): string | undefined { - if (n >= 0 && n <= 1) return PLURAL_ONE; + if (n >= 0 && n <= 1) { + return PLURAL_ONE; + } }, // Hebrew he(n: number): string | undefined { const v = Plural.getV(n); - if (n == 1 && v === 0) return PLURAL_ONE; - if (n == 2 && v === 0) return PLURAL_TWO; - if (n > 10 && v === 0 && n % 10 == 0) return PLURAL_MANY; + if (n == 1 && v === 0) { + return PLURAL_ONE; + } + if (n == 2 && v === 0) { + return PLURAL_TWO; + } + if (n > 10 && v === 0 && n % 10 == 0) { + return PLURAL_MANY; + } }, // Hindi hi(n: number): string | undefined { - if (n >= 0 && n <= 1) return PLURAL_ONE; + if (n >= 0 && n <= 1) { + return PLURAL_ONE; + } }, // Croatian @@ -269,12 +350,16 @@ const Plural = { // Hungarian hu(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Armenian hy(n: number): string | undefined { - if (n >= 0 && n < 2) return PLURAL_ONE; + if (n >= 0 && n < 2) { + return PLURAL_ONE; + } }, // Indonesian @@ -286,7 +371,9 @@ const Plural = { is(n: number): string | undefined { const f = Plural.getF(n); - if ((f === 0 && n % 10 === 1 && !(n % 100 === 11)) || !(f === 0)) return PLURAL_ONE; + if ((f === 0 && n % 10 === 1 && !(n % 100 === 11)) || !(f === 0)) { + return PLURAL_ONE; + } }, // Japanese @@ -301,12 +388,16 @@ const Plural = { // Georgian ka(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Kazakh kk(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Khmer @@ -316,7 +407,9 @@ const Plural = { // Kannada kn(n: number): string | undefined { - if (n >= 0 && n <= 1) return PLURAL_ONE; + if (n >= 0 && n <= 1) { + return PLURAL_ONE; + } }, // Korean @@ -326,17 +419,23 @@ const Plural = { // Kurdish ku(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Kyrgyz ky(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Luxembourgish lb(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Lao @@ -349,9 +448,15 @@ const Plural = { const mod10 = n % 10; const mod100 = n % 100; - if (mod10 == 1 && !(mod100 >= 11 && mod100 <= 19)) return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 9 && !(mod100 >= 11 && mod100 <= 19)) return PLURAL_FEW; - if (Plural.getF(n) != 0) return PLURAL_MANY; + if (mod10 == 1 && !(mod100 >= 11 && mod100 <= 19)) { + return PLURAL_ONE; + } + if (mod10 >= 2 && mod10 <= 9 && !(mod100 >= 11 && mod100 <= 19)) { + return PLURAL_FEW; + } + if (Plural.getF(n) != 0) { + return PLURAL_MANY; + } }, // Latvian @@ -363,9 +468,12 @@ const Plural = { const fMod10 = f % 10; const fMod100 = f % 100; - if (mod10 == 0 || (mod100 >= 11 && mod100 <= 19) || (v == 2 && fMod100 >= 11 && fMod100 <= 19)) return PLURAL_ZERO; - if ((mod10 == 1 && mod100 != 11) || (v == 2 && fMod10 == 1 && fMod100 != 11) || (v != 2 && fMod10 == 1)) + if (mod10 == 0 || (mod100 >= 11 && mod100 <= 19) || (v == 2 && fMod100 >= 11 && fMod100 <= 19)) { + return PLURAL_ZERO; + } + if ((mod10 == 1 && mod100 != 11) || (v == 2 && fMod10 == 1 && fMod100 != 11) || (v != 2 && fMod10 == 1)) { return PLURAL_ONE; + } }, // Macedonian @@ -375,17 +483,23 @@ const Plural = { // Malayalam ml(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Mongolian mn(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Marathi mr(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Malay @@ -397,9 +511,15 @@ const Plural = { mt(n: number): string | undefined { const mod100 = n % 100; - if (n == 1) return PLURAL_ONE; - if (n == 0 || (mod100 >= 2 && mod100 <= 10)) return PLURAL_FEW; - if (mod100 >= 11 && mod100 <= 19) return PLURAL_MANY; + if (n == 1) { + return PLURAL_ONE; + } + if (n == 0 || (mod100 >= 2 && mod100 <= 10)) { + return PLURAL_FEW; + } + if (mod100 >= 11 && mod100 <= 19) { + return PLURAL_MANY; + } }, // Burmese @@ -409,22 +529,30 @@ const Plural = { // Norwegian no(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Nepali ne(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Odia or(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Punjabi pa(n: number): string | undefined { - if (n == 1 || n == 0) return PLURAL_ONE; + if (n == 1 || n == 0) { + return PLURAL_ONE; + } }, // Polish @@ -433,23 +561,32 @@ const Plural = { const mod10 = n % 10; const mod100 = n % 100; - if (n == 1 && v == 0) return PLURAL_ONE; - if (v == 0 && mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW; + if (n == 1 && v == 0) { + return PLURAL_ONE; + } + if (v == 0 && mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { + return PLURAL_FEW; + } if ( v == 0 && ((n != 1 && mod10 >= 0 && mod10 <= 1) || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 12 && mod100 <= 14)) - ) + ) { return PLURAL_MANY; + } }, // Pashto ps(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Portuguese pt(n: number): string | undefined { - if (n >= 0 && n < 2) return PLURAL_ONE; + if (n >= 0 && n < 2) { + return PLURAL_ONE; + } }, // Romanian @@ -457,8 +594,12 @@ const Plural = { const v = Plural.getV(n); const mod100 = n % 100; - if (n == 1 && v === 0) return PLURAL_ONE; - if (v != 0 || n == 0 || (mod100 >= 2 && mod100 <= 19)) return PLURAL_FEW; + if (n == 1 && v === 0) { + return PLURAL_ONE; + } + if (v != 0 || n == 0 || (mod100 >= 2 && mod100 <= 19)) { + return PLURAL_FEW; + } }, // Russian @@ -467,20 +608,30 @@ const Plural = { const mod100 = n % 100; if (Plural.getV(n) == 0) { - if (mod10 == 1 && mod100 != 11) return PLURAL_ONE; - if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW; - if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) return PLURAL_MANY; + if (mod10 == 1 && mod100 != 11) { + return PLURAL_ONE; + } + if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) { + return PLURAL_FEW; + } + if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) { + return PLURAL_MANY; + } } }, // Sindhi sd(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Sinhala si(n: number): string | undefined { - if (n == 0 || n == 1 || (Math.floor(n) == 0 && Plural.getF(n) == 1)) return PLURAL_ONE; + if (n == 0 || n == 1 || (Math.floor(n) == 0 && Plural.getF(n) == 1)) { + return PLURAL_ONE; + } }, // Slovak @@ -494,14 +645,22 @@ const Plural = { const v = Plural.getV(n); const mod100 = n % 100; - if (v == 0 && mod100 == 1) return PLURAL_ONE; - if (v == 0 && mod100 == 2) return PLURAL_TWO; - if ((v == 0 && (mod100 == 3 || mod100 == 4)) || v != 0) return PLURAL_FEW; + if (v == 0 && mod100 == 1) { + return PLURAL_ONE; + } + if (v == 0 && mod100 == 2) { + return PLURAL_TWO; + } + if ((v == 0 && (mod100 == 3 || mod100 == 4)) || v != 0) { + return PLURAL_FEW; + } }, // Albanian sq(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Serbian @@ -512,12 +671,16 @@ const Plural = { // Tamil ta(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Telugu te(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Tajik @@ -532,17 +695,23 @@ const Plural = { // Turkmen tk(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Turkish tr(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Uyghur ug(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Ukrainian @@ -553,7 +722,9 @@ const Plural = { // Uzbek uz(n: number): string | undefined { - if (n == 1) return PLURAL_ONE; + if (n == 1) { + return PLURAL_ONE; + } }, // Vietnamese diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Image/Resizer.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Image/Resizer.ts index f542fd1c44..121b24fcdd 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Image/Resizer.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Image/Resizer.ts @@ -1,10 +1,10 @@ /** * This module allows resizing and conversion of HTMLImageElements to Blob and File objects * - * @author Tim Duesterhus, Maximilian Mader - * @copyright 2001-2020 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Image/Resizer + * @author Tim Duesterhus, Maximilian Mader + * @copyright 2001-2020 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Image/Resizer */ import * as FileUtil from "../FileUtil"; @@ -28,7 +28,9 @@ class ImageResizer { * Sets the default maximum width for this instance */ setMaxWidth(value: number): ImageResizer { - if (value == null) value = DEFAULT_WIDTH; + if (value == null) { + value = DEFAULT_WIDTH; + } this.maxWidth = value; return this; @@ -38,7 +40,9 @@ class ImageResizer { * Sets the default maximum height for this instance */ setMaxHeight(value: number): ImageResizer { - if (value == null) value = DEFAULT_HEIGHT; + if (value == null) { + value = DEFAULT_HEIGHT; + } this.maxHeight = value; return this; @@ -48,7 +52,9 @@ class ImageResizer { * Sets the default quality for this instance */ setQuality(value: number): ImageResizer { - if (value == null) value = DEFAULT_QUALITY; + if (value == null) { + value = DEFAULT_QUALITY; + } this.quality = value; return this; @@ -57,8 +63,10 @@ class ImageResizer { /** * Sets the default file type for this instance */ - setFileType(value): ImageResizer { - if (value == null) value = DEFAULT_FILETYPE; + setFileType(value: string): ImageResizer { + if (value == null) { + value = DEFAULT_FILETYPE; + } this.fileType = value; return this; @@ -73,7 +81,7 @@ class ImageResizer { fileType: string = this.fileType, quality: number = this.quality ): Promise { - const basename = fileName.match(/(.+)(\..+?)$/); + const basename = /(.+)(\..+?)$/.exec(fileName); let blob = await pica.toBlob(data.image, fileType, quality); @@ -134,7 +142,7 @@ class ImageResizer { maxWidth: number = this.maxWidth, maxHeight: number = this.maxHeight, quality: number = this.quality, - force: boolean = false, + force = false, cancelPromise ): Promise { const canvas = document.createElement("canvas"); @@ -142,7 +150,9 @@ class ImageResizer { if (window.createImageBitmap as any) { const bitmap = await createImageBitmap(image); - if (bitmap.height != image.height) throw new Error("Chrome Bug #1069965"); + if (bitmap.height != image.height) { + throw new Error("Chrome Bug #1069965"); + } } // Prevent upscaling diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/NumberUtil.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/NumberUtil.ts index a60f5b2695..f9ed77cf48 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/NumberUtil.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/NumberUtil.ts @@ -27,9 +27,11 @@ export function round(value: number, exp: number): number { // Shift let tmp = value.toString().split("e"); - value = Math.round(+(tmp[0] + "e" + (tmp[1] ? +tmp[1] - exp : -exp))); + let exponent = tmp[1] ? +tmp[1] - exp : -exp; + value = Math.round(+`${tmp[0]}e${exponent}`); // Shift back tmp = value.toString().split("e"); - return +(tmp[0] + "e" + (tmp[1] ? +tmp[1] + exp : exp)); + exponent = tmp[1] ? +tmp[1] + exp : exp; + return +`${tmp[0]}e${exponent}`; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Permission.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Permission.ts index c67a2aea66..9115ab1b2c 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Permission.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Permission.ts @@ -25,11 +25,7 @@ export function add(permission: string, value: boolean): void { * Adds all the permissions in the given object to the store. */ export function addObject(object: PermissionObject): void { - for (const key in object) { - if (object.hasOwnProperty(key)) { - add(key, object[key]); - } - } + Object.keys(object).forEach((key) => add(key, object[key])); } /** diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/StringUtil.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/StringUtil.ts index 67259fd657..48fc2b2626 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/StringUtil.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/StringUtil.ts @@ -42,7 +42,7 @@ export function escapeHTML(string: string): string { * @see https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/regexp.js#L25 */ export function escapeRegExp(string: string): string { - return String(string).replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1"); + return String(string).replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1"); } /** diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Template.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Template.ts index 11edf783d4..36d776a01a 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Template.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Template.ts @@ -46,6 +46,7 @@ class Template { "return " + template; + // eslint-disable-next-line @typescript-eslint/no-implied-eval this.fetch = new Function("StringUtil", "Language", "I18nPlural", "v", template).bind( undefined, StringUtil, @@ -60,8 +61,6 @@ class Template { /** * Evaluates the Template using the given parameters. - * - * @param {object} v Parameters to pass to the template. */ fetch(_v: object): string { // this will be replaced in the init function diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Timer/Repeating.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Timer/Repeating.ts index 0434bfcd4c..17d6727fd0 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Timer/Repeating.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Timer/Repeating.ts @@ -22,7 +22,7 @@ class RepeatingTimer { throw new TypeError("Expected a valid callback as first argument."); } if (delta < 0 || delta > 86_400 * 1_000) { - throw new RangeError("Invalid delta " + delta + ". Delta must be in the interval [0, 86400000]."); + throw new RangeError(`Invalid delta ${delta}. Delta must be in the interval [0, 86400000].`); } // curry callback with `this` as the first parameter diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Alignment.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Alignment.ts index afad6ec064..c6a0a282ee 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Alignment.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Alignment.ts @@ -36,78 +36,26 @@ const enum PointerClass { Right = 1, } -/** - * Calculates left/right position and verifies if the element would be still within the page's boundaries. - * - * @param {string} alignment align to this side of the reference element - * @param {Object} elDimensions element dimensions - * @param {Object} refDimensions reference element dimensions - * @param {Object} refOffsets position of reference element relative to the document - * @param {int} windowWidth window width - * @returns {Object} calculation results - */ -function tryAlignmentHorizontal( - alignment: HorizontalAlignment, - elDimensions, - refDimensions, - refOffsets, - windowWidth -): HorizontalResult { - let left: Offset = "auto"; - let right: Offset = "auto"; - let result = true; - - if (alignment === "left") { - left = refOffsets.left; - - if (left + elDimensions.width > windowWidth) { - result = false; - } - } else if (alignment === "right") { - if (refOffsets.left + refDimensions.width < elDimensions.width) { - result = false; - } else { - right = windowWidth - (refOffsets.left + refDimensions.width); - - if (right < 0) { - result = false; - } - } - } else { - left = refOffsets.left + refDimensions.width / 2 - elDimensions.width / 2; - left = ~~left; - - if (left < 0 || left + elDimensions.width > windowWidth) { - result = false; - } - } +interface ElementDimensions { + height: number; + width: number; +} - return { - align: alignment, - left: left, - right: right, - result: result, - }; +interface ElementOffset { + left: number; + top: number; } /** * Calculates top/bottom position and verifies if the element would be still within the page's boundaries. - * - * @param {string} alignment align to this side of the reference element - * @param {Object} elDimensions element dimensions - * @param {Object} refDimensions reference element dimensions - * @param {Object} refOffsets position of reference element relative to the document - * @param {int} windowHeight window height - * @param {int} verticalOffset desired gap between element and reference element - * @returns {object} calculation results */ function tryAlignmentVertical( alignment: VerticalAlignment, - elDimensions, - refDimensions, - refOffsets, - windowHeight, - verticalOffset + elDimensions: ElementDimensions, + refDimensions: ElementDimensions, + refOffsets: ElementOffset, + windowHeight: number, + verticalOffset: number ): VerticalResult { let bottom: Offset = "auto"; let top: Offset = "auto"; @@ -145,12 +93,55 @@ function tryAlignmentVertical( }; } +/** + * Calculates left/right position and verifies if the element would be still within the page's boundaries. + */ +function tryAlignmentHorizontal( + alignment: HorizontalAlignment, + elDimensions: ElementDimensions, + refDimensions: ElementDimensions, + refOffsets: ElementOffset, + windowWidth: number +): HorizontalResult { + let left: Offset = "auto"; + let right: Offset = "auto"; + let result = true; + + if (alignment === "left") { + left = refOffsets.left; + + if (left + elDimensions.width > windowWidth) { + result = false; + } + } else if (alignment === "right") { + if (refOffsets.left + refDimensions.width < elDimensions.width) { + result = false; + } else { + right = windowWidth - (refOffsets.left + refDimensions.width); + + if (right < 0) { + result = false; + } + } + } else { + left = refOffsets.left + refDimensions.width / 2 - elDimensions.width / 2; + left = ~~left; + + if (left < 0 || left + elDimensions.width > windowWidth) { + result = false; + } + } + + return { + align: alignment, + left: left, + right: right, + result: result, + }; +} + /** * Sets the alignment for target element relatively to the reference element. - * - * @param {Element} element target element - * @param {Element} referenceElement reference element - * @param {Object} options list of options to alter the behavior */ export function set(element: HTMLElement, referenceElement: HTMLElement, options?: AlignmentOptions): void { options = Core.extend( @@ -249,7 +240,7 @@ export function set(element: HTMLElement, referenceElement: HTMLElement, options refDimensions, refOffsets, windowHeight, - options.verticalOffset + options.verticalOffset! ); if (!vertical.result && (options.allowFlip === "both" || options.allowFlip === "vertical")) { const verticalFlipped = tryAlignmentVertical( @@ -258,7 +249,7 @@ export function set(element: HTMLElement, referenceElement: HTMLElement, options refDimensions, refOffsets, windowHeight, - options.verticalOffset + options.verticalOffset! ); // only use these results if it fits into the boundaries, otherwise both directions exceed and we honor the demanded direction if (verticalFlipped.result) { @@ -296,10 +287,10 @@ export function set(element: HTMLElement, referenceElement: HTMLElement, options } DomUtil.setStyles(element, { - bottom: bottom === "auto" ? bottom : Math.round(bottom) + "px", - left: left === "auto" ? left : Math.ceil(left) + "px", - right: right === "auto" ? right : Math.floor(right) + "px", - top: top === "auto" ? top : Math.round(top) + "px", + bottom: bottom === "auto" ? bottom : Math.round(bottom).toString() + "px", + left: left === "auto" ? left : Math.ceil(left).toString() + "px", + right: right === "auto" ? right : Math.floor(right).toString() + "px", + top: top === "auto" ? top : Math.round(top).toString() + "px", }); DomUtil.show(element); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dialog.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dialog.ts index 8f10490c43..8e48980a97 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dialog.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dialog.ts @@ -186,7 +186,7 @@ const UiDialog = { if (typeof html === "string" && html.trim() !== "") { setupData.source = html; } else { - import("../Ajax").then((Ajax) => { + void import("../Ajax").then((Ajax) => { const source = setupData.source as AjaxInitialization; Ajax.api(this as any, source.data, (data) => { if (data.returnValues && typeof data.returnValues.template === "string") { @@ -260,7 +260,7 @@ const UiDialog = { if (!options.closable) options.backdropCloseOnClick = false; if (options.closeConfirmMessage) { options.onBeforeClose = (id) => { - import("./Confirmation").then((UiConfirmation) => { + void import("./Confirmation").then((UiConfirmation) => { UiConfirmation.show({ confirm: this.close.bind(this, id), message: options!.closeConfirmMessage || "", @@ -316,7 +316,7 @@ const UiDialog = { const data = _dialogs.get(id as string); if (data === undefined) { - throw new Error("Expected a valid dialog id, '" + id + "' does not match any active dialog."); + throw new Error(`Expected a valid dialog id, '${id as string}' does not match any active dialog.`); } if (_validCallbacks.indexOf(key) === -1) { @@ -388,7 +388,9 @@ const UiDialog = { (event) => { let allowScroll = false; let element: HTMLElement | null = event.target as HTMLElement; - let clientHeight, scrollHeight, scrollTop; + let clientHeight: number; + let scrollHeight: number; + let scrollTop: number; for (;;) { clientHeight = element.clientHeight; scrollHeight = element.scrollHeight; @@ -627,7 +629,7 @@ const UiDialog = { // working around fractional values, without visually changing anything. unavailableHeight -= 1; - contentContainer.style.setProperty("margin-bottom", unavailableHeight + "px", ""); + contentContainer.style.setProperty("margin-bottom", `${unavailableHeight}px`, ""); } else { contentContainer.classList.remove("dialogForm"); contentContainer.style.removeProperty("margin-bottom"); @@ -636,7 +638,7 @@ const UiDialog = { unavailableHeight += DomUtil.outerHeight(data.header); const maximumHeight = window.innerHeight * (_dialogFullHeight ? 1 : 0.8) - unavailableHeight; - contentContainer.style.setProperty("max-height", ~~maximumHeight + "px", ""); + contentContainer.style.setProperty("max-height", `${~~maximumHeight}px`, ""); // fix for a calculation bug in Chrome causing the scrollbar to overlap the border if (Environment.browser() === "chrome") { diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Reusable.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Reusable.ts index 68fd93635c..f6c9c923c5 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Reusable.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Reusable.ts @@ -34,7 +34,7 @@ export function init(identifier: string, menu: HTMLElement): void { } const ghostElement = document.createElement("div"); - ghostElement.id = "reusableDropdownGhost" + _ghostElementId++; + ghostElement.id = `reusableDropdownGhost${_ghostElementId++}`; UiDropdownSimple.initFragment(ghostElement, menu); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts index 70b8d39617..ed1edaa741 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts @@ -410,7 +410,7 @@ const UiDropdownSimple = { _dropdowns.set(containerId, dropdown); _menus.set(containerId, menu); - if (!containerId.match(/^wcf\d+$/)) { + if (!/^wcf\d+$/.test(containerId)) { menu.dataset.source = containerId; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Fixed.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Fixed.ts index db261f881a..207f62b58a 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Fixed.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Fixed.ts @@ -78,7 +78,7 @@ function openSearchBar(): void { }); } - _pageHeaderSearch.style.setProperty("top", _pageHeaderPanel.clientHeight + "px", ""); + _pageHeaderSearch.style.setProperty("top", `${_pageHeaderPanel.clientHeight}px`, ""); _searchInput.focus(); window.setTimeout(() => { diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Menu.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Menu.ts index cfde2c1c10..de1907263b 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Menu.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Header/Menu.ts @@ -95,7 +95,7 @@ function showPrevious(event: MouseEvent): void { function setMarginLeft(offset: number): void { _marginLeft = Math.min(_marginLeft + offset, 0); - _firstElement.style.setProperty("margin-left", _marginLeft + "px", ""); + _firstElement.style.setProperty("margin-left", `${_marginLeft}px`, ""); } /** diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Menu/Abstract.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Menu/Abstract.ts index 1b9bff90dd..efb0c620b1 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Menu/Abstract.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Page/Menu/Abstract.ts @@ -39,7 +39,7 @@ abstract class UiPageMenuAbstract { private readonly activeList: HTMLOListElement[] = []; private readonly button: HTMLElement; private depth = 0; - private enabled: boolean = true; + private enabled = true; private readonly eventIdentifier: string; private readonly items = new Map(); private readonly menu: HTMLElement; @@ -324,11 +324,10 @@ abstract class UiPageMenuAbstract { if (appearsAt === "right") position = document.body.clientWidth - position; if (position > this.menu.offsetWidth) position = this.menu.offsetWidth; if (position < 0) position = 0; - this.menu.style.setProperty( - "transform", - "translateX(" + (appearsAt === "left" ? 1 : -1) * (position - this.menu.offsetWidth) + "px)" - ); - backdrop.style.setProperty(appearsAt, Math.min(this.menu.offsetWidth, position) + "px"); + + const offset = (appearsAt === "left" ? 1 : -1) * (position - this.menu.offsetWidth); + this.menu.style.setProperty("transform", `translateX(${offset}px)`); + backdrop.style.setProperty(appearsAt, Math.min(this.menu.offsetWidth, position).toString() + "px"); } }); } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Screen.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Screen.ts index 098815ece7..9ab15b8ab6 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Screen.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Screen.ts @@ -108,9 +108,9 @@ export function scrollDisable(): void { // setting translateY causes Mobile Safari to snap if (Environment.platform() === "ios") { pageContainer.style.setProperty("position", "relative", ""); - pageContainer.style.setProperty("top", "-" + _scrollTop + "px", ""); + pageContainer.style.setProperty("top", `-${_scrollTop}px`, ""); } else { - pageContainer.style.setProperty("margin-top", "-" + _scrollTop + "px", ""); + pageContainer.style.setProperty("margin-top", `-${_scrollTop}px`, ""); } document.documentElement.classList.add("disableScrolling"); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Search/Page.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Search/Page.ts index 6f69d68697..76b3e40f3f 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Search/Page.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Search/Page.ts @@ -73,7 +73,7 @@ export function init(objectType: string): void { dropdownMenu.dataset.dropdownAlignmentHorizontal = "right"; const minWidth = searchInput.clientWidth; - dropdownMenu.style.setProperty("min-width", minWidth + "px", ""); + dropdownMenu.style.setProperty("min-width", `${minWidth}px`, ""); // calculate offset to ignore the width caused by the submit button const parent = searchInput.parentElement!; @@ -82,7 +82,7 @@ export function init(objectType: string): void { const offsetTop = DomUtil.styleAsInt(window.getComputedStyle(parent), "padding-bottom"); dropdownMenu.style.setProperty( "transform", - "translateX(-" + Math.ceil(offsetRight) + "px) translateY(-" + offsetTop + "px)", + `translateX(-${Math.ceil(offsetRight)}px) translateY(-${offsetTop}px)`, "" ); } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Suggestion.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Suggestion.ts index 6ca21bc657..48b4d810e8 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Suggestion.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Suggestion.ts @@ -17,6 +17,17 @@ import { } from "../Ajax/Data"; import UiDropdownSimple from "./Dropdown/Simple"; +interface ItemData { + icon?: string; + label: string; + objectID: number; + type?: string; +} + +interface AjaxResponse extends DatabaseObjectActionResponse { + returnValues: ItemData[]; +} + class UiSuggestion implements AjaxCallbackObject { private readonly ajaxPayload: DatabaseObjectActionPayload; private readonly callbackSelect: CallbackSelect; @@ -196,7 +207,7 @@ class UiSuggestion implements AjaxCallbackObject { /** * Handles successful Ajax requests. */ - _ajaxSuccess(data: DatabaseObjectActionResponse): void { + _ajaxSuccess(data: AjaxResponse): void { if (this.dropdownMenu === null) { this.dropdownMenu = document.createElement("div"); this.dropdownMenu.className = "dropdownMenu"; @@ -210,13 +221,13 @@ class UiSuggestion implements AjaxCallbackObject { const anchor = document.createElement("a"); if (item.icon) { anchor.className = "box16"; - anchor.innerHTML = item.icon + " "; + anchor.innerHTML = `${item.icon} `; anchor.children[1].textContent = item.label; } else { anchor.textContent = item.label; } - anchor.dataset.objectId = item.objectID; + anchor.dataset.objectId = item.objectID.toString(); if (item.type) { anchor.dataset.type = item.type; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu.ts index ffd3b1ef63..266cee7b22 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu.ts @@ -59,7 +59,7 @@ function init() { }); // bind scroll listener - container.querySelectorAll(".tabMenu, .menu").forEach((menu) => { + container.querySelectorAll(".tabMenu, .menu").forEach((menu: HTMLElement) => { function callback() { timeout = null; @@ -136,7 +136,7 @@ function scrollEnable(isSetup) { _tabMenus.forEach((tabMenu) => { const activeTab = tabMenu.getActiveTab(); if (isSetup) { - rebuildMenuOverflow(activeTab.closest(".menu, .tabMenu")); + rebuildMenuOverflow(activeTab.closest(".menu, .tabMenu") as HTMLElement); } else { scrollToTab(activeTab); } @@ -170,10 +170,10 @@ function scrollMenu(list, left, scrollLeft, scrollWidth, width, paddingRight) { // new value is larger, we're scrolling towards the end if (scrollLeft < left) { - list.firstElementChild.style.setProperty("margin-left", scrollLeft - left + "px", ""); + list.firstElementChild.style.setProperty("margin-left", `${scrollLeft - left}px`, ""); } else { // new value is smaller, we're scrolling towards the start - list.style.setProperty("padding-left", scrollLeft - left + "px", ""); + list.style.setProperty("padding-left", `${scrollLeft - left}px`, ""); } setTimeout(() => { @@ -184,7 +184,7 @@ function scrollMenu(list, left, scrollLeft, scrollWidth, width, paddingRight) { }, 300); } -function rebuildMenuOverflow(menu) { +function rebuildMenuOverflow(menu: HTMLElement): void { if (!_enableTabScroll) { return; } @@ -306,12 +306,12 @@ export function getTabMenu(containerId: string): TabMenuSimple | undefined { return _tabMenus.get(containerId); } -export function scrollToTab(tab): void { +export function scrollToTab(tab: HTMLElement): void { if (!_enableTabScroll) { return; } - const list = tab.closest("ul"); + const list = tab.closest("ul")!; const width = list.clientWidth; const scrollLeft = list.scrollLeft; const scrollWidth = list.scrollWidth; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu/Simple.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu/Simple.ts index ffe29675a5..389abb169d 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu/Simple.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/TabMenu/Simple.ts @@ -247,7 +247,7 @@ class TabMenuSimple { } if (!tab) { - throw new Error("Expected a valid tab name, '" + name + "' given (tab menu id: '" + this.container.id + "')."); + throw new Error(`Expected a valid tab name, '${name}' given (tab menu id: '${this.container.id}').`); } } @@ -325,13 +325,9 @@ class TabMenuSimple { window.history.replaceState(undefined, "", location); } - // TODO - /* - require(['WoltLabSuite/Core/Ui/TabMenu'], function (UiTabMenu) { - //noinspection JSUnresolvedFunction - UiTabMenu.scrollToTab(tab); + void import("../TabMenu").then((UiTabMenu) => { + UiTabMenu.scrollToTab(tab!); }); - */ } /** @@ -396,7 +392,7 @@ class TabMenuSimple { if (!name) { if (tab.childElementCount === 1 && tab.children[0].nodeName === "A") { const link = tab.children[0] as HTMLAnchorElement; - if (link.href.match(/#([^#]+)$/)) { + if (/#([^#]+)$/.exec(link.href)) { name = RegExp.$1; if (document.getElementById(name) === null) { @@ -434,7 +430,7 @@ class TabMenuSimple { } static getIdentifierFromHash(): string { - if (window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)) { + if (/^#+([^/]+)+(?:\/.+)?/.exec(window.location.hash)) { return RegExp.$1; } diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/User/Trophy/List.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/User/Trophy/List.ts index 9aafde4480..51aba6ee18 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/User/Trophy/List.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/User/Trophy/List.ts @@ -42,7 +42,7 @@ class UiUserTrophyList implements AjaxCallbackObject, DialogCallbackObject { * Initializes the user trophy list. */ constructor() { - DomChangeListener.add("WoltLabSuite/Core/Ui/User/Trophy/List", this.rebuild.bind(this)); + DomChangeListener.add("WoltLabSuite/Core/Ui/User/Trophy/List", () => this.rebuild()); this.rebuild(); } @@ -83,7 +83,7 @@ class UiUserTrophyList implements AjaxCallbackObject, DialogCallbackObject { if (data) { // validate pageNo if (data.pageCount !== 0 && (this.currentPageNo < 1 || this.currentPageNo > data.pageCount)) { - throw new RangeError("pageNo must be between 1 and " + data.pageCount + " (" + this.currentPageNo + " given)."); + throw new RangeError(`pageNo must be between 1 and ${data.pageCount} (${this.currentPageNo} given).`); } } -- 2.20.1