diff --git a/package.json b/package.json
index b93da0d5f4a4..0fd3f16a7725 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"posttest": "agadoo internal/index.mjs",
"prepublishOnly": "npm run lint && PUBLISH=true npm test",
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly",
- "lint": "eslint '{src,test}/**/*.{ts,js}'"
+ "lint": "eslint \"{src,test}/**/*.{ts,js}\""
},
"repository": {
"type": "git",
diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
index 258376c3755e..73a89c90e89c 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 { valid_namespaces } from '../../../../utils/namespaces';
export class BaseAttributeWrapper {
node: Attribute;
@@ -65,16 +66,31 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
handle_select_value_binding(this, node.dependencies);
}
}
+
+ const namespace = this.parent.node.namespace;
+
+ // some processing only applies to known namespaces
+ if (namespace && !valid_namespaces.includes(namespace)) {
+ // attributes outside of the valid namespace may be case sensitive (eg svelte native). We leave them in their current case
+ this.name = this.node.name;
+ this.metadata = this.get_metadata();
+ 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.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);
}
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 000000000000..478d779e062a
--- /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 000000000000..9bc97600fec3
--- /dev/null
+++ b/test/runtime/samples/attribute-casing-unknown-namespace/main.svelte
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file