@@ -12,13 +12,7 @@ import {
12
12
escape_html ,
13
13
infer_namespace
14
14
} from '../../utils.js' ;
15
- import {
16
- AttributeAliases ,
17
- DOMBooleanAttributes ,
18
- DOMProperties ,
19
- PassiveEvents ,
20
- VoidElements
21
- } from '../../../constants.js' ;
15
+ import { DOMProperties , PassiveEvents , VoidElements } from '../../../constants.js' ;
22
16
import { is_custom_element_node , is_element_node } from '../../../nodes.js' ;
23
17
import * as b from '../../../../utils/builders.js' ;
24
18
import { error } from '../../../../errors.js' ;
@@ -29,6 +23,8 @@ import {
29
23
serialize_set_binding
30
24
} from '../utils.js' ;
31
25
import {
26
+ AttributeAliases ,
27
+ DOMBooleanAttributes ,
32
28
EACH_INDEX_REACTIVE ,
33
29
EACH_IS_CONTROLLED ,
34
30
EACH_ITEM_REACTIVE ,
@@ -37,6 +33,26 @@ import {
37
33
import { regex_is_valid_identifier } from '../../../patterns.js' ;
38
34
import { javascript_visitors_runes } from './javascript-runes.js' ;
39
35
36
+ /**
37
+ * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement } element
38
+ * @param {import('#compiler').Attribute } attribute
39
+ * @param {{ state: { metadata: { namespace: import('#compiler').Namespace }}} } context
40
+ */
41
+ function get_attribute_name ( element , attribute , context ) {
42
+ let name = attribute . name ;
43
+ if (
44
+ element . type === 'RegularElement' &&
45
+ ! element . metadata . svg &&
46
+ context . state . metadata . namespace !== 'foreign'
47
+ ) {
48
+ name = name . toLowerCase ( ) ;
49
+ if ( name in AttributeAliases ) {
50
+ name = AttributeAliases [ name ] ;
51
+ }
52
+ }
53
+ return name ;
54
+ }
55
+
40
56
/**
41
57
* Serializes each style directive into something like `$.style(element, style_property, value)`
42
58
* and adds it either to init or update, depending on whether or not the value or the attributes are dynamic.
@@ -259,18 +275,19 @@ function setup_select_synchronization(value_binding, context) {
259
275
* Returns the id of the spread_attribute variable if spread is deemed reactive, `null` otherwise.
260
276
* @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute> } attributes
261
277
* @param {import('../types.js').ComponentContext } context
278
+ * @param {import('#compiler').RegularElement } element
262
279
* @param {import('estree').Identifier } element_id
263
280
* @returns {string | null }
264
281
*/
265
- function serialize_element_spread_attributes ( attributes , context , element_id ) {
282
+ function serialize_element_spread_attributes ( attributes , context , element , element_id ) {
266
283
let is_reactive = false ;
267
284
268
285
/** @type {import('estree').Expression[] } */
269
286
const values = [ ] ;
270
287
271
288
for ( const attribute of attributes ) {
272
289
if ( attribute . type === 'Attribute' ) {
273
- const name = get_attribute_name ( attribute , context . state ) ;
290
+ const name = get_attribute_name ( element , attribute , context ) ;
274
291
// TODO: handle contains_call_expression
275
292
const [ , value ] = serialize_attribute_value ( attribute . value , context ) ;
276
293
values . push ( b . object ( [ b . init ( name , value ) ] ) ) ;
@@ -281,6 +298,9 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
281
298
is_reactive ||= attribute . metadata . dynamic ;
282
299
}
283
300
301
+ const lowercase_attributes =
302
+ element . metadata . svg || is_custom_element_node ( element ) ? b . false : b . true ;
303
+
284
304
if ( is_reactive ) {
285
305
const id = context . state . scope . generate ( 'spread_attributes' ) ;
286
306
context . state . init . push ( b . let ( id , undefined ) ) ;
@@ -294,6 +314,7 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
294
314
element_id ,
295
315
b . id ( id ) ,
296
316
b . array ( values ) ,
317
+ lowercase_attributes ,
297
318
b . literal ( context . state . analysis . stylesheet . id )
298
319
)
299
320
)
@@ -308,6 +329,7 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
308
329
element_id ,
309
330
b . literal ( null ) ,
310
331
b . array ( values ) ,
332
+ lowercase_attributes ,
311
333
b . literal ( context . state . analysis . stylesheet . id )
312
334
)
313
335
)
@@ -398,14 +420,15 @@ function serialize_dynamic_element_spread_attributes(attributes, context, elemen
398
420
* });
399
421
* ```
400
422
* Returns true if attribute is deemed reactive, false otherwise.
423
+ * @param {import('#compiler').RegularElement } element
401
424
* @param {import('estree').Identifier } node_id
402
425
* @param {import('#compiler').Attribute } attribute
403
426
* @param {import('../types.js').ComponentContext } context
404
427
* @returns {boolean }
405
428
*/
406
- function serialize_element_attribute_update_assignment ( node_id , attribute , context ) {
429
+ function serialize_element_attribute_update_assignment ( element , node_id , attribute , context ) {
407
430
const state = context . state ;
408
- const name = get_attribute_name ( attribute , state ) ;
431
+ const name = get_attribute_name ( element , attribute , context ) ;
409
432
let [ contains_call_expression , value ] = serialize_attribute_value ( attribute . value , context ) ;
410
433
411
434
// The foreign namespace doesn't have any special handling, everything goes through the attr function
@@ -672,21 +695,6 @@ function collect_parent_each_blocks(context) {
672
695
) ;
673
696
}
674
697
675
- /**
676
- * @param {import('#compiler').Attribute } attribute
677
- * @param {import('../types.js').ComponentClientTransformState } state
678
- */
679
- function get_attribute_name ( attribute , state ) {
680
- let name = attribute . name ;
681
- if ( state . metadata . namespace !== 'foreign' ) {
682
- name = name . toLowerCase ( ) ;
683
- if ( name !== 'class' && name in AttributeAliases ) {
684
- name = AttributeAliases [ name ] ;
685
- }
686
- }
687
- return name ;
688
- }
689
-
690
698
/**
691
699
* @param {import('#compiler').Component | import('#compiler').SvelteComponent | import('#compiler').SvelteSelf } node
692
700
* @param {string } component_name
@@ -1899,7 +1907,7 @@ export const template_visitors = {
1899
1907
// Then do attributes
1900
1908
let is_attributes_reactive = false ;
1901
1909
if ( node . metadata . has_spread ) {
1902
- const spread_id = serialize_element_spread_attributes ( attributes , context , node_id ) ;
1910
+ const spread_id = serialize_element_spread_attributes ( attributes , context , node , node_id ) ;
1903
1911
if ( child_metadata . namespace !== 'foreign' ) {
1904
1912
add_select_to_spread_update ( spread_id , node , context , node_id ) ;
1905
1913
}
@@ -1920,7 +1928,7 @@ export const template_visitors = {
1920
1928
attribute . name !== 'autofocus' &&
1921
1929
( attribute . value === true || is_text_attribute ( attribute ) )
1922
1930
) {
1923
- const name = get_attribute_name ( attribute , context . state ) ;
1931
+ const name = get_attribute_name ( node , attribute , context ) ;
1924
1932
const literal_value = /** @type {import('estree').Literal } */ (
1925
1933
serialize_attribute_value ( attribute . value , context ) [ 1 ]
1926
1934
) . value ;
@@ -1941,7 +1949,7 @@ export const template_visitors = {
1941
1949
const is =
1942
1950
is_custom_element && child_metadata . namespace !== 'foreign'
1943
1951
? serialize_custom_element_attribute_update_assignment ( node_id , attribute , context )
1944
- : serialize_element_attribute_update_assignment ( node_id , attribute , context ) ;
1952
+ : serialize_element_attribute_update_assignment ( node , node_id , attribute , context ) ;
1945
1953
if ( is ) is_attributes_reactive = true ;
1946
1954
}
1947
1955
}
0 commit comments