diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-11-19 12:31:35 -0400 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-11-19 12:31:35 -0400 |
commit | ec5f34cc804cdb47bb259a89c261ee6c44ea72e9 (patch) | |
tree | 37ea7edd6428a882a5b05917071be276d610f6cd | |
parent | 36e71fe735c13f452afdc5cd7b75fecedf27dab6 (diff) |
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.
-rw-r--r-- | src/util/html.js | 24 |
1 files changed, 18 insertions, 6 deletions
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) { |