@daz4126/helium 0.11.1 → 0.12.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 +56 -46
- package/package.json +1 -1
package/helium.js
CHANGED
|
@@ -9,62 +9,65 @@ export default function helium(data = {}) {
|
|
|
9
9
|
const $ = s => document.querySelector(s);
|
|
10
10
|
const html = s => Object.assign(document.createElement("template"),{innerHTML:s.trim()}).content.firstChild
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if(o.target)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
const update = (data,target,action,template) => {
|
|
13
|
+
const element = target instanceof Node ? target : (refs.get(target) || $(target));
|
|
14
|
+
if(element){
|
|
15
|
+
const content = html(template ? template(data) : data);
|
|
16
|
+
action ? element[action=="replace"?"replaceWith":action](content) : element.innerHTML = content;
|
|
17
|
+
return content
|
|
18
|
+
} else state[target] = data
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
const ajax = (u,m,o={},p={}) => {
|
|
23
|
+
if(o.loading) o.target = update(o.loading,o.target,o.action) || o.target;
|
|
24
|
+
const fd = p instanceof FormData, t = document.querySelector('meta[name="csrf-token"]')?.content;
|
|
25
|
+
fetch(u,{method:m,headers:{
|
|
26
|
+
Accept:"text/vnd.turbo-stream.html,application/json,text/html",
|
|
27
|
+
...(!fd&&m!=="GET"&&{"Content-Type":"application/json"}),
|
|
28
|
+
...(t&&{"X-CSRF-Token":t})
|
|
29
|
+
},body:m==="GET"?null:(fd?p:JSON.stringify(p)),credentials:"same-origin"})
|
|
30
|
+
.then(r=>r.headers.get("content-type")?.includes("json")?r.json():r.text())
|
|
31
|
+
.then(d=>o.loading?update(d,o.target,"replace",o.template):update(d,o.target,o.action,o.template))
|
|
32
|
+
.catch(e=>console.error("AJAX:",e.message));
|
|
33
|
+
}
|
|
31
34
|
|
|
32
35
|
const get = (u,t) => ajax(u,"GET",t);
|
|
33
36
|
const [post, put, patch, del] = ["POST","PUT","PATCH","DELETE"].map(m => (u, d, t) => ajax(u, m, t, d));
|
|
34
37
|
|
|
35
38
|
const handler = {
|
|
36
|
-
get: (t,
|
|
37
|
-
set: (t,
|
|
39
|
+
get: (t,p,r) => {const v = Reflect.get(t,p,r); return typeof v==="object"&&v!==null ? new Proxy(v,handler) : v},
|
|
40
|
+
set: (t,p,v) => {const res = Reflect.set(t,p,v); bindings.get(p)?.forEach(applyBinding); return res}
|
|
38
41
|
};
|
|
39
42
|
|
|
40
43
|
const state = new Proxy(data, handler);
|
|
41
44
|
let isUpdatingDOM = false;
|
|
42
45
|
|
|
43
46
|
function applyBinding(b,e={},elCtx=b.el){
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
47
|
+
const {el,prop,fn}=b;
|
|
48
|
+
const r=fn($,state,e,elCtx,html,...Object.values(data),...[...refs.values()]);
|
|
49
|
+
if(prop==="innerHTML"){isUpdatingDOM=1;el.innerHTML=Array.isArray(r)?r.join``:r;isUpdatingDOM=0}
|
|
50
|
+
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));
|
|
51
|
+
else if(prop==="style"&&r&&typeof r==="object")el.style=Object.entries(r).filter(([,v])=>v).map(([k,v])=>`${k}:${v}`).join(";")
|
|
52
|
+
else if(prop in el){if(el.type==="radio")el.checked=el.value===r;else el[prop]=prop==="textContent"?r:parseEx(r)}
|
|
53
|
+
else el.setAttribute(prop,parseEx(r))
|
|
54
|
+
}
|
|
52
55
|
|
|
53
56
|
const compile = (expr, withReturn = false) => {
|
|
54
57
|
try {
|
|
55
|
-
return new Function("$",
|
|
56
|
-
`with($data){${withReturn
|
|
58
|
+
return new Function("$","$data","$event","$el","$html","$get","$post","$put","$patch","$delete",...Object.keys(data),...[...refs.keys()],
|
|
59
|
+
`with($data){${withReturn?"return":""}(${expr.trim()})}`);
|
|
57
60
|
} catch {return () => expr}
|
|
58
61
|
};
|
|
59
62
|
|
|
60
|
-
const trackDependencies=fn=>{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
63
|
+
const trackDependencies = fn => {
|
|
64
|
+
const s=new Set(),p=new Proxy(state,{get:(t,k)=>{if(typeof k==="string")s.add(k);const v=t[k];return v&&typeof v==="object"?new Proxy(v,this):v}});
|
|
65
|
+
try{fn($,p,refs)}catch{};return[...s]
|
|
66
|
+
}
|
|
64
67
|
|
|
65
68
|
const cleanup = el => {
|
|
66
|
-
[el
|
|
67
|
-
listeners.get(e)?.forEach(({receiver,
|
|
69
|
+
[el,...el.querySelectorAll('*')].forEach(e => {
|
|
70
|
+
listeners.get(e)?.forEach(({receiver,event,handler}) => receiver.removeEventListener(event,handler));
|
|
68
71
|
listeners.delete(e);
|
|
69
72
|
});
|
|
70
73
|
};
|
|
@@ -151,14 +154,21 @@ const trackDependencies=fn=>{
|
|
|
151
154
|
}
|
|
152
155
|
if (!mods.includes("outside") || !el.contains(e.target)) {
|
|
153
156
|
if (isHttpMethod) {
|
|
154
|
-
const
|
|
155
|
-
|
|
157
|
+
const getAttr = name => el.getAttribute(`data-he-${name}`) || el.getAttribute(`@${name}`);
|
|
158
|
+
const [target, action] = (getAttr('target') || "").split(":");
|
|
159
|
+
const options = {
|
|
160
|
+
...exFn(getAttr('options') || '{}'),
|
|
161
|
+
...(target && { target }),
|
|
162
|
+
...(action && { action }),
|
|
163
|
+
...execFn(getAttr('template')) && { template: execFn(getAttr('template')) },
|
|
164
|
+
...getAttr('loading') && { loading: getAttr('loading') }
|
|
165
|
+
};
|
|
166
|
+
let paramsAttr = getAttr('params') || '{}';
|
|
156
167
|
if (!paramsAttr.trim().startsWith("{") && paramsAttr.includes(":")) {
|
|
157
168
|
const props = paramsAttr.split(":").map(s => s.trim());
|
|
158
169
|
paramsAttr = props.reduceRight((acc, key, i) => `{ ${key}: ${i == 1 ? `'${el[acc]}'` : acc} }`);
|
|
159
170
|
}
|
|
160
171
|
const params = exFn(paramsAttr);
|
|
161
|
-
console.log("params: ",params)
|
|
162
172
|
ajax(value, eventName.toUpperCase(), options, params);
|
|
163
173
|
} else {
|
|
164
174
|
exFn(value);
|
|
@@ -176,12 +186,12 @@ const trackDependencies=fn=>{
|
|
|
176
186
|
return newBindings;
|
|
177
187
|
}
|
|
178
188
|
new MutationObserver(ms=>{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}).observe(root,{childList:1,subtree:1});
|
|
189
|
+
if(isUpdatingDOM)return;
|
|
190
|
+
for(const m of ms){
|
|
191
|
+
m.removedNodes.forEach(n=>n.nodeType===1&&cleanup(n));
|
|
192
|
+
m.addedNodes.forEach(n=>n.nodeType===1&&!n.hasAttribute("data-he-p")&&processElements(n).forEach(applyBinding));
|
|
193
|
+
}
|
|
194
|
+
}).observe(root,{childList:1,subtree:1});
|
|
185
195
|
processElements(root);
|
|
186
196
|
for (const [key, items] of bindings.entries()) items.forEach(applyBinding);
|
|
187
197
|
}
|