1
1
/* @flow strict */
2
2
3
- import SelectorSet from 'selector-set'
4
- import formDataEntries from 'form-data-entries'
5
-
6
3
// Parse HTML text into document fragment.
7
4
function parseHTML ( document : Document , html : string ) : DocumentFragment {
8
5
const template = document . createElement ( 'template' )
@@ -12,7 +9,7 @@ function parseHTML(document: Document, html: string): DocumentFragment {
12
9
13
10
function serialize ( form : HTMLFormElement ) : string {
14
11
const params = new URLSearchParams ( )
15
- const entries = 'entries' in FormData . prototype ? new FormData ( form ) . entries ( ) : formDataEntries ( form )
12
+ const entries = new FormData ( form ) . entries ( )
16
13
for ( const [ name , value ] of [ ...entries ] ) {
17
14
params . append ( name , value . toString ( ) )
18
15
}
@@ -65,9 +62,9 @@ type Kicker = {
65
62
html : ( ) => Promise < SimpleResponse >
66
63
}
67
64
68
- export type RemoteFormHandler = ( form : HTMLFormElement , kicker : Kicker , req : SimpleRequest ) => void | Promise < void >
65
+ export type RemoteFormHandler = ( form : HTMLFormElement , kicker : Kicker , req : SimpleRequest ) => void
69
66
70
- let selectorSet : ? SelectorSet < RemoteFormHandler >
67
+ let formHandlers : Map < string , RemoteFormHandler [ ] >
71
68
72
69
const afterHandlers = [ ]
73
70
const beforeHandlers = [ ]
@@ -81,26 +78,39 @@ export function beforeRemote(fn: (form: HTMLFormElement) => mixed) {
81
78
}
82
79
83
80
export function remoteForm ( selector : string , fn : RemoteFormHandler ) {
84
- if ( ! selectorSet ) {
85
- selectorSet = new SelectorSet ( )
81
+ if ( ! formHandlers ) {
82
+ formHandlers = new Map < string , RemoteFormHandler [ ] > ( )
86
83
document . addEventListener ( 'submit' , handleSubmit )
87
84
}
88
- selectorSet . add ( selector , fn )
85
+ const handlers = formHandlers . get ( selector ) || [ ]
86
+ formHandlers . set ( selector , [ ...handlers , fn ] )
89
87
}
90
88
91
89
export function remoteUninstall ( selector : string , fn : RemoteFormHandler ) {
92
- if ( selectorSet ) {
93
- selectorSet . remove ( selector , fn )
90
+ if ( formHandlers ) {
91
+ const handlers = formHandlers . get ( selector ) || [ ]
92
+ formHandlers . set ( selector , handlers . filter ( x => x !== fn ) )
93
+ }
94
+ }
95
+
96
+ function getMatches ( el : HTMLElement ) : RemoteFormHandler [ ] {
97
+ const results = [ ]
98
+ for ( const selector of formHandlers . keys ( ) ) {
99
+ if ( el . matches ( selector ) ) {
100
+ const handlers = formHandlers . get ( selector ) || [ ]
101
+ results . push ( ...handlers )
102
+ }
94
103
}
104
+ return results
95
105
}
96
106
97
107
function handleSubmit ( event : Event ) {
98
108
if ( ! ( event . target instanceof HTMLFormElement ) ) {
99
109
return
100
110
}
101
111
const form = event . target
102
- const matches = selectorSet && selectorSet . matches ( form )
103
- if ( ! matches || matches . length === 0 ) {
112
+ const matches = getMatches ( form )
113
+ if ( matches . length === 0 ) {
104
114
return
105
115
}
106
116
@@ -143,7 +153,7 @@ function handleSubmit(event: Event) {
143
153
// Process each handler sequentially until it either completes or calls the
144
154
// kicker function.
145
155
async function processHandlers (
146
- matches : Array < * > ,
156
+ matches : RemoteFormHandler [ ] ,
147
157
form : HTMLFormElement ,
148
158
req : SimpleRequest ,
149
159
kickerPromise : Promise < SimpleResponse >
@@ -167,7 +177,7 @@ async function processHandlers(
167
177
return kick ( )
168
178
}
169
179
}
170
- await Promise . race ( [ kickerCalled , match . data . call ( null , form , kicker , req ) ] )
180
+ await Promise . race ( [ kickerCalled , match ( form , kicker , req ) ] )
171
181
}
172
182
return kickerWasCalled
173
183
}
0 commit comments