@@ -6,8 +6,9 @@ function parseDirectives(content) {
6
6
return directives ;
7
7
}
8
8
let currentActionName = '' ;
9
- let currentArgumentValue = '' ;
9
+ let currentArgumentsString = '' ;
10
10
let currentArguments = [ ] ;
11
+ let currentNamedArguments = { } ;
11
12
let currentModifiers = [ ] ;
12
13
let state = 'action' ;
13
14
const getLastActionName = function ( ) {
@@ -19,29 +20,39 @@ function parseDirectives(content) {
19
20
}
20
21
return directives [ directives . length - 1 ] . action ;
21
22
} ;
22
- const pushInstruction = function ( ) {
23
+ const pushDirective = function ( ) {
23
24
directives . push ( {
24
25
action : currentActionName ,
25
26
args : currentArguments ,
27
+ named : currentNamedArguments ,
26
28
modifiers : currentModifiers ,
27
29
getString : ( ) => {
28
30
return content ;
29
31
}
30
32
} ) ;
31
33
currentActionName = '' ;
32
- currentArgumentValue = '' ;
33
34
currentArguments = [ ] ;
35
+ currentNamedArguments = { } ;
34
36
currentModifiers = [ ] ;
35
37
state = 'action' ;
36
38
} ;
37
39
const pushArgument = function ( ) {
38
- currentArguments . push ( currentArgumentValue . trim ( ) ) ;
39
- currentArgumentValue = '' ;
40
+ const urlParams = new URLSearchParams ( '?' + currentArgumentsString ) ;
41
+ if ( currentArgumentsString . indexOf ( '=' ) === - 1 ) {
42
+ currentArguments = currentArgumentsString . split ( ',' ) . map ( ( arg ) => arg . trim ( ) ) ;
43
+ }
44
+ else {
45
+ currentNamedArguments = Object . fromEntries ( urlParams ) ;
46
+ }
47
+ currentArgumentsString = '' ;
40
48
} ;
41
49
const pushModifier = function ( ) {
42
50
if ( currentArguments . length > 1 ) {
43
51
throw new Error ( `The modifier "${ currentActionName } ()" does not support multiple arguments.` ) ;
44
52
}
53
+ if ( Object . keys ( currentNamedArguments ) . length > 0 ) {
54
+ throw new Error ( `The modifier "${ currentActionName } ()" does not support named arguments.` ) ;
55
+ }
45
56
currentModifiers . push ( {
46
57
name : currentActionName ,
47
58
value : currentArguments . length > 0 ? currentArguments [ 0 ] : null ,
@@ -60,7 +71,7 @@ function parseDirectives(content) {
60
71
}
61
72
if ( char === ' ' ) {
62
73
if ( currentActionName ) {
63
- pushInstruction ( ) ;
74
+ pushDirective ( ) ;
64
75
}
65
76
break ;
66
77
}
@@ -76,11 +87,7 @@ function parseDirectives(content) {
76
87
state = 'after_arguments' ;
77
88
break ;
78
89
}
79
- if ( char === ',' ) {
80
- pushArgument ( ) ;
81
- break ;
82
- }
83
- currentArgumentValue += char ;
90
+ currentArgumentsString += char ;
84
91
break ;
85
92
case 'after_arguments' :
86
93
if ( char === '|' ) {
@@ -90,15 +97,15 @@ function parseDirectives(content) {
90
97
if ( char !== ' ' ) {
91
98
throw new Error ( `Missing space after ${ getLastActionName ( ) } ()` ) ;
92
99
}
93
- pushInstruction ( ) ;
100
+ pushDirective ( ) ;
94
101
break ;
95
102
}
96
103
}
97
104
switch ( state ) {
98
105
case 'action' :
99
106
case 'after_arguments' :
100
107
if ( currentActionName ) {
101
- pushInstruction ( ) ;
108
+ pushDirective ( ) ;
102
109
}
103
110
break ;
104
111
default :
@@ -212,7 +219,7 @@ function getAllModelDirectiveFromElements(element) {
212
219
}
213
220
const directives = parseDirectives ( element . dataset . model ) ;
214
221
directives . forEach ( ( directive ) => {
215
- if ( directive . args . length > 0 ) {
222
+ if ( directive . args . length > 0 || directive . named . length > 0 ) {
216
223
throw new Error ( `The data-model="${ element . dataset . model } " format is invalid: it does not support passing arguments to the model.` ) ;
217
224
}
218
225
directive . action = normalizeModelName ( directive . action ) ;
@@ -229,7 +236,7 @@ function getModelDirectiveFromElement(element, throwOnMissing = true) {
229
236
if ( formElement && 'model' in formElement . dataset ) {
230
237
const directives = parseDirectives ( formElement . dataset . model || '*' ) ;
231
238
const directive = directives [ 0 ] ;
232
- if ( directive . args . length > 0 ) {
239
+ if ( directive . args . length > 0 || directive . named . length > 0 ) {
233
240
throw new Error ( `The data-model="${ formElement . dataset . model } " format is invalid: it does not support passing arguments to the model.` ) ;
234
241
}
235
242
directive . action = normalizeModelName ( element . getAttribute ( 'name' ) ) ;
@@ -2867,8 +2874,6 @@ class LiveControllerDefault extends Controller {
2867
2874
throw new Error ( `No action name provided on element: ${ getElementAsTagText ( event . currentTarget ) } . Did you forget to add the "data-live-action-param" attribute?` ) ;
2868
2875
}
2869
2876
const rawAction = params . action ;
2870
- const actionArgs = Object . assign ( { } , params ) ;
2871
- delete actionArgs . action ;
2872
2877
const directives = parseDirectives ( rawAction ) ;
2873
2878
let debounce = false ;
2874
2879
directives . forEach ( ( directive ) => {
@@ -2908,7 +2913,7 @@ class LiveControllerDefault extends Controller {
2908
2913
}
2909
2914
delete this . pendingFiles [ key ] ;
2910
2915
}
2911
- this . component . action ( directive . action , actionArgs , debounce ) ;
2916
+ this . component . action ( directive . action , directive . named , debounce ) ;
2912
2917
if ( getModelDirectiveFromElement ( event . currentTarget , false ) ) {
2913
2918
this . pendingActionTriggerModelElement = event . currentTarget ;
2914
2919
}
0 commit comments