@daz4126/helium 0.18.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.
Files changed (2) hide show
  1. package/helium.js +32 -40
  2. package/package.json +1 -1
package/helium.js CHANGED
@@ -117,32 +117,39 @@ function applyBinding(b,e={},elCtx=b.el){
117
117
  .map(([k,v])=>`${k}:${v}`).join(";");
118
118
 
119
119
  if (prop in el) {
120
- if(el.type==="radio") el.checked = el.value===r;
120
+ if (el.type === "radio" && prop != "checked") el.checked = el.value===r;
121
121
  else el[prop] = prop==="textContent"?r:parseEx(r);
122
122
  return;
123
123
  }
124
124
 
125
125
  el.setAttribute(prop, parseEx(r));
126
126
  }
127
-
127
+
128
128
  const compile = (expr, withReturn = false) => {
129
- // Auto-detect if this should be a statement block
130
- const hasStatements = /[;\r\n]/.test(expr);
131
- const useReturn = withReturn && (!hasStatements || expr.trim().startsWith('{') && expr.trim().endsWith('}'));
132
- const key = `${useReturn}:${expr}`;
129
+ const key = `${withReturn}:${expr}`;
133
130
  if (HELIUM.fnCache.has(key)) return HELIUM.fnCache.get(key);
134
131
  try {
135
132
  const fn = new Function(
136
133
  "$","$data","$event","$el","$html","$get","$post","$put","$patch","$delete",
137
134
  ...Object.keys(state), ...[...HELIUM.refs.keys()],
138
- useReturn
135
+ withReturn
139
136
  ? `with($data){return(${expr.trim()})}`
140
137
  : `with($data){${expr.trim()}}`
141
138
  );
142
139
  HELIUM.fnCache.set(key, fn);
143
140
  return fn;
144
141
  } catch {
145
- return () => expr;
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
+ }
146
153
  }
147
154
  };
148
155
 
@@ -218,15 +225,14 @@ function processElements(element) {
218
225
  }
219
226
  else if (name.startsWith(":") || name.startsWith("data-he-attr:")) {
220
227
  const fn = compile(value, true);
221
- deferredBindings.push(() => trackDependencies(fn, el).forEach(dep => addBinding(dep, {el, prop: name.slice(name.startsWith(":") ? 1 : 13), fn})));
228
+ deferredBindings.push({el, prop: name.slice(name.startsWith(":") ? 1 : 13), fn});
222
229
  }
223
230
  else if (he(name, "ref")) {
224
231
  HELIUM.refs.set("$" + value, el);
225
232
  }
226
233
  else if (he(name, "text", "html")) {
227
234
  const fn = compile(value, true);
228
- const b = {el, prop: he(name, "text") ? "textContent" : "innerHTML", fn};
229
- deferredBindings.push(() => trackDependencies(fn, el).forEach(dep => addBinding(dep, b)));
235
+ deferredBindings.push({el, prop: he(name, "text") ? "textContent" : "innerHTML", fn});
230
236
  }
231
237
  else if (he(name, "bind")) {
232
238
  const event = (isCheckbox || isRadio || isSelect) ? "change" : "input";
@@ -242,20 +248,17 @@ function processElements(element) {
242
248
  }
243
249
  else if (he(name, "hidden", "visible")) {
244
250
  const fn = compile(`${he(name, "hidden") ? "!" : ""}!(${value})`, true);
245
- deferredBindings.push(() => trackDependencies(fn, el).forEach(dep => addBinding(dep, {el, prop: "hidden", fn})));
251
+ deferredBindings.push({el, prop: "hidden", fn});
246
252
  }
247
253
  else if (he(name, "calculate")) {
248
254
  const calc = name.split(":")[1];
249
255
  const fn = compile(value, true);
250
- deferredBindings.push(() => trackDependencies(fn, el, true).forEach(key => addBinding(key, {el, calc, prop: null, fn})));
256
+ deferredBindings.push({el, calc, prop: null, fn});
251
257
  }
252
258
  else if (he(name, "effect")) {
253
259
  const keys = name.split(":").slice(1);
254
260
  const fn = compile(value, true);
255
- deferredBindings.push(() => {
256
- const tracked = keys.includes("*") ? [ALL] : trackDependencies(fn, el, true).concat(keys);
257
- tracked.forEach(key => addBinding(key, {el, prop: null, fn}));
258
- })
261
+ deferredBindings.push({el, prop: null, fn, keys});
259
262
  }
260
263
  else if (he(name, "init")) {
261
264
  initFn = compile(value, true);
@@ -291,11 +294,11 @@ function processElements(element) {
291
294
  ...(getAttr("template") && { template: execFn(getAttr("template")),}),
292
295
  ...(getAttr("loading") && { loading: execFn(getAttr("loading"))}),
293
296
  };
294
- let paramsAttr = getAttr('params') || '{}';
295
- if (!paramsAttr.trim().startsWith("{") && paramsAttr.includes(":")) {
296
- const props = paramsAttr.split(":").map(s => s.trim());
297
- paramsAttr = props.reduceRight((acc, key, i) => `{ ${key}: ${i == 1 ? `'${el[acc]}'` : acc} }`);
298
- }
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 ||= "{}";
299
302
  const params = exFn(paramsAttr);
300
303
  ajax(value, eventName.toUpperCase(), options, params);
301
304
  } else {
@@ -311,13 +314,13 @@ function processElements(element) {
311
314
  }
312
315
  }
313
316
  });
314
- deferredBindings.forEach(fn => fn());
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
+ })
315
321
  return newBindings;
316
322
  }
317
323
 
318
- // Disconnect old observer if it exists
319
- if (HELIUM.observer) HELIUM.observer.disconnect();
320
-
321
324
  // Create new observer
322
325
  HELIUM.observer = new MutationObserver(ms => {
323
326
  for (const m of ms) {
@@ -334,22 +337,11 @@ function processElements(element) {
334
337
 
335
338
  window.heliumTeardown = function() {
336
339
  if (HELIUM?.observer) HELIUM.observer.disconnect();
337
- HELIUM?.bindings?.clear();
338
- HELIUM?.refs?.clear();
339
- HELIUM?.parentKeys?.clear();
340
- HELIUM?.fnCache?.clear();
341
340
  HELIUM = null;
342
341
  }
343
342
 
344
343
  // Initialize on load
345
- document.addEventListener("DOMContentLoaded", () => helium());
346
-
344
+ document.addEventListener("DOMContentLoaded",_ => helium());
347
345
  // Turbo integration
348
- document.addEventListener("turbo:before-render", () => {
349
- if (HELIUM?.observer) HELIUM.observer.disconnect();
350
- window.heliumTeardown();
351
- });
352
-
353
- document.addEventListener("turbo:render", () => {
354
- helium();
355
- });
346
+ document.addEventListener("turbo:before-render",_ => window.heliumTeardown());
347
+ document.addEventListener("turbo:render",_ => helium());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daz4126/helium",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "main": "helium.js",
5
5
  "type": "module",
6
6
  "scripts": {