@daz4126/helium 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/helium.js +63 -17
- package/package.json +1 -1
package/helium.js
CHANGED
|
@@ -6,7 +6,7 @@ export default function helium(data = {}) {
|
|
|
6
6
|
let initFn;
|
|
7
7
|
const he = (n,...a) => a.map(b => `|@${b}|data-he-${b}|`).join``.includes(`|${n.split('.')[0]}|`);
|
|
8
8
|
const root = document.querySelector("[\\@helium]") || document.querySelector("[data-helium]") || document.body;
|
|
9
|
-
const [bindings, refs, listeners, processed] = [new Map(), new Map(), new WeakMap(), new WeakSet()];
|
|
9
|
+
const [bindings, refs, listeners, processed, parentKeys] = [new Map(), new Map(), new WeakMap(), new WeakSet(), new WeakMap()];
|
|
10
10
|
const $ = s => document.querySelector(s);
|
|
11
11
|
const html = s => Object.assign(document.createElement("template"),{innerHTML:s.trim()}).content.firstChild
|
|
12
12
|
|
|
@@ -17,8 +17,7 @@ export default function helium(data = {}) {
|
|
|
17
17
|
action ? element[action=="replace"?"replaceWith":action](content) : element.innerHTML = content;
|
|
18
18
|
return content
|
|
19
19
|
} else state[target] = data
|
|
20
|
-
}
|
|
21
|
-
|
|
20
|
+
}
|
|
22
21
|
|
|
23
22
|
const ajax = (u,m,o={},p={}) => {
|
|
24
23
|
if(o.loading) o.target = update(o.loading,o.target,o.action) || o.target;
|
|
@@ -43,22 +42,71 @@ const ajax = (u,m,o={},p={}) => {
|
|
|
43
42
|
const get = (u,t) => ajax(u,"GET",t);
|
|
44
43
|
const [post, put, patch, del] = ["POST","PUT","PATCH","DELETE"].map(m => (u, d, t) => ajax(u, m, t, d));
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
get: (t,p,r) => {
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const handler = {
|
|
46
|
+
get: (t,p,r) => {
|
|
47
|
+
const v = Reflect.get(t,p,r);
|
|
48
|
+
if (typeof v==="object" && v!==null) {
|
|
49
|
+
const proxy = new Proxy(v, handler);
|
|
50
|
+
parentKeys.set(v, p);
|
|
51
|
+
return proxy;
|
|
52
|
+
}
|
|
53
|
+
return v;
|
|
54
|
+
},
|
|
55
|
+
set: (t,p,v) => {
|
|
56
|
+
const res = Reflect.set(t,p,v);
|
|
57
|
+
if (Array.isArray(t) && !isNaN(p)) {
|
|
58
|
+
const parentKey = parentKeys.get(t);
|
|
59
|
+
if (parentKey) bindings.get(parentKey)?.forEach(applyBinding);
|
|
60
|
+
}
|
|
61
|
+
bindings.get(p)?.forEach(applyBinding);
|
|
62
|
+
return res
|
|
63
|
+
}
|
|
64
|
+
};
|
|
50
65
|
|
|
51
66
|
const state = new Proxy(data, handler);
|
|
52
|
-
let isUpdatingDOM = false;
|
|
53
67
|
|
|
54
68
|
function applyBinding(b,e={},elCtx=b.el){
|
|
55
69
|
const {el,prop,fn}=b;
|
|
56
70
|
const r=fn($,state,e,elCtx,html,...Object.values(data),...[...refs.values()]);
|
|
57
|
-
if(prop==="innerHTML"){
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
if(prop==="innerHTML" && Array.isArray(r) && el.children.length > 0){
|
|
72
|
+
const temp = html(`<${el.tagName.toLowerCase()}>${r.join``}</${el.tagName.toLowerCase()}>`);
|
|
73
|
+
const newChildren = [...temp.children];
|
|
74
|
+
|
|
75
|
+
const newItems = newChildren.map((child, idx) => ({
|
|
76
|
+
key: child.getAttribute("key") || child.dataset.key,
|
|
77
|
+
element: child,
|
|
78
|
+
index: idx
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
const existingItems = [...el.children].map((child, idx) => ({
|
|
82
|
+
key: child.getAttribute("key") || child.dataset.key,
|
|
83
|
+
element: child,
|
|
84
|
+
index: idx
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i < Math.max(newItems.length, existingItems.length); i++) {
|
|
88
|
+
const existing = existingItems[i];
|
|
89
|
+
const newItem = newItems[i];
|
|
90
|
+
|
|
91
|
+
if (!newItem && existing) {
|
|
92
|
+
cleanup(existing.element);
|
|
93
|
+
existing.element.remove();
|
|
94
|
+
} else if (newItem && !existing) {
|
|
95
|
+
el.appendChild(newItem.element);
|
|
96
|
+
} else if (newItem && existing) {
|
|
97
|
+
if (existing.element.outerHTML !== newItem.element.outerHTML) {
|
|
98
|
+
if(typeof Idiomorph === "object") {
|
|
99
|
+
Idiomorph.morph(existing.element, newItem.element.outerHTML);
|
|
100
|
+
} else {
|
|
101
|
+
cleanup(existing.element);
|
|
102
|
+
existing.element.replaceWith(newItem.element);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} else if(prop==="innerHTML"){
|
|
108
|
+
const content = Array.isArray(r)?r.join``:r
|
|
60
109
|
typeof Idiomorph === "object" ? Idiomorph.morph(el, content,{morphStyle:'innerHTML'}) : el.innerHTML = content;
|
|
61
|
-
isUpdatingDOM=0
|
|
62
110
|
}
|
|
63
111
|
else if(prop==="class"&&r&&typeof r==="object")for(const[k,v]of Object.entries(r))k.split(/\s+/).forEach(c=>el.classList.toggle(c,v));
|
|
64
112
|
else if(prop==="style"&&r&&typeof r==="object")el.style=Object.entries(r).filter(([,v])=>v).map(([k,v])=>`${k}:${v}`).join(";")
|
|
@@ -95,15 +143,14 @@ const trackDependencies = (fn, el) => {
|
|
|
95
143
|
};
|
|
96
144
|
|
|
97
145
|
function processElements(element) {
|
|
146
|
+
let count = 0
|
|
98
147
|
const newBindings = [];
|
|
99
|
-
if (element.nodeType == 1)
|
|
100
|
-
if (processed.has(element)) return newBindings;
|
|
101
|
-
processed.add(element);
|
|
102
|
-
}
|
|
148
|
+
if (element.nodeType == 1 && processed.has(element)) return newBindings;
|
|
103
149
|
|
|
104
150
|
const heElements=[element,...element.querySelectorAll("*")].filter(e=>[...e.attributes].some(a=>/^(@|:|data-he)/.test(a.name)))
|
|
105
151
|
|
|
106
152
|
heElements.forEach(el => {
|
|
153
|
+
count++
|
|
107
154
|
for (const {name, value} of el.attributes || []) {
|
|
108
155
|
if (he(name,"text","html","bind")) {
|
|
109
156
|
try {
|
|
@@ -211,7 +258,6 @@ const trackDependencies = (fn, el) => {
|
|
|
211
258
|
return newBindings;
|
|
212
259
|
}
|
|
213
260
|
new MutationObserver(ms=>{
|
|
214
|
-
if(isUpdatingDOM)return;
|
|
215
261
|
for(const m of ms){
|
|
216
262
|
m.removedNodes.forEach(n=>n.nodeType===1&&cleanup(n));
|
|
217
263
|
m.addedNodes.forEach(n=>n.nodeType===1&&!processed.has(n)&&processElements(n).forEach(applyBinding));
|