@@ -31,34 +31,37 @@ export function attr_effect(dom, attribute, value) {
31
31
}
32
32
33
33
/**
34
- * @param {Element } dom
34
+ * @param {Element } element
35
35
* @param {string } attribute
36
36
* @param {string | null } value
37
37
*/
38
- export function attr ( dom , attribute , value ) {
38
+ export function attr ( element , attribute , value ) {
39
39
value = value == null ? null : value + '' ;
40
40
41
- if ( DEV ) {
42
- check_src_in_dev_hydration ( dom , attribute , value ) ;
43
- }
41
+ // @ts -expect-error
42
+ var attributes = ( element . __attributes ??= { } ) ;
43
+
44
+ if ( hydrating ) {
45
+ attributes [ attribute ] = element . getAttribute ( attribute ) ;
46
+
47
+ if ( attribute === 'src' || attribute === 'href' || attribute === 'srcset' ) {
48
+ check_src_in_dev_hydration ( element , attribute , value ) ;
44
49
45
- if (
46
- ! hydrating ||
47
- ( dom . getAttribute ( attribute ) !== value &&
48
- // If we reset those, they would result in another network request, which we want to avoid.
50
+ // If we reset these attributes, they would result in another network request, which we want to avoid.
49
51
// We assume they are the same between client and server as checking if they are equal is expensive
50
52
// (we can't just compare the strings as they can be different between client and server but result in the
51
53
// same url, so we would need to create hidden anchor elements to compare them)
52
- attribute !== 'src' &&
53
- attribute !== 'href' &&
54
- attribute !== 'srcset' )
55
- ) {
56
- if ( value === null ) {
57
- dom . removeAttribute ( attribute ) ;
58
- } else {
59
- dom . setAttribute ( attribute , value ) ;
54
+ return ;
60
55
}
61
56
}
57
+
58
+ if ( attributes [ attribute ] === ( attributes [ attribute ] = value ) ) return ;
59
+
60
+ if ( value === null ) {
61
+ element . removeAttribute ( attribute ) ;
62
+ } else {
63
+ element . setAttribute ( attribute , value ) ;
64
+ }
62
65
}
63
66
64
67
/**
@@ -123,14 +126,14 @@ export function spread_attributes_effect(dom, attrs, lowercase_attributes, css_h
123
126
124
127
/**
125
128
* Spreads attributes onto a DOM element, taking into account the currently set attributes
126
- * @param {Element & ElementCSSInlineStyle } dom
129
+ * @param {Element & ElementCSSInlineStyle } element
127
130
* @param {Record<string, unknown> | undefined } prev
128
131
* @param {Record<string, unknown>[] } attrs
129
132
* @param {boolean } lowercase_attributes
130
133
* @param {string } css_hash
131
134
* @returns {Record<string, unknown> }
132
135
*/
133
- export function spread_attributes ( dom , prev , attrs , lowercase_attributes , css_hash ) {
136
+ export function spread_attributes ( element , prev , attrs , lowercase_attributes , css_hash ) {
134
137
var next = object_assign ( { } , ...attrs ) ;
135
138
var has_hash = css_hash . length !== 0 ;
136
139
@@ -144,8 +147,8 @@ export function spread_attributes(dom, prev, attrs, lowercase_attributes, css_ha
144
147
next . class = '' ;
145
148
}
146
149
147
- var setters = map_get ( setters_cache , dom . nodeName ) ;
148
- if ( ! setters ) map_set ( setters_cache , dom . nodeName , ( setters = get_setters ( dom ) ) ) ;
150
+ var setters = map_get ( setters_cache , element . nodeName ) ;
151
+ if ( ! setters ) map_set ( setters_cache , element . nodeName , ( setters = get_setters ( element ) ) ) ;
149
152
150
153
for ( key in next ) {
151
154
var value = next [ key ] ;
@@ -170,27 +173,27 @@ export function spread_attributes(dom, prev, attrs, lowercase_attributes, css_ha
170
173
}
171
174
172
175
if ( ! delegated && prev ?. [ key ] ) {
173
- dom . removeEventListener ( event_name , /** @type {any } */ ( prev [ key ] ) , opts ) ;
176
+ element . removeEventListener ( event_name , /** @type {any } */ ( prev [ key ] ) , opts ) ;
174
177
}
175
178
176
179
if ( value != null ) {
177
180
if ( ! delegated ) {
178
- dom . addEventListener ( event_name , value , opts ) ;
181
+ element . addEventListener ( event_name , value , opts ) ;
179
182
} else {
180
183
// @ts -ignore
181
- dom [ `__${ event_name } ` ] = value ;
184
+ element [ `__${ event_name } ` ] = value ;
182
185
delegate ( [ event_name ] ) ;
183
186
}
184
187
}
185
188
} else if ( value == null ) {
186
- dom . removeAttribute ( key ) ;
189
+ element . removeAttribute ( key ) ;
187
190
} else if ( key === 'style' ) {
188
- dom . style . cssText = value + '' ;
191
+ element . style . cssText = value + '' ;
189
192
} else if ( key === 'autofocus' ) {
190
- autofocus ( /** @type {HTMLElement } */ ( dom ) , Boolean ( value ) ) ;
193
+ autofocus ( /** @type {HTMLElement } */ ( element ) , Boolean ( value ) ) ;
191
194
} else if ( key === '__value' || key === 'value' ) {
192
195
// @ts -ignore
193
- dom . value = dom [ key ] = dom . __value = value ;
196
+ element . value = element [ key ] = element . __value = value ;
194
197
} else {
195
198
var name = key ;
196
199
if ( lowercase_attributes ) {
@@ -199,25 +202,19 @@ export function spread_attributes(dom, prev, attrs, lowercase_attributes, css_ha
199
202
}
200
203
201
204
if ( setters . includes ( name ) ) {
202
- if ( DEV ) {
203
- check_src_in_dev_hydration ( dom , name , value ) ;
204
- }
205
-
206
- if (
207
- ! hydrating ||
208
- // @ts -ignore see attr method for an explanation of src/srcset
209
- ( dom [ name ] !== value && name !== 'src' && name !== 'href' && name !== 'srcset' )
210
- ) {
205
+ if ( hydrating && ( name === 'src' || name === 'href' || name === 'srcset' ) ) {
206
+ check_src_in_dev_hydration ( element , name , value ) ;
207
+ } else {
211
208
// @ts -ignore
212
- dom [ name ] = value ;
209
+ element [ name ] = value ;
213
210
}
214
211
} else if ( typeof value !== 'function' ) {
215
212
if ( has_hash && name === 'class' ) {
216
213
if ( value ) value += ' ' ;
217
214
value += css_hash ;
218
215
}
219
216
220
- attr ( dom , name , value ) ;
217
+ attr ( element , name , value ) ;
221
218
}
222
219
}
223
220
}
@@ -301,22 +298,20 @@ function get_setters(element) {
301
298
}
302
299
303
300
/**
304
- * @param {any } dom
301
+ * @param {any } element
305
302
* @param {string } attribute
306
303
* @param {string | null } value
307
304
*/
308
- function check_src_in_dev_hydration ( dom , attribute , value ) {
309
- if ( ! hydrating ) return ;
310
- if ( attribute !== 'src' && attribute !== 'href' && attribute !== 'srcset' ) return ;
311
-
312
- if ( attribute === 'srcset' && srcset_url_equal ( dom , value ) ) return ;
313
- if ( src_url_equal ( dom . getAttribute ( attribute ) ?? '' , value ?? '' ) ) return ;
305
+ function check_src_in_dev_hydration ( element , attribute , value ) {
306
+ if ( ! DEV ) return ;
307
+ if ( attribute === 'srcset' && srcset_url_equal ( element , value ) ) return ;
308
+ if ( src_url_equal ( element . getAttribute ( attribute ) ?? '' , value ?? '' ) ) return ;
314
309
315
310
// eslint-disable-next-line no-console
316
311
console . error (
317
312
`Detected a ${ attribute } attribute value change during hydration. This will not be repaired during hydration, ` +
318
313
`the ${ attribute } value that came from the server will be used. Related element:` ,
319
- dom ,
314
+ element ,
320
315
' Differing value:' ,
321
316
value
322
317
) ;
0 commit comments