Skip to content

Commit f48001a

Browse files
fix: check for invalid bindings on window and document (#11676)
Fixes #11673
1 parent b788b72 commit f48001a

File tree

7 files changed

+86
-11
lines changed

7 files changed

+86
-11
lines changed

.changeset/plenty-elephants-fry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: check for invalid bindings on window and document

packages/svelte/src/compiler/phases/2-analyze/validation.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,23 @@ const validation = {
393393
);
394394
}
395395

396+
if (property.invalid_elements && property.invalid_elements.includes(parent.name)) {
397+
const valid_bindings = Object.entries(binding_properties)
398+
.filter(([_, binding_property]) => {
399+
return (
400+
binding_property.valid_elements?.includes(parent.name) ||
401+
(!binding_property.valid_elements &&
402+
!binding_property.invalid_elements?.includes(parent.name))
403+
);
404+
})
405+
.map(([property_name]) => property_name);
406+
e.bind_invalid_name(
407+
node,
408+
node.name,
409+
`Possible bindings for <${parent.name}> are ${valid_bindings.join(', ')}`
410+
);
411+
}
412+
396413
if (parent.name === 'input' && node.name !== 'this') {
397414
const type = /** @type {import('#compiler').Attribute | undefined} */ (
398415
parent.attributes.find((a) => a.type === 'Attribute' && a.name === 'type')

packages/svelte/src/compiler/phases/bindings.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* @property {string} [type] Set this to `set` if updates are written to the dom property
66
* @property {boolean} [omit_in_ssr] Set this to true if the binding should not be included in SSR
77
* @property {string[]} [valid_elements] If this is set, the binding is only valid on the given elements
8+
* @property {string[]} [invalid_elements] If this is set, the binding is invalid on the given elements
89
*/
910

1011
/**
@@ -131,28 +132,36 @@ export const binding_properties = {
131132
},
132133
// dimensions
133134
clientWidth: {
134-
omit_in_ssr: true
135+
omit_in_ssr: true,
136+
invalid_elements: ['svelte:window', 'svelte:document']
135137
},
136138
clientHeight: {
137-
omit_in_ssr: true
139+
omit_in_ssr: true,
140+
invalid_elements: ['svelte:window', 'svelte:document']
138141
},
139142
offsetWidth: {
140-
omit_in_ssr: true
143+
omit_in_ssr: true,
144+
invalid_elements: ['svelte:window', 'svelte:document']
141145
},
142146
offsetHeight: {
143-
omit_in_ssr: true
147+
omit_in_ssr: true,
148+
invalid_elements: ['svelte:window', 'svelte:document']
144149
},
145150
contentRect: {
146-
omit_in_ssr: true
151+
omit_in_ssr: true,
152+
invalid_elements: ['svelte:window', 'svelte:document']
147153
},
148154
contentBoxSize: {
149-
omit_in_ssr: true
155+
omit_in_ssr: true,
156+
invalid_elements: ['svelte:window', 'svelte:document']
150157
},
151158
borderBoxSize: {
152-
omit_in_ssr: true
159+
omit_in_ssr: true,
160+
invalid_elements: ['svelte:window', 'svelte:document']
153161
},
154162
devicePixelContentBoxSize: {
155-
omit_in_ssr: true
163+
omit_in_ssr: true,
164+
invalid_elements: ['svelte:window', 'svelte:document']
156165
},
157166
// checkbox/radio
158167
indeterminate: {
@@ -171,9 +180,15 @@ export const binding_properties = {
171180
this: {
172181
omit_in_ssr: true
173182
},
174-
innerText: {},
175-
innerHTML: {},
176-
textContent: {},
183+
innerText: {
184+
invalid_elements: ['svelte:window', 'svelte:document']
185+
},
186+
innerHTML: {
187+
invalid_elements: ['svelte:window', 'svelte:document']
188+
},
189+
textContent: {
190+
invalid_elements: ['svelte:window', 'svelte:document']
191+
},
177192
open: {
178193
event: 'toggle',
179194
type: 'set',
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "bind_invalid_name",
4+
"message": "`bind:clientWidth` is not a valid binding. Possible bindings for <svelte:document> are focused, fullscreenElement, visibilityState, this",
5+
"start": {
6+
"line": 5,
7+
"column": 17
8+
},
9+
"end": {
10+
"line": 5,
11+
"column": 39
12+
}
13+
}
14+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let foo;
3+
</script>
4+
5+
<svelte:document bind:clientWidth={foo} />
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "bind_invalid_name",
4+
"message": "`bind:clientWidth` is not a valid binding. Possible bindings for <svelte:window> are focused, innerWidth, innerHeight, outerWidth, outerHeight, scrollX, scrollY, online, devicePixelRatio, this",
5+
"start": {
6+
"line": 5,
7+
"column": 15
8+
},
9+
"end": {
10+
"line": 5,
11+
"column": 37
12+
}
13+
}
14+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let foo;
3+
</script>
4+
5+
<svelte:window bind:clientWidth={foo} />

0 commit comments

Comments
 (0)