From 0031b2d1d7e1755d87e564759687159eab1c5c69 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 29 Nov 2023 17:23:15 +0100 Subject: [PATCH] fix: port over props that were set prior to initialization Svelte 5 version of #9701 --- .changeset/hungry-tips-unite.md | 5 ++++ .../src/internal/client/custom-element.js | 10 ++++++++ .../set-property-before-mounted/_config.js | 25 +++++++++++++++++++ .../set-property-before-mounted/main.svelte | 5 ++++ 4 files changed, 45 insertions(+) create mode 100644 .changeset/hungry-tips-unite.md create mode 100644 packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/_config.js create mode 100644 packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/main.svelte diff --git a/.changeset/hungry-tips-unite.md b/.changeset/hungry-tips-unite.md new file mode 100644 index 000000000000..b138fd409d53 --- /dev/null +++ b/.changeset/hungry-tips-unite.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: port over props that were set prior to initialization diff --git a/packages/svelte/src/internal/client/custom-element.js b/packages/svelte/src/internal/client/custom-element.js index ded94b616d65..bafdbc00f36a 100644 --- a/packages/svelte/src/internal/client/custom-element.js +++ b/packages/svelte/src/internal/client/custom-element.js @@ -127,6 +127,16 @@ if (typeof HTMLElement === 'function') { this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, 'toProp'); } } + // Port over props that were set programmatically before ce was initialized + for (const key in this.$$p_d) { + // @ts-expect-error + if (!(key in this.$$d) && this[key] !== undefined) { + // @ts-expect-error + this.$$d[key] = this[key]; // don't transform, these were set through JavaScript + // @ts-expect-error + delete this[key]; // remove the property that shadows the getter/setter + } + } this.$$c = createClassComponent({ component: this.$$ctor, target: this.shadowRoot || this, diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/_config.js b/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/_config.js new file mode 100644 index 000000000000..843e16452216 --- /dev/null +++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/_config.js @@ -0,0 +1,25 @@ +import { test } from '../../assert'; + +const tick = () => Promise.resolve(); + +export default test({ + async test({ assert, target, componentCtor }) { + target.innerHTML = ''; + const ce = target.querySelector('custom-element'); + ce.prop = 1; + customElements.define('custom-element', componentCtor.element); + await tick(); + await tick(); + + const ce_root = target.querySelector('custom-element').shadowRoot; + const p = ce_root.querySelector('p'); + + assert.equal(p.textContent, '1'); + + ce.prop = 2; + await tick(); + await tick(); + + assert.equal(p.textContent, '2'); + } +}); diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/main.svelte b/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/main.svelte new file mode 100644 index 000000000000..0be0f59d9d0d --- /dev/null +++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/set-property-before-mounted/main.svelte @@ -0,0 +1,5 @@ + + +

{prop}