breaking: warn on self-closing non-void HTML tags (#11114)

* warn on self-closing non-void HTML tags

* fix tests

* changeset

* account for foreign namespace
pull/11223/head
Rich Harris 1 year ago committed by GitHub
parent 56654986a6
commit 42ce8d74e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
breaking: warn on self-closing non-void HTML tags

@ -15,7 +15,12 @@ import {
import { warn } from '../../warnings.js'; import { warn } from '../../warnings.js';
import fuzzymatch from '../1-parse/utils/fuzzymatch.js'; import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
import { binding_properties } from '../bindings.js'; import { binding_properties } from '../bindings.js';
import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js'; import {
ContentEditableBindings,
EventModifiers,
SVGElements,
VoidElements
} from '../constants.js';
import { is_custom_element_node } from '../nodes.js'; import { is_custom_element_node } from '../nodes.js';
import { import {
regex_illegal_attribute_character, regex_illegal_attribute_character,
@ -572,6 +577,21 @@ const validation = {
} }
} }
if (
context.state.analysis.source[node.end - 2] === '/' &&
context.state.options.namespace !== 'foreign' &&
!VoidElements.includes(node.name) &&
!SVGElements.includes(node.name)
) {
warn(
context.state.analysis.warnings,
node,
context.path,
'invalid-self-closing-tag',
node.name
);
}
context.next({ context.next({
...context.state, ...context.state,
parent_element: node.name parent_element: node.name

@ -250,6 +250,12 @@ const options = {
"The 'customElement' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?" "The 'customElement' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?"
}; };
const misc = {
/** @param {string} name */
'invalid-self-closing-tag': (name) =>
`Self-closing HTML tags for non-void elements are ambiguous — use <${name} ...></${name}> rather than <${name} ... />`
};
/** @satisfies {Warnings} */ /** @satisfies {Warnings} */
const warnings = { const warnings = {
...css, ...css,
@ -261,7 +267,8 @@ const warnings = {
...components, ...components,
...legacy, ...legacy,
...block, ...block,
...options ...options,
...misc
}; };
/** @typedef {typeof warnings} AllWarnings */ /** @typedef {typeof warnings} AllWarnings */

@ -5,7 +5,7 @@
<Nested> <Nested>
<div slot="slot1"> <div slot="slot1">
<div> <div>
<div slot="slot2" /> <div slot="slot2"></div>
</div> </div>
</div> </div>
</Nested> </Nested>

@ -5,7 +5,7 @@
<Nested> <Nested>
<div> <div>
<div> <div>
<div slot="slot2" /> <div slot="slot2"></div>
</div> </div>
</div> </div>
</Nested> </Nested>

@ -4,6 +4,6 @@
<Nested> <Nested>
<div slot="slot1"> <div slot="slot1">
<div slot="slot2" /> <div slot="slot2"></div>
</div> </div>
</Nested> </Nested>

@ -18,24 +18,24 @@
.c ~ .g { color: green; } .c ~ .g { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#await promise then value} {#await promise then value}
<div class="b" /> <div class="b"></div>
{:catch error} {:catch error}
<div class="c" /> <div class="c"></div>
{/await} {/await}
{#await promise} {#await promise}
<div class="d" /> <div class="d"></div>
{:catch error} {:catch error}
<div class="e" /> <div class="e"></div>
{/await} {/await}
{#await promise} {#await promise}
<div class="f" /> <div class="f"></div>
{:then error} {:then error}
<div class="g" /> <div class="g"></div>
{/await} {/await}
<div class="h" /> <div class="h"></div>

@ -17,14 +17,14 @@
.b ~ .d { color: green; } .b ~ .d { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#await promise} {#await promise}
<div class="b" /> <div class="b"></div>
{:then value} {:then value}
<div class="c" /> <div class="c"></div>
{:catch error} {:catch error}
<div class="d" /> <div class="d"></div>
{/await} {/await}
<div class="e" /> <div class="e"></div>

@ -27,11 +27,11 @@
} }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
<div class="c" /> <div class="c"></div>
{/each} {/each}
<div class="d" /> <div class="d"></div>

@ -35,43 +35,43 @@
.e ~ .f { color: green; } .e ~ .f { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as a} {#each array as a}
<div class="b" /> <div class="b"></div>
{#each array as b} {#each array as b}
<div class="c" /> <div class="c"></div>
{:else} {:else}
<div class="d" /> <div class="d"></div>
{/each} {/each}
{/each} {/each}
{#each array as c} {#each array as c}
{#each array as d} {#each array as d}
<div class="e" /> <div class="e"></div>
{/each} {/each}
{:else} {:else}
<div class="f" /> <div class="f"></div>
{/each} {/each}
{#each array as x} {#each array as x}
<div class="g" /> <div class="g"></div>
{#each array as y} {#each array as y}
{#each array as z} {#each array as z}
<div class="h" /> <div class="h"></div>
{/each} {/each}
{:else} {:else}
<div class="i" /> <div class="i"></div>
{/each} {/each}
<div class="j" /> <div class="j"></div>
{/each} {/each}
<div class="k" /> <div class="k"></div>
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="l" /> <div class="l"></div>
{:else} {:else}
<div class="m" /> <div class="m"></div>
{/each} {/each}
{/each} {/each}

@ -13,12 +13,12 @@
.b ~ .c { color: green; } .b ~ .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
{:else} {:else}
<div class="c" /> <div class="c"></div>
{/each} {/each}
<div class="d" /> <div class="d"></div>

@ -65,39 +65,39 @@
.g ~ .i { color: green; } .g ~ .i { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
<div class="c" /> <div class="c"></div>
{/each} {/each}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="d" /> <div class="d"></div>
{/each} {/each}
<div class="e" /> <div class="e"></div>
{/each} {/each}
<div class="f" /> <div class="f"></div>
{/each} {/each}
{#each array as item} {#each array as item}
<div class="g" /> <div class="g"></div>
{#each array as item} {#each array as item}
<div class="h" /> <div class="h"></div>
{#each array as item} {#each array as item}
<div class="i" /> <div class="i"></div>
{/each} {/each}
{/each} {/each}
{/each} {/each}
{#each array as item} {#each array as item}
<div class="j" /> <div class="j"></div>
{#each array as item} {#each array as item}
<div class="k" /> <div class="k"></div>
{#each array as item} {#each array as item}
<div class="l" /> <div class="l"></div>
{/each} {/each}
{/each} {/each}
{/each} {/each}
@ -105,9 +105,9 @@
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="m" /> <div class="m"></div>
{/each} {/each}
<div class="n" /> <div class="n"></div>
{/each} {/each}
<div class="o" /> <div class="o"></div>
{/each} {/each}

@ -8,13 +8,13 @@
} }
</style> </style>
<div /> <div></div>
{#each array as item} {#each array as item}
<span class="each" /> <span class="each"></span>
<div class="each" /> <div class="each"></div>
<span class="each" /> <span class="each"></span>
<div class="each" /> <div class="each"></div>
{/each} {/each}
<span /> <span></span>

@ -18,14 +18,14 @@
.b ~ .c { color: green; } .b ~ .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else} {:else}
{#each array as item} {#each array as item}
<div class="c" /> <div class="c"></div>
{/each} {/each}
{/if} {/if}
<div class="d" /> <div class="d"></div>

@ -14,12 +14,12 @@
.b ~ .c { color: green; } .b ~ .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else if bar} {:else if bar}
<div class="c" /> <div class="c"></div>
{/if} {/if}
<div class="d" /> <div class="d"></div>

@ -18,14 +18,14 @@
.c ~ .d { color: green; } .c ~ .d { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else if bar} {:else if bar}
<div class="c" /> <div class="c"></div>
{:else} {:else}
<div class="d" /> <div class="d"></div>
{/if} {/if}
<div class="e" /> <div class="e"></div>

@ -15,16 +15,16 @@
.b ~ .g { color: green; } .b ~ .g { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
<App> <App>
<div class="b" slot="a" /> <div class="b" slot="a"></div>
<div class="c" slot="b"> <div class="c" slot="b">
<div class="d" /> <div class="d"></div>
<div class="e" /> <div class="e"></div>
</div> </div>
<div class="f" slot="c" /> <div class="f" slot="c"></div>
</App> </App>
<div class="g" /> <div class="g"></div>

@ -8,10 +8,10 @@
</style> </style>
<div class="not-match"> <div class="not-match">
<div /> <div></div>
</div> </div>
<div class="match"> <div class="match">
<div /> <div></div>
<div /> <div></div>
</div> </div>

@ -16,9 +16,9 @@
</style> </style>
<div class="a"> <div class="a">
<span /> <span></span>
<b /> <b></b>
</div> </div>
<article class="b"></article> <article class="b"></article>
<p class="c"></p> <p class="c"></p>
<details class="d"></details> <details class="d"></details>

@ -5,5 +5,5 @@
</style> </style>
<div> <div>
<div /> <div></div>
</div> </div>

@ -5,5 +5,5 @@
</style> </style>
<div> <div>
<div /> <div></div>
</div> </div>

@ -1,4 +1,4 @@
<div /> <div></div>
<style> <style>
div { div {

@ -18,24 +18,24 @@
.c + .g { color: green; } .c + .g { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#await promise then value} {#await promise then value}
<div class="b" /> <div class="b"></div>
{:catch error} {:catch error}
<div class="c" /> <div class="c"></div>
{/await} {/await}
{#await promise} {#await promise}
<div class="d" /> <div class="d"></div>
{:catch error} {:catch error}
<div class="e" /> <div class="e"></div>
{/await} {/await}
{#await promise} {#await promise}
<div class="f" /> <div class="f"></div>
{:then error} {:then error}
<div class="g" /> <div class="g"></div>
{/await} {/await}
<div class="h" /> <div class="h"></div>

@ -17,14 +17,14 @@
.b + .d { color: green; } .b + .d { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#await promise} {#await promise}
<div class="b" /> <div class="b"></div>
{:then value} {:then value}
<div class="c" /> <div class="c"></div>
{:catch error} {:catch error}
<div class="d" /> <div class="d"></div>
{/await} {/await}
<div class="e" /> <div class="e"></div>

@ -28,11 +28,11 @@
} }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
<div class="c" /> <div class="c"></div>
{/each} {/each}
<div class="d" /> <div class="d"></div>

@ -32,43 +32,43 @@
.g + .h + .i + .j { color: green; } .g + .h + .i + .j { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as a} {#each array as a}
<div class="b" /> <div class="b"></div>
{#each array as b} {#each array as b}
<div class="c" /> <div class="c"></div>
{:else} {:else}
<div class="d" /> <div class="d"></div>
{/each} {/each}
{/each} {/each}
{#each array as c} {#each array as c}
{#each array as d} {#each array as d}
<div class="e" /> <div class="e"></div>
{/each} {/each}
{:else} {:else}
<div class="f" /> <div class="f"></div>
{/each} {/each}
{#each array as item} {#each array as item}
<div class="g" /> <div class="g"></div>
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="h" /> <div class="h"></div>
{/each} {/each}
{:else} {:else}
<div class="i" /> <div class="i"></div>
{/each} {/each}
<div class="j" /> <div class="j"></div>
{/each} {/each}
<div class="k" /> <div class="k"></div>
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="l" /> <div class="l"></div>
{:else} {:else}
<div class="m" /> <div class="m"></div>
{/each} {/each}
{/each} {/each}

@ -13,12 +13,12 @@
.b + .c { color: green; } .b + .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
{:else} {:else}
<div class="c" /> <div class="c"></div>
{/each} {/each}
<div class="d" /> <div class="d"></div>

@ -65,39 +65,39 @@
.g + .i { color: green; } .g + .i { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#each array as item} {#each array as item}
<div class="b" /> <div class="b"></div>
<div class="c" /> <div class="c"></div>
{/each} {/each}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="d" /> <div class="d"></div>
{/each} {/each}
<div class="e" /> <div class="e"></div>
{/each} {/each}
<div class="f" /> <div class="f"></div>
{/each} {/each}
{#each array as item} {#each array as item}
<div class="g" /> <div class="g"></div>
{#each array as item} {#each array as item}
<div class="h" /> <div class="h"></div>
{#each array as item} {#each array as item}
<div class="i" /> <div class="i"></div>
{/each} {/each}
{/each} {/each}
{/each} {/each}
{#each array as item} {#each array as item}
<div class="j" /> <div class="j"></div>
{#each array as item} {#each array as item}
<div class="k" /> <div class="k"></div>
{#each array as item} {#each array as item}
<div class="l" /> <div class="l"></div>
{/each} {/each}
{/each} {/each}
{/each} {/each}
@ -105,9 +105,9 @@
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
{#each array as item} {#each array as item}
<div class="m" /> <div class="m"></div>
{/each} {/each}
<div class="n" /> <div class="n"></div>
{/each} {/each}
<div class="o" /> <div class="o"></div>
{/each} {/each}

@ -8,13 +8,13 @@
} }
</style> </style>
<div /> <div></div>
{#each array as item} {#each array as item}
<span class="each" /> <span class="each"></span>
<div class="each" /> <div class="each"></div>
<span class="each" /> <span class="each"></span>
<div class="each" /> <div class="each"></div>
{/each} {/each}
<span /> <span></span>

@ -17,5 +17,5 @@
</div> </div>
{#each [] as _} {#each [] as _}
<p /> <p></p>
{/each} {/each}

@ -18,14 +18,14 @@
.b + .c { color: green; } .b + .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else} {:else}
{#each array as item} {#each array as item}
<div class="c" /> <div class="c"></div>
{/each} {/each}
{/if} {/if}
<div class="d" /> <div class="d"></div>

@ -14,12 +14,12 @@
.b + .c { color: green; } .b + .c { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else if bar} {:else if bar}
<div class="c" /> <div class="c"></div>
{/if} {/if}
<div class="d" /> <div class="d"></div>

@ -18,14 +18,14 @@
.c + .d { color: green; } .c + .d { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
{#if foo} {#if foo}
<div class="b" /> <div class="b"></div>
{:else if bar} {:else if bar}
<div class="c" /> <div class="c"></div>
{:else} {:else}
<div class="d" /> <div class="d"></div>
{/if} {/if}
<div class="e" /> <div class="e"></div>

@ -11,14 +11,14 @@
.c + .f { color: green; } .c + .f { color: green; }
</style> </style>
<div class="a" /> <div class="a"></div>
<App> <App>
<div class="b" slot="a" /> <div class="b" slot="a"></div>
<div class="c" slot="b"> <div class="c" slot="b">
<div class="d" /> <div class="d"></div>
<div class="e" /> <div class="e"></div>
</div> </div>
</App> </App>
<div class="f" /> <div class="f"></div>

@ -8,10 +8,10 @@
</style> </style>
<div class="not-match"> <div class="not-match">
<div /> <div></div>
</div> </div>
<div class="match"> <div class="match">
<div /> <div></div>
<div /> <div></div>
</div> </div>

@ -29,7 +29,7 @@
</style> </style>
<div class="a"> <div class="a">
<span /> <span></span>
<b /> <b></b>
</div> </div>
<article class="b"></article> <article class="b"></article>

@ -2,12 +2,12 @@
"html": { "html": {
"type": "Fragment", "type": "Fragment",
"start": 0, "start": 0,
"end": 11, "end": 16,
"children": [ "children": [
{ {
"type": "Element", "type": "Element",
"start": 0, "start": 0,
"end": 11, "end": 16,
"name": "div", "name": "div",
"attributes": [ "attributes": [
{ {

@ -1,6 +1,6 @@
<svelte:options customElement="custom-element" /> <svelte:options customElement="custom-element" />
<span class="icon" /> <span class="icon"></span>
<style> <style>
.icon::before { .icon::before {

@ -19,4 +19,4 @@
}); });
</script> </script>
<div bind:this={el} /> <div bind:this={el}></div>

@ -7,4 +7,4 @@
export let flagged = false; export let flagged = false;
</script> </script>
<my-widget class="foo" {items} flag1={flagged} flag2 /> <my-widget class="foo" {items} flag1={flagged} flag2></my-widget>

@ -14,7 +14,7 @@
<div>hi</div> <div>hi</div>
<p>hi</p> <p>hi</p>
<button on:click={() => (red = false)}>off</button> <button on:click={() => (red = false)}>off</button>
<my-widget {red} white /> <my-widget {red} white></my-widget>
<style> <style>
:host([red]) div { :host([red]) div {

@ -29,4 +29,4 @@
</script> </script>
<svelte:element this="{tag}" {name} id="a" /> <svelte:element this="{tag}" {name} id="a" />
<my-custom-element {name} id="b" /> <my-custom-element {name} id="b"></my-custom-element>

@ -7,4 +7,4 @@
}); });
</script> </script>
</svelte:head> </svelte:head>
<button /> <button></button>

@ -12,4 +12,4 @@
style="{foo}" style="{foo}"
style:background-color="{bg}en" style:background-color="{bg}en"
style:border-color={borderColor} style:border-color={borderColor}
/> ></p>

@ -2,4 +2,4 @@
export let backgroundColor = 255; export let backgroundColor = 255;
</script> </script>
<div style:background-color="rgb({backgroundColor}, 0, 0)" {...$$restProps} /> <div style:background-color="rgb({backgroundColor}, 0, 0)" {...$$restProps}></div>

@ -18,7 +18,7 @@
node.addEventListener('mouseenter', onMouseEnter); node.addEventListener('mouseenter', onMouseEnter);
node.addEventListener('mouseleave', onMouseLeave); node.addEventListener('mouseleave', onMouseLeave);
return { return {
destroy() { destroy() {
node.removeEventListener('mouseenter', onMouseEnter); node.removeEventListener('mouseenter', onMouseEnter);
@ -29,4 +29,4 @@
</script> </script>
<svelte:body use:tooltip="{'Perform an Action'}" /> <svelte:body use:tooltip="{'Perform an Action'}" />
<div bind:this={container} /> <div bind:this={container}></div>

@ -21,4 +21,4 @@
</script> </script>
<svelte:document use:tooltip="{'Perform an Action'}" /> <svelte:document use:tooltip="{'Perform an Action'}" />
<div bind:this={container} /> <div bind:this={container}></div>

@ -4,9 +4,9 @@ export default test({
get props() { get props() {
return { hidden: true }; return { hidden: true };
}, },
html: '<div hidden />', html: '<div hidden></div>',
test({ assert, component, target }) { test({ assert, component, target }) {
component.hidden = false; component.hidden = false;
assert.htmlEqual(target.innerHTML, '<div />'); assert.htmlEqual(target.innerHTML, '<div></div>');
} }
}); });

@ -2,4 +2,4 @@
export let hidden = false; export let hidden = false;
</script> </script>
<div {hidden} /> <div {hidden}></div>

@ -1,4 +1,4 @@
<page horizontalAlignment="center"> <page horizontalAlignment="center">
<button textWrap="true" text="button" /> <button textWrap="true" text="button"></button>
<text wordWrap="true" /> <text wordWrap="true" />
</page> </page>

@ -16,7 +16,7 @@
<span itemprop="ratingValue">4.6</span> ( <span itemprop="ratingValue">4.6</span> (
<span itemprop="ratingCount">8864</span> ratings ) <span itemprop="ratingCount">8864</span> ratings )
</div> </div>
<div itemref="offers" /> <div itemref="offers"></div>
</div> </div>
<div <div

@ -8,6 +8,6 @@
} }
</script> </script>
<button on:click={change} /> <button on:click={change}></button>
<input type="range" min="0" {max} bind:value /> <input type="range" min="0" {max} bind:value />
<p>{value} of {max}</p> <p>{value} of {max}</p>

@ -13,5 +13,5 @@
</script> </script>
{#each refs as xxx} {#each refs as xxx}
<div bind:this={xxx.ref} /> <div bind:this={xxx.ref}></div>
{/each} {/each}

@ -6,4 +6,4 @@
$: paths && logs.push('paths updated'); $: paths && logs.push('paths updated');
</script> </script>
<div bind:this={container[paths[0]]} /> <div bind:this={container[paths[0]]}></div>

@ -8,4 +8,4 @@
}); });
</script> </script>
<div id="target" /> <div id="target"></div>

@ -11,4 +11,4 @@
} }
} }
</script> </script>
<button on:click={click} /> <button on:click={click}></button>

@ -5,4 +5,4 @@
export const exists = true; export const exists = true;
</script> </script>
<button on:click={() => dispatch('bar')} /> <button on:click={() => dispatch('bar')}></button>

@ -7,5 +7,5 @@
</script> </script>
<Outer {prop} let:value> <Outer {prop} let:value>
<Inner><button on:click={() => { log(value); }} /></Inner> <Inner><button on:click={() => { log(value); }}></button></Inner>
</Outer> </Outer>

@ -12,4 +12,4 @@
} }
</script> </script>
<div use:render /> <div use:render></div>

@ -8,10 +8,10 @@
const array = [each_action]; const array = [each_action];
</script> </script>
<div use:action={collect} /> <div use:action={collect}></div>
<ul> <ul>
{#each array as action} {#each array as action}
<div use:action={collect} /> <div use:action={collect}></div>
{/each} {/each}
</ul> </ul>

@ -4,4 +4,4 @@
<svelte:document bind:fullscreenElement={fullscreen}/> <svelte:document bind:fullscreenElement={fullscreen}/>
<div /> <div></div>

@ -2,4 +2,4 @@
export let action; export let action;
</script> </script>
<div use:action /> <div use:action></div>

@ -2,6 +2,6 @@ import { test } from '../../test';
export default test({ export default test({
html: ` html: `
<div>'foo'<span/></div> <div>'foo'<span></span></div>
` `
}); });

@ -2,4 +2,4 @@
export let color = 'red'; export let color = 'red';
</script> </script>
<p style="height: 40px; color: blue;" style:color={color} /> <p style="height: 40px; color: blue;" style:color={color}></p>

@ -2,4 +2,4 @@
export let color = 'red'; export let color = 'red';
</script> </script>
<p style="height: 40px;" style:color={color} /> <p style="height: 40px;" style:color={color}></p>

@ -2,4 +2,4 @@
export let myColor = "red"; export let myColor = "red";
</script> </script>
<p style:--border-color={myColor} /> <p style:--border-color={myColor}></p>

@ -2,4 +2,4 @@
export let myColor = "red"; export let myColor = "red";
</script> </script>
<p style:color={myColor} /> <p style:color={myColor}></p>

@ -2,4 +2,4 @@
export let attack = '" onload="alert(\'uhoh\')" data-nothing="not important'; export let attack = '" onload="alert(\'uhoh\')" data-nothing="not important';
</script> </script>
<div style:--css-variable={attack} /> <div style:--css-variable={attack}></div>

@ -2,8 +2,8 @@
export let color = "red"; export let color = "red";
</script> </script>
<p style:color /> <p style:color></p>
{#each [1] as _} {#each [1] as _}
<p style:color /> <p style:color></p>
{/each} {/each}

@ -2,4 +2,4 @@
export let color = 'blue'; export let color = 'blue';
export let obj = { id: 'my-id', style: 'width: 65px' }; export let obj = { id: 'my-id', style: 'width: 65px' };
</script> </script>
<p {...obj} style:color={color} /> <p {...obj} style:color={color}></p>

@ -1 +1 @@
<p {...{ id: "my-id", style: "width: 65px" }} style:color="blue" /> <p {...{ id: "my-id", style: "width: 65px" }} style:color="blue"></p>

@ -4,4 +4,4 @@
export let border_color; export let border_color;
</script> </script>
<p style:color={"green"} style:transform="translateX({translate_x})" style:border="{border_width}px solid {border_color || 'pink'}" /> <p style:color={"green"} style:transform="translateX({translate_x})" style:border="{border_width}px solid {border_color || 'pink'}"></p>

@ -9,4 +9,4 @@
} }
</script> </script>
<p style:font-size="{settings.fontSize}px" style="background-color: {settings.bg}" /> <p style:font-size="{settings.fontSize}px" style="background-color: {settings.bg}"></p>

@ -3,5 +3,5 @@
</script> </script>
<div> <div>
<p style:color={myColor} /> <p style:color={myColor}></p>
</div> </div>

@ -3,5 +3,5 @@
</script> </script>
{#key value} {#key value}
<div /> <div></div>
{/key} {/key}

@ -9,4 +9,4 @@
<div>Length: {length}</div> <div>Length: {length}</div>
<div>Values: {values.join(',')}</div> <div>Values: {values.join(',')}</div>
<div {...$$restProps} /> <div {...$$restProps}></div>

@ -9,5 +9,5 @@
<div>Length: {length}</div> <div>Length: {length}</div>
<div>Values: {values.join(',')}</div> <div>Values: {values.join(',')}</div>
<div {...$$restProps} /> <div {...$$restProps}></div>
<div {...$$props} /> <div {...$$props}></div>

@ -21,4 +21,4 @@
$b = { foo: $b.foo + 1, baz: 0 }; $b = { foo: $b.foo + 1, baz: 0 };
}} /> }} />
<button on:click={update} /> <button on:click={update}></button>

@ -15,4 +15,4 @@
}); });
</script> </script>
<div bind:this={div} /> <div bind:this={div}></div>

@ -16,4 +16,4 @@
}); });
</script> </script>
<div bind:this={div} /> <div bind:this={div}></div>

@ -1,2 +1,2 @@
<button on:click="{() => { this.x = 1; }}" /> <button on:click="{() => { this.x = 1; }}"></button>
<button on:click="{function () { this.x = 1; }}" /> <button on:click="{function () { this.x = 1; }}"></button>

@ -15,11 +15,11 @@
</script> </script>
{#if visible} {#if visible}
<div id="both-in" transition:foo /> <div id="both-in" transition:foo></div>
<div id="in" in:foo /> <div id="in" in:foo></div>
{/if} {/if}
{#if !visible} {#if !visible}
<div id="out" out:foo /> <div id="out" out:foo></div>
<div id="both-out" transition:foo={{ duration: 500 }} /> <div id="both-out" transition:foo={{ duration: 500 }}></div>
{/if} {/if}

@ -11,8 +11,8 @@
let bool = true; let bool = true;
</script> </script>
<button on:click={() => (condition = false)} /> <button on:click={() => (condition = false)}></button>
<button on:click={() => (bool = !bool)} /> <button on:click={() => (bool = !bool)}></button>
{#if bool} {#if bool}
<div out:foo /> <div out:foo></div>
{/if} {/if}

@ -12,7 +12,7 @@
let bool = true; let bool = true;
</script> </script>
<button on:click={() => (bool = !bool)} /> <button on:click={() => (bool = !bool)}></button>
{#if bool} {#if bool}
<div out:foo /> <div out:foo></div>
{/if} {/if}

@ -5,6 +5,6 @@
</script> </script>
{#if $condition} {#if $condition}
<button on:click={() => ($condition = false)} id="1" /> <button on:click={() => ($condition = false)} id="1"></button>
<Component {condition} /> <Component {condition} />
{/if} {/if}

@ -4,6 +4,6 @@
let c = 3; let c = 3;
</script> </script>
<div class="{a}{b}{c}" /> <div class="{a}{b}{c}"></div>
<img src="{a}{b} hello, world {a}{c}" /> <img src="{a}{b} hello, world {a}{c}" />

@ -12,10 +12,10 @@
<!-- these will yield TypeScript errors, because it looks like e.g. `nested.with - string`, <!-- these will yield TypeScript errors, because it looks like e.g. `nested.with - string`,
in other words a number. Relatedly, people should not do this. It is stupid. --> in other words a number. Relatedly, people should not do this. It is stupid. -->
<div use:directive.b.c-d /> <div use:directive.b.c-d></div>
<div transition:directive.b.c-d /> <div transition:directive.b.c-d></div>
{#each [] as i (i)} {#each [] as i (i)}
<div animate:directive.b.c-d /> <div animate:directive.b.c-d></div>
{/each} {/each}
<div in:directive.b.c-d /> <div in:directive.b.c-d></div>
<div out:directive.b.c-d /> <div out:directive.b.c-d></div>

@ -2,4 +2,4 @@
export let id = null; export let id = null;
</script> </script>
<div {id} {...$$restProps} /> <div {id} {...$$restProps}></div>

@ -8,9 +8,9 @@
<input aria-activedescendant="some-id" tabindex={-1} /> <input aria-activedescendant="some-id" tabindex={-1} />
<input aria-activedescendant="some-id" tabindex="-1" /> <input aria-activedescendant="some-id" tabindex="-1" />
<svelte:element this={Math.random() ? 'input' : 'button'} aria-activedescendant="some-id" /> <svelte:element this={Math.random() ? 'input' : 'button'} aria-activedescendant="some-id" />
<div /> <div></div>
<div aria-activedescendant="some-id" role="tablist" tabindex={-1} /> <div aria-activedescendant="some-id" role="tablist" tabindex={-1}></div>
<div aria-activedescendant="some-id" role="tablist" tabindex="-1" /> <div aria-activedescendant="some-id" role="tablist" tabindex="-1"></div>
<!-- INVALID --> <!-- INVALID -->
<div aria-activedescendant="some-id" /> <div aria-activedescendant="some-id"></div>

@ -2,7 +2,7 @@
const abc = 'abc'; const abc = 'abc';
</script> </script>
<button aria-disabled="yes"/> <button aria-disabled="yes"></button>
<button aria-disabled="no"/> <button aria-disabled="no"></button>
<button aria-disabled={1234}/> <button aria-disabled={1234}></button>
<button aria-disabled={`${abc}`}/> <button aria-disabled={`${abc}`}></button>

@ -1,7 +1,7 @@
<div aria-level="yes" /> <div aria-level="yes"></div>
<div aria-level="no" /> <div aria-level="no"></div>
<div aria-level={`abc`} /> <div aria-level={`abc`}></div>
<div aria-level={true} /> <div aria-level={true}></div>
<div aria-level /> <div aria-level></div>
<div aria-level={"false"} /> <div aria-level={"false"}></div>
<div aria-level={!"false"} /> <div aria-level={!"false"}></div>

@ -1,7 +1,7 @@
<div aria-valuemax="yes" /> <div aria-valuemax="yes"></div>
<div aria-valuemax="no" /> <div aria-valuemax="no"></div>
<div aria-valuemax={`abc`} /> <div aria-valuemax={`abc`}></div>
<div aria-valuemax={true} /> <div aria-valuemax={true}></div>
<div aria-valuemax /> <div aria-valuemax></div>
<div aria-valuemax={'false'} /> <div aria-valuemax={'false'}></div>
<div aria-valuemax={!'false'} /> <div aria-valuemax={!'false'}></div>

@ -1,5 +1,5 @@
<div aria-label /> <div aria-label></div>
<div aria-label={true} /> <div aria-label={true}></div>
<div aria-label={false} /> <div aria-label={false}></div>
<div aria-label={1234} /> <div aria-label={1234}></div>
<div aria-label={!true} /> <div aria-label={!true}></div>

@ -1,6 +1,6 @@
<div aria-sort="" /> <div aria-sort=""></div>
<div aria-sort="incorrect" /> <div aria-sort="incorrect"></div>
<div aria-sort /> <div aria-sort></div>
<div aria-sort={true} /> <div aria-sort={true}></div>
<div aria-sort={"false"} /> <div aria-sort={"false"}></div>
<div aria-sort="ascending descending" /> <div aria-sort="ascending descending"></div>

@ -1,7 +1,7 @@
<div aria-relevant="" /> <div aria-relevant=""></div>
<div aria-relevant="foobar" /> <div aria-relevant="foobar"></div>
<div aria-relevant /> <div aria-relevant></div>
<div aria-relevant={true} /> <div aria-relevant={true}></div>
<div aria-relevant={"false"} /> <div aria-relevant={"false"}></div>
<div aria-relevant="additions removals_" /> <div aria-relevant="additions removals_"></div>
<div aria-relevant="additions removals_ " /> <div aria-relevant="additions removals_ "></div>

@ -2,7 +2,7 @@
const abc = 'abc'; const abc = 'abc';
</script> </script>
<div aria-checked="yes" /> <div aria-checked="yes"></div>
<div aria-checked="no" /> <div aria-checked="no"></div>
<div aria-checked={1234} /> <div aria-checked={1234}></div>
<div aria-checked={`${abc}`} /> <div aria-checked={`${abc}`}></div>

@ -10,65 +10,65 @@
<!-- should warn --> <!-- should warn -->
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} /> <div on:click={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} aria-hidden="false" /> <div on:click={noop} aria-hidden="false"></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<section on:click={noop} /> <section on:click={noop}></section>
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<main on:click={noop} /> <main on:click={noop}></main>
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<article on:click={noop} /> <article on:click={noop}></article>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<header on:click={noop} /> <header on:click={noop}></header>
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<footer on:click={noop} /> <footer on:click={noop}></footer>
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<footer onclick={noop} /> <footer onclick={noop}></footer>
<!-- should not warn --> <!-- should not warn -->
<div class="foo" /> <div class="foo"></div>
<a href="http://x.y.z" on:click={noop}>foo</a> <a href="http://x.y.z" on:click={noop}>foo</a>
<button on:click={noop} /> <button on:click={noop}></button>
<select on:click={noop} /> <select on:click={noop}></select>
<input type="button" on:click={noop} /> <input type="button" on:click={noop} />
<input type={dynamicTypeValue} on:click={noop} /> <input type={dynamicTypeValue} on:click={noop} />
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} {...props} /> <div on:click={noop} {...props}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keydown={noop} /> <div on:click={noop} on:keydown={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keyup={noop} /> <div on:click={noop} on:keyup={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keypress={noop} /> <div on:click={noop} on:keypress={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keydown={noop} on:keyup={noop} /> <div on:click={noop} on:keydown={noop} on:keyup={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keyup={noop} on:keypress={noop} /> <div on:click={noop} on:keyup={noop} on:keypress={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keypress={noop} on:keydown={noop} /> <div on:click={noop} on:keypress={noop} on:keydown={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} on:keydown={noop} on:keyup={noop} on:keypress={noop} /> <div on:click={noop} on:keydown={noop} on:keyup={noop} on:keypress={noop}></div>
<input on:click={noop} type="hidden" /> <input on:click={noop} type="hidden" />
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} aria-hidden /> <div on:click={noop} aria-hidden></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} aria-hidden="true" /> <div on:click={noop} aria-hidden="true"></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} aria-hidden="false" on:keydown={noop} /> <div on:click={noop} aria-hidden="false" on:keydown={noop}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:click={noop} aria-hidden={dynamicAriaHiddenValue} /> <div on:click={noop} aria-hidden={dynamicAriaHiddenValue}></div>
<div on:click={noop} role="presentation" /> <div on:click={noop} role="presentation"></div>
<div on:click={noop} role="none" /> <div on:click={noop} role="none"></div>
<div on:click={noop} role={dynamicRole} /> <div on:click={noop} role={dynamicRole}></div>
<div onclick={noop} role={dynamicRole} /> <div onclick={noop} role={dynamicRole}></div>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<svelte:element this={Math.random() ? 'button' : 'div'} on:click={noop} /> <svelte:element this={Math.random() ? 'button' : 'div'} on:click={noop} />

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save