From ec5f34cc804cdb47bb259a89c261ee6c44ea72e9 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 19 Nov 2024 12:31:35 -0400 Subject: html: Template.clone: use "ready" slot values This doesn't fix the issue in the context we were trying to fix, but it is semantically correct (where existing behavior is not), which we are not proving with a unit test. --- src/util/html.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/util/html.js b/src/util/html.js index 85464b72..913206d8 100644 --- a/src/util/html.js +++ b/src/util/html.js @@ -1469,7 +1469,13 @@ export class Template { this.#description, ]); - clone.setSlots(this.#slotValues); + // getSlotValue(), called via #getReadySlotValues(), is responsible for + // preparing slot values for consumption, which includes cloning mutable + // html/attributes. We reuse that behavior here, in a recursive manner, + // so that clone() is effectively "deep" - slots that may be mutated are + // cloned, so that this template and its clones will never mutate the same + // identities. + clone.setSlots(this.#getReadySlotValues()); return clone; } @@ -1795,17 +1801,23 @@ export class Template { return description; } - set content(_value) { - throw new Error(`Template content can't be changed after constructed`); - } - - get content() { + #getReadySlotValues() { const slots = {}; for (const slotName of Object.keys(this.description.slots ?? {})) { slots[slotName] = this.getSlotValue(slotName); } + return slots; + } + + set content(_value) { + throw new Error(`Template content can't be changed after constructed`); + } + + get content() { + const slots = this.#getReadySlotValues(); + try { return this.description.content(slots); } catch (caughtError) { -- cgit 1.3.0-6-gf8a5