Zuletzt aktiv 1740947436

Änderung a1b5ca89802e0f3a0f26d66108f1b589a2625cdd

hex.js Orginalformat Playground
1const hex = (function() {
2 const q = (el, sel) => !sel ? document.querySelectorAll(el) : el.querySelectorAll(sel);
3 const id = (sel) => document.getElementById(sel);
4 const q1 = (el, sel) => !sel ? document.querySelector(el) : el.querySelector(sel);
5 const isObj = (obj) => { var type = typeof obj; return type === 'object' && !!obj; };
6 const isSimple = (v) => {var type = typeof v; return type=== "number" || type === "string" || type === "boolean"; }
7 const arise = (fn) => document.addEventListener('DOMContentLoaded', fn, false);
8 const scrawl = (k, v) => localStorage.setItem(k, JSON.stringify(v));
9 const recall = (k) => JSON.parse(localStorage.getItem(k) || "null");
10
11 function setterFor(node) {
12 switch (node.tagName) {
13 case "INPUT":
14 return (val) => node.value = val;
15 default:
16 return (val) => { node.innerText = val; };
17 }
18 }
19
20 let templs = new Map();
21 function from(tempSel) {
22 let toClone;
23 if (templs.has(tempSel)) {
24 toClone = templs.get(tempSel);
25 } else {
26 let n = q1(tempSel);
27 if (n) {
28 templs.set(tempSel, n);
29 toClone = n;
30 } else {
31 throw tempSel + " failed";
32 }
33 }
34 return toClone.content.cloneNode(true);
35 }
36
37 function spell(template, config) {
38
39 return function(into, start) {
40 const basis = from(template)
41 const state = { vars: {}, dom: {}, setters: {} };
42 const interface = Object.create(spell);
43 const recursionGuard = new Set();
44
45 for (let [k, v] of Object.entries(config)) {
46 const makeProp = (el, initialValue) => {
47 state.setters[k] = setterFor(el);
48
49 Object.defineProperty(interface, k, {
50 get() { return state.vars[k] },
51 set(v) {
52 state.vars[k] = v;
53 state.setters[k]((v || "") + "");
54 }
55 });
56
57 interface[k] = initialValue;
58 }
59 if (typeof v === "string" && v) {
60 const el = q1(basis, v);
61 state.dom[k] = el;
62 makeProp(el, start[k]);
63 } else if (Array.isArray(v)) {
64 if (v.length <= 0) {
65 throw new Error("Empty array not valid!");
66 }
67 let el;
68 if (typeof v[0] === "string") {
69 el = q1(basis, v[0]);
70 state.dom[k] = el;
71 } else {
72 throw new Error(`Selector for ${k} must be a string!`);
73 }
74
75 if (v.length == 1 && (typeof v[0]) == "string") {
76 state.vars[k] = start[k];
77 makeProp(el, start[k]);
78 } else if (v.length == 2 && (typeof v[0]) === "string" && isSimple(v[1])) {
79 makeProp(el, start[k] || v[1]);
80 } else if (v.length == 2 && (typeof v[0]) === "string" && isObj(v[1])) {
81 makeProp(el, start[k]);
82 const obj = v[1];
83 if (obj.on) {
84 for (const [evt, fn] of Object.entries(obj.on)) {
85 let inner = fn.bind(interface);
86 let handler = function() {
87 if (recursionGuard.has(handler)) { return; }
88 try {
89 recursionGuard.add(handler);
90 inner(...arguments);
91 } finally {
92 recursionGuard.delete(handler);
93 }
94 };
95
96 el.addEventListener(evt, handler);
97 }
98 }
99 if (obj.init && typeof obj.init === "function") {
100 obj.init.call(interface, start);
101 }
102
103 } else if (v.length === 2 &&
104 (typeof v[0]) === "string" &&
105 (typeof v[1]) === "function"
106 && Array.isArray(start[k])
107 ) {
108 state.vars[k] = start[k].map((data) => v[1](el, data));
109 interface[k] = function(new_data) {
110 el.innerHTML = "";
111 state.vars[k] = new_data.map((data) => v[1](el, data));
112 }
113 } else {
114 throw new Error(`Invalid config: ${k}`);
115 }
116 }
117 }
118
119 interface._ = state;
120 into.appendChild(basis);
121 return interface;
122 }
123 }
124
125
126
127 return {q, q1, id, from, arise, scrawl, recall, spell};
128})();
129
130window.hex = hex;
131