@verbb/formie-browser 1.0.15 → 1.0.16
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.
- package/CHANGELOG.md +36 -0
- package/dist/chunks/{address-country-BcEQKw0T.js → address-country-DLJF-OkC.js} +4 -8
- package/dist/chunks/{address-finder-BWGINCSA.js → address-finder-QK1m1eyv.js} +1 -1
- package/dist/chunks/{address-state-DI3ndhMU.js → address-state-CHKit8AW.js} +26 -35
- package/dist/chunks/{api-BK9b340y.js → api-BPtH5RBA.js} +152 -120
- package/dist/chunks/{api-Dxl_CKw-.js → api-BR2Gqy37.js} +306 -301
- package/dist/chunks/{api-ghNr2uxX.js → api-CmuOZ0i3.js} +1 -1
- package/dist/chunks/{bpoint-BwtuyN_O.js → bpoint-GvYfyPjD.js} +1 -1
- package/dist/chunks/{calculations-YEoVCG2q.js → calculations-DeEmdUDq.js} +5 -7
- package/dist/chunks/{captcha-eu-DWLoQFKB.js → captcha-eu-eU_M6snp.js} +1 -1
- package/dist/chunks/{checkbox-radio-gsm8QPJg.js → checkbox-radio-CSXo6svm.js} +4 -12
- package/dist/chunks/{combobox-Ba08_cHL.js → combobox-CJh2DoSO.js} +292 -333
- package/dist/chunks/{conditions-Ceeg6ReZ.js → conditions-Dz3068K0.js} +56 -72
- package/dist/chunks/{country-from-ip-DDj_mFki.js → country-from-ip-BqQ-BqLH.js} +1 -1
- package/dist/chunks/{custom-google-maps-C4l2S3GO.js → custom-google-maps-rNm5VFbb.js} +2 -6
- package/dist/chunks/{custom-link-CLazgKYH.js → custom-link-CLqFCssQ.js} +1 -1
- package/dist/chunks/{custom-maps-DqcAlD0v.js → custom-maps-DgjYQDLj.js} +4 -8
- package/dist/chunks/{date-picker-DaPvMrop.js → date-picker-BVJxJVYT.js} +30 -47
- package/dist/chunks/{debug-BV0DvdHx.js → debug-rhzqP1j2.js} +2 -14
- package/dist/chunks/{dist-ZLeW0zZ3.js → dist-CJReDlDK.js} +13 -8
- package/dist/chunks/{eway-uw0DzU-L.js → eway-BZuTBAUW.js} +1 -1
- package/dist/chunks/{field-references.resolver-Ca8MguFv.js → field-references.resolver-uSHf5-NP.js} +1 -1
- package/dist/chunks/{file-upload-B8_mH012.js → file-upload-vEUr_EuP.js} +114 -108
- package/dist/chunks/{friendly-captcha-v1-CVXaXgDO.js → friendly-captcha-v1-C_cF1WD2.js} +2 -2
- package/dist/chunks/{friendly-captcha-v2-DkeIVTKI.js → friendly-captcha-v2-BenESH-n.js} +2 -2
- package/dist/chunks/{friendly-challenge-DPG9MJb1.js → friendly-challenge-BgPBEMXx.js} +21 -35
- package/dist/chunks/{go-cardless-c4wLJdOt.js → go-cardless-DWZeB0Bq.js} +2 -6
- package/dist/chunks/{google-address-JHYvjwgN.js → google-address-DQR6rsbh.js} +2 -2
- package/dist/chunks/{hcaptcha-Dt3ELLlP.js → hcaptcha-COilLmRT.js} +1 -1
- package/dist/chunks/{hidden-BZhXnNPe.js → hidden-Bc2TpcgF.js} +1 -1
- package/dist/chunks/{http-C2QdHuWO.js → http-Dj_skqaa.js} +1 -1
- package/dist/chunks/{leaflet-src-DE6rv6M-.js → leaflet-src-Cg-LUOD8.js} +74 -122
- package/dist/chunks/{loqate-m51iPyO1.js → loqate-ZZClcacr.js} +1 -1
- package/dist/chunks/{mollie-Bn0PX173.js → mollie-8OMXIYa8.js} +2 -6
- package/dist/chunks/{moneris-BRbUvI4t.js → moneris-qYHJ9EFy.js} +1 -1
- package/dist/chunks/opayo-DlWPEnla.js +159 -0
- package/dist/chunks/{paddle-CympHVvd.js → paddle-CArfWih0.js} +1 -1
- package/dist/chunks/{password-validation-C8_uO_c_.js → password-validation-HGOU9kf3.js} +2 -2
- package/dist/chunks/{paypal-h75h6wae.js → paypal-BcaMCMGY.js} +1 -1
- package/dist/chunks/{payway-C9rHTCC_.js → payway-vxC7_bfR.js} +3 -11
- package/dist/chunks/{phone-country-B8fv-L5_.js → phone-country-Bx9EG50h.js} +123 -140
- package/dist/chunks/{place-kit-BnZGQ-L1.js → place-kit-BKk8xDXf.js} +2 -2
- package/dist/chunks/{placekit-autocomplete.esm-CZZERYur.js → placekit-autocomplete.esm-D2A_0iVU.js} +2 -5
- package/dist/chunks/{recaptcha-enterprise-CUs8BO6V.js → recaptcha-enterprise-Cx6HUpMa.js} +6 -12
- package/dist/chunks/recaptcha-shared-CcMI-r8t.js +33 -0
- package/dist/chunks/{recaptcha-v2-checkbox-P1McW4Pv.js → recaptcha-v2-checkbox-DQ9BJzcv.js} +2 -2
- package/dist/chunks/{recaptcha-v2-invisible-FGDqozSP.js → recaptcha-v2-invisible-BP0T8Pan.js} +2 -2
- package/dist/chunks/recaptcha-v3-DKMGQ27K.js +38 -0
- package/dist/chunks/{repeater-CyhDbozO.js → repeater-BR0RUvTs.js} +3 -7
- package/dist/chunks/{rich-text-uV4o_pGk.js → rich-text-H2A6cm1t.js} +33 -11
- package/dist/chunks/{rolldown-runtime-DtPi1Y-2.js → rolldown-runtime-VHNaYcLd.js} +1 -1
- package/dist/chunks/{sdk-lkwSvlpM.js → sdk-_cmrRYgp.js} +4 -16
- package/dist/chunks/{shared-OKhSay59.js → shared-CJ1LIEh3.js} +1 -3
- package/dist/chunks/{signature-7cldFbqj.js → signature-CfKA_poI.js} +9 -41
- package/dist/chunks/{snaptcha-C3QLYxFT.js → snaptcha-P3EoSQud.js} +1 -1
- package/dist/chunks/{square-C1z5DPVw.js → square-Dyz0p_GU.js} +1 -1
- package/dist/chunks/{stripe-Dmkdkq1y.js → stripe-Bfd_jp_k.js} +3 -6
- package/dist/chunks/{summary-Bn-g5SDx.js → summary-B3CAebLV.js} +44 -36
- package/dist/chunks/{survey-likert-fk1hUPff.js → survey-likert-CEtUceag.js} +1 -1
- package/dist/chunks/{survey-rank-BsLGl2LX.js → survey-rank-Dtt97y6s.js} +3 -7
- package/dist/chunks/{survey-rating-DVS6e6fM.js → survey-rating-mlDMI0uq.js} +9 -23
- package/dist/chunks/{table-j7MlLLCc.js → table-0k6Md0IO.js} +1 -1
- package/dist/chunks/{text-limit-LGMPhFuC.js → text-limit-CTVML6s7.js} +10 -10
- package/dist/chunks/{turnstile-ptihQfLl.js → turnstile-Sp4ubowK.js} +1 -1
- package/dist/chunks/{upload-manager-BW7l-BhF.js → upload-manager-Ccg3d_4I.js} +11 -25
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +752 -756
- package/dist/js/core/create-formie-client.d.ts.map +1 -1
- package/dist/js/core/dom-events.d.ts +5 -0
- package/dist/js/core/dom-events.d.ts.map +1 -1
- package/dist/js/core/page-client-event.d.ts.map +1 -1
- package/dist/js/core/submit-result-state.d.ts.map +1 -1
- package/dist/js/core/submit-result-ui.d.ts.map +1 -1
- package/dist/js/core/validation-focus.d.ts.map +1 -1
- package/dist/js/modules/captchas/factories.d.ts.map +1 -1
- package/dist/js/modules/captchas/host.d.ts +4 -1
- package/dist/js/modules/captchas/host.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-shared.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-shared.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -1
- package/dist/js/modules/fields/address-state.d.ts.map +1 -1
- package/dist/js/modules/fields/combobox.d.ts +2 -0
- package/dist/js/modules/fields/combobox.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions.d.ts.map +1 -1
- package/dist/js/modules/fields/file-upload.d.ts.map +1 -1
- package/dist/js/modules/fields/phone-country.d.ts.map +1 -1
- package/dist/js/modules/fields/rich-text.d.ts.map +1 -1
- package/dist/js/modules/fields/summary.d.ts.map +1 -1
- package/dist/js/modules/fields/text-limit.d.ts.map +1 -1
- package/dist/js/modules/payments/factories.d.ts.map +1 -1
- package/dist/js/modules/payments/opayo.d.ts.map +1 -1
- package/dist/js/submit/pipeline.d.ts +2 -0
- package/dist/js/submit/pipeline.d.ts.map +1 -1
- package/dist/js/utils/form-started-at.d.ts +1 -0
- package/dist/js/utils/form-started-at.d.ts.map +1 -1
- package/dist/js/utils/unload-warning.d.ts +4 -0
- package/dist/js/utils/unload-warning.d.ts.map +1 -1
- package/dist/js/validation/rules/required.d.ts.map +1 -1
- package/dist/js/validation/submit-readiness.d.ts.map +1 -1
- package/dist/js/validation/validator.d.ts +1 -0
- package/dist/js/validation/validator.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/js/core/create-formie-client.ts +20 -18
- package/src/js/core/dom-events.ts +30 -1
- package/src/js/core/page-client-event.ts +5 -7
- package/src/js/core/submit-result-state.ts +13 -2
- package/src/js/core/submit-result-ui.ts +21 -0
- package/src/js/core/validation-focus.ts +17 -3
- package/src/js/modules/captchas/factories.ts +241 -101
- package/src/js/modules/captchas/host.ts +16 -0
- package/src/js/modules/captchas/recaptcha-enterprise.ts +1 -1
- package/src/js/modules/captchas/recaptcha-shared.ts +23 -5
- package/src/js/modules/captchas/recaptcha-v3.ts +23 -14
- package/src/js/modules/fields/address-state.ts +6 -4
- package/src/js/modules/fields/combobox.ts +19 -1
- package/src/js/modules/fields/conditions.ts +3 -0
- package/src/js/modules/fields/file-upload.ts +11 -4
- package/src/js/modules/fields/phone-country.ts +23 -0
- package/src/js/modules/fields/rich-text.ts +33 -0
- package/src/js/modules/fields/summary.ts +63 -10
- package/src/js/modules/fields/text-limit.ts +11 -0
- package/src/js/modules/payments/factories.ts +87 -54
- package/src/js/modules/payments/opayo.ts +7 -0
- package/src/js/submit/pipeline.ts +16 -9
- package/src/js/utils/form-started-at.ts +19 -4
- package/src/js/utils/unload-warning.ts +63 -7
- package/src/js/validation/rules/required.ts +6 -0
- package/src/js/validation/submit-readiness.ts +2 -0
- package/src/js/validation/validator.ts +15 -4
- package/src/vendor.d.ts +2 -0
- package/dist/chunks/opayo-BwWdInEP.js +0 -188
- package/dist/chunks/recaptcha-shared-DTbTw-MF.js +0 -27
- package/dist/chunks/recaptcha-v3-CflUHeZD.js +0 -28
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { FormieFormInstance } from '#contracts/client';
|
|
1
2
|
import type { FormAction, SubmitStage } from '#contracts/common';
|
|
2
3
|
import type { FormSubmitResult } from '#contracts/schema';
|
|
4
|
+
import { withFormEventInstance } from '#core/dom-events';
|
|
3
5
|
import { EventBus } from '#events/event-bus';
|
|
4
6
|
import { submitForm } from '#transport/forms-api';
|
|
5
7
|
import { createDebug } from '#utils/debug';
|
|
@@ -7,6 +9,7 @@ import { getFormPages, getValidationScope } from '#validation/scope';
|
|
|
7
9
|
import type { FormieValidator } from '#validation/validator';
|
|
8
10
|
|
|
9
11
|
export type SubmitPipelineContext = {
|
|
12
|
+
instance?: FormieFormInstance;
|
|
10
13
|
form: HTMLFormElement;
|
|
11
14
|
action: FormAction;
|
|
12
15
|
formData: FormData;
|
|
@@ -207,7 +210,7 @@ export async function runSubmitPipeline(
|
|
|
207
210
|
let dispatchResult: FormSubmitResult | null = null;
|
|
208
211
|
const finalSubmitAttempt = isFinalSubmitAttempt(form, action);
|
|
209
212
|
|
|
210
|
-
const context: SubmitPipelineContext = {
|
|
213
|
+
const context: SubmitPipelineContext = withFormEventInstance(form, {
|
|
211
214
|
form,
|
|
212
215
|
action,
|
|
213
216
|
formData: buildSubmitFormData(form, action),
|
|
@@ -218,6 +221,10 @@ export async function runSubmitPipeline(
|
|
|
218
221
|
},
|
|
219
222
|
isAborted: () => aborted,
|
|
220
223
|
abortReason: () => abortReason,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const emitSubmitResult = (eventName: string, result: FormSubmitResult) => {
|
|
227
|
+
return bus.emitSafe(eventName, withFormEventInstance(form, result));
|
|
221
228
|
};
|
|
222
229
|
|
|
223
230
|
const runners: Record<SubmitStage, StageRunner> = {
|
|
@@ -368,7 +375,7 @@ export async function runSubmitPipeline(
|
|
|
368
375
|
if (aborted) {
|
|
369
376
|
const abortedResult = getAbortedResult(stage, abortReason);
|
|
370
377
|
{
|
|
371
|
-
const emitReport = await
|
|
378
|
+
const emitReport = await emitSubmitResult('formie:submit:after', abortedResult);
|
|
372
379
|
if (emitReport.failed.length > 0) {
|
|
373
380
|
debug.warn('Submit after listeners failed (abort before stage).', {
|
|
374
381
|
stage,
|
|
@@ -377,7 +384,7 @@ export async function runSubmitPipeline(
|
|
|
377
384
|
}
|
|
378
385
|
}
|
|
379
386
|
if (finalSubmitAttempt) {
|
|
380
|
-
const emitReport = await
|
|
387
|
+
const emitReport = await emitSubmitResult('formie:submit:final:after', abortedResult);
|
|
381
388
|
if (emitReport.failed.length > 0) {
|
|
382
389
|
debug.warn('Final submit after listeners failed (abort before stage).', {
|
|
383
390
|
stage,
|
|
@@ -414,7 +421,7 @@ export async function runSubmitPipeline(
|
|
|
414
421
|
if (aborted) {
|
|
415
422
|
const abortedResult = getAbortedResult(stage, abortReason);
|
|
416
423
|
{
|
|
417
|
-
const emitReport = await
|
|
424
|
+
const emitReport = await emitSubmitResult('formie:submit:after', abortedResult);
|
|
418
425
|
if (emitReport.failed.length > 0) {
|
|
419
426
|
debug.warn('Submit after listeners failed (abort after stage).', {
|
|
420
427
|
stage,
|
|
@@ -423,7 +430,7 @@ export async function runSubmitPipeline(
|
|
|
423
430
|
}
|
|
424
431
|
}
|
|
425
432
|
if (finalSubmitAttempt) {
|
|
426
|
-
const emitReport = await
|
|
433
|
+
const emitReport = await emitSubmitResult('formie:submit:final:after', abortedResult);
|
|
427
434
|
if (emitReport.failed.length > 0) {
|
|
428
435
|
debug.warn('Final submit after listeners failed (abort after stage).', {
|
|
429
436
|
stage,
|
|
@@ -439,7 +446,7 @@ export async function runSubmitPipeline(
|
|
|
439
446
|
// matching stage after-hook so modules can clean up their own state.
|
|
440
447
|
if (stageResult && !stageResult.ok) {
|
|
441
448
|
{
|
|
442
|
-
const emitReport = await
|
|
449
|
+
const emitReport = await emitSubmitResult('formie:submit:after', stageResult);
|
|
443
450
|
if (emitReport.failed.length > 0) {
|
|
444
451
|
debug.warn('Submit after listeners failed (failed stage).', {
|
|
445
452
|
stage,
|
|
@@ -448,7 +455,7 @@ export async function runSubmitPipeline(
|
|
|
448
455
|
}
|
|
449
456
|
}
|
|
450
457
|
if (finalSubmitAttempt) {
|
|
451
|
-
const emitReport = await
|
|
458
|
+
const emitReport = await emitSubmitResult('formie:submit:final:after', stageResult);
|
|
452
459
|
if (emitReport.failed.length > 0) {
|
|
453
460
|
debug.warn('Final submit after listeners failed (failed stage).', {
|
|
454
461
|
stage,
|
|
@@ -473,7 +480,7 @@ export async function runSubmitPipeline(
|
|
|
473
480
|
};
|
|
474
481
|
|
|
475
482
|
{
|
|
476
|
-
const emitReport = await
|
|
483
|
+
const emitReport = await emitSubmitResult('formie:submit:after', successResult);
|
|
477
484
|
if (emitReport.failed.length > 0) {
|
|
478
485
|
debug.warn('Submit after listeners failed (success).', {
|
|
479
486
|
failed: emitReport.failed.length,
|
|
@@ -481,7 +488,7 @@ export async function runSubmitPipeline(
|
|
|
481
488
|
}
|
|
482
489
|
}
|
|
483
490
|
if (finalSubmitAttempt) {
|
|
484
|
-
const emitReport = await
|
|
491
|
+
const emitReport = await emitSubmitResult('formie:submit:final:after', successResult);
|
|
485
492
|
if (emitReport.failed.length > 0) {
|
|
486
493
|
debug.warn('Final submit after listeners failed (success).', {
|
|
487
494
|
failed: emitReport.failed.length,
|
|
@@ -11,15 +11,30 @@ export function ensureFormStartedAt(form: HTMLFormElement): void {
|
|
|
11
11
|
const renderId = renderIdInput?.value?.trim() ?? '';
|
|
12
12
|
const storageKey = renderId ? `${FORM_STARTED_AT_STORAGE_PREFIX}${renderId}` : null;
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
const continuing = ['submissionUid', 'progressId'].some((name) =>
|
|
15
|
+
form.querySelector<HTMLInputElement>(`input[name="${name}"]`)?.value.trim()
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// Reuse elapsed time for an existing draft or live mount, not a fresh visit.
|
|
19
|
+
let startedAt = startedAtInput.value || (continuing && storageKey ? sessionStorage.getItem(storageKey) : null);
|
|
15
20
|
|
|
16
21
|
if (!startedAt) {
|
|
17
22
|
startedAt = String(Date.now());
|
|
23
|
+
}
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
25
|
+
if (storageKey) {
|
|
26
|
+
sessionStorage.setItem(storageKey, startedAt);
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
startedAtInput.value = startedAt;
|
|
25
30
|
}
|
|
31
|
+
|
|
32
|
+
export function resetFormStartedAt(form: HTMLFormElement): void {
|
|
33
|
+
const input = form.querySelector<HTMLInputElement>('input[name="formStartedAt"]');
|
|
34
|
+
|
|
35
|
+
if (input) {
|
|
36
|
+
// Hidden input values survive form.reset(), so start the next submission explicitly.
|
|
37
|
+
input.value = String(Date.now());
|
|
38
|
+
ensureFormStartedAt(form);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isFormCsrfFieldName } from '#utils/csrf';
|
|
2
|
+
import { dispatchFormieDomEvent } from '#core/dom-events';
|
|
2
3
|
|
|
3
4
|
const DIRTY_TRACKING_IGNORED_FIELD_NAMES = new Set([
|
|
4
5
|
'action',
|
|
@@ -14,6 +15,37 @@ const DIRTY_TRACKING_IGNORED_FIELD_NAMES = new Set([
|
|
|
14
15
|
'progressId',
|
|
15
16
|
]);
|
|
16
17
|
|
|
18
|
+
type FormSnapshot = Array<[string, FormDataEntryValue]>;
|
|
19
|
+
|
|
20
|
+
export type FormUnloadWarningExclusionsEventDetail = {
|
|
21
|
+
readonly form: HTMLFormElement;
|
|
22
|
+
readonly exclude: (...fieldNames: string[]) => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function collectExcludedFieldNames(form: HTMLFormElement): Set<string> {
|
|
26
|
+
const excludedFieldNames = new Set<string>();
|
|
27
|
+
let collecting = true;
|
|
28
|
+
|
|
29
|
+
dispatchFormieDomEvent(form, 'formie:unload-warning:collect-exclusions', {
|
|
30
|
+
form,
|
|
31
|
+
exclude: (...fieldNames: string[]) => {
|
|
32
|
+
// Exclusions belong to this synchronous comparison, not a later check.
|
|
33
|
+
if (!collecting) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fieldNames.forEach((name) => {
|
|
38
|
+
if (typeof name === 'string' && name !== '') {
|
|
39
|
+
excludedFieldNames.add(name);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
} satisfies FormUnloadWarningExclusionsEventDetail);
|
|
44
|
+
collecting = false;
|
|
45
|
+
|
|
46
|
+
return excludedFieldNames;
|
|
47
|
+
}
|
|
48
|
+
|
|
17
49
|
function serializeStableValue(value: unknown, seen: WeakSet<object>): string {
|
|
18
50
|
if (value == null) {
|
|
19
51
|
return String(value);
|
|
@@ -82,9 +114,16 @@ function shouldTrackFieldName(name: string, form: HTMLFormElement): boolean {
|
|
|
82
114
|
return !DIRTY_TRACKING_IGNORED_FIELD_NAMES.has(normalizedName);
|
|
83
115
|
}
|
|
84
116
|
|
|
85
|
-
function buildTrackedSnapshot(
|
|
86
|
-
|
|
87
|
-
|
|
117
|
+
function buildTrackedSnapshot(
|
|
118
|
+
snapshot: FormSnapshot,
|
|
119
|
+
form: HTMLFormElement,
|
|
120
|
+
excludedFieldNames: Set<string>,
|
|
121
|
+
): string {
|
|
122
|
+
const entries = snapshot.filter(([name]) => {
|
|
123
|
+
return (
|
|
124
|
+
!excludedFieldNames.has(name) &&
|
|
125
|
+
shouldTrackFieldName(String(name || ''), form)
|
|
126
|
+
);
|
|
88
127
|
});
|
|
89
128
|
|
|
90
129
|
return stableSerialize(entries);
|
|
@@ -103,8 +142,9 @@ export function createFormUnloadWarningGuard(
|
|
|
103
142
|
shouldWarn?: () => boolean;
|
|
104
143
|
} = {},
|
|
105
144
|
): FormUnloadWarningGuard {
|
|
106
|
-
let baselineSnapshot:
|
|
145
|
+
let baselineSnapshot: FormSnapshot = [];
|
|
107
146
|
let isReady = false;
|
|
147
|
+
let destroyed = false;
|
|
108
148
|
let isDirty = false;
|
|
109
149
|
let animationFrameId: number | null = null;
|
|
110
150
|
let dirtyTimerId: number | null = null;
|
|
@@ -132,18 +172,31 @@ export function createFormUnloadWarningGuard(
|
|
|
132
172
|
return false;
|
|
133
173
|
}
|
|
134
174
|
|
|
135
|
-
|
|
175
|
+
// Apply the same current exclusions to both sides. A late registration
|
|
176
|
+
// must neither create a false edit nor reset genuine visitor changes.
|
|
177
|
+
const excludedFieldNames = collectExcludedFieldNames(form);
|
|
178
|
+
const currentSnapshot = Array.from(new FormData(form).entries());
|
|
179
|
+
isDirty =
|
|
180
|
+
buildTrackedSnapshot(currentSnapshot, form, excludedFieldNames) !==
|
|
181
|
+
buildTrackedSnapshot(baselineSnapshot, form, excludedFieldNames);
|
|
136
182
|
|
|
137
183
|
return isDirty;
|
|
138
184
|
};
|
|
139
185
|
|
|
140
186
|
const captureBaseline = (): void => {
|
|
141
|
-
|
|
187
|
+
if (destroyed) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
clearScheduledWork();
|
|
191
|
+
baselineSnapshot = Array.from(new FormData(form).entries());
|
|
142
192
|
isReady = true;
|
|
143
193
|
isDirty = false;
|
|
144
194
|
};
|
|
145
195
|
|
|
146
196
|
const scheduleBaselineCapture = (): void => {
|
|
197
|
+
if (destroyed) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
147
200
|
clearScheduledWork();
|
|
148
201
|
isReady = false;
|
|
149
202
|
|
|
@@ -183,13 +236,16 @@ export function createFormUnloadWarningGuard(
|
|
|
183
236
|
form.addEventListener('input', scheduleDirtyRefresh);
|
|
184
237
|
form.addEventListener('change', scheduleDirtyRefresh);
|
|
185
238
|
window.addEventListener('beforeunload', handleBeforeUnload);
|
|
186
|
-
|
|
239
|
+
captureBaseline();
|
|
187
240
|
|
|
188
241
|
return {
|
|
189
242
|
captureBaseline,
|
|
190
243
|
scheduleBaselineCapture,
|
|
191
244
|
refreshDirtyState,
|
|
192
245
|
destroy: () => {
|
|
246
|
+
destroyed = true;
|
|
247
|
+
isReady = false;
|
|
248
|
+
baselineSnapshot = [];
|
|
193
249
|
clearScheduledWork();
|
|
194
250
|
form.removeEventListener('input', scheduleDirtyRefresh);
|
|
195
251
|
form.removeEventListener('change', scheduleDirtyRefresh);
|
|
@@ -7,6 +7,12 @@ const required: ValidationRuleDefinition = {
|
|
|
7
7
|
return true;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// Required tables need rows, not a value in every cell. Cell values are
|
|
11
|
+
// optional, including unchecked checkboxes and blank email addresses.
|
|
12
|
+
if (input.closest('[data-formie-field-handle]')?.getAttribute('data-formie-field-type') === 'table') {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
if (input instanceof HTMLInputElement && input.type === 'file') {
|
|
11
17
|
if (input.files?.length) {
|
|
12
18
|
return true;
|
|
@@ -33,8 +33,10 @@ export function syncSubmitReadiness(form: HTMLFormElement, validator: FormieVali
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const { scope, final } = getValidationScope(form);
|
|
36
|
+
// Readiness observes DOM changes; redrawing errors here would retrigger it indefinitely.
|
|
36
37
|
const isReady = validator.isValid(scope, {
|
|
37
38
|
includeHiddenPages: final,
|
|
39
|
+
renderErrors: false,
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
form.setAttribute(SUBMIT_READY_ATTR, isReady ? 'true' : 'false');
|
|
@@ -25,6 +25,7 @@ type ValidatorDefinition = {
|
|
|
25
25
|
|
|
26
26
|
type ValidateOptions = {
|
|
27
27
|
includeHiddenPages?: boolean;
|
|
28
|
+
renderErrors?: boolean;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
const DEFAULT_PATTERNS: Record<string, RegExp> = {
|
|
@@ -40,11 +41,13 @@ const DEFAULT_PATTERNS: Record<string, RegExp> = {
|
|
|
40
41
|
const debug = createDebug('general', 'validator');
|
|
41
42
|
|
|
42
43
|
function isValidationInput(node: Element | null): node is ValidationInput {
|
|
44
|
+
// Enhancement libraries inject unnamed search controls that do not submit
|
|
45
|
+
// field values and must not inherit the field's validation rules.
|
|
43
46
|
return !!node && (
|
|
44
47
|
node instanceof HTMLInputElement ||
|
|
45
48
|
node instanceof HTMLSelectElement ||
|
|
46
49
|
node instanceof HTMLTextAreaElement
|
|
47
|
-
);
|
|
50
|
+
) && !!node.name;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
function isPainted(element: HTMLElement): boolean {
|
|
@@ -161,6 +164,7 @@ export class FormieValidator {
|
|
|
161
164
|
|
|
162
165
|
this.inputs(inputOrSelector).forEach((input) => {
|
|
163
166
|
let errorShown = false;
|
|
167
|
+
const renderErrors = options.renderErrors !== false && this.shouldShowError(input);
|
|
164
168
|
|
|
165
169
|
if (!this.isVisible(input, options)) {
|
|
166
170
|
return;
|
|
@@ -179,7 +183,7 @@ export class FormieValidator {
|
|
|
179
183
|
seenGroups.add(groupKey);
|
|
180
184
|
}
|
|
181
185
|
|
|
182
|
-
if (
|
|
186
|
+
if (renderErrors) {
|
|
183
187
|
this.removeError(input);
|
|
184
188
|
}
|
|
185
189
|
|
|
@@ -191,7 +195,7 @@ export class FormieValidator {
|
|
|
191
195
|
if (!isValid) {
|
|
192
196
|
const errorMessage = this.getErrorMessage(input, validatorName, validatorConfig, opts);
|
|
193
197
|
|
|
194
|
-
if (
|
|
198
|
+
if (renderErrors && !errorShown) {
|
|
195
199
|
this.showError(input, validatorName, errorMessage);
|
|
196
200
|
}
|
|
197
201
|
|
|
@@ -208,7 +212,7 @@ export class FormieValidator {
|
|
|
208
212
|
}
|
|
209
213
|
});
|
|
210
214
|
|
|
211
|
-
if (!errorShown &&
|
|
215
|
+
if (!errorShown && renderErrors) {
|
|
212
216
|
this.removeError(input);
|
|
213
217
|
}
|
|
214
218
|
});
|
|
@@ -497,6 +501,13 @@ export class FormieValidator {
|
|
|
497
501
|
}
|
|
498
502
|
}
|
|
499
503
|
|
|
504
|
+
// Third-party select enhancements hide the native value control without
|
|
505
|
+
// Formie's combobox marker. The containing field still determines whether
|
|
506
|
+
// its selected values need validation, including an empty required value.
|
|
507
|
+
if (element instanceof HTMLSelectElement && field instanceof HTMLElement) {
|
|
508
|
+
return isPainted(element) || isPainted(field);
|
|
509
|
+
}
|
|
510
|
+
|
|
500
511
|
return isPainted(element);
|
|
501
512
|
}
|
|
502
513
|
|
package/src/vendor.d.ts
CHANGED
|
@@ -58,7 +58,9 @@ declare module 'flatpickr/dist/l10n/index.js' {
|
|
|
58
58
|
|
|
59
59
|
declare module 'intl-tel-input' {
|
|
60
60
|
type IntlTelInputInstance = {
|
|
61
|
+
readonly promise: Promise<void>;
|
|
61
62
|
setCountry(country: string): void;
|
|
63
|
+
setNumber(number: string): void;
|
|
62
64
|
isValidNumber(): boolean;
|
|
63
65
|
getSelectedCountryData(): { iso2?: string } | null;
|
|
64
66
|
getValidationError(): number;
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./request-profile-DhwkeCpS.js";
|
|
2
|
-
import { t } from "./dist-ZLeW0zZ3.js";
|
|
3
|
-
import { s as n } from "./event-names-BCI2FLD8.js";
|
|
4
|
-
import { t as r } from "./api-Dxl_CKw-.js";
|
|
5
|
-
import { t as i } from "./debug-BV0DvdHx.js";
|
|
6
|
-
import { a } from "./theme-classes-DAQuEqdP.js";
|
|
7
|
-
import { t as o } from "./csrf-DxHg_ZYt.js";
|
|
8
|
-
import { r as s } from "./scripts-DrccjrFv.js";
|
|
9
|
-
import { t as c } from "./styles-BfoIZwJp.js";
|
|
10
|
-
//#endregion
|
|
11
|
-
//#region src/js/modules/payments/opayo.ts
|
|
12
|
-
c("opayo", ["@layer formie-theme{.formie-opayo-drop-in{box-sizing:border-box;width:100%;min-height:10rem}}"]);
|
|
13
|
-
var l = "FORMIE_OPAYO_SCRIPT", u = "https://live.opayo.eu.elavon.com/api/v1/js/sagepay.js", d = "https://sandbox.opayo.eu.elavon.com/api/v1/js/sagepay.js", f = "[data-formie-opayo-drop-in]", p = i("payments", "opayo"), m = n("opayo", "challenge"), h = "formie:payment:opayo:challenge:response";
|
|
14
|
-
function g(e) {
|
|
15
|
-
return e.checkoutMode === "dropIn";
|
|
16
|
-
}
|
|
17
|
-
async function _(n) {
|
|
18
|
-
let { form: r, handle: i, sessionToken: a, services: s } = n, c = new FormData();
|
|
19
|
-
o(c, r), c.set("action", "formie/payment-sessions/initialize"), c.append("handle", i), c.append("sessionToken", a);
|
|
20
|
-
try {
|
|
21
|
-
let i = await t(n.sessionEndpoint || r.action, {
|
|
22
|
-
method: "POST",
|
|
23
|
-
body: c
|
|
24
|
-
}, e(r));
|
|
25
|
-
return i.status < 200 || i.status >= 300 ? (s.addError(`${i.status}: ${i.statusText}`), p.warn("Merchant session request failed.", {
|
|
26
|
-
status: i.status,
|
|
27
|
-
statusText: i.statusText
|
|
28
|
-
}), null) : (await i.json()).merchantSessionKey || (s.addError("Unable to get merchant session."), p.warn("merchantSessionKey missing in session response."), null);
|
|
29
|
-
} catch {
|
|
30
|
-
return s.addError("Network error. Please try again."), p.warn("Network error requesting merchant session."), null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function v(e) {
|
|
34
|
-
return e.id ||= `formie-opayo-drop-in-${Math.random().toString(36).slice(2, 9)}`, e.id;
|
|
35
|
-
}
|
|
36
|
-
var y = r({
|
|
37
|
-
moduleId: "formie:opayo",
|
|
38
|
-
defaultRequiredInputSuffixes: ["opayoTokenId"],
|
|
39
|
-
load: async (e) => {
|
|
40
|
-
let { provider: t } = e.options, n = t.useSandbox ? d : u, r = g(t) ? "sagepayCheckout" : "sagepayOwnForm";
|
|
41
|
-
return await s(r, {
|
|
42
|
-
id: l,
|
|
43
|
-
src: n,
|
|
44
|
-
timeoutMs: 1e4
|
|
45
|
-
}), null;
|
|
46
|
-
},
|
|
47
|
-
mount: async ({ field: e, services: t, provider: n }) => {
|
|
48
|
-
if (!g(n)) return null;
|
|
49
|
-
let r = t.form, i = window.sagepayCheckout, a = e.querySelector(f);
|
|
50
|
-
if (!r?.action) return t.addError("Form action is missing."), p.warn("Missing form action before drop-in mount."), null;
|
|
51
|
-
if (!i) return t.addError("Opayo script failed to load."), p.warn("sagepayCheckout global not available."), null;
|
|
52
|
-
if (!a) return t.addError("Opayo drop-in container is missing."), p.warn("Drop-in container not found in payment field."), null;
|
|
53
|
-
let o = n.handle || "opayo", s = await _({
|
|
54
|
-
form: r,
|
|
55
|
-
handle: o,
|
|
56
|
-
sessionToken: n.sessionToken || "",
|
|
57
|
-
sessionEndpoint: n.sessionEndpoint,
|
|
58
|
-
services: t
|
|
59
|
-
});
|
|
60
|
-
if (!s) return null;
|
|
61
|
-
let c = v(a), l = {
|
|
62
|
-
checkout: null,
|
|
63
|
-
merchantSessionKey: s,
|
|
64
|
-
pendingAuthorize: null,
|
|
65
|
-
retriedTokenise: !1
|
|
66
|
-
};
|
|
67
|
-
return l.checkout = i({
|
|
68
|
-
merchantSessionKey: s,
|
|
69
|
-
containerSelector: `#${c}`,
|
|
70
|
-
onTokenise: (e) => {
|
|
71
|
-
let i = l.pendingAuthorize;
|
|
72
|
-
if (l.pendingAuthorize = null, !i) {
|
|
73
|
-
p.warn("Drop-in tokenisation completed without a pending authorize step.");
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
if (e.success && e.cardIdentifier) {
|
|
77
|
-
t.updateInputs("opayoTokenId", e.cardIdentifier), t.updateInputs("opayoSessionKey", l.merchantSessionKey), p.log("Drop-in tokenization succeeded.", { hasCardIdentifier: !!e.cardIdentifier }), i(!0);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
if (!l.retriedTokenise) {
|
|
81
|
-
l.retriedTokenise = !0, _({
|
|
82
|
-
form: r,
|
|
83
|
-
handle: o,
|
|
84
|
-
sessionToken: n.sessionToken || "",
|
|
85
|
-
sessionEndpoint: n.sessionEndpoint,
|
|
86
|
-
services: t
|
|
87
|
-
}).then((n) => {
|
|
88
|
-
if (!n) {
|
|
89
|
-
t.addError(e.errors?.[0]?.message || "Tokenization failed."), p.warn("Drop-in tokenization failed after session refresh.", e), i(!1);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
l.merchantSessionKey = n, l.pendingAuthorize = i, l.checkout.tokenise({ newMerchantSessionKey: n });
|
|
93
|
-
});
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
t.addError(e.errors?.[0]?.message || "Tokenization failed."), p.warn("Drop-in tokenization failed.", e), i(!1);
|
|
97
|
-
}
|
|
98
|
-
}), p.log("Drop-in checkout mounted.", { containerId: c }), l;
|
|
99
|
-
},
|
|
100
|
-
unmount: async ({ widget: e }) => {
|
|
101
|
-
e?.checkout?.destroy?.();
|
|
102
|
-
},
|
|
103
|
-
onBeforePayment: async (e) => {
|
|
104
|
-
let { field: t, services: n, options: r, provider: i, widget: a } = e, o = i.handle || "opayo", s = n.form;
|
|
105
|
-
if (!s?.action) return n.addError("Form action is missing."), p.warn("Missing form action before authorize."), !1;
|
|
106
|
-
if (g(i)) return a ? (a.retriedTokenise = !1, new Promise((e) => {
|
|
107
|
-
a.pendingAuthorize = e, a.checkout.tokenise();
|
|
108
|
-
})) : (n.addError("Opayo drop-in checkout is not ready."), p.warn("Drop-in authorize requested before widget mount."), !1);
|
|
109
|
-
let c = window.sagepayOwnForm;
|
|
110
|
-
if (!c) return n.addError("Opayo script failed to load."), p.warn("sagepayOwnForm global not available."), !1;
|
|
111
|
-
let l = t.querySelector("[data-opayo-card=\"cardholder-name\"]")?.value ?? "", u = t.querySelector("[data-opayo-card=\"card-number\"]")?.value ?? "", d = t.querySelector("[data-opayo-card=\"expiry-date\"]")?.value ?? "", f = t.querySelector("[data-opayo-card=\"security-code\"]")?.value ?? "";
|
|
112
|
-
u = u.replace(/[\s/]/g, ""), d = d.replace(/[\s/]/g, "");
|
|
113
|
-
let m = await _({
|
|
114
|
-
form: s,
|
|
115
|
-
handle: o,
|
|
116
|
-
sessionToken: i.sessionToken || "",
|
|
117
|
-
sessionEndpoint: i.sessionEndpoint,
|
|
118
|
-
services: n
|
|
119
|
-
});
|
|
120
|
-
return m ? new Promise((e) => {
|
|
121
|
-
c({ merchantSessionKey: m }).tokeniseCardDetails({
|
|
122
|
-
cardDetails: {
|
|
123
|
-
cardholderName: l,
|
|
124
|
-
cardNumber: u,
|
|
125
|
-
expiryDate: d,
|
|
126
|
-
securityCode: f
|
|
127
|
-
},
|
|
128
|
-
onTokenised: (t) => {
|
|
129
|
-
t.success && t.cardIdentifier ? (n.updateInputs("opayoTokenId", t.cardIdentifier), n.updateInputs("opayoSessionKey", m), p.log("Tokenization succeeded.", { hasCardIdentifier: !!t.cardIdentifier }), e(!0)) : (n.addError(t.errors?.[0]?.message || "Tokenization failed."), p.warn("Tokenization failed.", t), e(!1));
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}) : !1;
|
|
133
|
-
},
|
|
134
|
-
setup: async (e) => {
|
|
135
|
-
let { services: t } = e;
|
|
136
|
-
e.target;
|
|
137
|
-
let n = null, r = !1, i = () => {
|
|
138
|
-
n?.parentNode && n.parentNode.removeChild(n), n = null;
|
|
139
|
-
}, o = t.events.onForm(m, ((e) => {
|
|
140
|
-
let o = e.detail?.data;
|
|
141
|
-
if (!o?.acsUrl || !o?.creq) return;
|
|
142
|
-
r = !1, p.log("Received payment challenge event.", {
|
|
143
|
-
hasAcsUrl: !!o.acsUrl,
|
|
144
|
-
hasCreq: !!o.creq
|
|
145
|
-
});
|
|
146
|
-
let s = t.form, c = s?.querySelector("input[name*=\"opayoSessionKey\"]")?.value || "", l = document.createElement("div");
|
|
147
|
-
l.className = "formie-modal", l.id = `formie-opayo-dialog-${Math.random().toString(36).slice(2, 9)}`, l.innerHTML = "\n <div class=\"formie-modal-backdrop\" data-dialog-close></div>\n <div class=\"formie-modal-content\">\n <div data-formie-opayo-loading style=\"--formie-loading-width: 3rem; --formie-loading-height: 3rem; top: 50%; margin-top: -1.5rem;\"></div>\n <iframe width=\"100%\" height=\"100%\" style=\"width: 100%; height: 100%; position: relative; z-index: 1;\"></iframe>\n </div>\n ";
|
|
148
|
-
let u = l.querySelector("[data-formie-opayo-loading]");
|
|
149
|
-
u && a(u, s, "loading", !0);
|
|
150
|
-
let d = l.querySelector("iframe"), f = (e) => e.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<"), m = o.returnUrl || o.redirectUrl || "", h = `<form action="${f(o.acsUrl)}" method="post">
|
|
151
|
-
<input type="hidden" name="creq" value="${f(o.creq || "")}" />
|
|
152
|
-
<input type="hidden" name="threeDSSessionData" value="${f(o.threeDSSessionData || "")}" />
|
|
153
|
-
<input type="hidden" name="MD" value="${f(c)}" />
|
|
154
|
-
<input type="hidden" name="TermUrl" value="${f(m)}" />
|
|
155
|
-
<input type="hidden" name="ThreeDSNotificationURL" value="${f(m)}" />
|
|
156
|
-
</form><script>document.forms[0].submit();<\/script>`;
|
|
157
|
-
i(), document.body.appendChild(l), n = l, d?.contentWindow && (d.contentWindow.document.open(), d.contentWindow.document.write(h), d.contentWindow.document.close());
|
|
158
|
-
})), s = (e) => {
|
|
159
|
-
if (e.data?.message === h) {
|
|
160
|
-
if (!n) {
|
|
161
|
-
p.log("Ignoring 3DS response without active dialog.");
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
if (r) {
|
|
165
|
-
p.warn("Ignoring duplicate 3DS response while processing.");
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (r = !0, p.log("Received payment challenge response message.", e.data?.value), i(), t.removeError(), e.data?.value?.error) {
|
|
169
|
-
t.addError(e.data.value.error.message), t.releaseSubmitLoading(), r = !1;
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
t.updateInputs("opayo3DSComplete", e.data.value?.transactionId ?? ""), t.triggerSubmit();
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
return window.addEventListener("message", s), { destroy: () => {
|
|
176
|
-
o(), window.removeEventListener("message", s), i(), r = !1;
|
|
177
|
-
} };
|
|
178
|
-
},
|
|
179
|
-
onAfterSubmit: async ({ services: e }) => {
|
|
180
|
-
e.updateInputs([
|
|
181
|
-
"opayoTokenId",
|
|
182
|
-
"opayoSessionKey",
|
|
183
|
-
"opayo3DSComplete"
|
|
184
|
-
], "");
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
//#endregion
|
|
188
|
-
export { y as opayoModule };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { a as e, r as t } from "./api-BK9b340y.js";
|
|
2
|
-
import { r as n } from "./scripts-DrccjrFv.js";
|
|
3
|
-
//#region src/js/modules/captchas/recaptcha-shared.ts
|
|
4
|
-
async function r(r, i = !1, a) {
|
|
5
|
-
let o = typeof r.language == "string" && r.language.trim() !== "" ? r.language.trim() : "en", { async: s, defer: c } = t(r.loadingMethod), l = i ? "https://www.google.com/recaptcha/enterprise.js" : "https://www.recaptcha.net/recaptcha/api.js", u = typeof a == "string" && a.trim() !== "" ? a.trim() : "explicit", d = new URL(l);
|
|
6
|
-
return d.searchParams.set("render", u), d.searchParams.set("hl", o), u !== "explicit" && typeof r.badge == "string" && r.badge.trim() !== "" && d.searchParams.set("badge", r.badge.trim()), n("grecaptcha", {
|
|
7
|
-
id: i ? "FORMIE_RECAPTCHA_ENTERPRISE_SCRIPT" : "FORMIE_RECAPTCHA_SCRIPT",
|
|
8
|
-
src: d.toString(),
|
|
9
|
-
async: s,
|
|
10
|
-
defer: c,
|
|
11
|
-
timeoutMs: e
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
function i(e, t) {
|
|
15
|
-
let n = e.enterprise || e;
|
|
16
|
-
return new Promise((e, r) => {
|
|
17
|
-
try {
|
|
18
|
-
n.ready(() => {
|
|
19
|
-
Promise.resolve(t()).then(e).catch(r);
|
|
20
|
-
});
|
|
21
|
-
} catch (e) {
|
|
22
|
-
r(e);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
export { i as n, r as t };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./api-BK9b340y.js";
|
|
2
|
-
import { n as t, t as n } from "./recaptcha-shared-DTbTw-MF.js";
|
|
3
|
-
//#region src/js/modules/captchas/recaptcha-v3.ts
|
|
4
|
-
var r = e({
|
|
5
|
-
moduleId: "formie:recaptcha-v3",
|
|
6
|
-
defaultPlaceholderSelector: "[data-recaptcha-placeholder]",
|
|
7
|
-
defaultTokenFieldNames: ["g-recaptcha-response"],
|
|
8
|
-
load: ({ options: e }) => n(e.provider, !1, e.provider.siteKey || void 0),
|
|
9
|
-
mount: ({ api: e, provider: t }) => new Promise((n) => {
|
|
10
|
-
e.ready(() => {
|
|
11
|
-
n(t.siteKey || "recaptcha-v3");
|
|
12
|
-
});
|
|
13
|
-
}),
|
|
14
|
-
challenge: async ({ api: e, provider: n, placeholder: r, services: i, stageCtx: a }) => {
|
|
15
|
-
if (!i.tokens.has() && (await t(e, async () => {
|
|
16
|
-
let t = await e.execute(n.siteKey || "", { action: n.action || "submit" });
|
|
17
|
-
typeof t == "string" && t.trim() !== "" && i.tokens.write(t.trim());
|
|
18
|
-
}), !await i.tokens.wait(12e4))) {
|
|
19
|
-
let e = i.errors.getDefaultMessage();
|
|
20
|
-
i.errors.show(e, r), a.abort(e);
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
unmount: ({ services: e }) => {
|
|
24
|
-
e.tokens.clear();
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
//#endregion
|
|
28
|
-
export { r as recaptchaV3Module };
|