« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/util/html.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/html.js')
-rw-r--r--src/util/html.js24
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) {