Skip to content

Commit

Permalink
Introduce an external namespace
Browse files Browse the repository at this point in the history
A svelte specific custom namespace that preserves attribute case
  • Loading branch information
halfnelson committed Nov 20, 2020
1 parent 67dea94 commit 95ca937
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 9 deletions.
29 changes: 21 additions & 8 deletions src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Expression from '../../../nodes/shared/Expression';
import Text from '../../../nodes/Text';
import handle_select_value_binding from './handle_select_value_binding';
import { Identifier, Node } from 'estree';
import { external } from '../../../../utils/namespaces';

export class BaseAttributeWrapper {
node: Attribute;
Expand Down Expand Up @@ -67,15 +68,27 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
}
}

this.name = fix_attribute_casing(this.node.name);
this.metadata = this.get_metadata();
this.is_indirectly_bound_value = is_indirectly_bound_value(this);
this.property_name = this.is_indirectly_bound_value
? '__value'
: this.metadata && this.metadata.property_name;
if (this.parent.node.namespace && this.parent.node.namespace == external) {
// leave attribute case alone for elements in the "external" namespace
this.name = this.node.name;
this.metadata = this.get_metadata();
// since this is an external namespace, the following flags/properties can't apply
this.is_indirectly_bound_value = false;
this.property_name = null;
this.is_select_value_attribute = false;
this.is_input_value = false;
} else {
this.name = fix_attribute_casing(this.node.name);
this.metadata = this.get_metadata();
this.is_indirectly_bound_value = is_indirectly_bound_value(this);
this.property_name = this.is_indirectly_bound_value
? '__value'
: this.metadata && this.metadata.property_name;
this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select';
this.is_input_value = this.name === 'value' && this.parent.node.name === 'input';
}

this.is_src = this.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750
this.is_select_value_attribute = this.name === 'value' && this.parent.node.name === 'select';
this.is_input_value = this.name === 'value' && this.parent.node.name === 'input';
this.should_cache = should_cache(this);
}

Expand Down
6 changes: 5 additions & 1 deletion src/compiler/utils/namespaces.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
export const external = 'https://svelte.dev/docs';
export const html = 'http://www.w3.org/1999/xhtml';
export const mathml = 'http://www.w3.org/1998/Math/MathML';
export const svg = 'http://www.w3.org/2000/svg';
export const xlink = 'http://www.w3.org/1999/xlink';
export const xml = 'http://www.w3.org/XML/1998/namespace';
export const xmlns = 'http://www.w3.org/2000/xmlns';


export const valid_namespaces = [
'external',
'html',
'mathml',
'svg',
'xlink',
'xml',
'xmlns',
external,
html,
mathml,
svg,
Expand All @@ -20,4 +24,4 @@ export const valid_namespaces = [
xmlns
];

export const namespaces: Record<string, string> = { html, mathml, svg, xlink, xml, xmlns };
export const namespaces: Record<string, string> = { external, html, mathml, svg, xlink, xml, xmlns };
18 changes: 18 additions & 0 deletions test/runtime/samples/attribute-casing-native-namespace/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Test support for the external namespace preserving attribute case.

export default {
html: `
<page horizontalAlignment="center">
<button textWrap="true" text="button">
</page>
`,
options: {
hydrate: false // Hydration test will fail as case sensitivity is only handled for svg elements.
},

test({ assert, target }) {
const attr = sel => target.querySelector(sel).attributes[0].name;
assert.equal(attr('page'), 'horizontalAlignment');
assert.equal(attr('button'), 'textWrap');
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<svelte:options namespace="external" />
<page horizontalAlignment="center">
<button textWrap="true" text="button">
</page>

0 comments on commit 95ca937

Please sign in to comment.