Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,33 @@ export default [
],
},
},
{
// Library source must go through the free-function helpers in
// `Utils.ts` instead of calling the raw DOM event APIs directly —
// helper names mangle to single chars after minification, native
// property names like `addEventListener` are preserved verbatim.
files: ["src/**/*.ts"],
ignores: ["src/Utils.ts"],
rules: {
"no-restricted-syntax": [
"error",
{
selector:
"CallExpression[callee.property.name='addEventListener']",
message:
"Use `addListener` from './Utils.js' (saves bytes after minification).",
},
{
selector:
"CallExpression[callee.property.name='removeEventListener']",
message: "Use `removeListener` from './Utils.js'.",
},
{
selector:
"CallExpression[callee.property.name='dispatchEvent']",
message: "Use `dispatchEvent` from './Utils.js'.",
},
],
},
},
];
12 changes: 7 additions & 5 deletions src/CrossOrigin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import { Subscribable } from "./State/Subscribable.js";
import type * as Types from "./Types.js";
import { ObservedElementAccessibilities } from "./Consts.js";
import {
addListener,
getElementUId,
getInstanceContext,
getUId,
getWindowUId,
type HTMLElementWithUID,
removeListener,
} from "./Utils.js";
import { dom } from "./DOMAPI.js";

Expand Down Expand Up @@ -992,7 +994,7 @@ class CrossOriginTransactions {

this.setSendUp(sendUp);

this._owner().addEventListener("pagehide", this._onPageHide);
addListener(this._owner(), "pagehide", this._onPageHide);

this._ping();
}
Expand Down Expand Up @@ -1029,11 +1031,11 @@ class CrossOriginTransactions {
};
}

owner.addEventListener("message", this._onBrowserMessage);
addListener(owner, "message", this._onBrowserMessage);
}
}
} else if (this._isDefaultSendUp) {
owner.removeEventListener("message", this._onBrowserMessage);
removeListener(owner, "message", this._onBrowserMessage);
this._isDefaultSendUp = false;
}

Expand All @@ -1048,8 +1050,8 @@ class CrossOriginTransactions {
this._pingTimer = undefined;
}

owner.removeEventListener("message", this._onBrowserMessage);
owner.removeEventListener("pagehide", this._onPageHide);
removeListener(owner, "message", this._onBrowserMessage);
removeListener(owner, "pagehide", this._onPageHide);

await this._dead();

