@@ -85,9 +85,6 @@ export function RegularElement(node, context) {
85
85
const is_custom_element = is_custom_element_node ( node ) ;
86
86
let needs_content_reset = false ;
87
87
88
- /** @type {AST.BindDirective | null } */
89
- let value_binding = null ;
90
-
91
88
let is_content_editable = false ;
92
89
93
90
if ( is_custom_element ) {
@@ -105,15 +102,17 @@ export function RegularElement(node, context) {
105
102
}
106
103
}
107
104
108
- /** @type {Set<string> } */
109
- const names = new Set ( ) ;
105
+ /** @type {Map<string, AST.Attribute> } */
106
+ const lookup = new Map ( ) ;
107
+
108
+ /** @type {Map<string, AST.BindDirective> } */
109
+ const bindings = new Map ( ) ;
110
110
111
- /** @type {Set<string> } */
112
- const bindings = new Set ( ) ;
111
+ let has_spread = false ;
113
112
114
113
for ( const attribute of node . attributes ) {
115
114
if ( attribute . type === 'Attribute' ) {
116
- names . add ( attribute . name ) ;
115
+ lookup . set ( attribute . name , attribute ) ;
117
116
118
117
if (
119
118
( attribute . name === 'value' || attribute . name === 'checked' ) &&
@@ -128,16 +127,11 @@ export function RegularElement(node, context) {
128
127
is_content_editable = true ;
129
128
}
130
129
} else if ( attribute . type === 'SpreadAttribute' ) {
131
- names . add ( '*' ) ;
132
- needs_content_reset = true ;
130
+ has_spread = true ;
133
131
}
134
- if ( attribute . type === 'BindDirective' ) {
135
- bindings . add ( attribute . name ) ;
136
132
137
- if ( attribute . name === 'value' ) {
138
- value_binding = attribute ;
139
- needs_content_reset = true ;
140
- }
133
+ if ( attribute . type === 'BindDirective' ) {
134
+ bindings . set ( attribute . name , attribute ) ;
141
135
}
142
136
}
143
137
@@ -184,12 +178,12 @@ export function RegularElement(node, context) {
184
178
context . state . init . push ( b . stmt ( b . call ( '$.remove_input_defaults' , context . state . node ) ) ) ;
185
179
}
186
180
187
- if ( needs_content_reset && node . name === 'textarea' ) {
181
+ if ( node . name === 'textarea' && ( has_spread || bindings . has ( 'value' ) || needs_content_reset ) ) {
188
182
context . state . init . push ( b . stmt ( b . call ( '$.remove_textarea_child' , context . state . node ) ) ) ;
189
183
}
190
184
191
- if ( value_binding !== null && node . name === 'select' ) {
192
- setup_select_synchronization ( value_binding , context ) ;
185
+ if ( node . name === 'select' && bindings . has ( 'value' ) ) {
186
+ setup_select_synchronization ( /** @type { AST.BindDirective } */ ( bindings . get ( 'value' ) ) , context ) ;
193
187
}
194
188
195
189
const node_id = context . state . node ;
@@ -206,7 +200,7 @@ export function RegularElement(node, context) {
206
200
node ,
207
201
node_id ,
208
202
// If value binding exists, that one takes care of calling $.init_select
209
- value_binding === null && node . name === 'select'
203
+ node . name === 'select' && ! bindings . has ( 'value' )
210
204
) ;
211
205
is_attributes_reactive = true ;
212
206
} else {
@@ -256,7 +250,7 @@ export function RegularElement(node, context) {
256
250
}
257
251
258
252
// Apply the src and loading attributes for <img> elements after the element is appended to the document
259
- if ( node . name === 'img' && ( names . has ( '*' ) || names . has ( 'loading' ) ) ) {
253
+ if ( node . name === 'img' && ( has_spread || lookup . has ( 'loading' ) ) ) {
260
254
context . state . after_update . push ( b . stmt ( b . call ( '$.handle_lazy_img' , node_id ) ) ) ;
261
255
}
262
256
@@ -267,14 +261,14 @@ export function RegularElement(node, context) {
267
261
node_id ,
268
262
context ,
269
263
is_attributes_reactive ,
270
- names . has ( 'style' ) || node . metadata . has_spread
264
+ lookup . has ( 'style' ) || node . metadata . has_spread
271
265
) ;
272
266
273
267
if (
274
268
is_load_error_element ( node . name ) &&
275
- ( names . has ( '*' ) ||
276
- names . has ( 'onload' ) ||
277
- names . has ( 'onerror' ) ||
269
+ ( has_spread ||
270
+ lookup . has ( 'onload' ) ||
271
+ lookup . has ( 'onerror' ) ||
278
272
node . attributes . some ( ( attribute ) => attribute . type === 'UseDirective' ) )
279
273
) {
280
274
context . state . after_update . push ( b . stmt ( b . call ( '$.replay_events' , node_id ) ) ) ;
@@ -372,7 +366,7 @@ export function RegularElement(node, context) {
372
366
context . state . after_update . push ( ...child_state . after_update ) ;
373
367
}
374
368
375
- if ( names . has ( 'dir' ) ) {
369
+ if ( lookup . has ( 'dir' ) ) {
376
370
// This fixes an issue with Chromium where updates to text content within an element
377
371
// does not update the direction when set to auto. If we just re-assign the dir, this fixes it.
378
372
const dir = b . member ( node_id , 'dir' ) ;
0 commit comments