From 47ec86b4a3c56dce302eb1bb2ba537b1e74f4cd8 Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Tue, 7 Mar 2023 21:49:16 +0100
Subject: [PATCH] feat: template mapping

---
 application/source/dom/customelement.mjs | 62 ++++++++++++++----------
 1 file changed, 37 insertions(+), 25 deletions(-)

diff --git a/application/source/dom/customelement.mjs b/application/source/dom/customelement.mjs
index 69f7a1c37..2a3e69817 100644
--- a/application/source/dom/customelement.mjs
+++ b/application/source/dom/customelement.mjs
@@ -5,18 +5,18 @@
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
  */
 
-import { internalSymbol } from "../constants.mjs";
-import { extend } from "../data/extend.mjs";
-import { Pathfinder } from "../data/pathfinder.mjs";
+import {internalSymbol} from "../constants.mjs";
+import {extend} from "../data/extend.mjs";
+import {Pathfinder} from "../data/pathfinder.mjs";
 
-import { parseDataURL } from "../types/dataurl.mjs";
-import { getGlobalObject } from "../types/global.mjs";
+import {parseDataURL} from "../types/dataurl.mjs";
+import {getGlobalObject} from "../types/global.mjs";
 import {isArray, isFunction, isIterable, isObject, isString} from "../types/is.mjs";
-import { Observer } from "../types/observer.mjs";
-import { ProxyObserver } from "../types/proxyobserver.mjs";
-import { validateFunction, validateInstance, validateObject, validateString } from "../types/validate.mjs";
-import { clone } from "../util/clone.mjs";
-import { addAttributeToken, getLinkedObjects, hasObjectLink } from "./attributes.mjs";
+import {Observer} from "../types/observer.mjs";
+import {ProxyObserver} from "../types/proxyobserver.mjs";
+import {validateFunction, validateInstance, validateObject, validateString} from "../types/validate.mjs";
+import {clone} from "../util/clone.mjs";
+import {addAttributeToken, getLinkedObjects, hasObjectLink} from "./attributes.mjs";
 import {
     ATTRIBUTE_DISABLED,
     ATTRIBUTE_ERRORMESSAGE,
@@ -24,9 +24,9 @@ import {
     ATTRIBUTE_OPTIONS_SELECTOR,
     customElementUpdaterLinkSymbol,
 } from "./constants.mjs";
-import { findDocumentTemplate, Template } from "./template.mjs";
-import { addObjectWithUpdaterToElement } from "./updater.mjs";
-import { instanceSymbol } from "../constants.mjs";
+import {findDocumentTemplate, Template} from "./template.mjs";
+import {addObjectWithUpdaterToElement} from "./updater.mjs";
+import {instanceSymbol} from "../constants.mjs";
 import {getDocumentTranslations, Translations} from "../i18n/translations.mjs";
 
 export {
@@ -267,6 +267,7 @@ class CustomElement extends HTMLElement {
      * @property {Boolean} delegatesFocus=true A boolean that, when set to true, specifies behavior that mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
      * @property {Object} templates Templates
      * @property {string} templates.main=undefined Main template
+     * @property {Object} templateMapping Template mapping
      *
      * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow
      * @since 1.8.0
@@ -279,6 +280,7 @@ class CustomElement extends HTMLElement {
             templates: {
                 main: undefined,
             },
+            templateMapping: {},
         };
     }
 
@@ -288,7 +290,7 @@ class CustomElement extends HTMLElement {
      * The labels are defined in the options object.
      * The key of the label is used to retrieve the translation from the document.
      * If the translation is different from the label, the label is updated.
-     * 
+     *
      * Before you can use this method, you must have loaded the translations.
      *
      * @returns {Monster.DOM.CustomElement}
@@ -301,10 +303,10 @@ class CustomElement extends HTMLElement {
         }
 
         const labels = this.getOption("labels");
-        if(!isIterable(labels)){
+        if (!isIterable(labels)) {
             return this;
         }
-        
+
         for (const key in labels) {
             const text = translations.getText(key, labels[key]);
             if (text !== labels[key]) {
@@ -313,8 +315,8 @@ class CustomElement extends HTMLElement {
 
         }
         return this;
-    }    
-    
+    }
+
     /**
      * There is no check on the name by this class. the developer is responsible for assigning an appropriate tag.
      * if the name is not valid, registerCustomElement() will issue an error
@@ -327,7 +329,7 @@ class CustomElement extends HTMLElement {
     static getTag() {
         throw new Error("the method getTag must be overwritten by the derived class.");
     }
-    
+
 
     /**
      * At this point a `CSSStyleSheet` object can be returned. If the environment does not
@@ -354,7 +356,7 @@ class CustomElement extends HTMLElement {
     static getCSSStyleSheet() {
         return undefined;
     }
- 
+
     /**
      * attach a new observer
      *
@@ -398,7 +400,8 @@ class CustomElement extends HTMLElement {
 
         try {
             value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
-        } catch (e) {}
+        } catch (e) {
+        }
 
         if (value === undefined) return defaultValue;
         return value;
@@ -468,7 +471,8 @@ class CustomElement extends HTMLElement {
             try {
                 initShadowRoot.call(self);
                 elements = self.shadowRoot.childNodes;
-            } catch (e) {}
+            } catch (e) {
+            }
 
             try {
                 initCSSStylesheet.call(this);
@@ -519,7 +523,8 @@ class CustomElement extends HTMLElement {
      * @return {void}
      * @since 1.7.0
      */
-    disconnectedCallback() {}
+    disconnectedCallback() {
+    }
 
     /**
      * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
@@ -527,7 +532,8 @@ class CustomElement extends HTMLElement {
      * @return {void}
      * @since 1.7.0
      */
-    adoptedCallback() {}
+    adoptedCallback() {
+    }
 
     /**
      * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
@@ -816,7 +822,8 @@ function parseOptionsJSON(data) {
     try {
         let dataUrl = parseDataURL(data);
         data = dataUrl.content;
-    } catch (e) {}
+    } catch (e) {
+    }
 
     try {
         obj = JSON.parse(data);
@@ -838,6 +845,11 @@ function initHtmlContent() {
     } catch (e) {
         let html = this.getOption("templates.main", "");
         if (isString(html) && html.length > 0) {
+
+            const mapping = this.getOption("templateMapping", {});
+            if (isObject(mapping)) {
+                html = new Formatter(mapping).format(html);
+            }
             this.innerHTML = html;
         }
     }
-- 
GitLab