Skip to content

Commit f27f681

Browse files
committed
Prevent element property set from throwing errors for readonly properties. Fixes sveltejs#3681.
1 parent 30bf5fe commit f27f681

File tree

8 files changed

+61
-2
lines changed

8 files changed

+61
-2
lines changed

src/runtime/internal/dev.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { custom_event, append, insert, detach, listen, attr } from './dom';
1+
import { custom_event, append, insert, detach, listen, attr, set_attributes } from './dom';
22
import { SvelteComponent } from './Component';
33

44
export function dispatch_dev<T=any>(type: string, detail?: T) {
@@ -59,6 +59,14 @@ export function attr_dev(node: Element, attribute: string, value?: string) {
5959
else dispatch_dev("SvelteDOMSetAttribute", { node, attribute, value });
6060
}
6161

62+
export function set_attributes_dev(node: Element & ElementCSSInlineStyle, attributes: { [x: string]: string }) {
63+
for (const key in attributes) {
64+
if (!(key in node))
65+
console.warn(`Property "${key}" does not exist on ${node.nodeName}. When spreading attributes, ensure they are all valid attributes for that element.`);
66+
}
67+
set_attributes(node, attributes);
68+
}
69+
6270
export function prop_dev(node: Element, property: string, value?: any) {
6371
node[property] = value;
6472

src/runtime/internal/dom.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,13 @@ export function attr(node: Element, attribute: string, value?: string) {
9090
}
9191

9292
export function set_attributes(node: Element & ElementCSSInlineStyle, attributes: { [x: string]: string }) {
93+
let a;
9394
for (const key in attributes) {
9495
if (key === 'style') {
9596
node.style.cssText = attributes[key];
96-
} else if (key in node) {
97+
} else if (
98+
//@ts-ignore
99+
((a = Object.getOwnPropertyDescriptor(node.__proto__, key))) && a.set) {
97100
node[key] = attributes[key];
98101
} else {
99102
attr(node, key, attributes[key]);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default {
2+
skip_if_ssr: true,
3+
compileOptions: {
4+
dev: true
5+
},
6+
7+
warnings: [
8+
`Property "boohoo" does not exist on INPUT. When spreading attributes, ensure they are all valid attributes for that element.`,
9+
`Property "spigidilly" does not exist on INPUT. When spreading attributes, ensure they are all valid attributes for that element.`
10+
]
11+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script>
2+
const props = {
3+
boohoo: 'foo',
4+
spigidilly: 'bar',
5+
};
6+
</script>
7+
8+
<input {...props} />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default {
2+
3+
skip_if_ssr: true, // DOM and SSR output is different, a separate SSR test exists
4+
html: `<input form="qux" list="quu" />`,
5+
6+
test({ assert, target }) {
7+
const div = target.querySelector('input');
8+
assert.equal(div.value, 'bar');
9+
}
10+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
let props = {
3+
value: 'bar',
4+
form: 'qux',
5+
list: 'quu',
6+
};
7+
</script>
8+
9+
<input {...props} />
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<input value="bar" form="qux" list="quu" />
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
let props = {
3+
value: 'bar',
4+
form: 'qux',
5+
list: 'quu',
6+
};
7+
</script>
8+
9+
<input {...props} />

0 commit comments

Comments
 (0)