From 9b04e9c135fea480e5bcfdb92eaf3c81161ea803 Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Mon, 1 May 2023 17:09:16 +0200
Subject: [PATCH] refactor: monitor all attribute changes

---
 application/source/dom/customelement.mjs      | 35 +++++++---
 .../playground/dom-arguments/index.html       | 29 ++++++++
 development/playground/dom-arguments/main.mjs | 70 +++++++++++++++++++
 .../playground/dom-arguments/translation.json |  4 ++
 development/playground/dom-insert/index.html  | 12 ++--
 .../playground/i18n-control/index.html        | 34 +++++----
 .../playground/i18n-updater/updater.html      | 10 ++-
 7 files changed, 163 insertions(+), 31 deletions(-)
 create mode 100644 development/playground/dom-arguments/index.html
 create mode 100644 development/playground/dom-arguments/main.mjs
 create mode 100644 development/playground/dom-arguments/translation.json

diff --git a/application/source/dom/customelement.mjs b/application/source/dom/customelement.mjs
index e57ff7e43..edc1716b3 100644
--- a/application/source/dom/customelement.mjs
+++ b/application/source/dom/customelement.mjs
@@ -203,9 +203,9 @@ class CustomElement extends HTMLElement {
         this[internalSymbol] = new ProxyObserver({
             options: initOptionsFromAttributes(this, extend({}, this.defaults)),
         });
-        initAttributeChangeMutationObserver.call(this);        
-        initOptionObserver.call(this);
         this[initMethodSymbol]();
+        initOptionObserver.call(this);
+        initAttributeChangeMutationObserver.call(this);
     }
 
     /**
@@ -229,6 +229,28 @@ class CustomElement extends HTMLElement {
         return [ATTRIBUTE_OPTIONS, ATTRIBUTE_DISABLED];
     }
 
+    /**
+     * 
+     * @param attribute
+     * @param callback
+     * @returns {Monster.DOM.CustomElement}
+     */
+    addAttributeObserver(attribute, callback) {
+        validateFunction(callback);
+        this[attributeObserverSymbol][attribute] = callback;
+        return this;
+    }
+
+    /**
+     * 
+     * @param attribute
+     * @returns {Monster.DOM.CustomElement}
+     */
+    removeAttributeObserver(attribute) {
+        delete this[attributeObserverSymbol][attribute];
+        return this;
+    }
+
     /**
      * Derived classes can override and extend this method as follows.
      *
@@ -611,14 +633,6 @@ class CustomElement extends HTMLElement {
 function initAttributeChangeMutationObserver() {
     const self = this;
 
-    if (self[attributeObserverSymbol] === undefined) {
-        self[attributeObserverSymbol] = {};
-    }
-    
-    if(Object.keys(self[attributeObserverSymbol]).length === 0) {
-        return;
-    }
-
     new MutationObserver(function (mutations) {
         for (const mutation of mutations) {
             if (mutation.type === "attributes") {
@@ -628,7 +642,6 @@ function initAttributeChangeMutationObserver() {
     }).observe(self, {
         attributes: true,
         attributeOldValue: true,
-        attributeFilter: Object.keys(self[attributeObserverSymbol]),
     });
 }
 
diff --git a/development/playground/dom-arguments/index.html b/development/playground/dom-arguments/index.html
new file mode 100644
index 000000000..538ebea6d
--- /dev/null
+++ b/development/playground/dom-arguments/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Popper Button</title>
+    <script src="main.mjs" type="module"></script>
+</head>
+<body>
+<a href="../">Back</a>
+<main>
+<h1>Updater</h1>
+
+<script type="application/json" data-monster-role="translations">
+    {
+        "theListContainsNoEntries": "translation1",
+        "key2": {
+            "other": "translation2"
+        },
+        "multi": {
+            "two": "translation3"
+        }
+    }
+</script>
+
+<monster-1>Monster1</monster-1>
+</main>
+</body>
+</html>
diff --git a/development/playground/dom-arguments/main.mjs b/development/playground/dom-arguments/main.mjs
new file mode 100644
index 000000000..65759c0ef
--- /dev/null
+++ b/development/playground/dom-arguments/main.mjs
@@ -0,0 +1,70 @@
+import {Fetch} from '../../../application/source/i18n/providers/fetch.mjs';
+import {Updater} from '../../../application/source/dom/updater.mjs';
+import {
+    attributeObserverSymbol,
+    CustomElement,
+    registerCustomElement
+} from '../../../application/source/dom/customelement.mjs';
+import {domReady} from '../../../application/source/dom/ready.mjs';
+import {Embed} from '../../../application/source/i18n/providers/embed.mjs';
+import {ATTRIBUTE_OPTIONS_SELECTOR} from "../../../application/source/monster.mjs";
+
+
+const initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol");
+
+class Monster1 extends CustomElement {
+
+    constructor() {
+        super();
+     
+    }
+
+    get defaults() {
+        return Object.assign(
+            {},
+            super.defaults,
+            {
+                a: {
+                    b: {
+                        c: "d"
+                    }
+                }
+            });
+    };
+    
+    
+    [initMethodSymbol]() {
+        self = this;
+        console.log("initMethodSymbol");
+        this[attributeObserverSymbol]["data-monster-option-a-b-c"] = (value) => {
+            console.log("data-monster-option-a-b-c", value);
+            self.setOption("a.b.c", value);
+        };
+    }
+
+    /**
+     *
+     * @return {string}
+     */
+    static getTag() {
+        return "monster-1";
+    }
+
+}
+
+
+domReady.then(() => {
+
+   
+    const m1 = document.querySelector("monster-1");
+    console.log(m1);
+    
+    window.m1 = m1;
+
+
+// read from scritp tag with id i18n
+
+
+});
+
+registerCustomElement(Monster1);
diff --git a/development/playground/dom-arguments/translation.json b/development/playground/dom-arguments/translation.json
new file mode 100644
index 000000000..88b3d7123
--- /dev/null
+++ b/development/playground/dom-arguments/translation.json
@@ -0,0 +1,4 @@
+{
+  "key1": "value1",
+  "key2": "value2"
+}
\ No newline at end of file
diff --git a/development/playground/dom-insert/index.html b/development/playground/dom-insert/index.html
index f02d21146..cc1c3f049 100644
--- a/development/playground/dom-insert/index.html
+++ b/development/playground/dom-insert/index.html
@@ -1,10 +1,14 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
 <head>
