diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
index 258376c375..e470a1e0d8 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
@@ -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 { namespaces, valid_namespaces } from '../../../../utils/namespaces';
export class BaseAttributeWrapper {
node: Attribute;
@@ -65,17 +66,33 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
handle_select_value_binding(this, node.dependencies);
}
}
+
+ const namespace = this.parent.node.namespace;
+ // some processing only applies to html namespace (and not MathML, SVG, or Svelte Native etc)
+ if (namespace && namespace != 'html' && namespace != namespaces.html) {
+ // attributes outside of the html namespaced may be case sensitive
+ // namespaces for which we don't have case corrections, are left in their original case (required for svelte-native)
+ this.name = (valid_namespaces.indexOf(namespace) >= 0) ? fix_attribute_casing(this.node.name) : this.node.name;
+ this.is_indirectly_bound_value = false;
+ this.metadata = null;
+ 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.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_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);
+
}
render(block: Block) {
diff --git a/test/runtime/samples/attribute-casing-unknown-namespace/_config.js b/test/runtime/samples/attribute-casing-unknown-namespace/_config.js
new file mode 100644
index 0000000000..45ee778a49
--- /dev/null
+++ b/test/runtime/samples/attribute-casing-unknown-namespace/_config.js
@@ -0,0 +1,18 @@
+// Test support for unknown namespaces preserving attribute case (eg svelte-native).
+
+export default {
+ html: `
+
+
+ `,
+ options: {
+ hydrate: false, // Hydrations currently doesn't work, the 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")
+ }
+};
diff --git a/test/runtime/samples/attribute-casing-unknown-namespace/main.svelte b/test/runtime/samples/attribute-casing-unknown-namespace/main.svelte
new file mode 100644
index 0000000000..9bc97600fe
--- /dev/null
+++ b/test/runtime/samples/attribute-casing-unknown-namespace/main.svelte
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file