Skip to content

Commit a7eff88

Browse files
authored
add foreign namespace to preserve attribute case and skip HTML-specific a11y validations (#5652)
1 parent d5f2ddc commit a7eff88

File tree

18 files changed

+291
-139
lines changed

18 files changed

+291
-139
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
* Allow multiple instances of the same action on an element ([#5516](https://github.com/sveltejs/svelte/pull/5516))
6+
* Support `foreign` namespace, which disables certain HTML5-specific behaviour and checks ([#5652](https://github.com/sveltejs/svelte/pull/5652))
67
* Support inline comment sourcemaps in code from preprocessors ([#5854](https://github.com/sveltejs/svelte/pull/5854))
78

89
## 3.31.2

site/content/docs/02-template-syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,7 @@ The `<svelte:options>` element provides a place to specify per-component compile
15301530
* `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
15311531
* `accessors={true}` — adds getters and setters for the component's props
15321532
* `accessors={false}` — the default
1533-
* `namespace="..."` — the namespace where this component will be used, most commonly "svg"
1533+
* `namespace="..."` — the namespace where this component will be used, most commonly "svg"; use the "foreign" namespace to opt out of case-insensitive attribute names and HTML-specific warnings
15341534
* `tag="..."` — the name to use when compiling this component as a custom element
15351535

15361536
```sv

site/content/docs/04-compile-time.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ The following options can be passed to the compiler. None are required:
8080
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
8181
| `cssOutputFilename` | `null` | A `string` used for your CSS sourcemap.
8282
| `sveltePath` | `"svelte"` | The location of the `svelte` package. Any imports from `svelte` or `svelte/[module]` will be modified accordingly.
83-
83+
| `namespace` | `"html"` | The namespace of the element; e.g., `"mathml"`, `"svg"`, `"foreign"`.
8484

8585
---
8686

src/compiler/compile/Component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1349,7 +1349,8 @@ function process_component_options(component: Component, nodes) {
13491349
'accessors' in component.compile_options
13501350
? component.compile_options.accessors
13511351
: !!component.compile_options.customElement,
1352-
preserveWhitespace: !!component.compile_options.preserveWhitespace
1352+
preserveWhitespace: !!component.compile_options.preserveWhitespace,
1353+
namespace: component.compile_options.namespace
13531354
};
13541355

13551356
const node = nodes.find(node => node.name === 'svelte:options');

src/compiler/compile/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { CompileOptions, Warning } from '../interfaces';
66
import Component from './Component';
77
import fuzzymatch from '../utils/fuzzymatch';
88
import get_name_from_filename from './utils/get_name_from_filename';
9+
import { valid_namespaces } from '../utils/namespaces';
910

1011
const valid_options = [
1112
'format',
@@ -22,6 +23,7 @@ const valid_options = [
2223
'hydratable',
2324
'legacy',
2425
'customElement',
26+
'namespace',
2527
'tag',
2628
'css',
2729
'loopGuardTimeout',
@@ -30,7 +32,7 @@ const valid_options = [
3032
];
3133

3234
function validate_options(options: CompileOptions, warnings: Warning[]) {
33-
const { name, filename, loopGuardTimeout, dev } = options;
35+
const { name, filename, loopGuardTimeout, dev, namespace } = options;
3436

3537
Object.keys(options).forEach(key => {
3638
if (!valid_options.includes(key)) {
@@ -65,6 +67,15 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
6567
toString: () => message
6668
});
6769
}
70+
71+
if (namespace && valid_namespaces.indexOf(namespace) === -1) {
72+
const match = fuzzymatch(namespace, valid_namespaces);
73+
if (match) {
74+
throw new Error(`Invalid namespace '${namespace}' (did you mean '${match}'?)`);
75+
} else {
76+
throw new Error(`Invalid namespace '${namespace}'`);
77+
}
78+
}
6879
}
6980

7081
export default function compile(source: string, options: CompileOptions = {}) {

0 commit comments

Comments
 (0)