warn on duplicates

svelte-html
Simon Holthausen 10 months ago
parent d61291e752
commit a88e8148a7

@ -17,3 +17,11 @@ The following properties cannot be cloned with `$state.snapshot` — the return
%properties%
```
### svelte_html_duplicate_attribute
```
Duplicate attribute '%name%' across multiple `<svelte:html>` blocks, the latest value will be used.
```
This warning appears when you have multiple `<svelte:html>` blocks across several files, and they set the same attribute. In that case, the latest value wins. On the server and on the client for static attributes, that's the last occurence of the attribute. On the client for dynamic attributes that's the value which was updated last across all `<svelte:html>` blocks.

@ -9,3 +9,9 @@
> The following properties cannot be cloned with `$state.snapshot` — the return value contains the originals:
>
> %properties%
## svelte_html_duplicate_attribute
> Duplicate attribute '%name%' across multiple `<svelte:html>` blocks, the latest value will be used.
This warning appears when you have multiple `<svelte:html>` blocks across several files, and they set the same attribute. In that case, the latest value wins. On the server and on the client for static attributes, that's the last occurence of the attribute. On the client for dynamic attributes that's the value which was updated last across all `<svelte:html>` blocks.

@ -47,6 +47,12 @@ export function SvelteHTML(element, context) {
} else {
context.state.init.push(update);
}
if (context.state.options.dev) {
context.state.init.push(
b.stmt(b.call('$.validate_svelte_html_attribute', b.literal(name)))
);
}
}
}
}

@ -2,9 +2,10 @@ import { dev_current_component_function } from './runtime.js';
import { get_descriptor, is_array } from '../shared/utils.js';
import * as e from './errors.js';
import { FILENAME } from '../../constants.js';
import { render_effect } from './reactivity/effects.js';
import { render_effect, teardown } from './reactivity/effects.js';
import * as w from './warnings.js';
import { capture_store_binding } from './reactivity/store.js';
import { svelte_html_duplicate_attribute } from '../shared/warnings.js';
/**
* @param {() => any} collection
@ -104,3 +105,27 @@ export function validate_binding(binding, get_object, get_property, line, column
}
});
}
let svelte_html_attributes = new Map();
/**
* @param {string} name
*/
export function validate_svelte_html_attribute(name) {
const count = svelte_html_attributes.get(name) || 0;
if (count > 0) {
svelte_html_duplicate_attribute(name);
}
svelte_html_attributes.set(name, count + 1);
teardown(() => {
const count = svelte_html_attributes.get(name) || 1;
if (count === 1) {
svelte_html_attributes.delete(name);
} else {
svelte_html_attributes.set(name, count - 1);
}
});
}

@ -1,6 +1,7 @@
/** @import { Payload } from '#server' */
import { escape_html } from '../../../escaping.js';
import { svelte_html_duplicate_attribute } from '../../shared/warnings.js';
/**
* @param {Payload} payload
@ -8,6 +9,9 @@ import { escape_html } from '../../../escaping.js';
*/
export function svelte_html(payload, attributes) {
for (const name in attributes) {
if (payload.htmlAttributes.has(name)) {
svelte_html_duplicate_attribute(name);
}
payload.htmlAttributes.set(name, escape_html(attributes[name], true));
}
}

@ -35,4 +35,17 @@ ${properties}`
// TODO print a link to the documentation
console.warn("state_snapshot_uncloneable");
}
}
/**
* Duplicate attribute '%name%' across multiple `<svelte:html>` blocks, the latest value will be used.
* @param {string} name
*/
export function svelte_html_duplicate_attribute(name) {
if (DEV) {
console.warn(`%c[svelte] svelte_html_duplicate_attribute\n%cDuplicate attribute '${name}' across multiple \`<svelte:html>\` blocks, the latest value will be used.`, bold, normal);
} else {
// TODO print a link to the documentation
console.warn("svelte_html_duplicate_attribute");
}
}
Loading…
Cancel
Save