-    <script type="module" src="main.mjs"></script>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Popper Button</title>
+    <script src="main.mjs" type="module"></script>
 </head>
 <body>
-<h1>Updater</h1>
+<a href="../">Back</a>
+<main>
 
 
 <template id="current">
@@ -14,6 +18,6 @@
     <ul data-monster-insert="current path:a.b" >
     </ul>
 </div>
-
+</main>
 </body>
 </html>
diff --git a/development/playground/i18n-control/index.html b/development/playground/i18n-control/index.html
index 5113abe71..58b4a3b75 100644
--- a/development/playground/i18n-control/index.html
+++ b/development/playground/i18n-control/index.html
@@ -1,24 +1,30 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
 <head>
-    <script type="module" src="main.mjs"></script>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Popper Button</title>
+    <script src="main.mjs" type="module"></script>
 </head>
 <body>
-<h1>Updater</h1>
+<a href="../">Back</a>
+<main>
+    <h1>Updater</h1>
 
-<script type="application/json" data-monster-role="translations">
-    {
-        "theListContainsNoEntries": "translation1",
-        "key2": {
-            "other": "translation2"
-        },
-        "multi": {
-            "two": "translation3"
+    <script type="application/json" data-monster-role="translations">
+        {
+            "theListContainsNoEntries": "translation1",
+            "key2": {
+                "other": "translation2"
+            },
+            "multi": {
+                "two": "translation3"
+            }
         }
-    }
-</script>
+    </script>
 
-<monster-1>Monster1</monster-1>
+    <monster-1>Monster1</monster-1>
 
+</main>
 </body>
 </html>
diff --git a/development/playground/i18n-updater/updater.html b/development/playground/i18n-updater/updater.html
index 2d464036b..57c2737a7 100644
--- a/development/playground/i18n-updater/updater.html
+++ b/development/playground/i18n-updater/updater.html
@@ -1,12 +1,18 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
 <head>
-    <script type="module" src="updater.js"></script>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Popper Button</title>
+    <script src="main.mjs" type="module"></script>
 </head>
 <body>
+<a href="../">Back</a>
+<main>
 <h1>Updater</h1>
 
 <div data-monster-replace="i18n:key1"></div>
 <div data-monster-replace="i18n:key2"></div>
+</main>
 </body>
 </html>
-- 
GitLab