return;
}
- const button = document.createElement("span");
- button.tabIndex = 0;
- button.setAttribute("role", "button");
+ const button = document.createElement("button");
button.className = "icon icon24 fa-files-o pointer jsTooltip";
button.setAttribute("title", Language.get("wcf.message.bbcode.code.copy"));
UiNotification.show(Language.get("wcf.message.bbcode.code.copy.success"));
};
- button.addEventListener("click", clickCallback);
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
-
- void clickCallback();
- }
- });
-
+ button.addEventListener("click", () => clickCallback());
+
header.appendChild(button);
}
let _dateHour: HTMLSelectElement;
let _dateMinute: HTMLSelectElement;
let _dateMonth: HTMLSelectElement;
-let _dateMonthNext: HTMLAnchorElement;
-let _dateMonthPrevious: HTMLAnchorElement;
+let _dateMonthNext: HTMLButtonElement;
+let _dateMonthPrevious: HTMLButtonElement;
let _dateTime: HTMLElement;
let _dateYear: HTMLSelectElement;
let _datePicker: HTMLElement | null = null;
const header = document.createElement("header");
_datePicker.appendChild(header);
- _dateMonthPrevious = document.createElement("a");
+ _dateMonthPrevious = document.createElement("button");
_dateMonthPrevious.className = "previous jsTooltip";
- _dateMonthPrevious.href = "#";
- _dateMonthPrevious.setAttribute("role", "button");
- _dateMonthPrevious.tabIndex = 0;
_dateMonthPrevious.title = Language.get("wcf.date.datePicker.previousMonth");
_dateMonthPrevious.setAttribute("aria-label", Language.get("wcf.date.datePicker.previousMonth"));
_dateMonthPrevious.innerHTML = '<span class="icon icon16 fa-arrow-left"></span>';
- _dateMonthPrevious.addEventListener("click", (ev) => DatePicker.previousMonth(ev));
+ _dateMonthPrevious.addEventListener("click", () => DatePicker.previousMonth());
header.appendChild(_dateMonthPrevious);
const monthYearContainer = document.createElement("span");
_dateYear.addEventListener("change", changeYear);
monthYearContainer.appendChild(_dateYear);
- _dateMonthNext = document.createElement("a");
+ _dateMonthNext = document.createElement("button");
_dateMonthNext.className = "next jsTooltip";
- _dateMonthNext.href = "#";
- _dateMonthNext.setAttribute("role", "button");
- _dateMonthNext.tabIndex = 0;
_dateMonthNext.title = Language.get("wcf.date.datePicker.nextMonth");
_dateMonthNext.setAttribute("aria-label", Language.get("wcf.date.datePicker.nextMonth"));
_dateMonthNext.innerHTML = '<span class="icon icon16 fa-arrow-right"></span>';
- _dateMonthNext.addEventListener("click", (ev) => DatePicker.nextMonth(ev));
+ _dateMonthNext.addEventListener("click", () => DatePicker.nextMonth());
header.appendChild(_dateMonthNext);
_dateGrid = document.createElement("ul");
* Opens the date picker.
*/
function open(event: MouseEvent): void {
- event.preventDefault();
- event.stopPropagation();
-
createPicker();
const target = event.currentTarget as HTMLInputElement;
const container = document.createElement("div");
container.className = "inputAddon";
- const openButton = document.createElement("a");
+ const openButton = document.createElement("button");
openButton.className = "inputSuffix button jsTooltip";
- openButton.href = "#";
- openButton.setAttribute("role", "button");
- openButton.tabIndex = 0;
openButton.title = Language.get("wcf.date.datePicker");
openButton.setAttribute("aria-label", Language.get("wcf.date.datePicker"));
openButton.setAttribute("aria-haspopup", "true");
/**
* Shows the previous month.
*/
- previousMonth(event: MouseEvent): void {
- event.preventDefault();
-
+ previousMonth(): void {
if (_dateMonth.value === "0") {
_dateMonth.value = "11";
_dateYear.value = (+_dateYear.value - 1).toString();
/**
* Shows the next month.
*/
- nextMonth(event: MouseEvent): void {
- event.preventDefault();
-
+ nextMonth(): void {
if (_dateMonth.value === "11") {
_dateMonth.value = "0";
_dateYear.value = (+_dateYear.value + 1).toString();
header.appendChild(title);
if (options.closable) {
- const closeButton = document.createElement("a");
+ const closeButton = document.createElement("button");
closeButton.className = "dialogCloseButton jsTooltip";
- closeButton.href = "#";
- closeButton.setAttribute("role", "button");
- closeButton.tabIndex = 0;
closeButton.title = options.closeButtonLabel;
closeButton.setAttribute("aria-label", options.closeButtonLabel);
- closeButton.addEventListener("click", (ev) => this._close(ev));
+ closeButton.addEventListener("click", () => this._close());
header.appendChild(closeButton);
const span = document.createElement("span");
/**
* Handles clicks on the close button or the backdrop if enabled.
*/
- _close(event: MouseEvent): boolean {
- event.preventDefault();
-
+ _close(): boolean {
const data = _dialogs.get(_activeDialog!);
if (data === undefined) {
// Closing the dialog while it is already being closed
}
if (Core.stringToBool(_container.getAttribute("close-on-click"))) {
- this._close(event);
+ event.preventDefault();
+
+ this._close();
} else {
event.preventDefault();
}
const menuId = DomUtil.getUniqueId();
- const button = document.createElement("a");
+ const button = document.createElement("button");
button.classList.add("pageMenuMainItemToggle");
- button.tabIndex = 0;
- button.setAttribute("role", "button");
button.setAttribute("aria-expanded", "false");
button.setAttribute("aria-controls", menuId);
button.innerHTML = '<span class="icon icon24 fa-angle-down" aria-hidden="true"></span>';
list.id = menuId;
list.hidden = true;
- button.addEventListener("click", (event) => {
- event.preventDefault();
-
+ button.addEventListener("click", () => {
this.toggleList(button, list);
});
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
-
- button.click();
- }
- });
list.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
return listItem;
}
- private toggleList(button: HTMLAnchorElement, list: HTMLUListElement): void {
+ private toggleList(button: HTMLButtonElement, list: HTMLUListElement): void {
if (list.hidden) {
button.setAttribute("aria-expanded", "true");
list.hidden = false;
input.insertAdjacentElement("beforebegin", inputAddon);
inputAddon.appendChild(input);
- const button = document.createElement("span");
+ const button = document.createElement("button");
button.title = Language.get("wcf.global.form.password.button.show");
button.classList.add("button", "inputSuffix", "jsTooltip");
- button.setAttribute("role", "button");
- button.tabIndex = 0;
button.setAttribute("aria-hidden", "true");
inputAddon.appendChild(button);
button.addEventListener("click", () => {
toggle(input, button, icon);
});
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- toggle(input, button, icon);
- }
- });
// Hide the password when the form is being submitted to prevent
// it from being stored within the web browser's autocomplete list.
pollOptionInput.appendChild(sortHandle);
// buttons
- const addButton = document.createElement("a");
- listItem.setAttribute("role", "button");
- listItem.setAttribute("href", "#");
+ const addButton = document.createElement("button");
addButton.classList.add("icon", "icon16", "fa-plus", "jsTooltip", "jsAddOption", "pointer");
addButton.setAttribute("title", Language.get("wcf.poll.button.addOption"));
addButton.addEventListener("click", () => this.createOption());
pollOptionInput.appendChild(addButton);
- const deleteButton = document.createElement("a");
- deleteButton.setAttribute("role", "button");
- deleteButton.setAttribute("href", "#");
+ const deleteButton = document.createElement("button");
deleteButton.classList.add("icon", "icon16", "fa-times", "jsTooltip", "jsDeleteOption", "pointer");
deleteButton.setAttribute("title", Language.get("wcf.poll.button.removeOption"));
- deleteButton.addEventListener("click", (ev) => this.removeOption(ev));
+ deleteButton.addEventListener("click", () => this.removeOption(deleteButton));
pollOptionInput.appendChild(deleteButton);
// input field
/**
* Removes a poll option after clicking on its deletion button.
*/
- private removeOption(event: Event): void {
- event.preventDefault();
-
- const button = event.currentTarget as HTMLSpanElement;
+ private removeOption(button: HTMLButtonElement): void {
button.closest("li")!.remove();
this.optionCount--;
this._toggleReactPopover(elementData.objectId, elementData.reactButton!, ev);
});
elementData.reactButton.addEventListener("keydown", (event) => {
- if (event.key === "Enter") {
+ if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this._toggleReactPopover(elementData.objectId, elementData.reactButton!, null);
</div>
<div class="userMenuItemMeta"></div>
<div class="userMenuItemUnread">
- <a href="#" class="userMenuItemMarkAsRead" role="button">
+ <button class="userMenuItemMarkAsRead">
<span class="icon icon24 fa-check jsTooltip" title="${Language.get("wcf.global.button.markAsRead")}"></span>
- </a>
+ </button>
</div>
`;
element.querySelector(".userMenuItemMeta")!.append(time);
const markAsRead = element.querySelector(".userMenuItemMarkAsRead")!;
- markAsRead.addEventListener("click", async (event) => {
- event.preventDefault();
-
+ markAsRead.addEventListener("click", async () => {
await this.provider.markAsRead(itemData.objectId);
this.markAsRead(element);
if (!header) {
return;
}
- const button = document.createElement("span");
- button.tabIndex = 0;
- button.setAttribute("role", "button");
+ const button = document.createElement("button");
button.className = "icon icon24 fa-files-o pointer jsTooltip";
button.setAttribute("title", Language.get("wcf.message.bbcode.code.copy"));
const clickCallback = async () => {
await Clipboard.copyElementTextToClipboard(this.codeContainer);
UiNotification.show(Language.get("wcf.message.bbcode.code.copy.success"));
};
- button.addEventListener("click", clickCallback);
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- void clickCallback();
- }
- });
+ button.addEventListener("click", () => clickCallback());
header.appendChild(button);
}
async highlight() {
});
const header = document.createElement("header");
_datePicker.appendChild(header);
- _dateMonthPrevious = document.createElement("a");
+ _dateMonthPrevious = document.createElement("button");
_dateMonthPrevious.className = "previous jsTooltip";
- _dateMonthPrevious.href = "#";
- _dateMonthPrevious.setAttribute("role", "button");
- _dateMonthPrevious.tabIndex = 0;
_dateMonthPrevious.title = Language.get("wcf.date.datePicker.previousMonth");
_dateMonthPrevious.setAttribute("aria-label", Language.get("wcf.date.datePicker.previousMonth"));
_dateMonthPrevious.innerHTML = '<span class="icon icon16 fa-arrow-left"></span>';
- _dateMonthPrevious.addEventListener("click", (ev) => DatePicker.previousMonth(ev));
+ _dateMonthPrevious.addEventListener("click", () => DatePicker.previousMonth());
header.appendChild(_dateMonthPrevious);
const monthYearContainer = document.createElement("span");
header.appendChild(monthYearContainer);
_dateYear.setAttribute("aria-label", Language.get("wcf.date.datePicker.year"));
_dateYear.addEventListener("change", changeYear);
monthYearContainer.appendChild(_dateYear);
- _dateMonthNext = document.createElement("a");
+ _dateMonthNext = document.createElement("button");
_dateMonthNext.className = "next jsTooltip";
- _dateMonthNext.href = "#";
- _dateMonthNext.setAttribute("role", "button");
- _dateMonthNext.tabIndex = 0;
_dateMonthNext.title = Language.get("wcf.date.datePicker.nextMonth");
_dateMonthNext.setAttribute("aria-label", Language.get("wcf.date.datePicker.nextMonth"));
_dateMonthNext.innerHTML = '<span class="icon icon16 fa-arrow-right"></span>';
- _dateMonthNext.addEventListener("click", (ev) => DatePicker.nextMonth(ev));
+ _dateMonthNext.addEventListener("click", () => DatePicker.nextMonth());
header.appendChild(_dateMonthNext);
_dateGrid = document.createElement("ul");
_datePicker.appendChild(_dateGrid);
* Opens the date picker.
*/
function open(event) {
- event.preventDefault();
- event.stopPropagation();
createPicker();
const target = event.currentTarget;
const input = target.nodeName === "INPUT" ? target : target.previousElementSibling;
// create input addon
const container = document.createElement("div");
container.className = "inputAddon";
- const openButton = document.createElement("a");
+ const openButton = document.createElement("button");
openButton.className = "inputSuffix button jsTooltip";
- openButton.href = "#";
- openButton.setAttribute("role", "button");
- openButton.tabIndex = 0;
openButton.title = Language.get("wcf.date.datePicker");
openButton.setAttribute("aria-label", Language.get("wcf.date.datePicker"));
openButton.setAttribute("aria-haspopup", "true");
/**
* Shows the previous month.
*/
- previousMonth(event) {
- event.preventDefault();
+ previousMonth() {
if (_dateMonth.value === "0") {
_dateMonth.value = "11";
_dateYear.value = (+_dateYear.value - 1).toString();
/**
* Shows the next month.
*/
- nextMonth(event) {
- event.preventDefault();
+ nextMonth() {
if (_dateMonth.value === "11") {
_dateMonth.value = "0";
_dateYear.value = (+_dateYear.value + 1).toString();
title.id = titleId;
header.appendChild(title);
if (options.closable) {
- const closeButton = document.createElement("a");
+ const closeButton = document.createElement("button");
closeButton.className = "dialogCloseButton jsTooltip";
- closeButton.href = "#";
- closeButton.setAttribute("role", "button");
- closeButton.tabIndex = 0;
closeButton.title = options.closeButtonLabel;
closeButton.setAttribute("aria-label", options.closeButtonLabel);
- closeButton.addEventListener("click", (ev) => this._close(ev));
+ closeButton.addEventListener("click", () => this._close());
header.appendChild(closeButton);
const span = document.createElement("span");
span.className = "icon icon24 fa-times";
/**
* Handles clicks on the close button or the backdrop if enabled.
*/
- _close(event) {
- event.preventDefault();
+ _close() {
const data = _dialogs.get(_activeDialog);
if (data === undefined) {
// Closing the dialog while it is already being closed
return;
}
if (Core.stringToBool(_container.getAttribute("close-on-click"))) {
- this._close(event);
+ event.preventDefault();
+ this._close();
}
else {
event.preventDefault();
if (menuItem.children.length) {
listItem.classList.add("pageMenuMainItemExpandable");
const menuId = Util_1.default.getUniqueId();
- const button = document.createElement("a");
+ const button = document.createElement("button");
button.classList.add("pageMenuMainItemToggle");
- button.tabIndex = 0;
- button.setAttribute("role", "button");
button.setAttribute("aria-expanded", "false");
button.setAttribute("aria-controls", menuId);
button.innerHTML = '<span class="icon icon24 fa-angle-down" aria-hidden="true"></span>';
const list = this.buildMenuItemList(menuItem.children);
list.id = menuId;
list.hidden = true;
- button.addEventListener("click", (event) => {
- event.preventDefault();
+ button.addEventListener("click", () => {
this.toggleList(button, list);
});
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- button.click();
- }
- });
list.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
event.preventDefault();
inputAddon.classList.add("inputAddon");
input.insertAdjacentElement("beforebegin", inputAddon);
inputAddon.appendChild(input);
- const button = document.createElement("span");
+ const button = document.createElement("button");
button.title = Language.get("wcf.global.form.password.button.show");
button.classList.add("button", "inputSuffix", "jsTooltip");
- button.setAttribute("role", "button");
- button.tabIndex = 0;
button.setAttribute("aria-hidden", "true");
inputAddon.appendChild(button);
const icon = document.createElement("span");
button.addEventListener("click", () => {
toggle(input, button, icon);
});
- button.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- toggle(input, button, icon);
- }
- });
// Hide the password when the form is being submitted to prevent
// it from being stored within the web browser's autocomplete list.
// see https://github.com/WoltLab/WCF/issues/4554
sortHandle.classList.add("icon", "icon16", "fa-arrows", "sortableNodeHandle");
pollOptionInput.appendChild(sortHandle);
// buttons
- const addButton = document.createElement("a");
- listItem.setAttribute("role", "button");
- listItem.setAttribute("href", "#");
+ const addButton = document.createElement("button");
addButton.classList.add("icon", "icon16", "fa-plus", "jsTooltip", "jsAddOption", "pointer");
addButton.setAttribute("title", Language.get("wcf.poll.button.addOption"));
addButton.addEventListener("click", () => this.createOption());
pollOptionInput.appendChild(addButton);
- const deleteButton = document.createElement("a");
- deleteButton.setAttribute("role", "button");
- deleteButton.setAttribute("href", "#");
+ const deleteButton = document.createElement("button");
deleteButton.classList.add("icon", "icon16", "fa-times", "jsTooltip", "jsDeleteOption", "pointer");
deleteButton.setAttribute("title", Language.get("wcf.poll.button.removeOption"));
- deleteButton.addEventListener("click", (ev) => this.removeOption(ev));
+ deleteButton.addEventListener("click", () => this.removeOption(deleteButton));
pollOptionInput.appendChild(deleteButton);
// input field
const optionInput = document.createElement("input");
/**
* Removes a poll option after clicking on its deletion button.
*/
- removeOption(event) {
- event.preventDefault();
- const button = event.currentTarget;
+ removeOption(button) {
button.closest("li").remove();
this.optionCount--;
if (this.optionList.childElementCount === 0) {
this._toggleReactPopover(elementData.objectId, elementData.reactButton, ev);
});
elementData.reactButton.addEventListener("keydown", (event) => {
- if (event.key === "Enter") {
+ if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this._toggleReactPopover(elementData.objectId, elementData.reactButton, null);
}
</div>
<div class="userMenuItemMeta"></div>
<div class="userMenuItemUnread">
- <a href="#" class="userMenuItemMarkAsRead" role="button">
+ <button class="userMenuItemMarkAsRead">
<span class="icon icon24 fa-check jsTooltip" title="${Language.get("wcf.global.button.markAsRead")}"></span>
- </a>
+ </button>
</div>
`;
const time = (0, Util_1.getTimeElement)(new Date(itemData.time * 1000));
element.querySelector(".userMenuItemMeta").append(time);
const markAsRead = element.querySelector(".userMenuItemMarkAsRead");
- markAsRead.addEventListener("click", async (event) => {
- event.preventDefault();
+ markAsRead.addEventListener("click", async () => {
await this.provider.markAsRead(itemData.objectId);
this.markAsRead(element);
});