@@ -12,13 +12,7 @@ import {
1212 escape_html ,
1313 infer_namespace
1414} 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' ;
2216import { is_custom_element_node , is_element_node } from '../../../nodes.js' ;
2317import * as b from '../../../../utils/builders.js' ;
2418import { error } from '../../../../errors.js' ;
@@ -29,6 +23,8 @@ import {
2923 serialize_set_binding
3024} from '../utils.js' ;
3125import {
26+ AttributeAliases ,
27+ DOMBooleanAttributes ,
3228 EACH_INDEX_REACTIVE ,
3329 EACH_IS_CONTROLLED ,
3430 EACH_ITEM_REACTIVE ,
@@ -37,6 +33,26 @@ import {
3733import { regex_is_valid_identifier } from '../../../patterns.js' ;
3834import { javascript_visitors_runes } from './javascript-runes.js' ;
3935
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+
4056/**
4157 * Serializes each style directive into something like `$.style(element, style_property, value)`
4258 * 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) {
259275 * Returns the id of the spread_attribute variable if spread is deemed reactive, `null` otherwise.
260276 * @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute> } attributes
261277 * @param {import('../types.js').ComponentContext } context
278+ * @param {import('#compiler').RegularElement } element
262279 * @param {import('estree').Identifier } element_id
263280 * @returns {string | null }
264281 */
265- function serialize_element_spread_attributes ( attributes , context , element_id ) {
282+ function serialize_element_spread_attributes ( attributes , context , element , element_id ) {
266283 let is_reactive = false ;
267284
268285 /** @type {import('estree').Expression[] } */
269286 const values = [ ] ;
270287
271288 for ( const attribute of attributes ) {
272289 if ( attribute . type === 'Attribute' ) {
273- const name = get_attribute_name ( attribute , context . state ) ;
290+ const name = get_attribute_name ( element , attribute , context ) ;
274291 // TODO: handle contains_call_expression
275292 const [ , value ] = serialize_attribute_value ( attribute . value , context ) ;
276293 values . push ( b . object ( [ b . init ( name , value ) ] ) ) ;
@@ -281,6 +298,9 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
281298 is_reactive ||= attribute . metadata . dynamic ;
282299 }
283300
301+ const lowercase_attributes =
302+ element . metadata . svg || is_custom_element_node ( element ) ? b . false : b . true ;
303+
284304 if ( is_reactive ) {
285305 const id = context . state . scope . generate ( 'spread_attributes' ) ;
286306 context . state . init . push ( b . let ( id , undefined ) ) ;
@@ -294,6 +314,7 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
294314 element_id ,
295315 b . id ( id ) ,
296316 b . array ( values ) ,
317+ lowercase_attributes ,
297318 b . literal ( context . state . analysis . stylesheet . id )
298319 )
299320 )
@@ -308,6 +329,7 @@ function serialize_element_spread_attributes(attributes, context, element_id) {
308329 element_id ,
309330 b . literal ( null ) ,
310331 b . array ( values ) ,
332+ lowercase_attributes ,
311333 b . literal ( context . state . analysis . stylesheet . id )
312334 )
313335 )
@@ -398,14 +420,15 @@ function serialize_dynamic_element_spread_attributes(attributes, context, elemen
398420 * });
399421 * ```
400422 * Returns true if attribute is deemed reactive, false otherwise.
423+ * @param {import('#compiler').RegularElement } element
401424 * @param {import('estree').Identifier } node_id
402425 * @param {import('#compiler').Attribute } attribute
403426 * @param {import('../types.js').ComponentContext } context
404427 * @returns {boolean }
405428 */
406- function serialize_element_attribute_update_assignment ( node_id , attribute , context ) {
429+ function serialize_element_attribute_update_assignment ( element , node_id , attribute , context ) {
407430 const state = context . state ;
408- const name = get_attribute_name ( attribute , state ) ;
431+ const name = get_attribute_name ( element , attribute , context ) ;
409432 let [ contains_call_expression , value ] = serialize_attribute_value ( attribute . value , context ) ;
410433
411434 // 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) {
672695 ) ;
673696}
674697
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-
690698/**
691699 * @param {import('#compiler').Component | import('#compiler').SvelteComponent | import('#compiler').SvelteSelf } node
692700 * @param {string } component_name
@@ -1899,7 +1907,7 @@ export const template_visitors = {
18991907 // Then do attributes
19001908 let is_attributes_reactive = false ;
19011909 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 ) ;
19031911 if ( child_metadata . namespace !== 'foreign' ) {
19041912 add_select_to_spread_update ( spread_id , node , context , node_id ) ;
19051913 }
@@ -1920,7 +1928,7 @@ export const template_visitors = {
19201928 attribute . name !== 'autofocus' &&
19211929 ( attribute . value === true || is_text_attribute ( attribute ) )
19221930 ) {
1923- const name = get_attribute_name ( attribute , context . state ) ;
1931+ const name = get_attribute_name ( node , attribute , context ) ;
19241932 const literal_value = /** @type {import('estree').Literal } */ (
19251933 serialize_attribute_value ( attribute . value , context ) [ 1 ]
19261934 ) . value ;
@@ -1941,7 +1949,7 @@ export const template_visitors = {
19411949 const is =
19421950 is_custom_element && child_metadata . namespace !== 'foreign'
19431951 ? 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 ) ;
19451953 if ( is ) is_attributes_reactive = true ;
19461954 }
19471955 }
0 commit comments