@daz4126/helium 0.1.0 โ†’ 0.2.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 (3) hide show
  1. package/README.md +1 -1
  2. package/helium.js +189 -45
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ๐ŸŽˆHelium๐ŸŽˆ
2
2
 
3
- Light & powerful .... Helium makes HTML interactive!
3
+ The ultra-light library that makes HTML interactive!
4
4
 
5
5
  ```html
6
6
  <main @helium>
package/helium.js CHANGED
@@ -1,60 +1,204 @@
1
1
  export default function helium(data = {}) {
2
- const root = document.querySelector("[\\@helium]") || document.querySelector("[data-helium]") || document.body
3
- const [bindings, refs] = [new Map(), new Map()]
4
- const $ = selector => document.querySelector(selector)
2
+ const root =
3
+ document.querySelector("[\\@helium]") ||
4
+ document.querySelector("[data-helium]") ||
5
+ document.body;
6
+ const [bindings, refs] = [new Map(), new Map()];
7
+ const $ = (selector) => document.querySelector(selector);
5
8
  const state = new Proxy(data, {
6
- get(target, prop) { return target[prop] },
9
+ get(target, prop) {
10
+ return target[prop];
11
+ },
7
12
  set(target, prop, value) {
8
- target[prop] = value
9
- if (bindings.has(prop)) bindings.get(prop).forEach(binding => applyBinding(binding))
10
- return true
11
- }
12
- })
13
+ target[prop] = value;
14
+ if (bindings.has(prop))
15
+ bindings.get(prop).forEach((binding) => applyBinding(binding));
16
+ return true;
17
+ },
18
+ });
13
19
  function applyBinding(binding, event = {}, elCtx = binding.el) {
14
- const { el, prop, fn } = binding
15
- const result = fn($, state, event, elCtx, ...Object.values(data), ...[...refs.values()])
16
- if (prop in el) el[prop] = result
17
- else el.setAttribute(prop, result)
20
+ const { el, prop, fn } = binding;
21
+ const result = fn(
22
+ $,
23
+ state,
24
+ event,
25
+ elCtx,
26
+ ...Object.values(data),
27
+ ...[...refs.values()],
28
+ );
29
+ if (prop in el) el[prop] = result;
30
+ else el.setAttribute(prop, result);
18
31
  }
19
32
  function compileExpression(expr, withReturn = false) {
20
- try {
21
- return new Function("$", "$state", "$event", "$el", ...Object.keys(data), ...[...refs.keys()],`with($state) { ${withReturn ? "return" : ""} (${expr.trim()}) }`)
22
- } catch (err) { return () => expr }
33
+ try {
34
+ return new Function(
35
+ "$",
36
+ "$state",
37
+ "$event",
38
+ "$el",
39
+ ...Object.keys(data),
40
+ ...[...refs.keys()],
41
+ `with($state) { ${withReturn ? "return" : ""} (${expr.trim()}) }`,
42
+ );
43
+ } catch (err) {
44
+ return () => expr;
45
+ }
23
46
  }
24
47
  function processElements(element) {
25
- const heliumElements = [element, ...Array.from(element.querySelectorAll("*")).filter(el => Array.from(el.attributes).some(attr => attr.name.startsWith("data-he-"))),]
26
- const xpath = document.evaluate(".//*[@*[starts-with(name(), '@') or starts-with(name(), ':')]]",element,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null)
27
- for (let i = 0; i < xpath.snapshotLength; i++) heliumElements.push(xpath.snapshotItem(i))
28
- heliumElements.forEach(el => {
48
+ const heliumElements = [
49
+ element,
50
+ ...Array.from(element.querySelectorAll("*")).filter((el) =>
51
+ Array.from(el.attributes).some((attr) =>
52
+ attr.name.startsWith("data-he-"),
53
+ ),
54
+ ),
55
+ ];
56
+ const xpath = document.evaluate(
57
+ ".//*[@*[starts-with(name(), '@') or starts-with(name(), ':')]]",
58
+ element,
59
+ null,
60
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
61
+ null,
62
+ );
63
+ for (let i = 0; i < xpath.snapshotLength; i++)
64
+ heliumElements.push(xpath.snapshotItem(i));
65
+ heliumElements.forEach((el) => {
66
+ for (const { name, value } of el.attributes) {
67
+ if (
68
+ name == "@react" ||
69
+ name == "data-he-react" ||
70
+ name == "@bind" ||
71
+ name == "data-he-bind"
72
+ ) {
73
+ try {
74
+ new Function(`let ${value} = 1`);
75
+ state[value] ||=
76
+ name == "@react" || name == "data-he-react"
77
+ ? el.textContent
78
+ : el.value;
79
+ } catch (e) {}
80
+ }
81
+ }
82
+ });
83
+ heliumElements.forEach((el) => {
29
84
  for (const { name, value } of el.attributes) {
30
- if (name == "@data" || name == "data-he") Object.assign(state, compileExpression(value, true)($, state, {}, el, ...Object.values(data), ...[...refs.values()]))
31
- if (name == "@ref" || name == "data-he-ref") refs.set("$" + value, el)
32
- if (name == "@react" || name == "data-he-react") Object.keys(state).filter(key => value.includes(key)).forEach(val =>
33
- bindings.set(val, [...(bindings.get(val) || []), { el, prop: "textContent", expr: value, fn: compileExpression(value, true) }])
34
- )
85
+ if (name == "@data" || name == "data-he")
86
+ Object.assign(
87
+ state,
88
+ compileExpression(value, true)(
89
+ $,
90
+ state,
91
+ {},
92
+ el,
93
+ ...Object.values(data),
94
+ ...[...refs.values()],
95
+ ),
96
+ );
97
+ if (name == "@ref" || name == "data-he-ref") refs.set("$" + value, el);
98
+ if (name == "@react" || name == "data-he-react")
99
+ Object.keys(state)
100
+ .filter((key) => value.includes(key))
101
+ .forEach((val) =>
102
+ bindings.set(val, [
103
+ ...(bindings.get(val) || []),
104
+ {
105
+ el,
106
+ prop: "textContent",
107
+ expr: value,
108
+ fn: compileExpression(value, true),
109
+ },
110
+ ]),
111
+ );
35
112
  if (name == "@bind" || name == "data-he-bind") {
36
- el.addEventListener("input", e => (state[value] = e.target.value))
37
- bindings.set(value, [...(bindings.get(value) || []), { el, prop: "value", expr: value, fn: compileExpression(value, true) }])
38
- el.value = state[value]
113
+ el.addEventListener("input", (e) => (state[value] = e.target.value));
114
+ bindings.set(value, [
115
+ ...(bindings.get(value) || []),
116
+ {
117
+ el,
118
+ prop: "value",
119
+ expr: value,
120
+ fn: compileExpression(value, true),
121
+ },
122
+ ]);
123
+ el.value = state[value];
39
124
  }
40
- if (name == "@hidden" || name == "@visible" || name == "data-he-hidden" || name == "data-he-visible") Object.keys(state).filter(key => value.includes(key)).forEach(val => bindings.set(val, [...(bindings.get(val) || []), { el, prop: "hidden", expr: value, fn: compileExpression(`${(name == "@hidden" || name == "data-he-hidden") ? "!" : ""}!(${value})`, true) }]))
41
- if (name.startsWith(":")) Object.keys(state).filter(key => value.includes(key)).forEach(val => bindings.set(val, [...(bindings.get(val) || []), { el, prop: name.split(":")[1], expr: value, fn: compileExpression(value, true) }]))
42
- if (name == "@init" || name == "data-he-init") compileExpression(value, false)($, state, undefined, el, ...Object.values(data), ...[...refs.values()])
125
+ if (
126
+ name == "@hidden" ||
127
+ name == "@visible" ||
128
+ name == "data-he-hidden" ||
129
+ name == "data-he-visible"
130
+ )
131
+ Object.keys(state)
132
+ .filter((key) => value.includes(key))
133
+ .forEach((val) =>
134
+ bindings.set(val, [
135
+ ...(bindings.get(val) || []),
136
+ {
137
+ el,
138
+ prop: "hidden",
139
+ expr: value,
140
+ fn: compileExpression(
141
+ `${name == "@hidden" || name == "data-he-hidden" ? "!" : ""}!(${value})`,
142
+ true,
143
+ ),
144
+ },
145
+ ]),
146
+ );
147
+ if (name.startsWith(":"))
148
+ Object.keys(state)
149
+ .filter((key) => value.includes(key))
150
+ .forEach((val) =>
151
+ bindings.set(val, [
152
+ ...(bindings.get(val) || []),
153
+ {
154
+ el,
155
+ prop: name.split(":")[1],
156
+ expr: value,
157
+ fn: compileExpression(value, true),
158
+ },
159
+ ]),
160
+ );
161
+ if (name == "@init" || name == "data-he-init")
162
+ compileExpression(value, false)(
163
+ $,
164
+ state,
165
+ undefined,
166
+ el,
167
+ ...Object.values(data),
168
+ ...[...refs.values()],
169
+ );
43
170
  else if (name.startsWith("@") || name.startsWith("data-he-on")) {
44
- const [eventName, ...modifiers] = name.slice(name.startsWith("@") ? 1 : 10).split(".")
45
- const receiver = modifiers.includes("outside") ? document : el
171
+ const [eventName, ...modifiers] = name
172
+ .slice(name.startsWith("@") ? 1 : 10)
173
+ .split(".");
174
+ const receiver = modifiers.includes("outside") ? document : el;
46
175
  receiver.addEventListener(eventName, function _handler(e) {
47
- if (modifiers.includes("prevent")) e.preventDefault()
48
- if (!modifiers.includes("outside") || !el.contains(e.target)) compileExpression(value, false)($, state, e, el, ...Object.values(data), ...[...refs.values()])
49
- if (modifiers.includes("once")) el.removeEventListener(eventName, _handler)
50
- })}}})
51
- const observer = new MutationObserver(mutations => {
52
- for (const m of mutations) {
53
- for (const node of m.addedNodes) {
54
- if (node.nodeType === 1) processElements(node)
55
- }}})
56
- observer.observe(element, { childList: true, subtree: true })
57
- for (const [key, items] of bindings.entries()) items.forEach(binding => applyBinding(binding))
176
+ if (modifiers.includes("prevent")) e.preventDefault();
177
+ if (!modifiers.includes("outside") || !el.contains(e.target))
178
+ compileExpression(value, false)(
179
+ $,
180
+ state,
181
+ e,
182
+ el,
183
+ ...Object.values(data),
184
+ ...[...refs.values()],
185
+ );
186
+ if (modifiers.includes("once"))
187
+ el.removeEventListener(eventName, _handler);
188
+ });
189
+ }
190
+ }
191
+ });
192
+ const observer = new MutationObserver((mutations) => {
193
+ for (const m of mutations) {
194
+ for (const node of m.addedNodes) {
195
+ if (node.nodeType === 1) processElements(node);
196
+ }
197
+ }
198
+ });
199
+ observer.observe(element, { childList: true, subtree: true });
200
+ for (const [key, items] of bindings.entries())
201
+ items.forEach((binding) => applyBinding(binding));
58
202
  }
59
- processElements(root)
203
+ processElements(root);
60
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daz4126/helium",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "main": "helium.js",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "author": "DAZ",
14
14
  "license": "MIT",
15
- "description": "A light yet powerful library that makes HTML interactive",
15
+ "description": "The ultra-light library that makes HTML interactive",
16
16
  "repository": {
17
17
  "type": "git",
18
18
  "url": "git+https://github.com/daz-codes/helium.git"