export class TurnStilleCaptcha { sitekey = "{{.SiteKey}}"; /** * Initializes the TurnStilleCaptcha instance. * Creates a container for the captcha and appends it to the target element. * If the Cloudflare Turnstile script is already loaded, it runs the captcha. * Otherwise, it loads the script and initializes the captcha with the given properties. * @param {HTMLElement} target - The element to attach the captcha container to. * @param {Object} [props={}] - Optional properties for captcha initialization, such as theme. */ constructor(target, props = {}) { // create holder this.holder = document.createElement("div"); this.holder.id = "turnstile-container"; this.theme = props.theme || "auto"; target.appendChild(this.holder); // execute code if (window.turnstile) { this.runCaptcha(); } else { this.loadCloudflareScript(); } } runCaptcha() { setTimeout(() => { if (globalThis.turnstileInstance) { window.turnstile.remove(globalThis.turnstileInstance); } globalThis.turnstileInstance = window.turnstile.render(this.holder, { sitekey: this.sitekey, theme: this.theme, callback: (token) => { if (token) { const event = new CustomEvent("token", { detail: token, bubbles: true, }); this.holder.dispatchEvent(event); } }, error: (error) => { const event = new CustomEvent("failure", { detail: error, bubbles: true, }); this.holder.dispatchEvent(event); window.turnstile.reset(globalThis.turnstileInstance); }, }); }, 1000); } loadCloudflareScript() { const script = document.createElement("script"); script.id = "turnstile-script"; script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js"; // script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"; script.async = true; script.defer = true; script.onload = () => { const event = new CustomEvent("loaded", { detail: "Turnstile script loaded", bubbles: true, }); this.holder.dispatchEvent(event); this.runCaptcha(); }; script.onerror = () => { const event = new CustomEvent("failure", { detail: "Failed to load Turnstile script", bubbles: true, }); this.holder.dispatchEvent(event); }; document.head.appendChild(script); } }