Skip to content

Commit 95ca937

Browse files
committed
Introduce an external namespace
A svelte specific custom namespace that preserves attribute case
1 parent 67dea94 commit 95ca937

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

src/compiler/compile/render_dom/wrappers/Element/Attribute.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Expression from '../../../nodes/shared/Expression';
88
import Text from '../../../nodes/Text';
99
import handle_select_value_binding from './handle_select_value_binding';
1010
import { Identifier, Node } from 'estree';
11+
import { external } from '../../../../utils/namespaces';
1112

1213
export class BaseAttributeWrapper {
1314
node: Attribute;
@@ -67,15 +68,27 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
6768
}
6869
}
6970

70-
this.name = fix_attribute_casing(this.node.name);
71-
this.metadata = this.get_metadata();
72-
this.is_indirectly_bound_value = is_indirectly_bound_value(this);
73-
this.property_name = this.is_indirectly_bound_value
74-
? '__value'
75-
: this.metadata && this.metadata.property_name;
71+
if (this.parent.node.namespace && this.parent.node.namespace == external) {
72+
// leave attribute case alone for elements in the "external" namespace
73+
this.name = this.node.name;
74+
this.metadata = this.get_metadata();
75+
// since this is an external namespace, the following flags/properties can't apply
76+
this.is_indirectly_bound_value = false;
77+
this.property_name = null;
78+
this.is_select_value_attribute = false;
79+
this.is_input_value = false;
80+
} else {
81+
this.name = fix_attribute_casing(this.node.name);
82+
this.metadata = this.get_metadata();
83+
this.is_indirectly_bound_value = is_indirectly_bound_value(this);
84+
this.property_name = this.is_indirectly_bound_value
85+
? '__value'
86+
: this.metadata && this.metadata.property_name;
87+
this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select';
88+
this.is_input_value = this.name === 'value' && this.parent.node.name === 'input';
89+
}
90+
7691
this.is_src = this.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750
77-
this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select';
78-
this.is_input_value = this.name === 'value' && this.parent.node.name === 'input';
7992
this.should_cache = should_cache(this);
8093
}
8194

src/compiler/utils/namespaces.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1+
export const external = 'https://svelte.dev/docs';
12
export const html = 'http://www.w3.org/1999/xhtml';
23
export const mathml = 'http://www.w3.org/1998/Math/MathML';
34
export const svg = 'http://www.w3.org/2000/svg';
45
export const xlink = 'http://www.w3.org/1999/xlink';
56
export const xml = 'http://www.w3.org/XML/1998/namespace';
67
export const xmlns = 'http://www.w3.org/2000/xmlns';
78

9+
810
export const valid_namespaces = [
11+
'external',
912
'html',
1013
'mathml',
1114
'svg',
1215
'xlink',
1316
'xml',
1417
'xmlns',
18+
external,
1519
html,
1620
mathml,
1721
svg,
@@ -20,4 +24,4 @@ export const valid_namespaces = [
2024
xmlns
2125
];
2226

23-
export const namespaces: Record<string, string> = { html, mathml, svg, xlink, xml, xmlns };
27+
export const namespaces: Record<string, string> = { external, html, mathml, svg, xlink, xml, xmlns };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Test support for the external namespace preserving attribute case.
2+
3+
export default {
4+
html: `
5+
<page horizontalAlignment="center">
6+
<button textWrap="true" text="button">
7+
</page>
8+
`,
9+
options: {
10+
hydrate: false // Hydration test will fail as case sensitivity is only handled for svg elements.
11+
},
12+
13+
test({ assert, target }) {
14+
const attr = sel => target.querySelector(sel).attributes[0].name;
15+
assert.equal(attr('page'), 'horizontalAlignment');
16+
assert.equal(attr('button'), 'textWrap');
17+
}
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<svelte:options namespace="external" />
2+
<page horizontalAlignment="center">
3+
<button textWrap="true" text="button">
4+
</page>

0 commit comments

Comments
 (0)