@daz4126/helium 0.17.0 → 0.19.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 +37 -46
- package/package.json +1 -1
package/helium.js
CHANGED
|
@@ -8,7 +8,11 @@ let HELIUM = null;
|
|
|
8
8
|
window.helium = function() {
|
|
9
9
|
let initFn;
|
|
10
10
|
const ALL = Symbol("all");
|
|
11
|
-
const he = (n,...a) =>
|
|
11
|
+
const he = (n,...a) => {
|
|
12
|
+
const prefix = n.split(/[.:]/)[0];
|
|
13
|
+
if (prefix === ":" || prefix === "") return false;
|
|
14
|
+
return a.map(b => `|@${b}|data-he-${b}|`).join``.includes(`|${prefix}|`);
|
|
15
|
+
};
|
|
12
16
|
const root = document.querySelector("[\\@helium]") || document.querySelector("[data-helium]") || document.body;
|
|
13
17
|
|
|
14
18
|
// Initialize or reuse HELIUM object
|
|
@@ -104,7 +108,6 @@ function applyBinding(b,e={},elCtx=b.el){
|
|
|
104
108
|
? Idiomorph.morph(el, content,{morphStyle:'innerHTML'})
|
|
105
109
|
: el.innerHTML = content;
|
|
106
110
|
}
|
|
107
|
-
|
|
108
111
|
if (prop==="class" && r && typeof r==="object")
|
|
109
112
|
return Object.entries(r).forEach(([k,v]) =>
|
|
110
113
|
k.split(/\s+/).forEach(c => el.classList.toggle(c,v)));
|
|
@@ -114,32 +117,39 @@ function applyBinding(b,e={},elCtx=b.el){
|
|
|
114
117
|
.map(([k,v])=>`${k}:${v}`).join(";");
|
|
115
118
|
|
|
116
119
|
if (prop in el) {
|
|
117
|
-
if(el.type==="radio") el.checked = el.value===r;
|
|
120
|
+
if (el.type === "radio" && prop != "checked") el.checked = el.value===r;
|
|
118
121
|
else el[prop] = prop==="textContent"?r:parseEx(r);
|
|
119
122
|
return;
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
el.setAttribute(prop, parseEx(r));
|
|
123
126
|
}
|
|
124
|
-
|
|
127
|
+
|
|
125
128
|
const compile = (expr, withReturn = false) => {
|
|
126
|
-
|
|
127
|
-
const hasStatements = /[;\r\n]/.test(expr);
|
|
128
|
-
const useReturn = withReturn && (!hasStatements || expr.trim().startsWith('{') && expr.trim().endsWith('}'));
|
|
129
|
-
const key = `${useReturn}:${expr}`;
|
|
129
|
+
const key = `${withReturn}:${expr}`;
|
|
130
130
|
if (HELIUM.fnCache.has(key)) return HELIUM.fnCache.get(key);
|
|
131
131
|
try {
|
|
132
132
|
const fn = new Function(
|
|
133
133
|
"$","$data","$event","$el","$html","$get","$post","$put","$patch","$delete",
|
|
134
134
|
...Object.keys(state), ...[...HELIUM.refs.keys()],
|
|
135
|
-
|
|
135
|
+
withReturn
|
|
136
136
|
? `with($data){return(${expr.trim()})}`
|
|
137
137
|
: `with($data){${expr.trim()}}`
|
|
138
138
|
);
|
|
139
139
|
HELIUM.fnCache.set(key, fn);
|
|
140
140
|
return fn;
|
|
141
141
|
} catch {
|
|
142
|
-
|
|
142
|
+
try {
|
|
143
|
+
const fn = new Function(
|
|
144
|
+
"$","$data","$event","$el","$html","$get","$post","$put","$patch","$delete",
|
|
145
|
+
...Object.keys(state), ...[...HELIUM.refs.keys()],
|
|
146
|
+
`with($data){${expr.trim()}}`
|
|
147
|
+
);
|
|
148
|
+
HELIUM.fnCache.set(key, fn);
|
|
149
|
+
return fn;
|
|
150
|
+
} catch {
|
|
151
|
+
return () => expr;
|
|
152
|
+
}
|
|
143
153
|
}
|
|
144
154
|
};
|
|
145
155
|
|
|
@@ -215,15 +225,14 @@ function processElements(element) {
|
|
|
215
225
|
}
|
|
216
226
|
else if (name.startsWith(":") || name.startsWith("data-he-attr:")) {
|
|
217
227
|
const fn = compile(value, true);
|
|
218
|
-
deferredBindings.push(
|
|
228
|
+
deferredBindings.push({el, prop: name.slice(name.startsWith(":") ? 1 : 13), fn});
|
|
219
229
|
}
|
|
220
230
|
else if (he(name, "ref")) {
|
|
221
231
|
HELIUM.refs.set("$" + value, el);
|
|
222
232
|
}
|
|
223
233
|
else if (he(name, "text", "html")) {
|
|
224
234
|
const fn = compile(value, true);
|
|
225
|
-
|
|
226
|
-
deferredBindings.push(() => trackDependencies(fn, el).forEach(dep => addBinding(dep, b)));
|
|
235
|
+
deferredBindings.push({el, prop: he(name, "text") ? "textContent" : "innerHTML", fn});
|
|
227
236
|
}
|
|
228
237
|
else if (he(name, "bind")) {
|
|
229
238
|
const event = (isCheckbox || isRadio || isSelect) ? "change" : "input";
|
|
@@ -239,24 +248,17 @@ function processElements(element) {
|
|
|
239
248
|
}
|
|
240
249
|
else if (he(name, "hidden", "visible")) {
|
|
241
250
|
const fn = compile(`${he(name, "hidden") ? "!" : ""}!(${value})`, true);
|
|
242
|
-
deferredBindings.push(
|
|
251
|
+
deferredBindings.push({el, prop: "hidden", fn});
|
|
243
252
|
}
|
|
244
253
|
else if (he(name, "calculate")) {
|
|
245
254
|
const calc = name.split(":")[1];
|
|
246
255
|
const fn = compile(value, true);
|
|
247
|
-
deferredBindings.push(
|
|
256
|
+
deferredBindings.push({el, calc, prop: null, fn});
|
|
248
257
|
}
|
|
249
258
|
else if (he(name, "effect")) {
|
|
250
259
|
const keys = name.split(":").slice(1);
|
|
251
260
|
const fn = compile(value, true);
|
|
252
|
-
deferredBindings.push(
|
|
253
|
-
const tracked = keys.includes("*") ? [ALL] : trackDependencies(fn, el, true).concat(keys);
|
|
254
|
-
tracked.forEach(key => addBinding(key, {el, prop: null, fn}));
|
|
255
|
-
})
|
|
256
|
-
}
|
|
257
|
-
else if (he(name, "class")) {
|
|
258
|
-
const fn = compile(value, true);
|
|
259
|
-
deferredBindings.push(() => trackDependencies(fn, el).forEach(dep => addBinding(dep, {el, prop: "class", fn})));
|
|
261
|
+
deferredBindings.push({el, prop: null, fn, keys});
|
|
260
262
|
}
|
|
261
263
|
else if (he(name, "init")) {
|
|
262
264
|
initFn = compile(value, true);
|
|
@@ -292,11 +294,11 @@ function processElements(element) {
|
|
|
292
294
|
...(getAttr("template") && { template: execFn(getAttr("template")),}),
|
|
293
295
|
...(getAttr("loading") && { loading: execFn(getAttr("loading"))}),
|
|
294
296
|
};
|
|
295
|
-
let paramsAttr = getAttr(
|
|
296
|
-
if (!paramsAttr
|
|
297
|
-
const
|
|
298
|
-
paramsAttr =
|
|
299
|
-
}
|
|
297
|
+
let paramsAttr = getAttr("params");
|
|
298
|
+
if (!paramsAttr && el.hasAttribute("name")) {
|
|
299
|
+
const keys = el.getAttribute("name").match(/\w+/g).map(key => `${key}:`).join``;
|
|
300
|
+
paramsAttr = keys + isCheckbox ? "checked" : "value";
|
|
301
|
+
} else paramsAttr ||= "{}";
|
|
300
302
|
const params = exFn(paramsAttr);
|
|
301
303
|
ajax(value, eventName.toUpperCase(), options, params);
|
|
302
304
|
} else {
|
|
@@ -312,13 +314,13 @@ function processElements(element) {
|
|
|
312
314
|
}
|
|
313
315
|
}
|
|
314
316
|
});
|
|
315
|
-
deferredBindings.forEach(
|
|
317
|
+
deferredBindings.forEach(b => {
|
|
318
|
+
const tracked = b.keys?.includes("*") ? [ALL] : trackDependencies(b.fn, b.el, true).concat(b.keys);
|
|
319
|
+
tracked.forEach(key => addBinding(key, b));
|
|
320
|
+
})
|
|
316
321
|
return newBindings;
|
|
317
322
|
}
|
|
318
323
|
|
|
319
|
-
// Disconnect old observer if it exists
|
|
320
|
-
if (HELIUM.observer) HELIUM.observer.disconnect();
|
|
321
|
-
|
|
322
324
|
// Create new observer
|
|
323
325
|
HELIUM.observer = new MutationObserver(ms => {
|
|
324
326
|
for (const m of ms) {
|
|
@@ -335,22 +337,11 @@ function processElements(element) {
|
|
|
335
337
|
|
|
336
338
|
window.heliumTeardown = function() {
|
|
337
339
|
if (HELIUM?.observer) HELIUM.observer.disconnect();
|
|
338
|
-
HELIUM?.bindings?.clear();
|
|
339
|
-
HELIUM?.refs?.clear();
|
|
340
|
-
HELIUM?.parentKeys?.clear();
|
|
341
|
-
HELIUM?.fnCache?.clear();
|
|
342
340
|
HELIUM = null;
|
|
343
341
|
}
|
|
344
342
|
|
|
345
343
|
// Initialize on load
|
|
346
|
-
document.addEventListener("DOMContentLoaded",
|
|
347
|
-
|
|
344
|
+
document.addEventListener("DOMContentLoaded",_ => helium());
|
|
348
345
|
// Turbo integration
|
|
349
|
-
document.addEventListener("turbo:before-render", ()
|
|
350
|
-
|
|
351
|
-
window.heliumTeardown();
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
document.addEventListener("turbo:render", () => {
|
|
355
|
-
helium();
|
|
356
|
-
});
|
|
346
|
+
document.addEventListener("turbo:before-render",_ => window.heliumTeardown());
|
|
347
|
+
document.addEventListener("turbo:render",_ => helium());
|