Skip to content

Commit

Permalink
rename invoker to source
Browse files Browse the repository at this point in the history
  • Loading branch information
keithamus committed Jul 27, 2024
1 parent ecb51a9 commit b956980
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 29 deletions.
2 changes: 1 addition & 1 deletion invoker.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface InvokerMixin {

declare global {
interface CommandEvent extends Event {
invoker: Element;
source: Element;
command: string;
}
/* eslint-disable @typescript-eslint/no-empty-interface */
Expand Down
81 changes: 53 additions & 28 deletions invoker.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,45 +49,60 @@

const ShadowRoot = globalThis.ShadowRoot || function () {};

const invokeEventInvokers = new WeakMap();
const invokeEventActions = new WeakMap();
const commandEventSourceElements = new WeakMap();
const commandEventActions = new WeakMap();

class CommandEvent extends Event {
constructor(type, invokeEventInit = {}) {
super(type, invokeEventInit);
const { invoker, command } = invokeEventInit;
if (invoker != null && !(invoker instanceof Element)) {
throw new TypeError(`invoker must be an element`);
const { source, command } = invokeEventInit;
if (source != null && !(source instanceof Element)) {
throw new TypeError(`source must be an element`);
}
invokeEventInvokers.set(this, invoker || null);
invokeEventActions.set(this, command !== undefined ? String(command) : "");
commandEventSourceElements.set(this, source || null);
commandEventActions.set(
this,
command !== undefined ? String(command) : "",
);
}

get [Symbol.toStringTag]() {
return "CommandEvent";
}

get invoker() {
if (!invokeEventInvokers.has(this)) {
get source() {
if (!commandEventSourceElements.has(this)) {
throw new TypeError("illegal invocation");
}
const invoker = invokeEventInvokers.get(this);
if (!(invoker instanceof Element)) return null;
const invokerRoot = getRootNode(invoker);
const source = commandEventSourceElements.get(this);
if (!(source instanceof Element)) return null;
const invokerRoot = getRootNode(source);
if (invokerRoot !== getRootNode(this.target || document)) {
return invokerRoot.host;
}
return invoker;
return source;
}

get command() {
if (!invokeEventActions.has(this)) {
if (!commandEventActions.has(this)) {
throw new TypeError("illegal invocation");
}
return invokeEventActions.get(this);
return commandEventActions.get(this);
}

get action() {
throw new Error(
"CommandEvent#action was renamed to CommandEvent#command",
);
}

get source() {
throw new Error(
"CommandEvent#invoker was renamed to CommandEvent#source",
);
}
}
enumerate(CommandEvent.prototype, "invoker");
enumerate(CommandEvent.prototype, "source");
enumerate(CommandEvent.prototype, "command");

class InvokeEvent extends Event {
Expand Down Expand Up @@ -241,10 +256,10 @@
);
}

const invoker = event.target.closest(
const source = event.target.closest(
"button[commandfor], button[command], input[commandfor], input[command]",
);
if (!invoker) return;
if (!source) return;

if (this.form && this.getAttribute("type") !== "button") {
event.preventDefault();
Expand All @@ -255,22 +270,32 @@
);
}

if (
invoker.hasAttribute("command") !== invoker.hasAttribute("commandfor")
) {
const attr = invoker.hasAttribute("command") ? "command" : "commandfor";
const missing = invoker.hasAttribute("command")
? "commandfor"
: "command";
if (source.hasAttribute("command") !== source.hasAttribute("commandfor")) {
const attr = source.hasAttribute("command") ? "command" : "commandfor";
const missing = source.hasAttribute("command") ? "commandfor" : "command";
throw new Error(
`Element with ${attr} attribute must also have a ${missing} attribute to functon.`,
);
}

const invokee = invoker.commandForElement;
if (
source.command !== "show-popover" &&
source.command !== "hide-popover" &&
source.command !== "toggle-popover" &&
source.command !== "show-modal" &&
source.command !== "close" &&
!source.command.startsWith("--")
) {
console.warn(
`"${source.command}" is not a valid command value. Custom commands must begin with --`,
);
return;
}

const invokee = source.commandForElement;
const invokeEvent = new CommandEvent("command", {
command: invoker.command,
invoker,
command: source.command,
source,
});
invokee.dispatchEvent(invokeEvent);
if (invokeEvent.defaultPrevented) return;
Expand Down

0 comments on commit b956980

Please sign in to comment.