astro-altcha 0.1.5 → 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.
@@ -46,15 +46,17 @@ export type AltchaChallengeOptions<Algo extends Algorithm> = Algo extends "Argon
46
46
  } : OmitCreateChallengeOptions & {
47
47
  algorithm: Exclude<Algorithm, "Argon2id" | "Scrypt">;
48
48
  };
49
- export type AstroAltchaHydrationStrategy = "onfocus" | "onload";
49
+ export type AstroAltchaHydrationStrategy = "onfocus" | "onload" | "onhover";
50
50
  export type AltchaFormWidgetProps = {
51
51
  /** When the altcha-widget should be hydrated.
52
52
  *
53
53
  * `onfocus` - when the form is first focused
54
54
  *
55
55
  * `onload` - when the page first loads
56
+ *
57
+ * `onhover` - when the form is first hovered
56
58
  */
57
- hydrationStrategy?: "onfocus" | "onload";
59
+ hydrationStrategy?: AstroAltchaHydrationStrategy;
58
60
  debug?: boolean;
59
61
  } & Omit<WidgetAttributes, "name">;
60
62
  export type AltchaFormProps = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-altcha",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Altcha integration for Astro",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -18,66 +18,70 @@ const {
18
18
 
19
19
  <form {...formProps}>
20
20
  <slot />
21
- <altcha-widget
22
- data-astro-altcha="astro-altcha-form-widget"
23
- {name}
24
- {challenge}
25
- {...widgetProps}
26
- ></altcha-widget>
27
- <script
28
- is:inline
29
- data-astro-altcha="config"
30
- type="application/json"
31
- set:html={JSON.stringify({ hydrationStrategy, debug})}
32
- />
21
+ <template
22
+ data-astro-altcha="form-widget"
23
+ data-hydration-strategy={hydrationStrategy}
24
+ data-debug={debug}
25
+ >
26
+ <altcha-widget {name} {challenge} {...widgetProps}></altcha-widget>
27
+ </template>
33
28
  </form>
34
29
 
35
30
  <script>
36
31
  import type { WidgetAttributes, WidgetMethods } from "altcha/types";
37
32
  import type { AstroAltchaHydrationStrategy } from "astro-altcha/types";
38
33
 
39
- const altchaWidgets = document.querySelectorAll("altcha-widget");
34
+ const templates = document.querySelectorAll("template");
40
35
 
41
- for (const widget of altchaWidgets) {
42
- if (widget.getAttribute("data-astro-altcha") !== "astro-altcha-form-widget") {
36
+ for (const template of templates) {
37
+ if (template.dataset.astroAltcha !== "form-widget") {
43
38
  continue;
44
39
  }
45
40
 
46
- const form = widget.closest("form");
41
+ const form = template.closest("form");
47
42
  if (!form) {
48
- throw new Error("Widget must be placed inside a form element");
43
+ continue;
49
44
  }
50
45
 
51
- const config = form.querySelector("script");
52
- if (config?.getAttribute("data-astro-altcha") !== "config") continue;
46
+ const { hydrationStrategy, debug } = template.dataset;
47
+ const widget = template.content.querySelector("altcha-widget");
48
+ if (!widget) {
49
+ continue;
50
+ }
53
51
 
54
- const {
55
- hydrationStrategy,
56
- debug,
57
- }: {
58
- hydrationStrategy: AstroAltchaHydrationStrategy;
59
- debug: boolean;
60
- } = JSON.parse(config.innerText);
61
- if (hydrationStrategy === "onload") {
62
- await loadAltcha(form, widget, debug);
63
- } else {
64
- form.addEventListener("focusin", () => loadAltcha(form, widget, debug), {
65
- once: true,
66
- });
52
+ const mount = () => mountWidget(form, template, widget, debug === "true");
53
+
54
+ switch (hydrationStrategy as AstroAltchaHydrationStrategy) {
55
+ case "onload":
56
+ void mount();
57
+ break;
58
+ case "onfocus":
59
+ form.addEventListener("focusin", mount, { once: true });
60
+ break;
61
+ case "onhover":
62
+ form.addEventListener("mouseenter", mount, { once: true });
63
+ break;
67
64
  }
68
65
  }
69
66
 
70
- async function loadAltcha(
67
+ async function mountWidget(
71
68
  form: HTMLFormElement,
72
- widget: WidgetAttributes & WidgetMethods & HTMLElement,
69
+ template: HTMLTemplateElement,
70
+ widget: HTMLElement & WidgetAttributes & WidgetMethods,
73
71
  debug: boolean,
74
72
  ) {
75
73
  await import("altcha");
76
- widget.configure({ debug });
77
74
 
78
- const configureEvent = new CustomEvent("astro-altcha:init", {
79
- detail: { widget },
80
- });
81
- form.dispatchEvent(configureEvent);
75
+ const widgetReady = new Promise<void>((resolve) =>
76
+ widget.addEventListener("load", () => resolve(), { once: true }),
77
+ );
78
+
79
+ template.replaceWith(widget);
80
+ await widgetReady;
81
+
82
+ widget.configure({ debug });
83
+ form.dispatchEvent(
84
+ new CustomEvent("astro-altcha:init", { detail: { widget } }),
85
+ );
82
86
  }
83
87
  </script>