@daz4126/helium 0.23.0 → 0.24.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 +18 -58
  2. package/helium.js +20 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,11 +18,10 @@ It's really simple to use - just sprinkle the magic @attributes into your HTML a
18
18
 
19
19
  Helium is designed for developers who want:
20
20
 
21
- - **Zero build step** - Works directly in the browser with a simple script tag
22
- - **Minimal learning curve** - If you know HTML and basic JavaScript, you're ready
23
- - **Ultra-lightweight** - Under 3KB minified and gzipped
24
- - **Template-first** - Your HTML is the source of truth, not JavaScript
25
- - **Progressive enhancement** - Add interactivity gradually where you need it
21
+ - **Lightweight** - Just over 3KB minified and gzipped
22
+ - **Powerful** - Declarative JavaScript in your HTML
23
+ - **Zero build step** Works directly in the browser with no compiling
24
+ - **Easy to learn** If you know HTML and basic JavaScript, you're ready
26
25
 
27
26
  ## Installation
28
27
 
@@ -33,7 +32,6 @@ Just import from the CDN in a script tag directly in your HTML page:
33
32
  ```html
34
33
  <script type="module">
35
34
  import helium from 'https://cdn.jsdelivr.net/gh/daz-codes/helium/helium.js';
36
- helium();
37
35
  </script>
38
36
  ```
39
37
 
@@ -47,7 +45,6 @@ Then include it in your JavaScript file and call the helium() function:
47
45
 
48
46
  ```javascript
49
47
  import helium from "@daz4126/helium"
50
- helium()
51
48
  ```
52
49
 
53
50
  ### Automatic Initialization
@@ -705,34 +702,16 @@ Object containing all elements marked with `@ref` (prefixed with `$`):
705
702
  <button @click="console.log($username.value)">Log Username</button>
706
703
  ```
707
704
 
708
- ## Default Variables and Functions
705
+ ## Functions
709
706
 
710
- The helium function accepts a single JavaScript object as an argument. This can include default variable values and functions that can then be called inside the JavaScript expressions.
711
-
712
- ### Setting Default Values
713
-
714
- The following will set the count variable to an initial value of 29 and the name variable to "Helium":
715
-
716
- ```javascript
717
- helium({
718
- count: 29,
719
- name: "Helium"
720
- })
721
- ```
722
-
723
- These variables will be available in all Helium expressions:
724
-
725
- ```html
726
- <p @text="count"></p> <!-- Shows: 29 -->
727
- <p @text="name"></p> <!-- Shows: Helium -->
728
- ```
707
+ Functions can be imported using `@import` or defined using the `@data` attribute.
729
708
 
730
709
  ### Adding Functions
731
710
 
732
711
  You can add functions that can be called from event handlers and other expressions:
733
712
 
734
- ```javascript
735
- helium({
713
+ ```html
714
+ @data= "{
736
715
  appendTo(element) {
737
716
  const li = document.createElement("li")
738
717
  li.textContent = "New Item"
@@ -745,7 +724,7 @@ helium({
745
724
  currency: 'USD'
746
725
  }).format(amount)
747
726
  }
748
- })
727
+ }"
749
728
  ```
750
729
 
751
730
  Using these functions:
@@ -765,12 +744,12 @@ Using these functions:
765
744
 
766
745
  ❌ **This won't work as expected:**
767
746
 
768
- ```javascript
769
- helium({
747
+ ```html
748
+ @data = "{
770
749
  increment(n = 1) {
771
750
  count += n // 'count' is not defined in this scope
772
751
  }
773
- })
752
+ }"
774
753
  ```
775
754
 
776
755
  ```html
@@ -780,12 +759,12 @@ helium({
780
759
  ✅ **Instead, pass variables as arguments:**
781
760
 
782
761
  **Option 1: Pass specific variables**
783
- ```javascript
784
- helium({
762
+ ```html
763
+ @data = "{
785
764
  increment(currentCount, n = 1) {
786
765
  return currentCount + n
787
766
  }
788
- })
767
+ }"
789
768
  ```
790
769
 
791
770
  ```html
@@ -796,8 +775,8 @@ helium({
796
775
 
797
776
  This is the recommended approach when you need to update variables:
798
777
 
799
- ```javascript
800
- helium({
778
+ ```html
779
+ @data = "{
801
780
  increment(data, n = 1) {
802
781
  data.count += n // Will trigger reactivity
803
782
  },
@@ -807,7 +786,7 @@ helium({
807
786
  data.name = ''
808
787
  data.items = []
809
788
  }
810
- })
789
+ }"
811
790
  ```
812
791
 
813
792
  ```html
