diff --git a/docs/reference/actions.md b/docs/reference/actions.md index 6aa43db3..6bcbcdab 100644 --- a/docs/reference/actions.md +++ b/docs/reference/actions.md @@ -170,6 +170,7 @@ Custom action option | Description `:stop` | calls `.stopPropagation()` on the event before invoking the method `:prevent` | calls `.preventDefault()` on the event before invoking the method `:self` | only invokes the method if the event was fired by the element itself +`:!input` | suppress an event if it was fired while an input element has focus You can register your own action options with the `Application.registerActionOption` method. diff --git a/src/core/action_descriptor.ts b/src/core/action_descriptor.ts index 35a4a211..801eddea 100644 --- a/src/core/action_descriptor.ts +++ b/src/core/action_descriptor.ts @@ -30,6 +30,19 @@ export const defaultActionDescriptorFilters: ActionDescriptorFilters = { return true } }, + + input({ event, value }) { + if (value) return true + + const target = event.target + if (!(target instanceof Element)) return true + + const isInput = + target.tagName === "INPUT" || + target.tagName === "TEXTAREA" || + (target instanceof HTMLElement && target.isContentEditable) + return !isInput + }, } export interface ActionDescriptor { diff --git a/src/tests/modules/core/event_options_tests.ts b/src/tests/modules/core/event_options_tests.ts index 45027cd3..f6906a93 100644 --- a/src/tests/modules/core/event_options_tests.ts +++ b/src/tests/modules/core/event_options_tests.ts @@ -7,6 +7,7 @@ export default class EventOptionsTests extends LogControllerTestCase {
+
` @@ -178,6 +179,22 @@ export default class EventOptionsTests extends LogControllerTestCase { this.assertNoActions() } + async "test true input option"() { + await this.setAction(this.inputElement, "keydown@window->c#log:input") + + await this.triggerEvent(this.inputElement, "keydown") + + this.assertActions({ name: "log", eventType: "keydown" }) + } + + async "test false input option"() { + await this.setAction(this.inputElement, "keydown@window->c#log:!input") + + await this.triggerEvent(this.inputElement, "keydown") + + this.assertNoActions() + } + async "test custom action option callback params contain the controller instance"() { let lastActionOptions: { controller?: Controller } = {} @@ -313,4 +330,8 @@ export default class EventOptionsTests extends LogControllerTestCase { get detailsElement() { return this.findElement("details") } + + get inputElement() { + return this.findElement("input") + } }