Expand Down
44 changes: 28 additions & 16 deletions src/Deloser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import {
TabsterMoveFocusEvent,
} from "./Events.js";
import {
addListener,
dispatchEvent,
documentContains,
getElementUId,
isDisplayNone,
removeListener,
TabsterPart,
WeakHTMLElement,
} from "./Utils.js";
Expand Down Expand Up @@ -55,7 +58,8 @@ export class DeloserItem extends DeloserItemBase<Types.Deloser> {

if (available && deloserElement) {
if (
!deloserElement.dispatchEvent(
!dispatchEvent(
deloserElement,
new TabsterMoveFocusEvent({
by: "deloser",
owner: deloserElement,
Expand Down Expand Up @@ -611,7 +615,8 @@ export class Deloser
};

customFocusLostHandler(element: HTMLElement): boolean {
return element.dispatchEvent(
return dispatchEvent(
element,
new DeloserFocusLostEvent(this.getActions())
);
}
Expand Down Expand Up @@ -723,7 +728,8 @@ export class DeloserAPI implements Types.DeloserAPI {
this._tabster.focusedElement.subscribe(this._onFocus);
const doc = this._win().document;

doc.addEventListener(
addListener(
doc,
DeloserRestoreFocusEventName,
this._onRestoreFocus
);
Expand Down Expand Up @@ -758,7 +764,8 @@ export class DeloserAPI implements Types.DeloserAPI {

this._tabster.focusedElement.unsubscribe(this._onFocus);

win.document.removeEventListener(
removeListener(
win.document,
DeloserRestoreFocusEventName,
this._onRestoreFocus
);
Expand Down Expand Up @@ -927,18 +934,23 @@ export class DeloserAPI implements Types.DeloserAPI {
const curDeloserElement = curDeloser.getElement();
const el = curDeloser.findAvailable();

if (
el &&
(!curDeloserElement?.dispatchEvent(
new TabsterMoveFocusEvent({
by: "deloser",
owner: curDeloserElement,
next: el,
})
) ||
this._tabster.focusedElement.focus(el))
) {
return;
if (el) {
if (!curDeloserElement) {
return;
}
if (
!dispatchEvent(
curDeloserElement,
new TabsterMoveFocusEvent({
by: "deloser",
owner: curDeloserElement,
next: el,
})
) ||
this._tabster.focusedElement.focus(el)
) {
return;
}
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/Deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,31 @@ import {
MoverMoveFocusEvent,
MoverMemorizedElementEvent,
} from "./Events.js";
import { dispatchEvent } from "./Utils.js";

/** @deprecated This function is obsolete, use native element.dispatchEvent(new GroupperMoveFocusEvent(...)). */
export function dispatchGroupperMoveFocusEvent(
target: HTMLElement,
action: GroupperMoveFocusAction
) {
return target.dispatchEvent(new GroupperMoveFocusEvent({ action }));
return dispatchEvent(target, new GroupperMoveFocusEvent({ action }));
}

/** @deprecated This function is obsolete, use native element.dispatchEvent(new MoverMoveFocusEvent(...)). */
export function dispatchMoverMoveFocusEvent(
target: HTMLElement,
key: MoverKey
) {
return target.dispatchEvent(new MoverMoveFocusEvent({ key }));
return dispatchEvent(target, new MoverMoveFocusEvent({ key }));
}

/** @deprecated This function is obsolete, use native element.dispatchEvent(new MoverMemorizedElementEvent(...)). */
export function dispatchMoverMemorizedElementEvent(
target: HTMLElement,
memorizedElement: HTMLElement | undefined
) {
return target.dispatchEvent(
return dispatchEvent(
target,
new MoverMemorizedElementEvent({ memorizedElement })
);
}
33 changes: 20 additions & 13 deletions src/DummyInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ import {
} from "./Consts.js";
import { TabsterMoveFocusEvent } from "./Events.js";
import { dom } from "./DOMAPI.js";
import { hasSubFocusable, makeFocusIgnored, WeakHTMLElement } from "./Utils.js";
import {
addListener,
dispatchEvent,
hasSubFocusable,
makeFocusIgnored,
removeListener,
WeakHTMLElement,
} from "./Utils.js";

const _updateDummyInputsTimeout = 100;

Expand Down Expand Up @@ -91,8 +98,8 @@ export class DummyInput {
this._isPhantom = props.isPhantom ?? false;
this._fixedTarget = fixedTarget;

input.addEventListener("focusin", this._focusIn);
input.addEventListener("focusout", this._focusOut);
addListener(input, "focusin", this._focusIn);
addListener(input, "focusout", this._focusOut);

(input as HTMLElementWithDummyContainer).__tabsterDummyContainer =
element;
Expand Down Expand Up @@ -130,8 +137,8 @@ export class DummyInput {
delete this.onFocusOut;
delete this.input;

input.removeEventListener("focusin", this._focusIn);
input.removeEventListener("focusout", this._focusOut);
removeListener(input, "focusin", this._focusIn);
removeListener(input, "focusout", this._focusOut);

delete (input as HTMLElementWithDummyContainer).__tabsterDummyContainer;

Expand Down Expand Up @@ -404,7 +411,9 @@ export class DummyInputManager {
}

if (
parent?.dispatchEvent(
parent &&
dispatchEvent(
parent,
new TabsterMoveFocusEvent({
by: "root",
owner: parent,
Expand Down Expand Up @@ -786,7 +795,7 @@ class DummyInputManagerCore {
.__tabsterDummy;

for (const el of this._transformElements) {
el.removeEventListener("scroll", this._addTransformOffsets);
removeListener(el, "scroll", this._addTransformOffsets);
}
this._transformElements.clear();

Expand Down Expand Up @@ -922,7 +931,8 @@ class DummyInputManagerCore {

if (
toFocus &&
element.dispatchEvent(
dispatchEvent(
element,
new TabsterMoveFocusEvent({
by: "root",
owner: element,
Expand Down Expand Up @@ -1104,10 +1114,7 @@ class DummyInputManagerCore {
newTransformElements.add(element);

if (!transformElements.has(element)) {
element.addEventListener(
"scroll",
this._addTransformOffsets
);
addListener(element, "scroll", this._addTransformOffsets);
}

scrollTop += scrollTopLeft.scrollTop;
Expand All @@ -1117,7 +1124,7 @@ class DummyInputManagerCore {

for (const el of transformElements) {
if (!newTransformElements.has(el)) {
el.removeEventListener("scroll", this._addTransformOffsets);
removeListener(el, "scroll", this._addTransformOffsets);
}
}

Expand Down
27 changes: 18 additions & 9 deletions src/Groupper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ import {
DummyInputManagerPriorities,
getDummyInputContainer,
} from "./DummyInput.js";
import { getAdjacentElement, TabsterPart, WeakHTMLElement } from "./Utils.js";
import {
addListener,
dispatchEvent,
getAdjacentElement,
removeListener,
TabsterPart,
WeakHTMLElement,
} from "./Utils.js";
import { dom } from "./DOMAPI.js";

class GroupperDummyManager extends DummyInputManager {
Expand Down Expand Up @@ -451,9 +458,9 @@ export class GroupperAPI implements Types.GroupperAPI {
this._onFocus(activeElement as HTMLElement);
}

doc.addEventListener("mousedown", this._onMouseDown, true);
win.addEventListener("keydown", this._onKeyDown, true);
win.addEventListener(GroupperMoveFocusEventName, this._onMoveFocus);
addListener(doc, "mousedown", this._onMouseDown, true);
addListener(win, "keydown", this._onKeyDown, true);
addListener(win, GroupperMoveFocusEventName, this._onMoveFocus);
};

dispose(): void {
Expand All @@ -472,9 +479,9 @@ export class GroupperAPI implements Types.GroupperAPI {

this._tabster.focusedElement.unsubscribe(this._onFocus);

win.document.removeEventListener("mousedown", this._onMouseDown, true);
win.removeEventListener("keydown", this._onKeyDown, true);
win.removeEventListener(GroupperMoveFocusEventName, this._onMoveFocus);
removeListener(win.document, "mousedown", this._onMouseDown, true);
removeListener(win, "keydown", this._onKeyDown, true);
removeListener(win, GroupperMoveFocusEventName, this._onMoveFocus);

Object.keys(this._grouppers).forEach((groupperId) => {
if (this._grouppers[groupperId]) {
Expand Down Expand Up @@ -656,7 +663,8 @@ export class GroupperAPI implements Types.GroupperAPI {
next &&
(!relatedEvent ||
(relatedEvent &&
groupperElement.dispatchEvent(
dispatchEvent(
groupperElement,
new TabsterMoveFocusEvent({
by: "groupper",
owner: groupperElement,
Expand Down Expand Up @@ -716,7 +724,8 @@ export class GroupperAPI implements Types.GroupperAPI {
next &&
(!relatedEvent ||
(relatedEvent &&
groupperElement.dispatchEvent(
dispatchEvent(
groupperElement,
new TabsterMoveFocusEvent({
by: "groupper",
owner: groupperElement,
Expand Down
15 changes: 11 additions & 4 deletions src/Modalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ import {
DummyInputManagerPriorities,
getDummyInputContainer,
} from "./DummyInput.js";
import { augmentAttribute, TabsterPart, WeakHTMLElement } from "./Utils.js";
import {
addListener,
augmentAttribute,
dispatchEvent,
removeListener,
TabsterPart,
WeakHTMLElement,
} from "./Utils.js";
import { dom } from "./DOMAPI.js";

let _wasFocusedCounter = 0;
Expand Down Expand Up @@ -304,7 +311,7 @@ export class Modalizer
? new ModalizerActiveEvent(eventDetail)
: new ModalizerInactiveEvent(eventDetail);

el.dispatchEvent(event);
dispatchEvent(el, event);

if (event.defaultPrevented) {
defaultPrevented = true;
Expand Down Expand Up @@ -367,7 +374,7 @@ export class ModalizerAPI implements Types.ModalizerAPI {
}

const win = this._win();
win.addEventListener("keydown", this._onKeyDown, true);
addListener(win, "keydown", this._onKeyDown, true);

tabster.queueInit(() => {
this._tabster.focusedElement.subscribe(this._onFocus);
Expand All @@ -377,7 +384,7 @@ export class ModalizerAPI implements Types.ModalizerAPI {
dispose(): void {
const win = this._win();

win.removeEventListener("keydown", this._onKeyDown, true);
removeListener(win, "keydown", this._onKeyDown, true);

// Dispose all modalizers managed by the API
Object.keys(this._modalizers).forEach((modalizerId) => {
Expand Down
Loading
Loading