@daz4126/helium 0.11.0 → 0.11.1

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 +26 -35
  2. package/package.json +1 -1
package/helium.js CHANGED
@@ -7,9 +7,10 @@ export default function helium(data = {}) {
7
7
  const root = document.querySelector("[\\@helium]") || document.querySelector("[data-helium]") || document.body;
8
8
  const [bindings, refs, listeners] = [new Map(), new Map(), new WeakMap()];
9
9
  const $ = s => document.querySelector(s);
10
- const html = s => {const t = document.createElement("template"); t.innerHTML = s.trim(); return t.content.firstChild};
10
+ const html = s => Object.assign(document.createElement("template"),{innerHTML:s.trim()}).content.firstChild
11
11
 
12
12
  const ajax=(u,m,o={},p={})=>{
13
+ console.log("ajax: ", u,m,o.target,p)
13
14
  const fd=p instanceof FormData,t=document.querySelector('meta[name="csrf-token"]')?.content;
14
15
  fetch(u,{method:m,headers:{
15
16
  Accept:"text/vnd.turbo-stream.html,application/json,text/html",
@@ -23,8 +24,13 @@ const ajax=(u,m,o={},p={})=>{
23
24
  const c=o.template?o.template(d):d;
24
25
  o.action?o.target[o.action=="replace"?"replaceWith":o.action](html(c)):o.target.innerHTML=c;
25
26
  }
26
- }).catch(e=>console.error("AJAX:",e.message))
27
+ }).catch(e=>{
28
+ console.error("AJAX:",e.message);
29
+ })
27
30
  }
31
+
32
+ const get = (u,t) => ajax(u,"GET",t);
33
+ const [post, put, patch, del] = ["POST","PUT","PATCH","DELETE"].map(m => (u, d, t) => ajax(u, m, t, d));
28
34
 
29
35
  const handler = {
30
36
  get: (t, p, r) => {const v = Reflect.get(t, p, r); return typeof v == "object" && v != null ? new Proxy(v, handler) : v},
@@ -46,13 +52,13 @@ function applyBinding(b,e={},elCtx=b.el){
46
52
 
47
53
  const compile = (expr, withReturn = false) => {
48
54
  try {
49
- return new Function("$", "$data", "$event", "$el", "$html", ...Object.keys(data), ...[...refs.keys()],
55
+ return new Function("$", "$data", "$event", "$el", "$html","$get", "$post", "$put","$patch","$delete",...Object.keys(data), ...[...refs.keys()],
50
56
  `with($data){${withReturn ? "return" : ""}(${expr.trim()})}`);
51
57
  } catch {return () => expr}
52
58
  };
53
59
 
54
60
  const trackDependencies=fn=>{
55
- const s=new Set(),p=new Proxy(data,{get:(t,k)=>{if(typeof k=="string")s.add(k);const v=t[k];return v&&typeof v=="object"?new Proxy(v,this):v}});
61
+ 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}});
56
62
  try{fn($,p,refs)}catch{};return[...s]
57
63
  }
58
64
 
@@ -89,47 +95,40 @@ const trackDependencies=fn=>{
89
95
  };
90
96
 
