Skip to content

Commit

Permalink
Pass the ActionEvent (with params) to registerActionOption callbacks (#…
Browse files Browse the repository at this point in the history
…692)

- Add ability for registerActionOption callbacks to receive the event after `params` have been resolved
- Relates to #668
  • Loading branch information
lb- authored Jun 26, 2023
1 parent 4ef73b0 commit 7bf453c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
12 changes: 6 additions & 6 deletions docs/reference/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@ route the event to the controller action, return `true`.

The callback accepts a single object argument with the following keys:

Name | Description
--------|------------
name | String: The option's name (`"open"` in the example above)
value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`)
event | [Event][]: The event instance
element | [Element]: The element where the action descriptor is declared
| Name | Description |
| ------- | ----------------------------------------------------------------------------------------------------- |
| name | String: The option's name (`"open"` in the example above) |
| value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`) |
| event | [Event][]: The event instance, including with the `params` action parameters on the submitter element |
| element | [Element]: The element where the action descriptor is declared |

[toggle]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLDetailsElement/toggle_event
[Event]: https://developer.mozilla.org/en-US/docs/web/api/event
Expand Down
15 changes: 9 additions & 6 deletions src/core/binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ export class Binding {
}

handleEvent(event: Event) {
if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(event)) {
this.invokeWithEvent(event)
const actionEvent = this.prepareActionEvent(event)
if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
this.invokeWithEvent(actionEvent)
}
}

Expand Down Expand Up @@ -65,12 +66,14 @@ export class Binding {
return passes
}

private invokeWithEvent(event: Event) {
private prepareActionEvent(event: Event): ActionEvent {
return Object.assign(event, { params: this.action.params })
}

private invokeWithEvent(event: ActionEvent) {
const { target, currentTarget } = event
try {
const { params } = this.action
const actionEvent: ActionEvent = Object.assign(event, { params })
this.method.call(this.controller, actionEvent)
this.method.call(this.controller, event)
this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName })
} catch (error: any) {
const { identifier, controller, element, index } = this
Expand Down
37 changes: 37 additions & 0 deletions src/tests/modules/core/event_options_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,43 @@ export default class EventOptionsTests extends LogControllerTestCase {
this.assertActions({ name: "log", eventType: "toggle" })
}

async "test custom action option callback event contains params"() {
let lastActionEventParams: Object = {}

// clone the params to ensure we check the value as the callback receives it
// not the event after all actions have resolved

const mockCallback = ({ event: { params = {} } = {} }) => {
lastActionEventParams = { ...params }
}

this.application.registerActionOption("all", (options: Object) => {
mockCallback(options)
return true
})

this.buttonElement.setAttribute("data-c-custom-number-param", "41")
this.buttonElement.setAttribute("data-c-custom-string-param", "validation")
this.buttonElement.setAttribute("data-c-custom-boolean-param", "true")
this.buttonElement.setAttribute("data-d-should-ignore-param", "_IGNORED_")

await this.setAction(this.buttonElement, "click->c#log:all")

await this.triggerEvent(this.buttonElement, "click")

this.assertActions({ name: "log", identifier: "c", eventType: "click", currentTarget: this.buttonElement })

const expectedEventParams = {
customBoolean: true,
customNumber: 41,
customString: "validation",
}

this.assert.deepEqual(this.controllerConstructor.actionLog[0].params, expectedEventParams)

this.assert.deepEqual(lastActionEventParams, expectedEventParams)
}

setAction(element: Element, value: string) {
element.setAttribute("data-action", value)
return this.nextFrame
Expand Down

0 comments on commit 7bf453c

Please sign in to comment.