fix: don't lowercase attributes with custom renderers

pull/18058/head
paoloricciuti 5 months ago
parent a0650d0611
commit e2cedcd93e

@ -137,7 +137,7 @@ function objectify(item) {
attributes.properties.push( attributes.properties.push(
b.prop( b.prop(
'init', 'init',
b.key(fix_attribute_casing(key)), b.key(item.is_html ? fix_attribute_casing(key) : key),
value === undefined ? b.void0 : b.literal(value) value === undefined ? b.void0 : b.literal(value)
) )
); );

@ -235,7 +235,7 @@ export function RegularElement(node, context) {
continue; continue;
} }
const name = get_attribute_name(node, attribute); const name = get_attribute_name(node, attribute, !!context.state.analysis.custom_renderer);
if ( if (
!is_custom_element && !is_custom_element &&

@ -132,9 +132,10 @@ export function build_attribute_value(value, context, memoize = (value) => value
/** /**
* @param {AST.RegularElement | AST.SvelteElement} element * @param {AST.RegularElement | AST.SvelteElement} element
* @param {AST.Attribute} attribute * @param {AST.Attribute} attribute
* @param {boolean} [custom_renderer]
*/ */
export function get_attribute_name(element, attribute) { export function get_attribute_name(element, attribute, custom_renderer) {
if (!element.metadata.svg && !element.metadata.mathml) { if (!custom_renderer && !element.metadata.svg && !element.metadata.mathml) {
return normalize_attribute(attribute.name); return normalize_attribute(attribute.name);
} }

@ -579,7 +579,7 @@ export function set_element_checked(element, checked) {
*/ */
export function set_element_default_value(element, value) { export function set_element_default_value(element, value) {
if (renderer) { if (renderer) {
renderer.setAttribute(element, 'defaultvalue', value); renderer.setAttribute(element, 'defaultValue', value);
return; return;
} }
// @ts-expect-error // @ts-expect-error
@ -599,9 +599,9 @@ export function set_element_default_value(element, value) {
export function set_element_default_checked(element, checked) { export function set_element_default_checked(element, checked) {
if (renderer) { if (renderer) {
if (checked) { if (checked) {
renderer.setAttribute(element, 'defaultchecked', ''); renderer.setAttribute(element, 'defaultChecked', '');
} else { } else {
renderer.removeAttribute(element, 'defaultchecked'); renderer.removeAttribute(element, 'defaultChecked');
} }
return; return;
} }

@ -0,0 +1,37 @@
import { test } from '../../test';
export default test({
test({ assert, target }) {
const elements = target.children.filter((/** @type {any} */ n) => n.type === 'element');
assert.equal(elements.length, 4);
// Static camelCase attribute should preserve casing
const div1 = elements[0];
assert.equal(div1.name, 'div');
assert.equal(div1.attributes['dataColor'], 'red');
// Should NOT have a lowercased version
assert.equal(div1.attributes['datacolor'], undefined);
// Dynamic camelCase attribute should preserve casing
const div2 = elements[1];
assert.equal(div2.name, 'div');
assert.equal(div2.attributes['viewBox'], '0 0 100 100');
// Should NOT have a lowercased version
assert.equal(div2.attributes['viewbox'], undefined);
// Static tabIndex should preserve casing
const span = elements[2];
assert.equal(span.name, 'span');
assert.equal(span.attributes['tabIndex'], '0');
// Should NOT have a lowercased version
assert.equal(span.attributes['tabindex'], undefined);
// Spread camelCase attributes should preserve casing
const p = elements[3];
assert.equal(p.name, 'p');
assert.equal(p.attributes['dataValue'], 'spread');
// Should NOT have a lowercased version
assert.equal(p.attributes['datavalue'], undefined);
}
});

@ -0,0 +1,9 @@
<script>
let box = $state('0 0 100 100');
let spread = $derived({ dataValue: 'spread', onClick: () => {} });
</script>
<div dataColor="red">static camelCase</div>
<div viewBox={box}>dynamic camelCase</div>
<span tabIndex="0">static tabIndex</span>
<p {...spread}>spread camelCase</p>

@ -27,16 +27,16 @@ export default test({
assert.equal(input_checked.attributes['type'], 'checkbox'); assert.equal(input_checked.attributes['type'], 'checkbox');
assert.equal(input_checked.attributes['checked'], ''); assert.equal(input_checked.attributes['checked'], '');
// Input 3: value="fixed" defaultvalue="default_val" // Input 3: value="fixed" defaultValue="default_val"
const input_default_value = inputs[2]; const input_default_value = inputs[2];
assert.equal(input_default_value.attributes['value'], 'fixed'); assert.equal(input_default_value.attributes['value'], 'fixed');
assert.equal(input_default_value.attributes['defaultvalue'], 'default_val'); assert.equal(input_default_value.attributes['defaultValue'], 'default_val');
// Input 4: type="checkbox" checked="" defaultchecked="" // Input 4: type="checkbox" checked="" defaultChecked=""
const input_default_checked = inputs[3]; const input_default_checked = inputs[3];
assert.equal(input_default_checked.attributes['type'], 'checkbox'); assert.equal(input_default_checked.attributes['type'], 'checkbox');
assert.equal(input_default_checked.attributes['checked'], ''); assert.equal(input_default_checked.attributes['checked'], '');
assert.equal(input_default_checked.attributes['defaultchecked'], ''); assert.equal(input_default_checked.attributes['defaultChecked'], '');
// Input 5: spread attributes // Input 5: spread attributes
const input_spread = inputs[4]; const input_spread = inputs[4];
@ -56,12 +56,12 @@ export default test({
// Input 2: checked should be removed // Input 2: checked should be removed
assert.equal(input_checked.attributes['checked'], undefined); assert.equal(input_checked.attributes['checked'], undefined);
// Input 3: defaultvalue="new_default", value still "fixed" // Input 3: defaultValue="new_default", value still "fixed"
assert.equal(input_default_value.attributes['value'], 'fixed'); assert.equal(input_default_value.attributes['value'], 'fixed');
assert.equal(input_default_value.attributes['defaultvalue'], 'new_default'); assert.equal(input_default_value.attributes['defaultValue'], 'new_default');
// Input 4: defaultchecked should be removed // Input 4: defaultChecked should be removed
assert.equal(input_default_checked.attributes['defaultchecked'], undefined); assert.equal(input_default_checked.attributes['defaultChecked'], undefined);
// Input 5: spread attributes should update value to "world" // Input 5: spread attributes should update value to "world"
assert.equal(input_spread.attributes['value'], 'world'); assert.equal(input_spread.attributes['value'], 'world');

Loading…
Cancel
Save