91
97
  heElements.forEach(el => {
92
- const execFn = v => compile(v, true)($, state, {}, el, html, ...Object.values(data), ...[...refs.values()]);
98
+ const execFn = v => compile(v, true)($, state, {}, el, html,get,post, put,patch,del, ...Object.values(data), ...[...refs.values()]);
93
99
  const inputType = el.type?.toLowerCase();
94
100
  const isCheckbox = inputType == "checkbox", isRadio = inputType == "radio", isSelect = el.tagName == "SELECT";
95
101
 
96
102
  for (const {name, value} of el.attributes || []) {
97
103
  if (["@data","data-he"].includes(name)) Object.assign(state, execFn(value));
98
- if (he(name,"ref")) refs.set("$" + value, el);
99
-
104
+ if (he(name,"ref")) refs.set("$" + value, el);
100
105
  if (he(name,"text","html")) {
101
106
  const fn = compile(value, true);
102
107
  const b = {el, prop: he(name,"text") ? "textContent" : "innerHTML", fn};
103
108
  trackDependencies(fn, el).forEach(dep => addBinding(dep, b));
104
109
  }
105
-
106
110
  if (he(name,"bind")) {
107
111
  const event = (isCheckbox || isRadio || isSelect) ? "change" : "input";
108
112
  const prop = isCheckbox ? "checked" : "value";
109
- const inputHandler = e => state[value] = isCheckbox ? e.target.checked : e.target.value;
110
-
113
+ const inputHandler = e => state[value] = isCheckbox ? e.target.checked : e.target.value;
111
114
  el.addEventListener(event, inputHandler);
112
115
  if (!listeners.has(el)) listeners.set(el, []);
113
116
  listeners.get(el).push({receiver: el, event, handler: inputHandler});
114
- addBinding(value, {el, prop, fn: compile(value, true)});
115
-
117
+ addBinding(value, {el, prop, fn: compile(value, true)});
116
118
  if (isCheckbox) el.checked = !!state[value];
117
119
  else if (isRadio) el.checked = el.value == state[value];
118
120
  else el.value = state[value] ?? "";
119
121
  }
120
-
121
122
  if (he(name,"hidden","visible")) {
122
123
  const fn = compile(`${he(name,"hidden") ? "!" : ""}!(${value})`, true);
123
124
  trackDependencies(fn, el).forEach(dep => addBinding(dep, {el, prop: "hidden", fn}));
124
125
  }
125
-
126
126
  if (name.startsWith(":")) {
127
127
  const fn = compile(value, true);
128
128
  trackDependencies(fn, el).forEach(dep => addBinding(dep, {el, prop: name.slice(1), fn}));
129
129
  }
130
-
131
130
  if (he(name,"init")) {
132
- compile(value, false)($, state, undefined, el, html, ...Object.values(data), ...[...refs.values()]);
131
+ execFn(value);
133
132
  } else if (name.startsWith("@") || name.startsWith("data-he")) {
134
133
  const fullName = name.startsWith("@") ? name.slice(1) : name.slice(8);
135
134
  const [eventName, ...mods] = fullName.split(".");
@@ -138,40 +137,35 @@ const trackDependencies=fn=>{
138
137
  const receiver = mods.includes("outside") || mods.includes("document") ? document : el;
139
138
  const debounceMod = mods.find(m => m.startsWith("debounce"));
140
139
  const debounceDelay = debounceMod ? (t => t && !isNaN(t) ? Number(t) : 300)(debounceMod.split(":")[1]) : 0;
141
-
142
140
  const _handler = e => {
143
- if (mods.includes("prevent")) e.preventDefault();
144
-
141
+ const exFn = v => compile(v, true)($, state, e, el, html,get,post,put,patch,del, ...Object.values(data), ...[...refs.values()])
142
+ if (mods.includes("prevent")) e.preventDefault();
145
143
  const keyMods = {shift: "shiftKey", ctrl: "ctrlKey", alt: "altKey", meta: "metaKey"};
146
- for (const [mod, prop] of Object.entries(keyMods)) if (mods.includes(mod) && !e[prop]) return;
147
-
144
+ for (const [mod, prop] of Object.entries(keyMods)) if (mods.includes(mod) && !e[prop]) return;
148
145
  if (["keydown","keyup","keypress"].includes(event)) {
149
146
  const last = mods[mods.length - 1];
150
147
  if (last && !["prevent","once","outside","document"].includes(last)) {
151
148
  const keyName = e.key == " " ? "Space" : e.key == "Escape" ? "Esc" : e.key;
152
149
  if (keyName.toLowerCase() !== last.toLowerCase()) return;
153
150
  }
154
- }
155
-
156
- if (!mods.includes("outside") || !el.contains(e.target)) {
151
+ }
152
+ if (!mods.includes("outside") || !el.contains(e.target)) {
157
153
  if (isHttpMethod) {
158
- const options = compile(el.getAttribute('data-he-options') || el.getAttribute('options') || '{}', true)($, state, e, el, html, ...Object.values(data), ...[...refs.values()]);
159
- let paramsAttr = el.getAttribute('data-he-params') || el.getAttribute('params') || '{}';
160
-
154
+ const options = exFn(el.getAttribute('data-he-options') || el.getAttribute('options') || '{}');
155
+ let paramsAttr = el.getAttribute('data-he-params') || el.getAttribute('params') || '{}';
161
156
  if (!paramsAttr.trim().startsWith("{") && paramsAttr.includes(":")) {
162
157
  const props = paramsAttr.split(":").map(s => s.trim());
163
158
  paramsAttr = props.reduceRight((acc, key, i) => `{ ${key}: ${i == 1 ? `'${el[acc]}'` : acc} }`);
164
159
  }
165
- const params = compile(paramsAttr, true)($, state, e, el, html, ...Object.values(data), ...[...refs.values()]);
160
+ const params = exFn(paramsAttr);
161
+ console.log("params: ",params)
166
162
  ajax(value, eventName.toUpperCase(), options, params);
167
163
  } else {
168
- compile(value, false)($, state, e, el, html, ...Object.values(data), ...[...refs.values()]);
164
+ exFn(value);
169
165
  }
170
- }
171
-
166
+ }
172
167
  if (mods.includes("once")) receiver.removeEventListener(event, handler);
173
168
  };
174
-
175
169
  const handler = debounceDelay > 0 ? debounce(_handler, debounceDelay) : _handler;
176
170
  receiver.addEventListener(event, handler);
177
171
  if (!listeners.has(el)) listeners.set(el, []);
@@ -179,10 +173,8 @@ const trackDependencies=fn=>{
179
173
  }
180
174
  }
181
175
  });
182
-
183
176
  return newBindings;
184
177
  }
185
-
186
178
  new MutationObserver(ms=>{
187
179
  if(isUpdatingDOM)return;
188
180
  for(const m of ms){
@@ -190,7 +182,6 @@ const trackDependencies=fn=>{
190
182
  m.addedNodes.forEach(n=>n.nodeType==1&&!n.hasAttribute("data-he-p")&&processElements(n).forEach(applyBinding));
191
183
  }
192
184
  }).observe(root,{childList:1,subtree:1});
193
-
194
185
  processElements(root);
195
186
  for (const [key, items] of bindings.entries()) items.forEach(applyBinding);
196
187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daz4126/helium",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "main": "helium.js",
5
5
  "type": "module",
6
6
  "scripts": {