@@ -829,7 +808,6 @@ If you include [Idiomorph](https://github.com/bigskysoftware/idiomorph), Helium
829
808
  <script src="https://unpkg.com/idiomorph@0.3.0/dist/idiomorph.min.js"></script>
830
809
  <script type="module">
831
810
  import helium from 'https://cdn.jsdelivr.net/gh/daz-codes/helium/helium.js';
832
- helium();
833
811
  </script>
834
812
  ```
835
813
 
@@ -891,24 +869,6 @@ Helium automatically integrates with Turbo Drive:
891
869
 
892
870
  No additional configuration needed - just use Helium with Turbo normally.
893
871
 
894
- ### Manual Cleanup
895
-
896
- If you need to manually clean up Helium (for example, when unmounting a section of your page):
897
-
898
- ```javascript
899
- window.heliumTeardown()
900
- ```
901
-
902
- This will:
903
- - Disconnect the MutationObserver
904
- - Remove all event listeners
905
- - Clear all internal state
906
-
907
- To reinitialize after teardown:
908
- ```javascript
909
- helium()
910
- ```
911
-
912
872
  ## Security Considerations
913
873
 
914
874
  ### XSS Prevention
package/helium.js CHANGED
@@ -34,7 +34,7 @@ window.helium = function() {
34
34
 
35
35
  const update = (data,targets,actions,template) => {
36
36
  const newTargets = [];
37
- targets?.forEach((target,i) => {
37
+ targets.forEach((target,i) => {
38
38
  const element = target instanceof Node ? target : (HELIUM.refs.get(target.trim()) || $(target.trim()));
39
39
  if(element){
40
40
  const content = template ? template(data) : data;
@@ -46,7 +46,7 @@ window.helium = function() {
46
46
  }
47
47
 
48
48
  const ajax = (url,method,options={},params={}) => {
49
- if(options.loading && options.target) options.target = update(options.loading,options.target,options.action) || options.target;
49
+ if(options.loading) options.target = update(options.loading,options.target,options.action) || options.target;
50
50
  const fd = params instanceof FormData, token = document.querySelector('meta[name="csrf-token"]')?.content;
51
51
  const path = new URL(url, window.location.href);
52
52
  const sameOrigin = path.origin === window.location.origin;
@@ -180,7 +180,7 @@ const trackDependencies = (fn, el, excludeChanged = false) => {
180
180
  });
181
181
  };
182
182
 
183
- function processElements(element) {
183
+ async function processElements(element) {
184
184
  const newBindings = [];
185
185
  const deferredBindings = [];
186
186
 
@@ -191,6 +191,20 @@ function processElements(element) {
191
191
  HELIUM.bindings.set(val, b.calc ? [b,...(HELIUM.bindings.get(val) || [])] : [...(HELIUM.bindings.get(val) || []), b]);
192
192
  b.calc ? newBindings.unshift(b) : newBindings.push(b);
193
193
  };
194
+
195
+ heElements.forEach(async el => {
196
+ const importAttr = el.getAttribute("@import") || el.getAttribute("data-he-import");
197
+ if (importAttr) {
198
+ importAttr.split(",").map(m => m.trim()).forEach(async moduleName => {
199
+ try {
200
+ const module = await import(`helium_modules/${moduleName}.js`);
201
+ Object.keys(module).forEach(key => state[key] = module[key]);
202
+ } catch (error) {
203
+ console.error(`Failed to import module: ${moduleName}`, error.message);
204
+ }
205
+ })
206
+ }
207
+ })
194
208
 
195
209
  heElements.forEach(el => {
196
210
  HELIUM.processed.add(el);
@@ -249,9 +263,6 @@ function processElements(element) {
249
263
  else if (he(name, "effect")) {
250
264
  deferredBindings.push({el, prop: null, fn: compile(value, true), keys: name.split(":").slice(1)});
251
265
  }
252
- else if (he(name, "import")) {
253
- value.split(",").map(s => s.trim()).forEach(v => state[v] = window[v]);
254
- }
255
266
  else if (he(name, "init")) {
256
267
  initFn = compile(value, true);
257
268
  }
@@ -278,9 +289,9 @@ function processElements(element) {
278
289
  if (!mods.includes("outside") || !el.contains(e.target)) {
279
290
  if (isHttpMethod) {
280
291
  const getAttr = name => el.getAttribute(`data-he-${name}`) || el.getAttribute(`@${name}`);
281
- const pairs = getAttr('target')?.split(",")?.map(p => p.split(":").map(s => s.trim()));
282
- const target = pairs?.map(([target]) => target);
283
- const action = pairs?.map(([, action]) => action);
292
+ const pairs = (getAttr('target') || "").split(",").map(p => p.split(":").map(s => s.trim()));
293
+ const target = pairs.map(([target]) => target);
294
+ const action = pairs.map(([, action]) => action);
284
295
  const options = {
285
296
  ...(getAttr("options") && parseEx(getAttr("options") || "{}")),
286
297
  ...(target && { target }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daz4126/helium",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "main": "helium.js",
5
5
  "type": "module",
6
6
  "scripts": {