PageSourceSearch

https://fania.com/wp-content/plugins/klr-router/assets/form.js?ver=1.8

js fania.com collected 2026-09-24 17:47:30 UTC 7,463 bytes, 231 lines download raw bytes

1(function () {
2  // If localization failed, let the browser submit normally (no-JS fallback).
3  if (typeof window.KLR_FORM === 'undefined' || !window.KLR_FORM.endpoint) {
4    console.warn('[KLR] KLR_FORM missing; using normal form POST.');
5    return;
6  }
7
8  function qs(root, sel) {
9    return root ? root.querySelector(sel) : null;
10  }
11
12  function setStatus(form, msg, ok) {
13    var box = qs(form, '.klr-status');
14    if (!box) return;
15    box.textContent = msg || '';
16    box.setAttribute('data-ok', ok ? '1' : '0');
17  }
18
19  function serialize(form) {
20    var fd = new FormData(form);
21    var out = {};
22    fd.forEach(function (v, k) {
23      if (out[k] !== undefined) {
24        if (!Array.isArray(out[k])) out[k] = [out[k]];
25        out[k].push(v);
26      } else {
27        out[k] = v;
28      }
29    });
30    return out;
31  }
32
33  // --- Turnstile helpers ----------------------------------------------------
34  function turnstileEnabled() {
35    return !!(window.KLR_FORM &&
36      window.KLR_FORM.turnstile &&
37      window.KLR_FORM.turnstile.enabled &&
38      window.KLR_FORM.turnstile.siteKey);
39  }
40
41  // We store per-form widget state on the form element
42  function initTurnstileForForm(form) {
43    if (!turnstileEnabled()) return;
44
45    var holder = qs(form, '[data-klr-turnstile]');
46    if (!holder) return;
47
48    // Prevent double-render
49    if (form.__klr_ts_inited) return;
50
51    // Turnstile script must be loaded (it defines window.turnstile)
52    if (typeof window.turnstile === 'undefined' || !window.turnstile.render) {
53      // Script may still be loading; we retry a few times.
54      var tries = 0;
55      var t = setInterval(function () {
56        tries++;
57        if (typeof window.turnstile !== 'undefined' && window.turnstile.render) {
58          clearInterval(t);
59          initTurnstileForForm(form);
60        } else if (tries > 40) { // ~4s
61          clearInterval(t);
62          console.warn('[KLR] Turnstile script did not load.');
63        }
64      }, 100);
65      return;
66    }
67
68    // IMPORTANT: Invisible Turnstile requires execute() to get a token.
69    // If you want visible/managed instead, change size to 'normal'.
70    var size = (window.KLR_FORM.turnstile.size || 'invisible'); // default invisible
71
72    form.__klr_ts_inited = true;
73    form.__klr_ts_size = size;
74    form.__klr_ts_token = '';
75    form.__klr_ts_pending = null;
76
77    // Ensure hidden field exists
78    var hidden = qs(form, 'input[name="turnstile_token"]');
79    if (!hidden) {
80      hidden = document.createElement('input');
81      hidden.type = 'hidden';
82      hidden.name = 'turnstile_token';
83      hidden.value = '';
84      form.appendChild(hidden);
85    }
86
87    // Render widget
88    var widgetId = window.turnstile.render(holder, {
89      sitekey: window.KLR_FORM.turnstile.siteKey,
90      size: size, // 'invisible' or 'normal'/'compact'
91      callback: function (token) {
92        form.__klr_ts_token = token || '';
93        hidden.value = token || '';
94
95        // Resolve any pending execute() waiters
96        if (form.__klr_ts_pending && typeof form.__klr_ts_pending.resolve === 'function') {
97          form.__klr_ts_pending.resolve(token || '');
98          form.__klr_ts_pending = null;
99        }
100      },
101      'expired-callback': function () {
102        form.__klr_ts_token = '';
103        hidden.value = '';
104      },
105      'error-callback': function () {
106        form.__klr_ts_token = '';
107        hidden.value = '';
108        if (form.__klr_ts_pending && typeof form.__klr_ts_pending.reject === 'function') {
109          form.__klr_ts_pending.reject(new Error('Anti-spam check failed. Please try again.'));
110          form.__klr_ts_pending = null;
111        }
112      }
113    });
114
115    form.__klr_ts_widgetId = widgetId;
116  }
117
118  // Returns a Promise<string token>
119  function getTurnstileToken(form) {
120    if (!turnstileEnabled()) return Promise.resolve('');
121
122    // If TS not rendered yet, initialize now
123    initTurnstileForForm(form);
124
125    var size = form.__klr_ts_size || (window.KLR_FORM.turnstile.size || 'invisible');
126    var widgetId = form.__klr_ts_widgetId;
127
128    if (!widgetId && typeof window.turnstile !== 'undefined') {
129      // Not rendered (script still loading or missing holder)
130      return Promise.reject(new Error('Anti-spam is not ready yet. Please try again.'));
131    }
132
133    // If we already have a token, use it
134    if (form.__klr_ts_token) return Promise.resolve(form.__klr_ts_token);
135
136    // Invisible mode: execute on submit and wait for callback to provide token
137    if (size === 'invisible') {
138      return new Promise(function (resolve, reject) {
139        // Only one pending wait at a time
140        form.__klr_ts_pending = { resolve: resolve, reject: reject };
141
142        try {
143          window.turnstile.execute(widgetId);
144        } catch (e) {
145          form.__klr_ts_pending = null;
146          reject(new Error('Please complete the anti-spam check.'));
147          return;
148        }
149
150        // Safety timeout (so we don’t hang forever)
151        setTimeout(function () {
152          if (form.__klr_ts_pending) {
153            form.__klr_ts_pending = null;
154            reject(new Error('Please complete the anti-spam check.'));
155          }
156        }, 8000);
157      });
158    }
159
160    // Visible/managed mode: user must interact (token arrives via callback)
161    return Promise.reject(new Error('Please complete the anti-spam check.'));
162  }
163
164  function resetTurnstile(form) {
165    if (!turnstileEnabled()) return;
166
167    try {
168      if (typeof window.turnstile !== 'undefined' && form.__klr_ts_widgetId !== undefined) {
169        window.turnstile.reset(form.__klr_ts_widgetId);
170      }
171    } catch (e) {}
172
173    form.__klr_ts_token = '';
174    var hidden = qs(form, 'input[name="turnstile_token"]');
175    if (hidden) hidden.value = '';
176  }
177
178  async function submitViaAjax(form) {
179    setStatus(form, 'Submitting...', true);
180
181    var payload = serialize(form);
182
183    // Turnstile: ensure token exists when enabled
184    if (turnstileEnabled()) {
185      var token = await getTurnstileToken(form);
186      if (!token) throw new Error('Please complete the anti-spam check.');
187      payload.turnstile_token = token;
188    }
189
190    var resp = await fetch(window.KLR_FORM.endpoint, {
191      method: 'POST',
192      credentials: 'same-origin',
193      headers: {
194        'Content-Type': 'application/json'
195      },
196      body: JSON.stringify(payload)
197    });
198
199    var data = null;
200    try { data = await resp.json(); } catch (e) {}
201
202    if (!resp.ok || !data || data.ok !== true) {
203      var msg = (data && data.message) ? data.message : ('Request failed (' + resp.status + ')');
204      throw new Error(msg);
205    }
206
207    setStatus(form, window.KLR_FORM.successMessage || data.message || 'Thanks! You are signed up.', true);
208    form.reset();
209
210    // reset Turnstile after success so the next submit works
211    resetTurnstile(form);
212  }
213
214  document.addEventListener('DOMContentLoaded', function () {
215    document.querySelectorAll('form[data-klr-form]').forEach(function (form) {
216      // Pre-init Turnstile (so invisible widgets are ready before submit)
217      initTurnstileForForm(form);
218
219      form.addEventListener('submit', function (e) {
220        e.preventDefault();
221        submitViaAjax(form).catch(function (err) {
222          console.error('[KLR] Submit failed', err);
223          setStatus(form, err && err.message ? err.message : 'Something went wrong. Please try again.', false);
224
225          // If token expired/invalid, reset so user can retry
226          resetTurnstile(form);
227        });
228      });
229    });
230  });
231})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.