From 83e84b7e4cbbc60ae5cc55ae2ec26c04b03b9c32 Mon Sep 17 00:00:00 2001 From: Stephen Sugden Date: Fri, 17 Feb 2023 12:04:07 +0100 Subject: [PATCH] Move defaultEventNames into Schema This allows applications to extend the mapping with support for custom elements. Closes #660 --- src/core/action.ts | 21 ++----------------- src/core/schema.ts | 17 +++++++++++++++ .../core/action_custom_default_event_tests.ts | 20 ++++++++++++++++++ 3 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 src/tests/modules/core/action_custom_default_event_tests.ts diff --git a/src/core/action.ts b/src/core/action.ts index 3350ea84..4774a782 100644 --- a/src/core/action.ts +++ b/src/core/action.ts @@ -1,6 +1,6 @@ import { ActionDescriptor, parseActionDescriptorString, stringifyEventTarget } from "./action_descriptor" import { Token } from "../mutation-observers" -import { Schema } from "./schema" +import { getDefaultEventNameForElement, Schema } from "./schema" import { camelize } from "./string_helpers" import { hasProperty } from "./utils" @@ -23,7 +23,7 @@ export class Action { this.element = element this.index = index this.eventTarget = descriptor.eventTarget || element - this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name") + this.eventName = descriptor.eventName || getDefaultEventNameForElement(element, schema) || error("missing event name") this.eventOptions = descriptor.eventOptions || {} this.identifier = descriptor.identifier || error("missing identifier") this.methodName = descriptor.methodName || error("missing method name") @@ -86,23 +86,6 @@ export class Action { } } -const defaultEventNames: { [tagName: string]: (element: Element) => string } = { - a: () => "click", - button: () => "click", - form: () => "submit", - details: () => "toggle", - input: (e) => (e.getAttribute("type") == "submit" ? "click" : "input"), - select: () => "change", - textarea: () => "input", -} - -export function getDefaultEventNameForElement(element: Element): string | undefined { - const tagName = element.tagName.toLowerCase() - if (tagName in defaultEventNames) { - return defaultEventNames[tagName](element) - } -} - function error(message: string): never { throw new Error(message) } diff --git a/src/core/schema.ts b/src/core/schema.ts index 20845d20..99a326ce 100644 --- a/src/core/schema.ts +++ b/src/core/schema.ts @@ -5,6 +5,7 @@ export interface Schema { targetAttributeForScope(identifier: string): string outletAttributeForScope(identifier: string, outlet: string): string keyMappings: { [key: string]: string } + defaultEventNames: { [tagName: string]: (element: Element) => string } } export const defaultSchema: Schema = { @@ -29,6 +30,22 @@ export const defaultSchema: Schema = { // [0-9] ...objectFromEntries("0123456789".split("").map((n) => [n, n])), }, + defaultEventNames: { + a: () => "click", + button: () => "click", + form: () => "submit", + details: () => "toggle", + input: (e) => (e.getAttribute("type") == "submit" ? "click" : "input"), + select: () => "change", + textarea: () => "input", + } +} + +export function getDefaultEventNameForElement(element: Element, schema = defaultSchema): string | undefined { + const tagName = element.tagName.toLowerCase() + if (tagName in schema.defaultEventNames) { + return schema.defaultEventNames[tagName](element) + } } function objectFromEntries(array: [string, any][]): object { diff --git a/src/tests/modules/core/action_custom_default_event_tests.ts b/src/tests/modules/core/action_custom_default_event_tests.ts new file mode 100644 index 00000000..5017e5a4 --- /dev/null +++ b/src/tests/modules/core/action_custom_default_event_tests.ts @@ -0,0 +1,20 @@ +import { TestApplication } from "../../cases/application_test_case" +import { LogControllerTestCase } from "../../cases/log_controller_test_case" +import { Schema, defaultSchema } from "../../../core/schema" +import { Application } from "../../../core/application" + +export default class ActionKeyboardFilterTests extends LogControllerTestCase { + schema: Schema = { + ...defaultSchema, + defaultEventNames: { ...defaultSchema.defaultEventNames, "some-element": () => "click" }, + } + application: Application = new TestApplication(this.fixtureElement, this.schema) + + identifier = "c" + fixtureHTML = `` + + async "test default event"() { + await this.triggerEvent("some-element", "click") + this.assertActions({ name: "log", eventType: "click" }) + } +}