Skip to content

Commit 6534aa0

Browse files
fix: Add check for builtin custom elements in set_custom_element_data (#16592)
Fixes #16591 This PR introduces a check for builtin custom elements (is attribute) inside the set_custom_element_data helper in order to correctly set properties that have a setter.
1 parent 7105736 commit 6534aa0

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

.changeset/fuzzy-shrimps-dream.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: Add check for builtin custom elements in `set_custom_element_data`

packages/svelte/src/internal/client/dom/elements/attributes.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ export function set_custom_element_data(node, prop, value) {
238238
// Don't compute setters for custom elements while they aren't registered yet,
239239
// because during their upgrade/instantiation they might add more setters.
240240
// Instead, fall back to a simple "an object, then set as property" heuristic.
241-
(setters_cache.has(node.nodeName) ||
241+
(setters_cache.has(node.getAttribute('is') || node.nodeName) ||
242242
// customElements may not be available in browser extension contexts
243243
!customElements ||
244-
customElements.get(node.tagName.toLowerCase())
244+
customElements.get(node.getAttribute('is') || node.tagName.toLowerCase())
245245
? get_setters(node).includes(prop)
246246
: value && typeof value === 'object')
247247
) {
@@ -546,9 +546,10 @@ var setters_cache = new Map();
546546

547547
/** @param {Element} element */
548548
function get_setters(element) {
549-
var setters = setters_cache.get(element.nodeName);
549+
var cache_key = element.getAttribute('is') || element.nodeName;
550+
var setters = setters_cache.get(cache_key);
550551
if (setters) return setters;
551-
setters_cache.set(element.nodeName, (setters = []));
552+
setters_cache.set(cache_key, (setters = []));
552553

553554
var descriptors;
554555
var proto = element; // In the case of custom elements there might be setters on the instance

packages/svelte/tests/runtime-runes/samples/custom-element-attributes/_config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@ export default test({
2020
const [value1, value2] = target.querySelectorAll('value-element');
2121
assert.equal(value1.shadowRoot?.innerHTML, '<span>test</span>');
2222
assert.equal(value2.shadowRoot?.innerHTML, '<span>test</span>');
23+
24+
const value_builtin = target.querySelector('div');
25+
assert.equal(value_builtin?.shadowRoot?.innerHTML, '<span>test</span>');
2326
}
2427
});

packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,29 @@
1515
}
1616
});
1717
}
18+
if(!customElements.get('value-builtin')) {
19+
customElements.define('value-builtin', class extends HTMLDivElement {
20+
21+
constructor() {
22+
super();
23+
this.attachShadow({ mode: 'open' });
24+
}
25+
26+
set value(v) {
27+
if (this.__value !== v) {
28+
this.__value = v;
29+
this.shadowRoot.innerHTML = `<span>${v}</span>`;
30+
}
31+
}
32+
}, {
33+
extends: 'div'
34+
});
35+
}
1836
</script>
1937

2038
<my-element string="test" object={{ test: true }}></my-element>
2139
<a is="my-link" string="test" object={{ test: true }}></a>
2240

2341
<value-element value="test"></value-element>
2442
<value-element {...{value: "test"}}></value-element>
43+
<div is="value-builtin" value="test"></div>

0 commit comments

Comments
 (0)