« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/util/html.js21
-rw-r--r--test/html.js27
2 files changed, 43 insertions, 5 deletions
diff --git a/src/util/html.js b/src/util/html.js
index e808eefa..3980b9aa 100644
--- a/src/util/html.js
+++ b/src/util/html.js
@@ -214,6 +214,10 @@ export class Tag {
       return '';
     }
 
+    if (!this.tagName) {
+      return contentString;
+    }
+
     const openTag = (attributesString
       ? `<${this.tagName} ${attributesString}>`
       : `<${this.tagName}>`);
@@ -385,12 +389,17 @@ export class Template {
   }
 
   setSlot(slotName, content) {
-    return this.#slotContents[slotName] = new Tag(null, null, content);
+    if (Array.isArray(content)) {
+      this.#slotContents[slotName] = content;
+    } else {
+      this.#slotContents[slotName] = [content];
+    }
   }
 
   getSlot(slotName) {
     if (this.#slotContents[slotName]) {
-      return this.#slotContents[slotName];
+      const contents = this.#slotContents[slotName].map(item => item.valueOf());
+      return new Tag(null, null, contents).valueOf();
     } else {
       return [];
     }
@@ -458,9 +467,13 @@ export class Slot {
 
   valueOf() {
     if (this.#handleContent) {
-      return this.#handleContent(this.content);
+      const result = this.#handleContent(this.content);
+      if (result === null || result === undefined) {
+        throw new Error(`Expected function for slot ${this.slotName} to return a value, got ${result}`);
+      }
+      return result.valueOf();
     } else {
-      return this.content;
+      return this.content.valueOf();
     }
   }
 }
diff --git a/test/html.js b/test/html.js
index 9cb062fe..25d6070d 100644
--- a/test/html.js
+++ b/test/html.js
@@ -203,7 +203,7 @@ test(`Tag (properties from attributes - mutating)`, t => {
 });
 
 test(`Tag.toString`, t => {
-  t.plan(7);
+  t.plan(9);
 
   // 1: basic behavior
 
@@ -294,6 +294,31 @@ test(`Tag.toString`, t => {
     `    <hr style="color: magenta">\n` +
     `    <p>Shenanigans!</p>\n` +
     `</article>`);
+
+  // 8-9: empty tagName passes content through directly
+
+  const tag8 =
+    html.tag(null, [
+      html.tag('h1', `Foo`),
+      html.tag(`h2`, `Bar`),
+    ]);
+
+  t.is(tag8.toString(),
+    `<h1>Foo</h1>\n` +
+    `<h2>Bar</h2>`);
+
+  const tag9 =
+    html.tag(null, {
+      [html.joinChildren]: html.tag('br'),
+    }, [
+      `Say it with me...`,
+      `Supercalifragilisticexpialidocious!`
+    ]);
+
+  t.is(tag9.toString(),
+    `Say it with me...\n` +
+    `<br>\n` +
+    `Supercalifragilisticexpialidocious!`);
 });
 
 test(`Tag.toString (onlyIfContent)`, t => {