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;
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;
* 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;
}
// 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);
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"),
});
let message;
if (data !== null) {
if (data.returnValues && data.returnValues.description) {
- details += "<br><p>Description:</p><p>" + data.returnValues.description + "</p>";
+ details += `<br><p>Description:</p><p>${data.returnValues.description}</p>`;
}
if (data.file && data.line) {
- details += "<br><p>File:</p><p>" + data.file + " in line " + data.line + "</p>";
+ details += `<br><p>File:</p><p>${data.file} in line ${data.line}</p>`;
+ }
+ if (data.stacktrace) {
+ details += `<br><p>Stacktrace:</p><p>${data.stacktrace}</p>`;
+ }
+ else if (data.exceptionID) {
+ details += `<br><p>Exception ID: <code>${data.exceptionID}</code></p>`;
}
- if (data.stacktrace)
- details += "<br><p>Stacktrace:</p><p>" + data.stacktrace + "</p>";
- else if (data.exceptionID)
- details += "<br><p>Exception ID: <code>" + data.exceptionID + "</code></p>";
message = data.message;
- data.previous.forEach(function (previous) {
- details += "<hr><p>" + previous.message + "</p>";
- details += "<br><p>Stacktrace</p><p>" + previous.stacktrace + "</p>";
+ data.previous.forEach((previous) => {
+ details += `<hr><p>${previous.message}</p>`;
+ details += `<br><p>Stacktrace</p><p>${previous.stacktrace}</p>`;
});
}
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 '<div class="ajaxDebugMessage"><p>' + message + "</p>" + details + "</div>";
+ return `<div class="ajaxDebugMessage"><p>${message}</p>${details}</div>`;
}
/**
* Finalizes a request.
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;
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;
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();
}
}
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;
}
* 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;
*/
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;
}) {
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;
}
timeoutId = setTimeout(doLater, waitMilliseconds);
if (shouldCallNow) {
- func.apply(context, args);
+ func.apply(this, args);
}
};
}
let months = "";
const monthNames = Language.get("__monthsShort");
for (let i = 0; i < 12; i++) {
- months += '<option value="' + i + '">' + monthNames[i] + "</option>";
+ months += `<option value="${i}">${monthNames[i]}</option>`;
}
_dateMonth.innerHTML = months;
_dateYear = document.createElement("select");
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);
let tmp = "";
for (let i = 0; i < 24; i++) {
date.setHours(i);
- tmp += '<option value="' + i + '">' + DateUtil.format(date, timeFormat) + "</option>";
+ const value = DateUtil.format(date, timeFormat);
+ tmp += `<option value="${i}">${value}</option>`;
}
_dateHour.innerHTML = tmp;
_dateTime.appendChild(_dateHour);
_dateMinute.addEventListener("change", formatValue);
tmp = "";
for (let i = 0; i < 60; i++) {
- tmp += '<option value="' + i + '">' + (i < 10 ? "0" + i.toString() : i) + "</option>";
+ const value = i < 10 ? "0" + i.toString() : i;
+ tmp += `<option value="${i}">${value}</option>`;
}
_dateMinute.innerHTML = tmp;
_dateTime.appendChild(_dateMinute);
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) {
* 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());
}
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}'.`);
// create options for month and year
let years = "";
for (let i = _minDate.getFullYear(), last = _maxDate.getFullYear(); i <= last; i++) {
- years += '<option value="' + i + '">' + i + "</option>";
+ years += `<option value="${i}">${i}</option>`;
}
_dateYear.innerHTML = years;
_dateYear.value = year.toString();
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();
_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);
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) {
(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");
}
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) {
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";
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("");
},
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("");
*/
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() {
getUniqueId() {
let elementId;
do {
- elementId = "wcf" + _idCounter++;
+ elementId = `wcf${_idCounter++}`;
} while (document.getElementById(elementId) !== null);
return elementId;
},
*/
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.
*/
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 = {};
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]) {
},
// 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) {
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)
// 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) {
},
// 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) {
// 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) {
},
// 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) {
},
// Kannada
kn(n) {
- if (n >= 0 && n <= 1)
+ if (n >= 0 && n <= 1) {
return PLURAL_ONE;
+ }
},
// Korean
ko(_n) {
},
// 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) {
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) {
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) {
},
// 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) {
// 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) {
},
// 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) {
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) {
},
// 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) {
},
// 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) {
},
// Uzbek
uz(n) {
- if (n == 1)
+ if (n == 1) {
return PLURAL_ONE;
+ }
},
// Vietnamese
vi(_n) {
/**
* 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 <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Image/Resizer
+ * @author Tim Duesterhus, Maximilian Mader
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Image/Resizer
*/
define(["require", "exports", "tslib", "../FileUtil", "./ExifUtil", "pica"], function (require, exports, tslib_1, FileUtil, ExifUtil, pica_1) {
"use strict";
* Sets the default maximum width for this instance
*/
setMaxWidth(value) {
- if (value == null)
+ if (value == null) {
value = DEFAULT_WIDTH;
+ }
this.maxWidth = value;
return this;
}
* Sets the default maximum height for this instance
*/
setMaxHeight(value) {
- if (value == null)
+ if (value == null) {
value = DEFAULT_HEIGHT;
+ }
this.maxHeight = value;
return this;
}
* Sets the default quality for this instance
*/
setQuality(value) {
- if (value == null)
+ if (value == null) {
value = DEFAULT_QUALITY;
+ }
this.quality = value;
return this;
}
* Sets the default file type for this instance
*/
setFileType(value) {
- if (value == null)
+ if (value == null) {
value = DEFAULT_FILETYPE;
+ }
this.fileType = value;
return this;
}
* 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);
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);
}
// 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;
});
* 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;
/**
* @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;
/**
"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) {
}
/**
* 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
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);
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<string, int>} elDimensions element dimensions
- * @param {Object<string, int>} refDimensions reference element dimensions
- * @param {Object<string, int>} refOffsets position of reference element relative to the document
- * @param {int} windowWidth window width
- * @returns {Object<string, *>} 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<string, int>} elDimensions element dimensions
- * @param {Object<string, int>} refDimensions reference element dimensions
- * @param {Object<string, int>} 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<string, *>} calculation results
*/
function tryAlignmentVertical(alignment, elDimensions, refDimensions, refOffsets, windowHeight, verticalOffset) {
let bottom = "auto";
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<string, *>} options list of options to alter the behavior
*/
function set(element, referenceElement, options) {
options = Core.extend({
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");
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") {
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 || "",
}
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.");
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;
// 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");
}
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) {
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);
}
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
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;
*/
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
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");
}
});
}
// 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");
}
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() {
const anchor = document.createElement("a");
if (item.icon) {
anchor.className = "box16";
- anchor.innerHTML = item.icon + " <span></span>";
+ anchor.innerHTML = `${item.icon} <span></span>`;
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;
}
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");
});
}
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 || "");
// 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
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;
return this.tabs;
}
static getIdentifierFromHash() {
- if (window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)) {
+ if (/^#+([^/]+)+(?:\/.+)?/.exec(window.location.hash)) {
return RegExp.$1;
}
return "";
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();
}
/**
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)) {
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;
}
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) {
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) {
/**
* Sets a specific option.
*/
- setOption(key: string, value: any): void {
+ setOption(key: string, value: unknown): void {
this._options[key] = value;
}
* 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];
}
// force-invoke the background queue
if (data && data.forceBackgroundQueuePerform) {
- import("../BackgroundQueue").then((backgroundQueue) => backgroundQueue.invoke());
+ void import("../BackgroundQueue").then((backgroundQueue) => backgroundQueue.invoke());
}
}
}
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"),
});
/**
* 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 += "<br><p>Description:</p><p>" + data.returnValues.description + "</p>";
+ details += `<br><p>Description:</p><p>${data.returnValues.description}</p>`;
}
if (data.file && data.line) {
- details += "<br><p>File:</p><p>" + data.file + " in line " + data.line + "</p>";
+ details += `<br><p>File:</p><p>${data.file} in line ${data.line}</p>`;
}
- if (data.stacktrace) details += "<br><p>Stacktrace:</p><p>" + data.stacktrace + "</p>";
- else if (data.exceptionID) details += "<br><p>Exception ID: <code>" + data.exceptionID + "</code></p>";
+ if (data.stacktrace) {
+ details += `<br><p>Stacktrace:</p><p>${data.stacktrace}</p>`;
+ } else if (data.exceptionID) {
+ details += `<br><p>Exception ID: <code>${data.exceptionID}</code></p>`;
+ }
message = data.message;
- data.previous.forEach(function (previous) {
- details += "<hr><p>" + previous.message + "</p>";
- details += "<br><p>Stacktrace</p><p>" + previous.stacktrace + "</p>";
+ data.previous.forEach((previous) => {
+ details += `<hr><p>${previous.message}</p>`;
+ details += `<br><p>Stacktrace</p><p>${previous.stacktrace}</p>`;
});
} 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 '<div class="ajaxDebugMessage"><p>' + message + "</p>" + details + "</div>";
+ return `<div class="ajaxDebugMessage"><p>${message}</p>${details}</div>`;
}
/**
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),
};
}
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;
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();
}
}
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;
/**
* 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;
}
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("&");
}
let timeoutId: ReturnType<typeof setTimeout> | undefined;
return function (this: ThisParameterType<F>, ...args: Parameters<F>) {
- const context = this;
-
- const doLater = function () {
+ const doLater = () => {
timeoutId = undefined;
if (!options.isImmediate) {
- func.apply(context, args);
+ func.apply(this, args);
}
};
timeoutId = setTimeout(doLater, waitMilliseconds);
if (shouldCallNow) {
- func.apply(context, args);
+ func.apply(this, args);
}
};
}
let months = "";
const monthNames = Language.get("__monthsShort");
for (let i = 0; i < 12; i++) {
- months += '<option value="' + i + '">' + monthNames[i] + "</option>";
+ months += `<option value="${i}">${monthNames[i]}</option>`;
}
_dateMonth.innerHTML = months;
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];
let tmp = "";
for (let i = 0; i < 24; i++) {
date.setHours(i);
- tmp += '<option value="' + i + '">' + DateUtil.format(date, timeFormat) + "</option>";
+
+ const value = DateUtil.format(date, timeFormat);
+ tmp += `<option value="${i}">${value}</option>`;
}
_dateHour.innerHTML = tmp;
tmp = "";
for (let i = 0; i < 60; i++) {
- tmp += '<option value="' + i + '">' + (i < 10 ? "0" + i.toString() : i) + "</option>";
+ const value = i < 10 ? "0" + i.toString() : i;
+ tmp += `<option value="${i}">${value}</option>`;
}
_dateMinute.innerHTML = tmp;
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;
* Sets up callbacks and event listeners.
*/
function setup() {
- if (_didInit) return;
+ if (_didInit) {
+ return;
+ }
_didInit = true;
_firstDayOfWeek = parseInt(Language.get("wcf.date.firstDayOfTheWeek"), 10);
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}'.`);
// create options for month and year
let years = "";
for (let i = _minDate.getFullYear(), last = _maxDate.getFullYear(); i <= last; i++) {
- years += '<option value="' + i + '">' + i + "</option>";
+ years += `<option value="${i}">${i}</option>`;
}
_dateYear.innerHTML = years;
_dateYear.value = year.toString();
}
// 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();
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) {
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");
(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");
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;
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);
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("");
},
// 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.");
static fromObject(object: object): Dictionary<any> {
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;
}
let elementId: string;
do {
- elementId = "wcf" + _idCounter++;
+ elementId = `wcf${_idCounter++}`;
} while (document.getElementById(elementId) !== null);
return elementId;
*/
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" : "");
+ });
},
/**
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;
}
// 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);
// 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
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
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)
// 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
// 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
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
// 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
// Kannada
kn(n: number): string | undefined {
- if (n >= 0 && n <= 1) return PLURAL_ONE;
+ if (n >= 0 && n <= 1) {
+ return PLURAL_ONE;
+ }
},
// Korean
// 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
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
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
// 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
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
// 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
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
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
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
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
// 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
// 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
// Uzbek
uz(n: number): string | undefined {
- if (n == 1) return PLURAL_ONE;
+ if (n == 1) {
+ return PLURAL_ONE;
+ }
},
// Vietnamese
/**
* 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 <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Image/Resizer
+ * @author Tim Duesterhus, Maximilian Mader
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Image/Resizer
*/
import * as FileUtil from "../FileUtil";
* 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;
* 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;
* 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;
/**
* 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;
fileType: string = this.fileType,
quality: number = this.quality
): Promise<File> {
- const basename = fileName.match(/(.+)(\..+?)$/);
+ const basename = /(.+)(\..+?)$/.exec(fileName);
let blob = await pica.toBlob(data.image, fileType, quality);
maxWidth: number = this.maxWidth,
maxHeight: number = this.maxHeight,
quality: number = this.quality,
- force: boolean = false,
+ force = false,
cancelPromise
): Promise<HTMLCanvasElement | undefined> {
const canvas = document.createElement("canvas");
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
// 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}`;
}
* 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]));
}
/**
* @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");
}
/**
"return " +
template;
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
this.fetch = new Function("StringUtil", "Language", "I18nPlural", "v", template).bind(
undefined,
StringUtil,
/**
* 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
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
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<string, int>} elDimensions element dimensions
- * @param {Object<string, int>} refDimensions reference element dimensions
- * @param {Object<string, int>} refOffsets position of reference element relative to the document
- * @param {int} windowWidth window width
- * @returns {Object<string, *>} 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<string, int>} elDimensions element dimensions
- * @param {Object<string, int>} refDimensions reference element dimensions
- * @param {Object<string, int>} 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<string, *>} 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";
};
}
+/**
+ * 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<string, *>} options list of options to alter the behavior
*/
export function set(element: HTMLElement, referenceElement: HTMLElement, options?: AlignmentOptions): void {
options = Core.extend(
refDimensions,
refOffsets,
windowHeight,
- options.verticalOffset
+ options.verticalOffset!
);
if (!vertical.result && (options.allowFlip === "both" || options.allowFlip === "vertical")) {
const verticalFlipped = tryAlignmentVertical(
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) {
}
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);
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") {
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 || "",
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) {
(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;
// 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");
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") {
}
const ghostElement = document.createElement("div");
- ghostElement.id = "reusableDropdownGhost" + _ghostElementId++;
+ ghostElement.id = `reusableDropdownGhost${_ghostElementId++}`;
UiDropdownSimple.initFragment(ghostElement, menu);
_dropdowns.set(containerId, dropdown);
_menus.set(containerId, menu);
- if (!containerId.match(/^wcf\d+$/)) {
+ if (!/^wcf\d+$/.test(containerId)) {
menu.dataset.source = containerId;
}
});
}
- _pageHeaderSearch.style.setProperty("top", _pageHeaderPanel.clientHeight + "px", "");
+ _pageHeaderSearch.style.setProperty("top", `${_pageHeaderPanel.clientHeight}px`, "");
_searchInput.focus();
window.setTimeout(() => {
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`, "");
}
/**
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<HTMLAnchorElement, ItemData>();
private readonly menu: HTMLElement;
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");
}
});
}
// 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");
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 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)`,
""
);
}
} 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;
/**
* 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";
const anchor = document.createElement("a");
if (item.icon) {
anchor.className = "box16";
- anchor.innerHTML = item.icon + " <span></span>";
+ anchor.innerHTML = `${item.icon} <span></span>`;
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;
}
});
// bind scroll listener
- container.querySelectorAll(".tabMenu, .menu").forEach((menu) => {
+ container.querySelectorAll(".tabMenu, .menu").forEach((menu: HTMLElement) => {
function callback() {
timeout = null;
_tabMenus.forEach((tabMenu) => {
const activeTab = tabMenu.getActiveTab();
if (isSetup) {
- rebuildMenuOverflow(activeTab.closest(".menu, .tabMenu"));
+ rebuildMenuOverflow(activeTab.closest(".menu, .tabMenu") as HTMLElement);
} else {
scrollToTab(activeTab);
}
// 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(() => {
}, 300);
}
-function rebuildMenuOverflow(menu) {
+function rebuildMenuOverflow(menu: HTMLElement): void {
if (!_enableTabScroll) {
return;
}
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;
}
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}').`);
}
}
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!);
});
- */
}
/**
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) {
}
static getIdentifierFromHash(): string {
- if (window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)) {
+ if (/^#+([^/]+)+(?:\/.+)?/.exec(window.location.hash)) {
return RegExp.$1;
}
* 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();
}
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).`);
}
}