« get me outta code hell

html: new Stationery class for instantiating Templates - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-06-12 14:51:08 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-06-12 14:51:08 -0300
commitf12890facba502805f03a64c76f386c4531abbcc (patch)
tree2709849226850f0781098bf4e1c2d467ebdb3266
parentc8fabb4ad0e13758c13d58c86b9859c63ff127b0 (diff)
html: new Stationery class for instantiating Templates
-rw-r--r--src/util/html.js25
-rw-r--r--test/unit/util/html.js28
2 files changed, 52 insertions, 1 deletions
diff --git a/src/util/html.js b/src/util/html.js
index f5c1dee0..b75820e8 100644
--- a/src/util/html.js
+++ b/src/util/html.js
@@ -489,7 +489,10 @@ export class Template {
   #slotValues = {};
 
   constructor(description) {
-    Template.validateDescription(description);
+    if (!description[Stationery.validated]) {
+      Template.validateDescription(description);
+    }
+
     this.#description = description;
   }
 
@@ -779,3 +782,23 @@ export class Template {
     return this.content.toString();
   }
 }
+
+export function stationery(description) {
+  return new Stationery(description);
+}
+
+export class Stationery {
+  #templateDescription = null;
+
+  static validated = Symbol('Stationery.validated');
+
+  constructor(templateDescription) {
+    Template.validateDescription(templateDescription);
+    templateDescription[Stationery.validated] = true;
+    this.#templateDescription = templateDescription;
+  }
+
+  template() {
+    return new Template(this.#templateDescription);
+  }
+}
diff --git a/test/unit/util/html.js b/test/unit/util/html.js
index 82f96b48..01a510ec 100644
--- a/test/unit/util/html.js
+++ b/test/unit/util/html.js
@@ -904,3 +904,31 @@ t.test(`Template - slot value errors`, t => {
       `arrayOfHTML length: 0`,
     ]).toString());
 });
+
+t.test(`Stationery`, t => {
+  t.plan(3);
+
+  // 1-3: basic behavior
+
+  const stationery1 = new html.Stationery({
+    slots: {
+      slot1: {type: 'string', default: 'apricot'},
+      slot2: {type: 'string', default: 'disaster'},
+    },
+
+    content: ({slot1, slot2}) => html.tag('span', `${slot1} ${slot2}`),
+  });
+
+  const template1 = stationery1.template();
+  const template2 = stationery1.template();
+
+  template2.setSlots({slot1: 'aquaduct', slot2: 'dichotomy'});
+
+  const template3 = stationery1.template();
+
+  template3.setSlots({slot2: 'vinaigrette'});
+
+  t.equal(template1.toString(), `<span>apricot disaster</span>`);
+  t.equal(template2.toString(), `<span>aquaduct dichotomy</span>`);
+  t.equal(template3.toString(), `<span>apricot vinaigrette</span>`);
+});