fix: don't lowercase attributes with custom renderers

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

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

@ -235,7 +235,7 @@ export function RegularElement(node, context) {
continue;
}
const name = get_attribute_name(node, attribute);
const name = get_attribute_name(node, attribute, !!context.state.analysis.custom_renderer);
if (
!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.Attribute} attribute
* @param {boolean} [custom_renderer]
*/
export function get_attribute_name(element, attribute) {
if (!element.metadata.svg && !element.metadata.mathml) {
export function get_attribute_name(element, attribute, custom_renderer) {
if (!custom_renderer && !element.metadata.svg && !element.metadata.mathml) {
return normalize_attribute(attribute.name);
}

@ -579,7 +579,7 @@ export function set_element_checked(element, checked) {
*/
export function set_element_default_value(element, value) {
if (renderer) {
renderer.setAttribute(element, 'defaultvalue', value);
renderer.setAttribute(element, 'defaultValue', value);
return;
}
// @ts-expect-error
@ -599,9 +599,9 @@ export function set_element_default_value(element, value) {
export function set_element_default_checked(element, checked) {
if (renderer) {
if (checked) {
renderer.setAttribute(element, 'defaultchecked', '');
renderer.setAttribute(element, 'defaultChecked', '');
} else {
renderer.removeAttribute(element, 'defaultchecked');
renderer.removeAttribute(element, 'defaultChecked');
}
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['checked'], '');
// Input 3: value="fixed" defaultvalue="default_val"
// Input 3: value="fixed" defaultValue="default_val"
const input_default_value = inputs[2];
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];
assert.equal(input_default_checked.attributes['type'], 'checkbox');
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
const input_spread = inputs[4];
@ -56,12 +56,12 @@ export default test({
// Input 2: checked should be removed
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['defaultvalue'], 'new_default');
assert.equal(input_default_value.attributes['defaultValue'], 'new_default');
// Input 4: defaultchecked should be removed
assert.equal(input_default_checked.attributes['defaultchecked'], undefined);
// Input 4: defaultChecked should be removed
assert.equal(input_default_checked.attributes['defaultChecked'], undefined);
// Input 5: spread attributes should update value to "world"
assert.equal(input_spread.attributes['value'], 'world');

Loading…
Cancel
Save