swal_rails 0.3.1.beta1

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/Appraisals +43 -0
  3. data/CHANGELOG.md +73 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +973 -0
  6. data/Rakefile +12 -0
  7. data/app/assets/javascripts/swal_rails/chain.js +38 -0
  8. data/app/assets/javascripts/swal_rails/confirm.js +93 -0
  9. data/app/assets/javascripts/swal_rails/controllers/swal_controller.js +54 -0
  10. data/app/assets/javascripts/swal_rails/flash.js +24 -0
  11. data/app/assets/javascripts/swal_rails/index.js +62 -0
  12. data/app/assets/stylesheets/swal_rails/index.css +5 -0
  13. data/config/importmap.rb +9 -0
  14. data/config/locales/swal_rails.en.yml +19 -0
  15. data/config/locales/swal_rails.fr.yml +19 -0
  16. data/gemfiles/rails_7_2.gemfile +25 -0
  17. data/gemfiles/rails_8_0.gemfile +25 -0
  18. data/gemfiles/rails_8_1.gemfile +25 -0
  19. data/gemfiles/rails_8_1_sprockets.gemfile +25 -0
  20. data/lib/generators/swal_rails/install/install_generator.rb +138 -0
  21. data/lib/generators/swal_rails/install/templates/initializer.rb +33 -0
  22. data/lib/generators/swal_rails/locales/locales_generator.rb +19 -0
  23. data/lib/swal_rails/configuration.rb +88 -0
  24. data/lib/swal_rails/engine.rb +55 -0
  25. data/lib/swal_rails/helpers.rb +96 -0
  26. data/lib/swal_rails/version.rb +6 -0
  27. data/lib/swal_rails.rb +25 -0
  28. data/vendor/javascript/sweetalert2/LICENSE +22 -0
  29. data/vendor/javascript/sweetalert2/sweetalert2.all.js +4814 -0
  30. data/vendor/javascript/sweetalert2/sweetalert2.all.min.js +6 -0
  31. data/vendor/javascript/sweetalert2/sweetalert2.esm.all.js +4805 -0
  32. data/vendor/javascript/sweetalert2/sweetalert2.esm.all.min.js +6 -0
  33. data/vendor/javascript/sweetalert2/sweetalert2.esm.js +4804 -0
  34. data/vendor/javascript/sweetalert2/sweetalert2.esm.min.js +5 -0
  35. data/vendor/javascript/sweetalert2/sweetalert2.js +4813 -0
  36. data/vendor/javascript/sweetalert2/sweetalert2.min.js +5 -0
  37. data/vendor/stylesheets/sweetalert2/LICENSE +22 -0
  38. data/vendor/stylesheets/sweetalert2/sweetalert2.css +1233 -0
  39. data/vendor/stylesheets/sweetalert2/sweetalert2.min.css +1 -0
  40. data/vendor/stylesheets/sweetalert2/themes/bootstrap-4.css +167 -0
  41. data/vendor/stylesheets/sweetalert2/themes/bootstrap-5.css +173 -0
  42. data/vendor/stylesheets/sweetalert2/themes/borderless.css +46 -0
  43. data/vendor/stylesheets/sweetalert2/themes/bulma.css +94 -0
  44. data/vendor/stylesheets/sweetalert2/themes/material-ui.css +183 -0
  45. data/vendor/stylesheets/sweetalert2/themes/minimal.css +40 -0
  46. metadata +124 -0
@@ -0,0 +1,4804 @@
1
+ /*!
2
+ * sweetalert2 v11.26.24
3
+ * Released under the MIT License.
4
+ */
5
+ function _assertClassBrand(e, t, n) {
6
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
7
+ throw new TypeError("Private element is not present on this object");
8
+ }
9
+ function _checkPrivateRedeclaration(e, t) {
10
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
11
+ }
12
+ function _classPrivateFieldGet2(s, a) {
13
+ return s.get(_assertClassBrand(s, a));
14
+ }
15
+ function _classPrivateFieldInitSpec(e, t, a) {
16
+ _checkPrivateRedeclaration(e, t), t.set(e, a);
17
+ }
18
+ function _classPrivateFieldSet2(s, a, r) {
19
+ return s.set(_assertClassBrand(s, a), r), r;
20
+ }
21
+
22
+ const RESTORE_FOCUS_TIMEOUT = 100;
23
+
24
+ /** @type {GlobalState} */
25
+ const globalState = {};
26
+ const focusPreviousActiveElement = () => {
27
+ if (globalState.previousActiveElement instanceof HTMLElement) {
28
+ globalState.previousActiveElement.focus();
29
+ globalState.previousActiveElement = null;
30
+ } else if (document.body) {
31
+ document.body.focus();
32
+ }
33
+ };
34
+
35
+ /**
36
+ * Restore previous active (focused) element
37
+ *
38
+ * @param {boolean} returnFocus
39
+ * @returns {Promise<void>}
40
+ */
41
+ const restoreActiveElement = returnFocus => {
42
+ return new Promise(resolve => {
43
+ if (!returnFocus) {
44
+ return resolve();
45
+ }
46
+ const x = window.scrollX;
47
+ const y = window.scrollY;
48
+ globalState.restoreFocusTimeout = setTimeout(() => {
49
+ focusPreviousActiveElement();
50
+ resolve();
51
+ }, RESTORE_FOCUS_TIMEOUT); // issues/900
52
+
53
+ window.scrollTo(x, y);
54
+ });
55
+ };
56
+
57
+ const swalPrefix = 'swal2-';
58
+
59
+ /**
60
+ * @typedef {Record<SwalClass, string>} SwalClasses
61
+ */
62
+
63
+ /**
64
+ * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
65
+ * @typedef {Record<SwalIcon, string>} SwalIcons
66
+ */
67
+
68
+ /** @type {SwalClass[]} */
69
+ const classNames = ['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error', 'draggable', 'dragging'];
70
+ const swalClasses = classNames.reduce((acc, className) => {
71
+ acc[className] = swalPrefix + className;
72
+ return acc;
73
+ }, /** @type {SwalClasses} */{});
74
+
75
+ /** @type {SwalIcon[]} */
76
+ const icons = ['success', 'warning', 'info', 'question', 'error'];
77
+ const iconTypes = icons.reduce((acc, icon) => {
78
+ acc[icon] = swalPrefix + icon;
79
+ return acc;
80
+ }, /** @type {SwalIcons} */{});
81
+
82
+ const consolePrefix = 'SweetAlert2:';
83
+
84
+ /**
85
+ * Capitalize the first letter of a string
86
+ *
87
+ * @param {string} str
88
+ * @returns {string}
89
+ */
90
+ const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
91
+
92
+ /**
93
+ * Standardize console warnings
94
+ *
95
+ * @param {string | string[]} message
96
+ */
97
+ const warn = message => {
98
+ console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
99
+ };
100
+
101
+ /**
102
+ * Standardize console errors
103
+ *
104
+ * @param {string} message
105
+ */
106
+ const error = message => {
107
+ console.error(`${consolePrefix} ${message}`);
108
+ };
109
+
110
+ /**
111
+ * Private global state for `warnOnce`
112
+ *
113
+ * @type {string[]}
114
+ * @private
115
+ */
116
+ const previousWarnOnceMessages = [];
117
+
118
+ /**
119
+ * Show a console warning, but only if it hasn't already been shown
120
+ *
121
+ * @param {string} message
122
+ */
123
+ const warnOnce = message => {
124
+ if (!previousWarnOnceMessages.includes(message)) {
125
+ previousWarnOnceMessages.push(message);
126
+ warn(message);
127
+ }
128
+ };
129
+
130
+ /**
131
+ * Show a one-time console warning about deprecated params/methods
132
+ *
133
+ * @param {string} deprecatedParam
134
+ * @param {string?} useInstead
135
+ */
136
+ const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
137
+ warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
138
+ };
139
+
140
+ /**
141
+ * If `arg` is a function, call it (with no arguments or context) and return the result.
142
+ * Otherwise, just pass the value through
143
+ *
144
+ * @param {(() => *) | *} arg
145
+ * @returns {*}
146
+ */
147
+ const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
148
+
149
+ /**
150
+ * @param {*} arg
151
+ * @returns {boolean}
152
+ */
153
+ const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
154
+
155
+ /**
156
+ * @param {*} arg
157
+ * @returns {Promise<*>}
158
+ */
159
+ const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
160
+
161
+ /**
162
+ * @param {*} arg
163
+ * @returns {boolean}
164
+ */
165
+ const isPromise = arg => arg && Promise.resolve(arg) === arg;
166
+
167
+ /**
168
+ * @returns {boolean}
169
+ */
170
+ const isFirefox = () => navigator.userAgent.includes('Firefox');
171
+
172
+ /**
173
+ * Gets the popup container which contains the backdrop and the popup itself.
174
+ *
175
+ * @returns {HTMLElement | null}
176
+ */
177
+ const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
178
+
179
+ /**
180
+ * @param {string} selectorString
181
+ * @returns {HTMLElement | null}
182
+ */
183
+ const elementBySelector = selectorString => {
184
+ const container = getContainer();
185
+ return container ? container.querySelector(selectorString) : null;
186
+ };
187
+
188
+ /**
189
+ * @param {string} className
190
+ * @returns {HTMLElement | null}
191
+ */
192
+ const elementByClass = className => {
193
+ return elementBySelector(`.${className}`);
194
+ };
195
+
196
+ /**
197
+ * @returns {HTMLElement | null}
198
+ */
199
+ const getPopup = () => elementByClass(swalClasses.popup);
200
+
201
+ /**
202
+ * @returns {HTMLElement | null}
203
+ */
204
+ const getIcon = () => elementByClass(swalClasses.icon);
205
+
206
+ /**
207
+ * @returns {HTMLElement | null}
208
+ */
209
+ const getIconContent = () => elementByClass(swalClasses['icon-content']);
210
+
211
+ /**
212
+ * @returns {HTMLElement | null}
213
+ */
214
+ const getTitle = () => elementByClass(swalClasses.title);
215
+
216
+ /**
217
+ * @returns {HTMLElement | null}
218
+ */
219
+ const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
220
+
221
+ /**
222
+ * @returns {HTMLElement | null}
223
+ */
224
+ const getImage = () => elementByClass(swalClasses.image);
225
+
226
+ /**
227
+ * @returns {HTMLElement | null}
228
+ */
229
+ const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
230
+
231
+ /**
232
+ * @returns {HTMLElement | null}
233
+ */
234
+ const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
235
+
236
+ /**
237
+ * @returns {HTMLButtonElement | null}
238
+ */
239
+ const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
240
+
241
+ /**
242
+ * @returns {HTMLButtonElement | null}
243
+ */
244
+ const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
245
+
246
+ /**
247
+ * @returns {HTMLButtonElement | null}
248
+ */
249
+ const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
250
+
251
+ /**
252
+ * @returns {HTMLElement | null}
253
+ */
254
+ const getInputLabel = () => elementByClass(swalClasses['input-label']);
255
+
256
+ /**
257
+ * @returns {HTMLElement | null}
258
+ */
259
+ const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
260
+
261
+ /**
262
+ * @returns {HTMLElement | null}
263
+ */
264
+ const getActions = () => elementByClass(swalClasses.actions);
265
+
266
+ /**
267
+ * @returns {HTMLElement | null}
268
+ */
269
+ const getFooter = () => elementByClass(swalClasses.footer);
270
+
271
+ /**
272
+ * @returns {HTMLElement | null}
273
+ */
274
+ const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
275
+
276
+ /**
277
+ * @returns {HTMLElement | null}
278
+ */
279
+ const getCloseButton = () => elementByClass(swalClasses.close);
280
+
281
+ // https://github.com/jkup/focusable/blob/master/index.js
282
+ const focusable = `
283
+ a[href],
284
+ area[href],
285
+ input:not([disabled]),
286
+ select:not([disabled]),
287
+ textarea:not([disabled]),
288
+ button:not([disabled]),
289
+ iframe,
290
+ object,
291
+ embed,
292
+ [tabindex="0"],
293
+ [contenteditable],
294
+ audio[controls],
295
+ video[controls],
296
+ summary
297
+ `;
298
+ /**
299
+ * @returns {HTMLElement[]}
300
+ */
301
+ const getFocusableElements = () => {
302
+ const popup = getPopup();
303
+ if (!popup) {
304
+ return [];
305
+ }
306
+ /** @type {NodeListOf<HTMLElement>} */
307
+ const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
308
+ const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
309
+ // sort according to tabindex
310
+ .sort((a, b) => {
311
+ const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
312
+ const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
313
+ if (tabindexA > tabindexB) {
314
+ return 1;
315
+ } else if (tabindexA < tabindexB) {
316
+ return -1;
317
+ }
318
+ return 0;
319
+ });
320
+
321
+ /** @type {NodeListOf<HTMLElement>} */
322
+ const otherFocusableElements = popup.querySelectorAll(focusable);
323
+ const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
324
+ return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
325
+ };
326
+
327
+ /**
328
+ * @returns {boolean}
329
+ */
330
+ const isModal = () => {
331
+ return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
332
+ };
333
+
334
+ /**
335
+ * @returns {boolean}
336
+ */
337
+ const isToast = () => {
338
+ const popup = getPopup();
339
+ if (!popup) {
340
+ return false;
341
+ }
342
+ return hasClass(popup, swalClasses.toast);
343
+ };
344
+
345
+ /**
346
+ * @returns {boolean}
347
+ */
348
+ const isLoading = () => {
349
+ const popup = getPopup();
350
+ if (!popup) {
351
+ return false;
352
+ }
353
+ return popup.hasAttribute('data-loading');
354
+ };
355
+
356
+ /**
357
+ * Securely set innerHTML of an element
358
+ * https://github.com/sweetalert2/sweetalert2/issues/1926
359
+ *
360
+ * @param {HTMLElement} elem
361
+ * @param {string} html
362
+ */
363
+ const setInnerHtml = (elem, html) => {
364
+ elem.textContent = '';
365
+ if (html) {
366
+ const parser = new DOMParser();
367
+ const parsed = parser.parseFromString(html, `text/html`);
368
+ const head = parsed.querySelector('head');
369
+ if (head) {
370
+ Array.from(head.childNodes).forEach(child => {
371
+ elem.appendChild(child);
372
+ });
373
+ }
374
+ const body = parsed.querySelector('body');
375
+ if (body) {
376
+ Array.from(body.childNodes).forEach(child => {
377
+ if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
378
+ elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
379
+ } else {
380
+ elem.appendChild(child);
381
+ }
382
+ });
383
+ }
384
+ }
385
+ };
386
+
387
+ /**
388
+ * @param {HTMLElement} elem
389
+ * @param {string} className
390
+ * @returns {boolean}
391
+ */
392
+ const hasClass = (elem, className) => {
393
+ if (!className) {
394
+ return false;
395
+ }
396
+ const classList = className.split(/\s+/);
397
+ for (let i = 0; i < classList.length; i++) {
398
+ if (!elem.classList.contains(classList[i])) {
399
+ return false;
400
+ }
401
+ }
402
+ return true;
403
+ };
404
+
405
+ /**
406
+ * @param {HTMLElement} elem
407
+ * @param {SweetAlertOptions} params
408
+ */
409
+ const removeCustomClasses = (elem, params) => {
410
+ Array.from(elem.classList).forEach(className => {
411
+ if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
412
+ elem.classList.remove(className);
413
+ }
414
+ });
415
+ };
416
+
417
+ /**
418
+ * @param {HTMLElement} elem
419
+ * @param {SweetAlertOptions} params
420
+ * @param {string} className
421
+ */
422
+ const applyCustomClass = (elem, params, className) => {
423
+ removeCustomClasses(elem, params);
424
+ if (!params.customClass) {
425
+ return;
426
+ }
427
+ const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
428
+ if (!customClass) {
429
+ return;
430
+ }
431
+ if (typeof customClass !== 'string' && !customClass.forEach) {
432
+ warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
433
+ return;
434
+ }
435
+ addClass(elem, customClass);
436
+ };
437
+
438
+ /**
439
+ * @param {HTMLElement} popup
440
+ * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
441
+ * @returns {HTMLInputElement | null}
442
+ */
443
+ const getInput$1 = (popup, inputClass) => {
444
+ if (!inputClass) {
445
+ return null;
446
+ }
447
+ switch (inputClass) {
448
+ case 'select':
449
+ case 'textarea':
450
+ case 'file':
451
+ return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
452
+ case 'checkbox':
453
+ return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
454
+ case 'radio':
455
+ return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
456
+ case 'range':
457
+ return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
458
+ default:
459
+ return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
460
+ }
461
+ };
462
+
463
+ /**
464
+ * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
465
+ */
466
+ const focusInput = input => {
467
+ input.focus();
468
+
469
+ // place cursor at end of text in text input
470
+ if (input.type !== 'file') {
471
+ // http://stackoverflow.com/a/2345915
472
+ const val = input.value;
473
+ input.value = '';
474
+ input.value = val;
475
+ }
476
+ };
477
+
478
+ /**
479
+ * @param {HTMLElement | HTMLElement[] | null} target
480
+ * @param {string | string[] | readonly string[] | undefined} classList
481
+ * @param {boolean} condition
482
+ */
483
+ const toggleClass = (target, classList, condition) => {
484
+ if (!target || !classList) {
485
+ return;
486
+ }
487
+ const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
488
+ const targets = Array.isArray(target) ? target : [target];
489
+ targets.forEach(elem => {
490
+ classes.forEach(className => {
491
+ if (condition) {
492
+ elem.classList.add(className);
493
+ } else {
494
+ elem.classList.remove(className);
495
+ }
496
+ });
497
+ });
498
+ };
499
+
500
+ /**
501
+ * @param {HTMLElement | HTMLElement[] | null} target
502
+ * @param {string | string[] | readonly string[] | undefined} classList
503
+ */
504
+ const addClass = (target, classList) => {
505
+ toggleClass(target, classList, true);
506
+ };
507
+
508
+ /**
509
+ * @param {HTMLElement | HTMLElement[] | null} target
510
+ * @param {string | string[] | readonly string[] | undefined} classList
511
+ */
512
+ const removeClass = (target, classList) => {
513
+ toggleClass(target, classList, false);
514
+ };
515
+
516
+ /**
517
+ * Get direct child of an element by class name
518
+ *
519
+ * @param {HTMLElement} elem
520
+ * @param {string} className
521
+ * @returns {HTMLElement | undefined}
522
+ */
523
+ const getDirectChildByClass = (elem, className) => {
524
+ const children = Array.from(elem.children);
525
+ for (let i = 0; i < children.length; i++) {
526
+ const child = children[i];
527
+ if (child instanceof HTMLElement && hasClass(child, className)) {
528
+ return child;
529
+ }
530
+ }
531
+ };
532
+
533
+ /**
534
+ * @param {HTMLElement} elem
535
+ * @param {string} property
536
+ * @param {string | number | null | undefined} value
537
+ */
538
+ const applyNumericalStyle = (elem, property, value) => {
539
+ if (value === `${parseInt(`${value}`)}`) {
540
+ value = parseInt(value);
541
+ }
542
+ if (value || value === 0) {
543
+ elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
544
+ } else {
545
+ elem.style.removeProperty(property);
546
+ }
547
+ };
548
+
549
+ /**
550
+ * @param {HTMLElement | null} elem
551
+ * @param {string} display
552
+ */
553
+ const show = (elem, display = 'flex') => {
554
+ if (!elem) {
555
+ return;
556
+ }
557
+ elem.style.display = display;
558
+ };
559
+
560
+ /**
561
+ * @param {HTMLElement | null} elem
562
+ */
563
+ const hide = elem => {
564
+ if (!elem) {
565
+ return;
566
+ }
567
+ elem.style.display = 'none';
568
+ };
569
+
570
+ /**
571
+ * @param {HTMLElement | null} elem
572
+ * @param {string} display
573
+ */
574
+ const showWhenInnerHtmlPresent = (elem, display = 'block') => {
575
+ if (!elem) {
576
+ return;
577
+ }
578
+ new MutationObserver(() => {
579
+ toggle(elem, elem.innerHTML, display);
580
+ }).observe(elem, {
581
+ childList: true,
582
+ subtree: true
583
+ });
584
+ };
585
+
586
+ /**
587
+ * @param {HTMLElement} parent
588
+ * @param {string} selector
589
+ * @param {string} property
590
+ * @param {string} value
591
+ */
592
+ const setStyle = (parent, selector, property, value) => {
593
+ /** @type {HTMLElement | null} */
594
+ const el = parent.querySelector(selector);
595
+ if (el) {
596
+ el.style.setProperty(property, value);
597
+ }
598
+ };
599
+
600
+ /**
601
+ * @param {HTMLElement} elem
602
+ * @param {boolean | string | null | undefined} condition
603
+ * @param {string} display
604
+ */
605
+ const toggle = (elem, condition, display = 'flex') => {
606
+ if (condition) {
607
+ show(elem, display);
608
+ } else {
609
+ hide(elem);
610
+ }
611
+ };
612
+
613
+ /**
614
+ * borrowed from jquery $(elem).is(':visible') implementation
615
+ *
616
+ * @param {HTMLElement | null} elem
617
+ * @returns {boolean}
618
+ */
619
+ const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
620
+
621
+ /**
622
+ * @returns {boolean}
623
+ */
624
+ const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
625
+
626
+ /**
627
+ * @param {HTMLElement} elem
628
+ * @returns {boolean}
629
+ */
630
+ const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
631
+
632
+ /**
633
+ * @param {HTMLElement} element
634
+ * @param {HTMLElement} stopElement
635
+ * @returns {boolean}
636
+ */
637
+ const selfOrParentIsScrollable = (element, stopElement) => {
638
+ let parent = /** @type {HTMLElement | null} */element;
639
+ while (parent && parent !== stopElement) {
640
+ if (isScrollable(parent)) {
641
+ return true;
642
+ }
643
+ parent = parent.parentElement;
644
+ }
645
+ return false;
646
+ };
647
+
648
+ /**
649
+ * borrowed from https://stackoverflow.com/a/46352119
650
+ *
651
+ * @param {HTMLElement} elem
652
+ * @returns {boolean}
653
+ */
654
+ const hasCssAnimation = elem => {
655
+ const style = window.getComputedStyle(elem);
656
+ const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
657
+ const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
658
+ return animDuration > 0 || transDuration > 0;
659
+ };
660
+
661
+ /**
662
+ * @param {number} timer
663
+ * @param {boolean} reset
664
+ */
665
+ const animateTimerProgressBar = (timer, reset = false) => {
666
+ const timerProgressBar = getTimerProgressBar();
667
+ if (!timerProgressBar) {
668
+ return;
669
+ }
670
+ if (isVisible$1(timerProgressBar)) {
671
+ if (reset) {
672
+ timerProgressBar.style.transition = 'none';
673
+ timerProgressBar.style.width = '100%';
674
+ }
675
+ setTimeout(() => {
676
+ timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
677
+ timerProgressBar.style.width = '0%';
678
+ }, 10);
679
+ }
680
+ };
681
+ const stopTimerProgressBar = () => {
682
+ const timerProgressBar = getTimerProgressBar();
683
+ if (!timerProgressBar) {
684
+ return;
685
+ }
686
+ const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
687
+ timerProgressBar.style.removeProperty('transition');
688
+ timerProgressBar.style.width = '100%';
689
+ const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
690
+ const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
691
+ timerProgressBar.style.width = `${timerProgressBarPercent}%`;
692
+ };
693
+
694
+ /**
695
+ * Detect Node env
696
+ *
697
+ * @returns {boolean}
698
+ */
699
+ const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
700
+
701
+ const sweetHTML = `
702
+ <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
703
+ <button type="button" class="${swalClasses.close}"></button>
704
+ <ul class="${swalClasses['progress-steps']}"></ul>
705
+ <div class="${swalClasses.icon}"></div>
706
+ <img class="${swalClasses.image}" />
707
+ <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
708
+ <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
709
+ <input class="${swalClasses.input}" id="${swalClasses.input}" />
710
+ <input type="file" class="${swalClasses.file}" />
711
+ <div class="${swalClasses.range}">
712
+ <input type="range" />
713
+ <output></output>
714
+ </div>
715
+ <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
716
+ <div class="${swalClasses.radio}"></div>
717
+ <label class="${swalClasses.checkbox}">
718
+ <input type="checkbox" id="${swalClasses.checkbox}" />
719
+ <span class="${swalClasses.label}"></span>
720
+ </label>
721
+ <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
722
+ <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
723
+ <div class="${swalClasses.actions}">
724
+ <div class="${swalClasses.loader}"></div>
725
+ <button type="button" class="${swalClasses.confirm}"></button>
726
+ <button type="button" class="${swalClasses.deny}"></button>
727
+ <button type="button" class="${swalClasses.cancel}"></button>
728
+ </div>
729
+ <div class="${swalClasses.footer}"></div>
730
+ <div class="${swalClasses['timer-progress-bar-container']}">
731
+ <div class="${swalClasses['timer-progress-bar']}"></div>
732
+ </div>
733
+ </div>
734
+ `.replace(/(^|\n)\s*/g, '');
735
+
736
+ /**
737
+ * @returns {boolean}
738
+ */
739
+ const resetOldContainer = () => {
740
+ const oldContainer = getContainer();
741
+ if (!oldContainer) {
742
+ return false;
743
+ }
744
+ oldContainer.remove();
745
+ removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
746
+ // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
747
+ swalClasses['has-column']]);
748
+ return true;
749
+ };
750
+ const resetValidationMessage$1 = () => {
751
+ if (globalState.currentInstance) {
752
+ globalState.currentInstance.resetValidationMessage();
753
+ }
754
+ };
755
+ const addInputChangeListeners = () => {
756
+ const popup = getPopup();
757
+ if (!popup) {
758
+ return;
759
+ }
760
+ const input = getDirectChildByClass(popup, swalClasses.input);
761
+ const file = getDirectChildByClass(popup, swalClasses.file);
762
+ /** @type {HTMLInputElement | null} */
763
+ const range = popup.querySelector(`.${swalClasses.range} input`);
764
+ /** @type {HTMLOutputElement | null} */
765
+ const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
766
+ const select = getDirectChildByClass(popup, swalClasses.select);
767
+ /** @type {HTMLInputElement | null} */
768
+ const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
769
+ const textarea = getDirectChildByClass(popup, swalClasses.textarea);
770
+ if (input) {
771
+ input.oninput = resetValidationMessage$1;
772
+ }
773
+ if (file) {
774
+ file.onchange = resetValidationMessage$1;
775
+ }
776
+ if (select) {
777
+ select.onchange = resetValidationMessage$1;
778
+ }
779
+ if (checkbox) {
780
+ checkbox.onchange = resetValidationMessage$1;
781
+ }
782
+ if (textarea) {
783
+ textarea.oninput = resetValidationMessage$1;
784
+ }
785
+ if (range && rangeOutput) {
786
+ range.oninput = () => {
787
+ resetValidationMessage$1();
788
+ rangeOutput.value = range.value;
789
+ };
790
+ range.onchange = () => {
791
+ resetValidationMessage$1();
792
+ rangeOutput.value = range.value;
793
+ };
794
+ }
795
+ };
796
+
797
+ /**
798
+ * @param {string | HTMLElement} target
799
+ * @returns {HTMLElement}
800
+ */
801
+ const getTarget = target => {
802
+ if (typeof target === 'string') {
803
+ const element = document.querySelector(target);
804
+ if (!element) {
805
+ throw new Error(`Target element "${target}" not found`);
806
+ }
807
+ return /** @type {HTMLElement} */element;
808
+ }
809
+ return target;
810
+ };
811
+
812
+ /**
813
+ * @param {SweetAlertOptions} params
814
+ */
815
+ const setupAccessibility = params => {
816
+ const popup = getPopup();
817
+ if (!popup) {
818
+ return;
819
+ }
820
+ popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
821
+ popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
822
+ if (!params.toast) {
823
+ popup.setAttribute('aria-modal', 'true');
824
+ }
825
+ };
826
+
827
+ /**
828
+ * @param {HTMLElement} targetElement
829
+ */
830
+ const setupRTL = targetElement => {
831
+ if (window.getComputedStyle(targetElement).direction === 'rtl') {
832
+ addClass(getContainer(), swalClasses.rtl);
833
+ globalState.isRTL = true;
834
+ }
835
+ };
836
+
837
+ /**
838
+ * Add modal + backdrop to DOM
839
+ *
840
+ * @param {SweetAlertOptions} params
841
+ */
842
+ const init = params => {
843
+ // Clean up the old popup container if it exists
844
+ const oldContainerExisted = resetOldContainer();
845
+ if (isNodeEnv()) {
846
+ error('SweetAlert2 requires document to initialize');
847
+ return;
848
+ }
849
+ const container = document.createElement('div');
850
+ container.className = swalClasses.container;
851
+ if (oldContainerExisted) {
852
+ addClass(container, swalClasses['no-transition']);
853
+ }
854
+ setInnerHtml(container, sweetHTML);
855
+ container.dataset['swal2Theme'] = params.theme;
856
+ const targetElement = getTarget(params.target || 'body');
857
+ targetElement.appendChild(container);
858
+ if (params.topLayer) {
859
+ container.setAttribute('popover', '');
860
+ container.showPopover();
861
+ }
862
+ setupAccessibility(params);
863
+ setupRTL(targetElement);
864
+ addInputChangeListeners();
865
+ };
866
+
867
+ /**
868
+ * @param {HTMLElement | object | string} param
869
+ * @param {HTMLElement} target
870
+ */
871
+ const parseHtmlToContainer = (param, target) => {
872
+ // DOM element
873
+ if (param instanceof HTMLElement) {
874
+ target.appendChild(param);
875
+ }
876
+
877
+ // Object
878
+ else if (typeof param === 'object') {
879
+ handleObject(param, target);
880
+ }
881
+
882
+ // Plain string
883
+ else if (param) {
884
+ setInnerHtml(target, param);
885
+ }
886
+ };
887
+
888
+ /**
889
+ * @param {object} param
890
+ * @param {HTMLElement} target
891
+ */
892
+ const handleObject = (param, target) => {
893
+ // JQuery element(s)
894
+ if ('jquery' in param) {
895
+ handleJqueryElem(target, param);
896
+ }
897
+
898
+ // For other objects use their string representation
899
+ else {
900
+ setInnerHtml(target, param.toString());
901
+ }
902
+ };
903
+
904
+ /**
905
+ * @param {HTMLElement} target
906
+ * @param {any} elem
907
+ */
908
+ const handleJqueryElem = (target, elem) => {
909
+ target.textContent = '';
910
+ if (0 in elem) {
911
+ for (let i = 0; i in elem; i++) {
912
+ target.appendChild(elem[i].cloneNode(true));
913
+ }
914
+ } else {
915
+ target.appendChild(elem.cloneNode(true));
916
+ }
917
+ };
918
+
919
+ /**
920
+ * @param {SweetAlert} instance
921
+ * @param {SweetAlertOptions} params
922
+ */
923
+ const renderActions = (instance, params) => {
924
+ const actions = getActions();
925
+ const loader = getLoader();
926
+ if (!actions || !loader) {
927
+ return;
928
+ }
929
+
930
+ // Actions (buttons) wrapper
931
+ if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
932
+ hide(actions);
933
+ } else {
934
+ show(actions);
935
+ }
936
+
937
+ // Custom class
938
+ applyCustomClass(actions, params, 'actions');
939
+
940
+ // Render all the buttons
941
+ renderButtons(actions, loader, params);
942
+
943
+ // Loader
944
+ setInnerHtml(loader, params.loaderHtml || '');
945
+ applyCustomClass(loader, params, 'loader');
946
+ };
947
+
948
+ /**
949
+ * @param {HTMLElement} actions
950
+ * @param {HTMLElement} loader
951
+ * @param {SweetAlertOptions} params
952
+ */
953
+ function renderButtons(actions, loader, params) {
954
+ const confirmButton = getConfirmButton();
955
+ const denyButton = getDenyButton();
956
+ const cancelButton = getCancelButton();
957
+ if (!confirmButton || !denyButton || !cancelButton) {
958
+ return;
959
+ }
960
+
961
+ // Render buttons
962
+ renderButton(confirmButton, 'confirm', params);
963
+ renderButton(denyButton, 'deny', params);
964
+ renderButton(cancelButton, 'cancel', params);
965
+ handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
966
+ if (params.reverseButtons) {
967
+ if (params.toast) {
968
+ actions.insertBefore(cancelButton, confirmButton);
969
+ actions.insertBefore(denyButton, confirmButton);
970
+ } else {
971
+ actions.insertBefore(cancelButton, loader);
972
+ actions.insertBefore(denyButton, loader);
973
+ actions.insertBefore(confirmButton, loader);
974
+ }
975
+ }
976
+ }
977
+
978
+ /**
979
+ * @param {HTMLElement} confirmButton
980
+ * @param {HTMLElement} denyButton
981
+ * @param {HTMLElement} cancelButton
982
+ * @param {SweetAlertOptions} params
983
+ */
984
+ function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
985
+ if (!params.buttonsStyling) {
986
+ removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
987
+ return;
988
+ }
989
+ addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
990
+
991
+ // Apply custom background colors and outline colors to action buttons
992
+ /** @type {[HTMLElement, string, string | undefined][]} */
993
+ const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
994
+ buttons.forEach(([button, type, color]) => {
995
+ if (color) {
996
+ button.style.setProperty(`--swal2-${type}-button-background-color`, color);
997
+ }
998
+ applyOutlineColor(button);
999
+ });
1000
+ }
1001
+
1002
+ /**
1003
+ * @param {HTMLElement} button
1004
+ */
1005
+ function applyOutlineColor(button) {
1006
+ const buttonStyle = window.getComputedStyle(button);
1007
+ if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
1008
+ // If the button already has a custom outline color, no need to change it
1009
+ return;
1010
+ }
1011
+ const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
1012
+ button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
1013
+ }
1014
+
1015
+ /**
1016
+ * @param {HTMLElement} button
1017
+ * @param {'confirm' | 'deny' | 'cancel'} buttonType
1018
+ * @param {SweetAlertOptions} params
1019
+ */
1020
+ function renderButton(button, buttonType, params) {
1021
+ const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
1022
+ toggle(button, params[`show${buttonName}Button`], 'inline-block');
1023
+ setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
1024
+ button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
1025
+
1026
+ // Add buttons custom classes
1027
+ button.className = swalClasses[buttonType];
1028
+ applyCustomClass(button, params, `${buttonType}Button`);
1029
+ }
1030
+
1031
+ /**
1032
+ * @param {SweetAlert} instance
1033
+ * @param {SweetAlertOptions} params
1034
+ */
1035
+ const renderCloseButton = (instance, params) => {
1036
+ const closeButton = getCloseButton();
1037
+ if (!closeButton) {
1038
+ return;
1039
+ }
1040
+ setInnerHtml(closeButton, params.closeButtonHtml || '');
1041
+
1042
+ // Custom class
1043
+ applyCustomClass(closeButton, params, 'closeButton');
1044
+ toggle(closeButton, params.showCloseButton);
1045
+ closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
1046
+ };
1047
+
1048
+ /**
1049
+ * @param {SweetAlert} instance
1050
+ * @param {SweetAlertOptions} params
1051
+ */
1052
+ const renderContainer = (instance, params) => {
1053
+ const container = getContainer();
1054
+ if (!container) {
1055
+ return;
1056
+ }
1057
+ handleBackdropParam(container, params.backdrop);
1058
+ handlePositionParam(container, params.position);
1059
+ handleGrowParam(container, params.grow);
1060
+
1061
+ // Custom class
1062
+ applyCustomClass(container, params, 'container');
1063
+ };
1064
+
1065
+ /**
1066
+ * @param {HTMLElement} container
1067
+ * @param {SweetAlertOptions['backdrop']} backdrop
1068
+ */
1069
+ function handleBackdropParam(container, backdrop) {
1070
+ if (typeof backdrop === 'string') {
1071
+ container.style.background = backdrop;
1072
+ } else if (!backdrop) {
1073
+ addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
1074
+ }
1075
+ }
1076
+
1077
+ /**
1078
+ * @param {HTMLElement} container
1079
+ * @param {SweetAlertOptions['position']} position
1080
+ */
1081
+ function handlePositionParam(container, position) {
1082
+ if (!position) {
1083
+ return;
1084
+ }
1085
+ if (position in swalClasses) {
1086
+ addClass(container, swalClasses[position]);
1087
+ } else {
1088
+ warn('The "position" parameter is not valid, defaulting to "center"');
1089
+ addClass(container, swalClasses.center);
1090
+ }
1091
+ }
1092
+
1093
+ /**
1094
+ * @param {HTMLElement} container
1095
+ * @param {SweetAlertOptions['grow']} grow
1096
+ */
1097
+ function handleGrowParam(container, grow) {
1098
+ if (!grow) {
1099
+ return;
1100
+ }
1101
+ addClass(container, swalClasses[`grow-${grow}`]);
1102
+ }
1103
+
1104
+ /**
1105
+ * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
1106
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
1107
+ * This is the approach that Babel will probably take to implement private methods/fields
1108
+ * https://github.com/tc39/proposal-private-methods
1109
+ * https://github.com/babel/babel/pull/7555
1110
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
1111
+ * then we can use that language feature.
1112
+ */
1113
+
1114
+ var privateProps = {
1115
+ innerParams: new WeakMap(),
1116
+ domCache: new WeakMap(),
1117
+ focusedElement: new WeakMap()
1118
+ };
1119
+
1120
+ /// <reference path="../../../../sweetalert2.d.ts"/>
1121
+
1122
+
1123
+ /** @type {InputClass[]} */
1124
+ const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
1125
+
1126
+ /**
1127
+ * @param {SweetAlert} instance
1128
+ * @param {SweetAlertOptions} params
1129
+ */
1130
+ const renderInput = (instance, params) => {
1131
+ const popup = getPopup();
1132
+ if (!popup) {
1133
+ return;
1134
+ }
1135
+ const innerParams = privateProps.innerParams.get(instance);
1136
+ const rerender = !innerParams || params.input !== innerParams.input;
1137
+ inputClasses.forEach(inputClass => {
1138
+ const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
1139
+ if (!inputContainer) {
1140
+ return;
1141
+ }
1142
+
1143
+ // set attributes
1144
+ setAttributes(inputClass, params.inputAttributes);
1145
+
1146
+ // set class
1147
+ inputContainer.className = swalClasses[inputClass];
1148
+ if (rerender) {
1149
+ hide(inputContainer);
1150
+ }
1151
+ });
1152
+ if (params.input) {
1153
+ if (rerender) {
1154
+ showInput(params);
1155
+ }
1156
+ // set custom class
1157
+ setCustomClass(params);
1158
+ }
1159
+ };
1160
+
1161
+ /**
1162
+ * @param {SweetAlertOptions} params
1163
+ */
1164
+ const showInput = params => {
1165
+ if (!params.input) {
1166
+ return;
1167
+ }
1168
+ if (!renderInputType[params.input]) {
1169
+ error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
1170
+ return;
1171
+ }
1172
+ const inputContainer = getInputContainer(params.input);
1173
+ if (!inputContainer) {
1174
+ return;
1175
+ }
1176
+ const input = renderInputType[params.input](inputContainer, params);
1177
+ show(inputContainer);
1178
+
1179
+ // input autofocus
1180
+ if (params.inputAutoFocus) {
1181
+ setTimeout(() => {
1182
+ focusInput(input);
1183
+ });
1184
+ }
1185
+ };
1186
+
1187
+ /**
1188
+ * @param {HTMLInputElement} input
1189
+ */
1190
+ const removeAttributes = input => {
1191
+ for (let i = 0; i < input.attributes.length; i++) {
1192
+ const attrName = input.attributes[i].name;
1193
+ if (!['id', 'type', 'value', 'style'].includes(attrName)) {
1194
+ input.removeAttribute(attrName);
1195
+ }
1196
+ }
1197
+ };
1198
+
1199
+ /**
1200
+ * @param {InputClass} inputClass
1201
+ * @param {SweetAlertOptions['inputAttributes']} inputAttributes
1202
+ */
1203
+ const setAttributes = (inputClass, inputAttributes) => {
1204
+ const popup = getPopup();
1205
+ if (!popup) {
1206
+ return;
1207
+ }
1208
+ const input = getInput$1(popup, inputClass);
1209
+ if (!input) {
1210
+ return;
1211
+ }
1212
+ removeAttributes(input);
1213
+ for (const attr in inputAttributes) {
1214
+ input.setAttribute(attr, inputAttributes[attr]);
1215
+ }
1216
+ };
1217
+
1218
+ /**
1219
+ * @param {SweetAlertOptions} params
1220
+ */
1221
+ const setCustomClass = params => {
1222
+ if (!params.input) {
1223
+ return;
1224
+ }
1225
+ const inputContainer = getInputContainer(params.input);
1226
+ if (inputContainer) {
1227
+ applyCustomClass(inputContainer, params, 'input');
1228
+ }
1229
+ };
1230
+
1231
+ /**
1232
+ * @param {HTMLInputElement | HTMLTextAreaElement} input
1233
+ * @param {SweetAlertOptions} params
1234
+ */
1235
+ const setInputPlaceholder = (input, params) => {
1236
+ if (!input.placeholder && params.inputPlaceholder) {
1237
+ input.placeholder = params.inputPlaceholder;
1238
+ }
1239
+ };
1240
+
1241
+ /**
1242
+ * @param {Input} input
1243
+ * @param {Input} prependTo
1244
+ * @param {SweetAlertOptions} params
1245
+ */
1246
+ const setInputLabel = (input, prependTo, params) => {
1247
+ if (params.inputLabel) {
1248
+ const label = document.createElement('label');
1249
+ const labelClass = swalClasses['input-label'];
1250
+ label.setAttribute('for', input.id);
1251
+ label.className = labelClass;
1252
+ if (typeof params.customClass === 'object') {
1253
+ addClass(label, params.customClass.inputLabel);
1254
+ }
1255
+ label.innerText = params.inputLabel;
1256
+ prependTo.insertAdjacentElement('beforebegin', label);
1257
+ }
1258
+ };
1259
+
1260
+ /**
1261
+ * @param {SweetAlertInput} inputType
1262
+ * @returns {HTMLElement | undefined}
1263
+ */
1264
+ const getInputContainer = inputType => {
1265
+ const popup = getPopup();
1266
+ if (!popup) {
1267
+ return;
1268
+ }
1269
+ return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
1270
+ };
1271
+
1272
+ /**
1273
+ * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
1274
+ * @param {SweetAlertOptions['inputValue']} inputValue
1275
+ */
1276
+ const checkAndSetInputValue = (input, inputValue) => {
1277
+ if (['string', 'number'].includes(typeof inputValue)) {
1278
+ input.value = `${inputValue}`;
1279
+ } else if (!isPromise(inputValue)) {
1280
+ warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
1281
+ }
1282
+ };
1283
+
1284
+ /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
1285
+ const renderInputType = {};
1286
+
1287
+ /**
1288
+ * @param {Input | HTMLElement} input
1289
+ * @param {SweetAlertOptions} params
1290
+ * @returns {Input}
1291
+ */
1292
+ renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = renderInputType.search = renderInputType.date = renderInputType['datetime-local'] = renderInputType.time = renderInputType.week = renderInputType.month = /** @type {(input: Input | HTMLElement, params: SweetAlertOptions) => Input} */
1293
+ (input, params) => {
1294
+ // oxfmt-ignore
1295
+ const inputElement = /** @type {HTMLInputElement} */input;
1296
+ checkAndSetInputValue(inputElement, params.inputValue);
1297
+ setInputLabel(inputElement, inputElement, params);
1298
+ setInputPlaceholder(inputElement, params);
1299
+ // oxfmt-ignore
1300
+ inputElement.type = /** @type {string} */params.input;
1301
+ return inputElement;
1302
+ };
1303
+
1304
+ /**
1305
+ * @param {Input | HTMLElement} input
1306
+ * @param {SweetAlertOptions} params
1307
+ * @returns {Input}
1308
+ */
1309
+ renderInputType.file = (input, params) => {
1310
+ const inputElement = /** @type {HTMLInputElement} */input;
1311
+ setInputLabel(inputElement, inputElement, params);
1312
+ setInputPlaceholder(inputElement, params);
1313
+ return inputElement;
1314
+ };
1315
+
1316
+ /**
1317
+ * @param {Input | HTMLElement} range
1318
+ * @param {SweetAlertOptions} params
1319
+ * @returns {Input}
1320
+ */
1321
+ renderInputType.range = (range, params) => {
1322
+ const rangeContainer = /** @type {HTMLElement} */range;
1323
+ const rangeInput = rangeContainer.querySelector('input');
1324
+ const rangeOutput = rangeContainer.querySelector('output');
1325
+ if (rangeInput) {
1326
+ checkAndSetInputValue(rangeInput, params.inputValue);
1327
+ rangeInput.type = /** @type {string} */params.input;
1328
+ setInputLabel(rangeInput, /** @type {Input} */range, params);
1329
+ }
1330
+ if (rangeOutput) {
1331
+ checkAndSetInputValue(rangeOutput, params.inputValue);
1332
+ }
1333
+ return /** @type {Input} */range;
1334
+ };
1335
+
1336
+ /**
1337
+ * @param {Input | HTMLElement} select
1338
+ * @param {SweetAlertOptions} params
1339
+ * @returns {Input}
1340
+ */
1341
+ renderInputType.select = (select, params) => {
1342
+ const selectElement = /** @type {HTMLSelectElement} */select;
1343
+ selectElement.textContent = '';
1344
+ if (params.inputPlaceholder) {
1345
+ const placeholder = document.createElement('option');
1346
+ setInnerHtml(placeholder, params.inputPlaceholder);
1347
+ placeholder.value = '';
1348
+ placeholder.disabled = true;
1349
+ placeholder.selected = true;
1350
+ selectElement.appendChild(placeholder);
1351
+ }
1352
+ setInputLabel(selectElement, selectElement, params);
1353
+ return selectElement;
1354
+ };
1355
+
1356
+ /**
1357
+ * @param {Input | HTMLElement} radio
1358
+ * @returns {Input}
1359
+ */
1360
+ renderInputType.radio = radio => {
1361
+ const radioElement = /** @type {HTMLElement} */radio;
1362
+ radioElement.textContent = '';
1363
+ return /** @type {Input} */radio;
1364
+ };
1365
+
1366
+ /**
1367
+ * @param {Input | HTMLElement} checkboxContainer
1368
+ * @param {SweetAlertOptions} params
1369
+ * @returns {Input}
1370
+ */
1371
+ renderInputType.checkbox = (checkboxContainer, params) => {
1372
+ const popup = getPopup();
1373
+ if (!popup) {
1374
+ throw new Error('Popup not found');
1375
+ }
1376
+ const checkbox = getInput$1(popup, 'checkbox');
1377
+ if (!checkbox) {
1378
+ throw new Error('Checkbox input not found');
1379
+ }
1380
+ checkbox.value = '1';
1381
+ checkbox.checked = Boolean(params.inputValue);
1382
+ const containerElement = /** @type {HTMLElement} */checkboxContainer;
1383
+ const label = containerElement.querySelector('span');
1384
+ if (label) {
1385
+ const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
1386
+ if (placeholderOrLabel) {
1387
+ setInnerHtml(label, placeholderOrLabel);
1388
+ }
1389
+ }
1390
+ return checkbox;
1391
+ };
1392
+
1393
+ /**
1394
+ * @param {Input | HTMLElement} textarea
1395
+ * @param {SweetAlertOptions} params
1396
+ * @returns {Input}
1397
+ */
1398
+ renderInputType.textarea = (textarea, params) => {
1399
+ const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
1400
+ checkAndSetInputValue(textareaElement, params.inputValue);
1401
+ setInputPlaceholder(textareaElement, params);
1402
+ setInputLabel(textareaElement, textareaElement, params);
1403
+
1404
+ /**
1405
+ * @param {HTMLElement} el
1406
+ * @returns {number}
1407
+ */
1408
+ const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
1409
+
1410
+ // https://github.com/sweetalert2/sweetalert2/issues/2291
1411
+ setTimeout(() => {
1412
+ // https://github.com/sweetalert2/sweetalert2/issues/1699
1413
+ if ('MutationObserver' in window) {
1414
+ const popup = getPopup();
1415
+ if (!popup) {
1416
+ return;
1417
+ }
1418
+ const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
1419
+ const textareaResizeHandler = () => {
1420
+ // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
1421
+ if (!document.body.contains(textareaElement)) {
1422
+ return;
1423
+ }
1424
+ const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
1425
+ const popupElement = getPopup();
1426
+ if (popupElement) {
1427
+ if (textareaWidth > initialPopupWidth) {
1428
+ popupElement.style.width = `${textareaWidth}px`;
1429
+ } else {
1430
+ applyNumericalStyle(popupElement, 'width', params.width);
1431
+ }
1432
+ }
1433
+ };
1434
+ new MutationObserver(textareaResizeHandler).observe(textareaElement, {
1435
+ attributes: true,
1436
+ attributeFilter: ['style']
1437
+ });
1438
+ }
1439
+ });
1440
+ return textareaElement;
1441
+ };
1442
+
1443
+ /**
1444
+ * @param {SweetAlert} instance
1445
+ * @param {SweetAlertOptions} params
1446
+ */
1447
+ const renderContent = (instance, params) => {
1448
+ const htmlContainer = getHtmlContainer();
1449
+ if (!htmlContainer) {
1450
+ return;
1451
+ }
1452
+ showWhenInnerHtmlPresent(htmlContainer);
1453
+ applyCustomClass(htmlContainer, params, 'htmlContainer');
1454
+
1455
+ // Content as HTML
1456
+ if (params.html) {
1457
+ parseHtmlToContainer(params.html, htmlContainer);
1458
+ show(htmlContainer, 'block');
1459
+ }
1460
+
1461
+ // Content as plain text
1462
+ else if (params.text) {
1463
+ htmlContainer.textContent = params.text;
1464
+ show(htmlContainer, 'block');
1465
+ }
1466
+
1467
+ // No content
1468
+ else {
1469
+ hide(htmlContainer);
1470
+ }
1471
+ renderInput(instance, params);
1472
+ };
1473
+
1474
+ /**
1475
+ * @param {SweetAlert} instance
1476
+ * @param {SweetAlertOptions} params
1477
+ */
1478
+ const renderFooter = (instance, params) => {
1479
+ const footer = getFooter();
1480
+ if (!footer) {
1481
+ return;
1482
+ }
1483
+ showWhenInnerHtmlPresent(footer);
1484
+ toggle(footer, Boolean(params.footer), 'block');
1485
+ if (params.footer) {
1486
+ parseHtmlToContainer(params.footer, footer);
1487
+ }
1488
+
1489
+ // Custom class
1490
+ applyCustomClass(footer, params, 'footer');
1491
+ };
1492
+
1493
+ /**
1494
+ * @param {SweetAlert} instance
1495
+ * @param {SweetAlertOptions} params
1496
+ */
1497
+ const renderIcon = (instance, params) => {
1498
+ const innerParams = privateProps.innerParams.get(instance);
1499
+ const icon = getIcon();
1500
+ if (!icon) {
1501
+ return;
1502
+ }
1503
+
1504
+ // if the given icon already rendered, apply the styling without re-rendering the icon
1505
+ if (innerParams && params.icon === innerParams.icon) {
1506
+ // Custom or default content
1507
+ setContent(icon, params);
1508
+ applyStyles(icon, params);
1509
+ return;
1510
+ }
1511
+ if (!params.icon && !params.iconHtml) {
1512
+ hide(icon);
1513
+ return;
1514
+ }
1515
+ if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
1516
+ error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
1517
+ hide(icon);
1518
+ return;
1519
+ }
1520
+ show(icon);
1521
+
1522
+ // Custom or default content
1523
+ setContent(icon, params);
1524
+ applyStyles(icon, params);
1525
+
1526
+ // Animate icon
1527
+ addClass(icon, params.showClass && params.showClass.icon);
1528
+
1529
+ // Re-adjust the success icon on system theme change
1530
+ const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
1531
+ colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
1532
+ };
1533
+
1534
+ /**
1535
+ * @param {HTMLElement} icon
1536
+ * @param {SweetAlertOptions} params
1537
+ */
1538
+ const applyStyles = (icon, params) => {
1539
+ for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
1540
+ if (params.icon !== iconType) {
1541
+ removeClass(icon, iconClassName);
1542
+ }
1543
+ }
1544
+ addClass(icon, params.icon && iconTypes[params.icon]);
1545
+
1546
+ // Icon color
1547
+ setColor(icon, params);
1548
+
1549
+ // Success icon background color
1550
+ adjustSuccessIconBackgroundColor();
1551
+
1552
+ // Custom class
1553
+ applyCustomClass(icon, params, 'icon');
1554
+ };
1555
+
1556
+ // Adjust success icon background color to match the popup background color
1557
+ const adjustSuccessIconBackgroundColor = () => {
1558
+ const popup = getPopup();
1559
+ if (!popup) {
1560
+ return;
1561
+ }
1562
+ const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
1563
+ /** @type {NodeListOf<HTMLElement>} */
1564
+ const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
1565
+ for (let i = 0; i < successIconParts.length; i++) {
1566
+ successIconParts[i].style.backgroundColor = popupBackgroundColor;
1567
+ }
1568
+ };
1569
+
1570
+ /**
1571
+ *
1572
+ * @param {SweetAlertOptions} params
1573
+ * @returns {string}
1574
+ */
1575
+ const successIconHtml = params => `
1576
+ ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
1577
+ <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
1578
+ <div class="swal2-success-ring"></div>
1579
+ ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
1580
+ ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
1581
+ `;
1582
+ const errorIconHtml = `
1583
+ <span class="swal2-x-mark">
1584
+ <span class="swal2-x-mark-line-left"></span>
1585
+ <span class="swal2-x-mark-line-right"></span>
1586
+ </span>
1587
+ `;
1588
+
1589
+ /**
1590
+ * @param {HTMLElement} icon
1591
+ * @param {SweetAlertOptions} params
1592
+ */
1593
+ const setContent = (icon, params) => {
1594
+ if (!params.icon && !params.iconHtml) {
1595
+ return;
1596
+ }
1597
+ let oldContent = icon.innerHTML;
1598
+ let newContent = '';
1599
+ if (params.iconHtml) {
1600
+ newContent = iconContent(params.iconHtml);
1601
+ } else if (params.icon === 'success') {
1602
+ newContent = successIconHtml(params);
1603
+ oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
1604
+ } else if (params.icon === 'error') {
1605
+ newContent = errorIconHtml;
1606
+ } else if (params.icon) {
1607
+ const defaultIconHtml = {
1608
+ question: '?',
1609
+ warning: '!',
1610
+ info: 'i'
1611
+ };
1612
+ newContent = iconContent(defaultIconHtml[params.icon]);
1613
+ }
1614
+ if (oldContent.trim() !== newContent.trim()) {
1615
+ setInnerHtml(icon, newContent);
1616
+ }
1617
+ };
1618
+
1619
+ /**
1620
+ * @param {HTMLElement} icon
1621
+ * @param {SweetAlertOptions} params
1622
+ */
1623
+ const setColor = (icon, params) => {
1624
+ if (!params.iconColor) {
1625
+ return;
1626
+ }
1627
+ icon.style.color = params.iconColor;
1628
+ icon.style.borderColor = params.iconColor;
1629
+ for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
1630
+ setStyle(icon, sel, 'background-color', params.iconColor);
1631
+ }
1632
+ setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
1633
+ };
1634
+
1635
+ /**
1636
+ * @param {string} content
1637
+ * @returns {string}
1638
+ */
1639
+ const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
1640
+
1641
+ /**
1642
+ * @param {SweetAlert} instance
1643
+ * @param {SweetAlertOptions} params
1644
+ */
1645
+ const renderImage = (instance, params) => {
1646
+ const image = getImage();
1647
+ if (!image) {
1648
+ return;
1649
+ }
1650
+ if (!params.imageUrl) {
1651
+ hide(image);
1652
+ return;
1653
+ }
1654
+ show(image, '');
1655
+
1656
+ // Src, alt
1657
+ image.setAttribute('src', params.imageUrl);
1658
+ image.setAttribute('alt', params.imageAlt || '');
1659
+
1660
+ // Width, height
1661
+ applyNumericalStyle(image, 'width', params.imageWidth);
1662
+ applyNumericalStyle(image, 'height', params.imageHeight);
1663
+
1664
+ // Class
1665
+ image.className = swalClasses.image;
1666
+ applyCustomClass(image, params, 'image');
1667
+ };
1668
+
1669
+ let dragging = false;
1670
+ let mousedownX = 0;
1671
+ let mousedownY = 0;
1672
+ let initialX = 0;
1673
+ let initialY = 0;
1674
+
1675
+ /**
1676
+ * @param {HTMLElement} popup
1677
+ */
1678
+ const addDraggableListeners = popup => {
1679
+ popup.addEventListener('mousedown', down);
1680
+ document.body.addEventListener('mousemove', move);
1681
+ popup.addEventListener('mouseup', up);
1682
+ popup.addEventListener('touchstart', down);
1683
+ document.body.addEventListener('touchmove', move);
1684
+ popup.addEventListener('touchend', up);
1685
+ };
1686
+
1687
+ /**
1688
+ * @param {HTMLElement} popup
1689
+ */
1690
+ const removeDraggableListeners = popup => {
1691
+ popup.removeEventListener('mousedown', down);
1692
+ document.body.removeEventListener('mousemove', move);
1693
+ popup.removeEventListener('mouseup', up);
1694
+ popup.removeEventListener('touchstart', down);
1695
+ document.body.removeEventListener('touchmove', move);
1696
+ popup.removeEventListener('touchend', up);
1697
+ };
1698
+
1699
+ /**
1700
+ * @param {MouseEvent | TouchEvent} event
1701
+ */
1702
+ const down = event => {
1703
+ const popup = getPopup();
1704
+ if (!popup) {
1705
+ return;
1706
+ }
1707
+ const icon = getIcon();
1708
+ if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
1709
+ dragging = true;
1710
+ const clientXY = getClientXY(event);
1711
+ mousedownX = clientXY.clientX;
1712
+ mousedownY = clientXY.clientY;
1713
+ initialX = parseInt(popup.style.insetInlineStart) || 0;
1714
+ initialY = parseInt(popup.style.insetBlockStart) || 0;
1715
+ addClass(popup, 'swal2-dragging');
1716
+ }
1717
+ };
1718
+
1719
+ /**
1720
+ * @param {MouseEvent | TouchEvent} event
1721
+ */
1722
+ const move = event => {
1723
+ const popup = getPopup();
1724
+ if (!popup) {
1725
+ return;
1726
+ }
1727
+ if (dragging) {
1728
+ let {
1729
+ clientX,
1730
+ clientY
1731
+ } = getClientXY(event);
1732
+ const deltaX = clientX - mousedownX;
1733
+ // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
1734
+ popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
1735
+ popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
1736
+ }
1737
+ };
1738
+ const up = () => {
1739
+ const popup = getPopup();
1740
+ dragging = false;
1741
+ removeClass(popup, 'swal2-dragging');
1742
+ };
1743
+
1744
+ /**
1745
+ * @param {MouseEvent | TouchEvent} event
1746
+ * @returns {{ clientX: number, clientY: number }}
1747
+ */
1748
+ const getClientXY = event => {
1749
+ const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
1750
+ return {
1751
+ clientX: source.clientX,
1752
+ clientY: source.clientY
1753
+ };
1754
+ };
1755
+
1756
+ /**
1757
+ * @param {SweetAlert} instance
1758
+ * @param {SweetAlertOptions} params
1759
+ */
1760
+ const renderPopup = (instance, params) => {
1761
+ const container = getContainer();
1762
+ const popup = getPopup();
1763
+ if (!container || !popup) {
1764
+ return;
1765
+ }
1766
+
1767
+ // Width
1768
+ // https://github.com/sweetalert2/sweetalert2/issues/2170
1769
+ if (params.toast) {
1770
+ applyNumericalStyle(container, 'width', params.width);
1771
+ popup.style.width = '100%';
1772
+ const loader = getLoader();
1773
+ if (loader) {
1774
+ popup.insertBefore(loader, getIcon());
1775
+ }
1776
+ } else {
1777
+ applyNumericalStyle(popup, 'width', params.width);
1778
+ }
1779
+
1780
+ // Padding
1781
+ applyNumericalStyle(popup, 'padding', params.padding);
1782
+
1783
+ // Color
1784
+ if (params.color) {
1785
+ popup.style.color = params.color;
1786
+ }
1787
+
1788
+ // Background
1789
+ if (params.background) {
1790
+ popup.style.background = params.background;
1791
+ }
1792
+ hide(getValidationMessage());
1793
+
1794
+ // Classes
1795
+ addClasses$1(popup, params);
1796
+ if (params.draggable && !params.toast) {
1797
+ addClass(popup, swalClasses.draggable);
1798
+ addDraggableListeners(popup);
1799
+ } else {
1800
+ removeClass(popup, swalClasses.draggable);
1801
+ removeDraggableListeners(popup);
1802
+ }
1803
+ };
1804
+
1805
+ /**
1806
+ * @param {HTMLElement} popup
1807
+ * @param {SweetAlertOptions} params
1808
+ */
1809
+ const addClasses$1 = (popup, params) => {
1810
+ const showClass = params.showClass || {};
1811
+ // Default Class + showClass when updating Swal.update({})
1812
+ popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
1813
+ if (params.toast) {
1814
+ addClass([document.documentElement, document.body], swalClasses['toast-shown']);
1815
+ addClass(popup, swalClasses.toast);
1816
+ } else {
1817
+ addClass(popup, swalClasses.modal);
1818
+ }
1819
+
1820
+ // Custom class
1821
+ applyCustomClass(popup, params, 'popup');
1822
+ // TODO: remove in the next major
1823
+ if (typeof params.customClass === 'string') {
1824
+ addClass(popup, params.customClass);
1825
+ }
1826
+
1827
+ // Icon class (#1842)
1828
+ if (params.icon) {
1829
+ addClass(popup, swalClasses[`icon-${params.icon}`]);
1830
+ }
1831
+ };
1832
+
1833
+ /**
1834
+ * @param {SweetAlert} instance
1835
+ * @param {SweetAlertOptions} params
1836
+ */
1837
+ const renderProgressSteps = (instance, params) => {
1838
+ const progressStepsContainer = getProgressSteps();
1839
+ if (!progressStepsContainer) {
1840
+ return;
1841
+ }
1842
+ const {
1843
+ progressSteps,
1844
+ currentProgressStep
1845
+ } = params;
1846
+ if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
1847
+ hide(progressStepsContainer);
1848
+ return;
1849
+ }
1850
+ show(progressStepsContainer);
1851
+ progressStepsContainer.textContent = '';
1852
+ if (currentProgressStep >= progressSteps.length) {
1853
+ warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
1854
+ }
1855
+ progressSteps.forEach((step, index) => {
1856
+ const stepEl = createStepElement(step);
1857
+ progressStepsContainer.appendChild(stepEl);
1858
+ if (index === currentProgressStep) {
1859
+ addClass(stepEl, swalClasses['active-progress-step']);
1860
+ }
1861
+ if (index !== progressSteps.length - 1) {
1862
+ const lineEl = createLineElement(params);
1863
+ progressStepsContainer.appendChild(lineEl);
1864
+ }
1865
+ });
1866
+ };
1867
+
1868
+ /**
1869
+ * @param {string} step
1870
+ * @returns {HTMLLIElement}
1871
+ */
1872
+ const createStepElement = step => {
1873
+ const stepEl = document.createElement('li');
1874
+ addClass(stepEl, swalClasses['progress-step']);
1875
+ setInnerHtml(stepEl, step);
1876
+ return stepEl;
1877
+ };
1878
+
1879
+ /**
1880
+ * @param {SweetAlertOptions} params
1881
+ * @returns {HTMLLIElement}
1882
+ */
1883
+ const createLineElement = params => {
1884
+ const lineEl = document.createElement('li');
1885
+ addClass(lineEl, swalClasses['progress-step-line']);
1886
+ if (params.progressStepsDistance) {
1887
+ applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
1888
+ }
1889
+ return lineEl;
1890
+ };
1891
+
1892
+ /**
1893
+ * @param {SweetAlert} instance
1894
+ * @param {SweetAlertOptions} params
1895
+ */
1896
+ const renderTitle = (instance, params) => {
1897
+ const title = getTitle();
1898
+ if (!title) {
1899
+ return;
1900
+ }
1901
+ showWhenInnerHtmlPresent(title);
1902
+ toggle(title, Boolean(params.title || params.titleText), 'block');
1903
+ if (params.title) {
1904
+ parseHtmlToContainer(params.title, title);
1905
+ }
1906
+ if (params.titleText) {
1907
+ title.innerText = params.titleText;
1908
+ }
1909
+
1910
+ // Custom class
1911
+ applyCustomClass(title, params, 'title');
1912
+ };
1913
+
1914
+ /**
1915
+ * @param {SweetAlert} instance
1916
+ * @param {SweetAlertOptions} params
1917
+ */
1918
+ const render = (instance, params) => {
1919
+ var _globalState$eventEmi;
1920
+ renderPopup(instance, params);
1921
+ renderContainer(instance, params);
1922
+ renderProgressSteps(instance, params);
1923
+ renderIcon(instance, params);
1924
+ renderImage(instance, params);
1925
+ renderTitle(instance, params);
1926
+ renderCloseButton(instance, params);
1927
+ renderContent(instance, params);
1928
+ renderActions(instance, params);
1929
+ renderFooter(instance, params);
1930
+ const popup = getPopup();
1931
+ if (typeof params.didRender === 'function' && popup) {
1932
+ params.didRender(popup);
1933
+ }
1934
+ (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
1935
+ };
1936
+
1937
+ /*
1938
+ * Global function to determine if SweetAlert2 popup is shown
1939
+ */
1940
+ const isVisible = () => {
1941
+ return isVisible$1(getPopup());
1942
+ };
1943
+
1944
+ /*
1945
+ * Global function to click 'Confirm' button
1946
+ */
1947
+ const clickConfirm = () => {
1948
+ var _dom$getConfirmButton;
1949
+ return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
1950
+ };
1951
+
1952
+ /*
1953
+ * Global function to click 'Deny' button
1954
+ */
1955
+ const clickDeny = () => {
1956
+ var _dom$getDenyButton;
1957
+ return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
1958
+ };
1959
+
1960
+ /*
1961
+ * Global function to click 'Cancel' button
1962
+ */
1963
+ const clickCancel = () => {
1964
+ var _dom$getCancelButton;
1965
+ return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
1966
+ };
1967
+
1968
+ /** @type {Record<DismissReason, DismissReason>} */
1969
+ const DismissReason = Object.freeze({
1970
+ cancel: 'cancel',
1971
+ backdrop: 'backdrop',
1972
+ close: 'close',
1973
+ esc: 'esc',
1974
+ timer: 'timer'
1975
+ });
1976
+
1977
+ /**
1978
+ * @param {GlobalState} globalState
1979
+ */
1980
+ const removeKeydownHandler = globalState => {
1981
+ if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
1982
+ const handler = /** @type {EventListenerOrEventListenerObject} */
1983
+ /** @type {unknown} */globalState.keydownHandler;
1984
+ globalState.keydownTarget.removeEventListener('keydown', handler, {
1985
+ capture: globalState.keydownListenerCapture
1986
+ });
1987
+ globalState.keydownHandlerAdded = false;
1988
+ }
1989
+ };
1990
+
1991
+ /**
1992
+ * @param {GlobalState} globalState
1993
+ * @param {SweetAlertOptions} innerParams
1994
+ * @param {(dismiss: DismissReason) => void} dismissWith
1995
+ */
1996
+ const addKeydownHandler = (globalState, innerParams, dismissWith) => {
1997
+ removeKeydownHandler(globalState);
1998
+ if (!innerParams.toast) {
1999
+ /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
2000
+ const handler = e => keydownHandler(innerParams, e, dismissWith);
2001
+ globalState.keydownHandler = handler;
2002
+ const target = innerParams.keydownListenerCapture ? window : getPopup();
2003
+ if (target) {
2004
+ globalState.keydownTarget = target;
2005
+ globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
2006
+ const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
2007
+ globalState.keydownTarget.addEventListener('keydown', eventHandler, {
2008
+ capture: globalState.keydownListenerCapture
2009
+ });
2010
+ globalState.keydownHandlerAdded = true;
2011
+ }
2012
+ }
2013
+ };
2014
+
2015
+ /**
2016
+ * @param {number} index
2017
+ * @param {number} increment
2018
+ * @returns {boolean} shouldPreventDefault
2019
+ */
2020
+ const setFocus = (index, increment) => {
2021
+ var _dom$getPopup;
2022
+ const focusableElements = getFocusableElements();
2023
+ // search for visible elements and select the next possible match
2024
+ if (focusableElements.length) {
2025
+ index = index + increment;
2026
+
2027
+ // shift + tab when .swal2-popup is focused
2028
+ if (index === -2) {
2029
+ index = focusableElements.length - 1;
2030
+ }
2031
+
2032
+ // rollover to first item
2033
+ if (index === focusableElements.length) {
2034
+ index = 0;
2035
+
2036
+ // go to last item
2037
+ } else if (index === -1) {
2038
+ index = focusableElements.length - 1;
2039
+ }
2040
+ focusableElements[index].focus();
2041
+
2042
+ // don't prevent default for iframes (Firefox fix)
2043
+ // https://github.com/sweetalert2/sweetalert2/issues/2931
2044
+ if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
2045
+ return false;
2046
+ }
2047
+ return true;
2048
+ }
2049
+ // no visible focusable elements, focus the popup
2050
+ (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
2051
+ return true;
2052
+ };
2053
+ const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
2054
+ const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
2055
+
2056
+ /**
2057
+ * @param {SweetAlertOptions} innerParams
2058
+ * @param {KeyboardEvent} event
2059
+ * @param {(dismiss: DismissReason) => void} dismissWith
2060
+ */
2061
+ const keydownHandler = (innerParams, event, dismissWith) => {
2062
+ if (!innerParams) {
2063
+ return; // This instance has already been destroyed
2064
+ }
2065
+
2066
+ // Ignore keydown during IME composition
2067
+ // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
2068
+ // https://github.com/sweetalert2/sweetalert2/issues/720
2069
+ // https://github.com/sweetalert2/sweetalert2/issues/2406
2070
+ if (event.isComposing || event.keyCode === 229) {
2071
+ return;
2072
+ }
2073
+ if (innerParams.stopKeydownPropagation) {
2074
+ event.stopPropagation();
2075
+ }
2076
+
2077
+ // ENTER
2078
+ if (event.key === 'Enter') {
2079
+ handleEnter(event, innerParams);
2080
+ }
2081
+
2082
+ // TAB
2083
+ else if (event.key === 'Tab') {
2084
+ handleTab(event);
2085
+ }
2086
+
2087
+ // ARROWS - switch focus between buttons
2088
+ else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
2089
+ handleArrows(event.key);
2090
+ }
2091
+
2092
+ // ESC
2093
+ else if (event.key === 'Escape') {
2094
+ handleEsc(event, innerParams, dismissWith);
2095
+ }
2096
+ };
2097
+
2098
+ /**
2099
+ * @param {KeyboardEvent} event
2100
+ * @param {SweetAlertOptions} innerParams
2101
+ */
2102
+ const handleEnter = (event, innerParams) => {
2103
+ // https://github.com/sweetalert2/sweetalert2/issues/2386
2104
+ if (!callIfFunction(innerParams.allowEnterKey)) {
2105
+ return;
2106
+ }
2107
+ const popup = getPopup();
2108
+ if (!popup || !innerParams.input) {
2109
+ return;
2110
+ }
2111
+ const input = getInput$1(popup, innerParams.input);
2112
+ if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
2113
+ if (['textarea', 'file'].includes(innerParams.input)) {
2114
+ return; // do not submit
2115
+ }
2116
+ clickConfirm();
2117
+ event.preventDefault();
2118
+ }
2119
+ };
2120
+
2121
+ /**
2122
+ * @param {KeyboardEvent} event
2123
+ */
2124
+ const handleTab = event => {
2125
+ const targetElement = event.target;
2126
+ const focusableElements = getFocusableElements();
2127
+ let btnIndex = -1;
2128
+ for (let i = 0; i < focusableElements.length; i++) {
2129
+ if (targetElement === focusableElements[i]) {
2130
+ btnIndex = i;
2131
+ break;
2132
+ }
2133
+ }
2134
+
2135
+ // don't prevent default for iframes (Firefox fix)
2136
+ // https://github.com/sweetalert2/sweetalert2/issues/2931
2137
+ let shouldPreventDefault = true;
2138
+
2139
+ // Cycle to the next button
2140
+ if (!event.shiftKey) {
2141
+ shouldPreventDefault = setFocus(btnIndex, 1);
2142
+ }
2143
+
2144
+ // Cycle to the prev button
2145
+ else {
2146
+ shouldPreventDefault = setFocus(btnIndex, -1);
2147
+ }
2148
+ event.stopPropagation();
2149
+ if (shouldPreventDefault) {
2150
+ event.preventDefault();
2151
+ }
2152
+ };
2153
+
2154
+ /**
2155
+ * @param {string} key
2156
+ */
2157
+ const handleArrows = key => {
2158
+ const actions = getActions();
2159
+ const confirmButton = getConfirmButton();
2160
+ const denyButton = getDenyButton();
2161
+ const cancelButton = getCancelButton();
2162
+ if (!actions || !confirmButton || !denyButton || !cancelButton) {
2163
+ return;
2164
+ }
2165
+ /** @type HTMLElement[] */
2166
+ const buttons = [confirmButton, denyButton, cancelButton];
2167
+ if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
2168
+ return;
2169
+ }
2170
+ const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
2171
+ let buttonToFocus = document.activeElement;
2172
+ if (!buttonToFocus) {
2173
+ return;
2174
+ }
2175
+ for (let i = 0; i < actions.children.length; i++) {
2176
+ buttonToFocus = buttonToFocus[sibling];
2177
+ if (!buttonToFocus) {
2178
+ return;
2179
+ }
2180
+ if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
2181
+ break;
2182
+ }
2183
+ }
2184
+ if (buttonToFocus instanceof HTMLButtonElement) {
2185
+ buttonToFocus.focus();
2186
+ }
2187
+ };
2188
+
2189
+ /**
2190
+ * @param {KeyboardEvent} event
2191
+ * @param {SweetAlertOptions} innerParams
2192
+ * @param {(dismiss: DismissReason) => void} dismissWith
2193
+ */
2194
+ const handleEsc = (event, innerParams, dismissWith) => {
2195
+ event.preventDefault();
2196
+ if (callIfFunction(innerParams.allowEscapeKey)) {
2197
+ dismissWith(DismissReason.esc);
2198
+ }
2199
+ };
2200
+
2201
+ /**
2202
+ * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
2203
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
2204
+ * This is the approach that Babel will probably take to implement private methods/fields
2205
+ * https://github.com/tc39/proposal-private-methods
2206
+ * https://github.com/babel/babel/pull/7555
2207
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
2208
+ * then we can use that language feature.
2209
+ */
2210
+
2211
+ var privateMethods = {
2212
+ swalPromiseResolve: new WeakMap(),
2213
+ swalPromiseReject: new WeakMap()
2214
+ };
2215
+
2216
+ // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
2217
+ // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
2218
+ // elements not within the active modal dialog will not be surfaced if a user opens a screen
2219
+ // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
2220
+
2221
+ const setAriaHidden = () => {
2222
+ const container = getContainer();
2223
+ const bodyChildren = Array.from(document.body.children);
2224
+ bodyChildren.forEach(el => {
2225
+ if (el.contains(container)) {
2226
+ return;
2227
+ }
2228
+ if (el.hasAttribute('aria-hidden')) {
2229
+ el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
2230
+ }
2231
+ el.setAttribute('aria-hidden', 'true');
2232
+ });
2233
+ };
2234
+ const unsetAriaHidden = () => {
2235
+ const bodyChildren = Array.from(document.body.children);
2236
+ bodyChildren.forEach(el => {
2237
+ if (el.hasAttribute('data-previous-aria-hidden')) {
2238
+ el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
2239
+ el.removeAttribute('data-previous-aria-hidden');
2240
+ } else {
2241
+ el.removeAttribute('aria-hidden');
2242
+ }
2243
+ });
2244
+ };
2245
+
2246
+ // @ts-ignore
2247
+ const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
2248
+
2249
+ // @ts-ignore
2250
+ const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
2251
+
2252
+ /**
2253
+ * Fix iOS scrolling
2254
+ * http://stackoverflow.com/q/39626302
2255
+ */
2256
+ const iOSfix = () => {
2257
+ if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
2258
+ const offset = document.body.scrollTop;
2259
+ document.body.style.top = `${offset * -1}px`;
2260
+ addClass(document.body, swalClasses.iosfix);
2261
+ lockBodyScroll();
2262
+ }
2263
+ };
2264
+
2265
+ /**
2266
+ * https://github.com/sweetalert2/sweetalert2/issues/1246
2267
+ */
2268
+ const lockBodyScroll = () => {
2269
+ const container = getContainer();
2270
+ if (!container) {
2271
+ return;
2272
+ }
2273
+ /** @type {boolean} */
2274
+ let preventTouchMove;
2275
+ /**
2276
+ * @param {TouchEvent} event
2277
+ */
2278
+ container.ontouchstart = event => {
2279
+ preventTouchMove = shouldPreventTouchMove(event);
2280
+ };
2281
+ /**
2282
+ * @param {TouchEvent} event
2283
+ */
2284
+ container.ontouchmove = event => {
2285
+ if (preventTouchMove) {
2286
+ event.preventDefault();
2287
+ event.stopPropagation();
2288
+ }
2289
+ };
2290
+ };
2291
+
2292
+ /**
2293
+ * @param {TouchEvent} event
2294
+ * @returns {boolean}
2295
+ */
2296
+ const shouldPreventTouchMove = event => {
2297
+ const target = event.target;
2298
+ const container = getContainer();
2299
+ const htmlContainer = getHtmlContainer();
2300
+ if (!container || !htmlContainer) {
2301
+ return false;
2302
+ }
2303
+ if (isStylus(event) || isZoom(event)) {
2304
+ return false;
2305
+ }
2306
+ if (target === container) {
2307
+ return true;
2308
+ }
2309
+ if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
2310
+ // #2823
2311
+ target.tagName !== 'INPUT' &&
2312
+ // #1603
2313
+ target.tagName !== 'TEXTAREA' &&
2314
+ // #2266
2315
+ !(isScrollable(htmlContainer) &&
2316
+ // #1944
2317
+ htmlContainer.contains(target))) {
2318
+ return true;
2319
+ }
2320
+ return false;
2321
+ };
2322
+
2323
+ /**
2324
+ * https://github.com/sweetalert2/sweetalert2/issues/1786
2325
+ *
2326
+ * @param {TouchEvent} event
2327
+ * @returns {boolean}
2328
+ */
2329
+ const isStylus = event => {
2330
+ return Boolean(event.touches && event.touches.length &&
2331
+ // @ts-ignore - touchType is not a standard property
2332
+ event.touches[0].touchType === 'stylus');
2333
+ };
2334
+
2335
+ /**
2336
+ * https://github.com/sweetalert2/sweetalert2/issues/1891
2337
+ *
2338
+ * @param {TouchEvent} event
2339
+ * @returns {boolean}
2340
+ */
2341
+ const isZoom = event => {
2342
+ return event.touches && event.touches.length > 1;
2343
+ };
2344
+ const undoIOSfix = () => {
2345
+ if (hasClass(document.body, swalClasses.iosfix)) {
2346
+ const offset = parseInt(document.body.style.top, 10);
2347
+ removeClass(document.body, swalClasses.iosfix);
2348
+ document.body.style.top = '';
2349
+ document.body.scrollTop = offset * -1;
2350
+ }
2351
+ };
2352
+
2353
+ /**
2354
+ * Measure scrollbar width for padding body during modal show/hide
2355
+ * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
2356
+ *
2357
+ * @returns {number}
2358
+ */
2359
+ const measureScrollbar = () => {
2360
+ const scrollDiv = document.createElement('div');
2361
+ scrollDiv.className = swalClasses['scrollbar-measure'];
2362
+ document.body.appendChild(scrollDiv);
2363
+ const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
2364
+ document.body.removeChild(scrollDiv);
2365
+ return scrollbarWidth;
2366
+ };
2367
+
2368
+ /**
2369
+ * Remember state in cases where opening and handling a modal will fiddle with it.
2370
+ * @type {number | null}
2371
+ */
2372
+ let previousBodyPadding = null;
2373
+
2374
+ /**
2375
+ * @param {string} initialBodyOverflow
2376
+ */
2377
+ const replaceScrollbarWithPadding = initialBodyOverflow => {
2378
+ // for queues, do not do this more than once
2379
+ if (previousBodyPadding !== null) {
2380
+ return;
2381
+ }
2382
+ // if the body has overflow
2383
+ if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
2384
+ ) {
2385
+ // add padding so the content doesn't shift after removal of scrollbar
2386
+ previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
2387
+ document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
2388
+ }
2389
+ };
2390
+ const undoReplaceScrollbarWithPadding = () => {
2391
+ if (previousBodyPadding !== null) {
2392
+ document.body.style.paddingRight = `${previousBodyPadding}px`;
2393
+ previousBodyPadding = null;
2394
+ }
2395
+ };
2396
+
2397
+ /**
2398
+ * @param {SweetAlert} instance
2399
+ * @param {HTMLElement} container
2400
+ * @param {boolean} returnFocus
2401
+ * @param {(() => void) | undefined} didClose
2402
+ */
2403
+ function removePopupAndResetState(instance, container, returnFocus, didClose) {
2404
+ if (isToast()) {
2405
+ triggerDidCloseAndDispose(instance, didClose);
2406
+ } else {
2407
+ restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
2408
+ removeKeydownHandler(globalState);
2409
+ }
2410
+
2411
+ // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
2412
+ // for some reason removing the container in Safari will scroll the document to bottom
2413
+ if (isSafariOrIOS) {
2414
+ container.setAttribute('style', 'display:none !important');
2415
+ container.removeAttribute('class');
2416
+ container.innerHTML = '';
2417
+ } else {
2418
+ container.remove();
2419
+ }
2420
+ if (isModal()) {
2421
+ undoReplaceScrollbarWithPadding();
2422
+ undoIOSfix();
2423
+ unsetAriaHidden();
2424
+ }
2425
+ removeBodyClasses();
2426
+ }
2427
+
2428
+ /**
2429
+ * Remove SweetAlert2 classes from body
2430
+ */
2431
+ function removeBodyClasses() {
2432
+ removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
2433
+ }
2434
+
2435
+ /**
2436
+ * Instance method to close sweetAlert
2437
+ *
2438
+ * @param {SweetAlertResult | undefined} resolveValue
2439
+ * @this {SweetAlert}
2440
+ */
2441
+ function close(resolveValue) {
2442
+ resolveValue = prepareResolveValue(resolveValue);
2443
+ const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
2444
+ const didClose = triggerClosePopup(this);
2445
+ if (this.isAwaitingPromise) {
2446
+ // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
2447
+ if (!resolveValue.isDismissed) {
2448
+ handleAwaitingPromise(this);
2449
+ swalPromiseResolve(resolveValue);
2450
+ }
2451
+ } else if (didClose) {
2452
+ // Resolve Swal promise
2453
+ swalPromiseResolve(resolveValue);
2454
+ }
2455
+ }
2456
+
2457
+ /**
2458
+ * @param {SweetAlert} instance
2459
+ * @returns {boolean}
2460
+ */
2461
+ const triggerClosePopup = instance => {
2462
+ const popup = getPopup();
2463
+ if (!popup) {
2464
+ return false;
2465
+ }
2466
+ const innerParams = privateProps.innerParams.get(instance);
2467
+ if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
2468
+ return false;
2469
+ }
2470
+ removeClass(popup, innerParams.showClass.popup);
2471
+ addClass(popup, innerParams.hideClass.popup);
2472
+ const backdrop = getContainer();
2473
+ removeClass(backdrop, innerParams.showClass.backdrop);
2474
+ addClass(backdrop, innerParams.hideClass.backdrop);
2475
+ handlePopupAnimation(instance, popup, innerParams);
2476
+ return true;
2477
+ };
2478
+
2479
+ /**
2480
+ * @param {Error | string} error
2481
+ * @this {SweetAlert}
2482
+ */
2483
+ function rejectPromise(error) {
2484
+ const rejectPromise = privateMethods.swalPromiseReject.get(this);
2485
+ handleAwaitingPromise(this);
2486
+ if (rejectPromise) {
2487
+ // Reject Swal promise
2488
+ rejectPromise(error);
2489
+ }
2490
+ }
2491
+
2492
+ /**
2493
+ * @param {SweetAlert} instance
2494
+ */
2495
+ const handleAwaitingPromise = instance => {
2496
+ if (instance.isAwaitingPromise) {
2497
+ // @ts-ignore
2498
+ delete instance.isAwaitingPromise;
2499
+ // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
2500
+ if (!privateProps.innerParams.get(instance)) {
2501
+ instance._destroy();
2502
+ }
2503
+ }
2504
+ };
2505
+
2506
+ /**
2507
+ * @param {SweetAlertResult | undefined} resolveValue
2508
+ * @returns {SweetAlertResult}
2509
+ */
2510
+ const prepareResolveValue = resolveValue => {
2511
+ // When user calls Swal.close()
2512
+ if (typeof resolveValue === 'undefined') {
2513
+ return {
2514
+ isConfirmed: false,
2515
+ isDenied: false,
2516
+ isDismissed: true
2517
+ };
2518
+ }
2519
+ return Object.assign({
2520
+ isConfirmed: false,
2521
+ isDenied: false,
2522
+ isDismissed: false
2523
+ }, resolveValue);
2524
+ };
2525
+
2526
+ /**
2527
+ * @param {SweetAlert} instance
2528
+ * @param {HTMLElement} popup
2529
+ * @param {SweetAlertOptions} innerParams
2530
+ */
2531
+ const handlePopupAnimation = (instance, popup, innerParams) => {
2532
+ var _globalState$eventEmi;
2533
+ const container = getContainer();
2534
+ // If animation is supported, animate
2535
+ const animationIsSupported = hasCssAnimation(popup);
2536
+ if (typeof innerParams.willClose === 'function') {
2537
+ innerParams.willClose(popup);
2538
+ }
2539
+ (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
2540
+ if (animationIsSupported && container) {
2541
+ animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
2542
+ } else if (container) {
2543
+ // Otherwise, remove immediately
2544
+ removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
2545
+ }
2546
+ };
2547
+
2548
+ /**
2549
+ * @param {SweetAlert} instance
2550
+ * @param {HTMLElement} popup
2551
+ * @param {HTMLElement} container
2552
+ * @param {boolean} returnFocus
2553
+ * @param {(() => void) | undefined} didClose
2554
+ */
2555
+ const animatePopup = (instance, popup, container, returnFocus, didClose) => {
2556
+ globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
2557
+ /**
2558
+ * @param {AnimationEvent | TransitionEvent} e
2559
+ */
2560
+ const swalCloseAnimationFinished = function (e) {
2561
+ if (e.target === popup) {
2562
+ var _globalState$swalClos;
2563
+ (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
2564
+ delete globalState.swalCloseEventFinishedCallback;
2565
+ popup.removeEventListener('animationend', swalCloseAnimationFinished);
2566
+ popup.removeEventListener('transitionend', swalCloseAnimationFinished);
2567
+ }
2568
+ };
2569
+ popup.addEventListener('animationend', swalCloseAnimationFinished);
2570
+ popup.addEventListener('transitionend', swalCloseAnimationFinished);
2571
+ };
2572
+
2573
+ /**
2574
+ * @param {SweetAlert} instance
2575
+ * @param {(() => void) | undefined} didClose
2576
+ */
2577
+ const triggerDidCloseAndDispose = (instance, didClose) => {
2578
+ setTimeout(() => {
2579
+ var _globalState$eventEmi2;
2580
+ if (typeof didClose === 'function') {
2581
+ didClose.bind(instance.params)();
2582
+ }
2583
+ (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
2584
+ // instance might have been destroyed already
2585
+ if (instance._destroy) {
2586
+ instance._destroy();
2587
+ }
2588
+ });
2589
+ };
2590
+
2591
+ /**
2592
+ * Shows loader (spinner), this is useful with AJAX requests.
2593
+ * By default the loader be shown instead of the "Confirm" button.
2594
+ *
2595
+ * @param {HTMLButtonElement | null} [buttonToReplace]
2596
+ */
2597
+ const showLoading = buttonToReplace => {
2598
+ let popup = getPopup();
2599
+ if (!popup) {
2600
+ new Swal();
2601
+ }
2602
+ popup = getPopup();
2603
+ if (!popup) {
2604
+ return;
2605
+ }
2606
+ const loader = getLoader();
2607
+ if (isToast()) {
2608
+ hide(getIcon());
2609
+ } else {
2610
+ replaceButton(popup, buttonToReplace);
2611
+ }
2612
+ show(loader);
2613
+ popup.setAttribute('data-loading', 'true');
2614
+ popup.setAttribute('aria-busy', 'true');
2615
+ popup.focus();
2616
+ };
2617
+
2618
+ /**
2619
+ * @param {HTMLElement} popup
2620
+ * @param {HTMLButtonElement | null} [buttonToReplace]
2621
+ */
2622
+ const replaceButton = (popup, buttonToReplace) => {
2623
+ const actions = getActions();
2624
+ const loader = getLoader();
2625
+ if (!actions || !loader) {
2626
+ return;
2627
+ }
2628
+ if (!buttonToReplace && isVisible$1(getConfirmButton())) {
2629
+ buttonToReplace = getConfirmButton();
2630
+ }
2631
+ show(actions);
2632
+ if (buttonToReplace) {
2633
+ hide(buttonToReplace);
2634
+ loader.setAttribute('data-button-to-replace', buttonToReplace.className);
2635
+ actions.insertBefore(loader, buttonToReplace);
2636
+ }
2637
+ addClass([popup, actions], swalClasses.loading);
2638
+ };
2639
+
2640
+ /**
2641
+ * @param {SweetAlert} instance
2642
+ * @param {SweetAlertOptions} params
2643
+ */
2644
+ const handleInputOptionsAndValue = (instance, params) => {
2645
+ if (params.input === 'select' || params.input === 'radio') {
2646
+ handleInputOptions(instance, params);
2647
+ } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
2648
+ showLoading(getConfirmButton());
2649
+ handleInputValue(instance, params);
2650
+ }
2651
+ };
2652
+
2653
+ /**
2654
+ * @param {SweetAlert} instance
2655
+ * @param {SweetAlertOptions} innerParams
2656
+ * @returns {SweetAlertInputValue}
2657
+ */
2658
+ const getInputValue = (instance, innerParams) => {
2659
+ const input = instance.getInput();
2660
+ if (!input) {
2661
+ return null;
2662
+ }
2663
+ switch (innerParams.input) {
2664
+ case 'checkbox':
2665
+ return getCheckboxValue(input);
2666
+ case 'radio':
2667
+ return getRadioValue(input);
2668
+ case 'file':
2669
+ return getFileValue(input);
2670
+ default:
2671
+ return innerParams.inputAutoTrim ? input.value.trim() : input.value;
2672
+ }
2673
+ };
2674
+
2675
+ /**
2676
+ * @param {HTMLInputElement} input
2677
+ * @returns {number}
2678
+ */
2679
+ const getCheckboxValue = input => input.checked ? 1 : 0;
2680
+
2681
+ /**
2682
+ * @param {HTMLInputElement} input
2683
+ * @returns {string | null}
2684
+ */
2685
+ const getRadioValue = input => input.checked ? input.value : null;
2686
+
2687
+ /**
2688
+ * @param {HTMLInputElement} input
2689
+ * @returns {FileList | File | null}
2690
+ */
2691
+ const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
2692
+
2693
+ /**
2694
+ * @param {SweetAlert} instance
2695
+ * @param {SweetAlertOptions} params
2696
+ */
2697
+ const handleInputOptions = (instance, params) => {
2698
+ const popup = getPopup();
2699
+ if (!popup) {
2700
+ return;
2701
+ }
2702
+ /**
2703
+ * @param {*} inputOptions
2704
+ */
2705
+ const processInputOptions = inputOptions => {
2706
+ if (params.input === 'select') {
2707
+ populateSelectOptions(popup, formatInputOptions(inputOptions), params);
2708
+ } else if (params.input === 'radio') {
2709
+ populateRadioOptions(popup, formatInputOptions(inputOptions), params);
2710
+ }
2711
+ };
2712
+ if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
2713
+ showLoading(getConfirmButton());
2714
+ asPromise(params.inputOptions).then(inputOptions => {
2715
+ instance.hideLoading();
2716
+ processInputOptions(inputOptions);
2717
+ });
2718
+ } else if (typeof params.inputOptions === 'object') {
2719
+ processInputOptions(params.inputOptions);
2720
+ } else {
2721
+ error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
2722
+ }
2723
+ };
2724
+
2725
+ /**
2726
+ * @param {SweetAlert} instance
2727
+ * @param {SweetAlertOptions} params
2728
+ */
2729
+ const handleInputValue = (instance, params) => {
2730
+ const input = instance.getInput();
2731
+ if (!input) {
2732
+ return;
2733
+ }
2734
+ hide(input);
2735
+ asPromise(params.inputValue).then(inputValue => {
2736
+ input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
2737
+ show(input);
2738
+ input.focus();
2739
+ instance.hideLoading();
2740
+ }).catch(err => {
2741
+ error(`Error in inputValue promise: ${err}`);
2742
+ input.value = '';
2743
+ show(input);
2744
+ input.focus();
2745
+ instance.hideLoading();
2746
+ });
2747
+ };
2748
+
2749
+ /**
2750
+ * @param {HTMLElement} popup
2751
+ * @param {InputOptionFlattened[]} inputOptions
2752
+ * @param {SweetAlertOptions} params
2753
+ */
2754
+ function populateSelectOptions(popup, inputOptions, params) {
2755
+ const select = getDirectChildByClass(popup, swalClasses.select);
2756
+ if (!select) {
2757
+ return;
2758
+ }
2759
+ /**
2760
+ * @param {HTMLElement} parent
2761
+ * @param {string} optionLabel
2762
+ * @param {string} optionValue
2763
+ */
2764
+ const renderOption = (parent, optionLabel, optionValue) => {
2765
+ const option = document.createElement('option');
2766
+ option.value = optionValue;
2767
+ setInnerHtml(option, optionLabel);
2768
+ option.selected = isSelected(optionValue, params.inputValue);
2769
+ parent.appendChild(option);
2770
+ };
2771
+ inputOptions.forEach(inputOption => {
2772
+ const optionValue = inputOption[0];
2773
+ const optionLabel = inputOption[1];
2774
+ // <optgroup> spec:
2775
+ // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
2776
+ // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
2777
+ // check whether this is a <optgroup>
2778
+ if (Array.isArray(optionLabel)) {
2779
+ // if it is an array, then it is an <optgroup>
2780
+ const optgroup = document.createElement('optgroup');
2781
+ optgroup.label = optionValue;
2782
+ optgroup.disabled = false; // not configurable for now
2783
+ select.appendChild(optgroup);
2784
+ optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
2785
+ } else {
2786
+ // case of <option>
2787
+ renderOption(select, optionLabel, optionValue);
2788
+ }
2789
+ });
2790
+ select.focus();
2791
+ }
2792
+
2793
+ /**
2794
+ * @param {HTMLElement} popup
2795
+ * @param {InputOptionFlattened[]} inputOptions
2796
+ * @param {SweetAlertOptions} params
2797
+ */
2798
+ function populateRadioOptions(popup, inputOptions, params) {
2799
+ const radio = getDirectChildByClass(popup, swalClasses.radio);
2800
+ if (!radio) {
2801
+ return;
2802
+ }
2803
+ inputOptions.forEach(inputOption => {
2804
+ const radioValue = inputOption[0];
2805
+ const radioLabel = inputOption[1];
2806
+ const radioInput = document.createElement('input');
2807
+ const radioLabelElement = document.createElement('label');
2808
+ radioInput.type = 'radio';
2809
+ radioInput.name = swalClasses.radio;
2810
+ radioInput.value = radioValue;
2811
+ if (isSelected(radioValue, params.inputValue)) {
2812
+ radioInput.checked = true;
2813
+ }
2814
+ const label = document.createElement('span');
2815
+ setInnerHtml(label, radioLabel);
2816
+ label.className = swalClasses.label;
2817
+ radioLabelElement.appendChild(radioInput);
2818
+ radioLabelElement.appendChild(label);
2819
+ radio.appendChild(radioLabelElement);
2820
+ });
2821
+ const radios = radio.querySelectorAll('input');
2822
+ if (radios.length) {
2823
+ radios[0].focus();
2824
+ }
2825
+ }
2826
+
2827
+ /**
2828
+ * Converts `inputOptions` into an array of `[value, label]`s
2829
+ *
2830
+ * @param {*} inputOptions
2831
+ * @typedef {string[]} InputOptionFlattened
2832
+ * @returns {InputOptionFlattened[]}
2833
+ */
2834
+ const formatInputOptions = inputOptions => {
2835
+ const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
2836
+ return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
2837
+ };
2838
+
2839
+ /**
2840
+ * @param {string} optionValue
2841
+ * @param {SweetAlertInputValue} inputValue
2842
+ * @returns {boolean}
2843
+ */
2844
+ const isSelected = (optionValue, inputValue) => {
2845
+ return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
2846
+ };
2847
+
2848
+ /**
2849
+ * @param {SweetAlert} instance
2850
+ */
2851
+ const handleConfirmButtonClick = instance => {
2852
+ const innerParams = privateProps.innerParams.get(instance);
2853
+ instance.disableButtons();
2854
+ if (innerParams.input) {
2855
+ handleConfirmOrDenyWithInput(instance, 'confirm');
2856
+ } else {
2857
+ confirm(instance, true);
2858
+ }
2859
+ };
2860
+
2861
+ /**
2862
+ * @param {SweetAlert} instance
2863
+ */
2864
+ const handleDenyButtonClick = instance => {
2865
+ const innerParams = privateProps.innerParams.get(instance);
2866
+ instance.disableButtons();
2867
+ if (innerParams.returnInputValueOnDeny) {
2868
+ handleConfirmOrDenyWithInput(instance, 'deny');
2869
+ } else {
2870
+ deny(instance, false);
2871
+ }
2872
+ };
2873
+
2874
+ /**
2875
+ * @param {SweetAlert} instance
2876
+ * @param {(dismiss: DismissReason) => void} dismissWith
2877
+ */
2878
+ const handleCancelButtonClick = (instance, dismissWith) => {
2879
+ instance.disableButtons();
2880
+ dismissWith(DismissReason.cancel);
2881
+ };
2882
+
2883
+ /**
2884
+ * @param {SweetAlert} instance
2885
+ * @param {'confirm' | 'deny'} type
2886
+ */
2887
+ const handleConfirmOrDenyWithInput = (instance, type) => {
2888
+ const innerParams = privateProps.innerParams.get(instance);
2889
+ if (!innerParams.input) {
2890
+ error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
2891
+ return;
2892
+ }
2893
+ const input = instance.getInput();
2894
+ const inputValue = getInputValue(instance, innerParams);
2895
+ if (innerParams.inputValidator) {
2896
+ handleInputValidator(instance, inputValue, type);
2897
+ } else if (input && !input.checkValidity()) {
2898
+ instance.enableButtons();
2899
+ instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
2900
+ } else if (type === 'deny') {
2901
+ deny(instance, inputValue);
2902
+ } else {
2903
+ confirm(instance, inputValue);
2904
+ }
2905
+ };
2906
+
2907
+ /**
2908
+ * @param {SweetAlert} instance
2909
+ * @param {SweetAlertInputValue} inputValue
2910
+ * @param {'confirm' | 'deny'} type
2911
+ */
2912
+ const handleInputValidator = (instance, inputValue, type) => {
2913
+ const innerParams = privateProps.innerParams.get(instance);
2914
+ instance.disableInput();
2915
+ const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
2916
+ validationPromise.then(validationMessage => {
2917
+ instance.enableButtons();
2918
+ instance.enableInput();
2919
+ if (validationMessage) {
2920
+ instance.showValidationMessage(validationMessage);
2921
+ } else if (type === 'deny') {
2922
+ deny(instance, inputValue);
2923
+ } else {
2924
+ confirm(instance, inputValue);
2925
+ }
2926
+ });
2927
+ };
2928
+
2929
+ /**
2930
+ * @param {SweetAlert} instance
2931
+ * @param {*} value
2932
+ */
2933
+ const deny = (instance, value) => {
2934
+ const innerParams = privateProps.innerParams.get(instance);
2935
+ if (innerParams.showLoaderOnDeny) {
2936
+ showLoading(getDenyButton());
2937
+ }
2938
+ if (innerParams.preDeny) {
2939
+ instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preDeny's promise is received
2940
+ const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
2941
+ preDenyPromise.then(preDenyValue => {
2942
+ if (preDenyValue === false) {
2943
+ instance.hideLoading();
2944
+ handleAwaitingPromise(instance);
2945
+ } else {
2946
+ instance.close(/** @type SweetAlertResult */{
2947
+ isDenied: true,
2948
+ value: typeof preDenyValue === 'undefined' ? value : preDenyValue
2949
+ });
2950
+ }
2951
+ }).catch(error => rejectWith(instance, error));
2952
+ } else {
2953
+ instance.close(/** @type SweetAlertResult */{
2954
+ isDenied: true,
2955
+ value
2956
+ });
2957
+ }
2958
+ };
2959
+
2960
+ /**
2961
+ * @param {SweetAlert} instance
2962
+ * @param {*} value
2963
+ */
2964
+ const succeedWith = (instance, value) => {
2965
+ instance.close(/** @type SweetAlertResult */{
2966
+ isConfirmed: true,
2967
+ value
2968
+ });
2969
+ };
2970
+
2971
+ /**
2972
+ *
2973
+ * @param {SweetAlert} instance
2974
+ * @param {string} error
2975
+ */
2976
+ const rejectWith = (instance, error) => {
2977
+ instance.rejectPromise(error);
2978
+ };
2979
+
2980
+ /**
2981
+ *
2982
+ * @param {SweetAlert} instance
2983
+ * @param {*} value
2984
+ */
2985
+ const confirm = (instance, value) => {
2986
+ const innerParams = privateProps.innerParams.get(instance);
2987
+ if (innerParams.showLoaderOnConfirm) {
2988
+ showLoading();
2989
+ }
2990
+ if (innerParams.preConfirm) {
2991
+ instance.resetValidationMessage();
2992
+ instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preConfirm's promise is received
2993
+ const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
2994
+ preConfirmPromise.then(preConfirmValue => {
2995
+ if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
2996
+ instance.hideLoading();
2997
+ handleAwaitingPromise(instance);
2998
+ } else {
2999
+ succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
3000
+ }
3001
+ }).catch(error => rejectWith(instance, error));
3002
+ } else {
3003
+ succeedWith(instance, value);
3004
+ }
3005
+ };
3006
+
3007
+ /**
3008
+ * Hides loader and shows back the button which was hidden by .showLoading()
3009
+ * @this {SweetAlert}
3010
+ */
3011
+ function hideLoading() {
3012
+ // do nothing if popup is closed
3013
+ const innerParams = privateProps.innerParams.get(this);
3014
+ if (!innerParams) {
3015
+ return;
3016
+ }
3017
+ const domCache = privateProps.domCache.get(this);
3018
+ hide(domCache.loader);
3019
+ if (isToast()) {
3020
+ if (innerParams.icon) {
3021
+ show(getIcon());
3022
+ }
3023
+ } else {
3024
+ showRelatedButton(domCache);
3025
+ }
3026
+ removeClass([domCache.popup, domCache.actions], swalClasses.loading);
3027
+ domCache.popup.removeAttribute('aria-busy');
3028
+ domCache.popup.removeAttribute('data-loading');
3029
+ domCache.confirmButton.disabled = false;
3030
+ domCache.denyButton.disabled = false;
3031
+ domCache.cancelButton.disabled = false;
3032
+ const focusedElement = privateProps.focusedElement.get(this);
3033
+ if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
3034
+ focusedElement.focus();
3035
+ }
3036
+ privateProps.focusedElement.delete(this);
3037
+ }
3038
+
3039
+ /**
3040
+ * @param {DomCache} domCache
3041
+ */
3042
+ const showRelatedButton = domCache => {
3043
+ const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
3044
+ const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
3045
+ if (buttonToReplace.length) {
3046
+ show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
3047
+ } else if (allButtonsAreHidden()) {
3048
+ hide(domCache.actions);
3049
+ }
3050
+ };
3051
+
3052
+ /**
3053
+ * Gets the input DOM node, this method works with input parameter.
3054
+ *
3055
+ * @returns {HTMLInputElement | null}
3056
+ * @this {SweetAlert}
3057
+ */
3058
+ function getInput() {
3059
+ const innerParams = privateProps.innerParams.get(this);
3060
+ const domCache = privateProps.domCache.get(this);
3061
+ if (!domCache) {
3062
+ return null;
3063
+ }
3064
+ return getInput$1(domCache.popup, innerParams.input);
3065
+ }
3066
+
3067
+ /**
3068
+ * @param {SweetAlert} instance
3069
+ * @param {string[]} buttons
3070
+ * @param {boolean} disabled
3071
+ */
3072
+ function setButtonsDisabled(instance, buttons, disabled) {
3073
+ const domCache = privateProps.domCache.get(instance);
3074
+ buttons.forEach(button => {
3075
+ domCache[button].disabled = disabled;
3076
+ });
3077
+ }
3078
+
3079
+ /**
3080
+ * @param {HTMLInputElement | null} input
3081
+ * @param {boolean} disabled
3082
+ */
3083
+ function setInputDisabled(input, disabled) {
3084
+ const popup = getPopup();
3085
+ if (!popup || !input) {
3086
+ return;
3087
+ }
3088
+ if (input.type === 'radio') {
3089
+ /** @type {NodeListOf<HTMLInputElement>} */
3090
+ const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
3091
+ for (let i = 0; i < radios.length; i++) {
3092
+ radios[i].disabled = disabled;
3093
+ }
3094
+ } else {
3095
+ input.disabled = disabled;
3096
+ }
3097
+ }
3098
+
3099
+ /**
3100
+ * Enable all the buttons
3101
+ * @this {SweetAlert}
3102
+ */
3103
+ function enableButtons() {
3104
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
3105
+ const focusedElement = privateProps.focusedElement.get(this);
3106
+ if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
3107
+ focusedElement.focus();
3108
+ }
3109
+ privateProps.focusedElement.delete(this);
3110
+ }
3111
+
3112
+ /**
3113
+ * Disable all the buttons
3114
+ * @this {SweetAlert}
3115
+ */
3116
+ function disableButtons() {
3117
+ privateProps.focusedElement.set(this, document.activeElement);
3118
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
3119
+ }
3120
+
3121
+ /**
3122
+ * Enable the input field
3123
+ * @this {SweetAlert}
3124
+ */
3125
+ function enableInput() {
3126
+ setInputDisabled(this.getInput(), false);
3127
+ }
3128
+
3129
+ /**
3130
+ * Disable the input field
3131
+ * @this {SweetAlert}
3132
+ */
3133
+ function disableInput() {
3134
+ setInputDisabled(this.getInput(), true);
3135
+ }
3136
+
3137
+ /**
3138
+ * Show block with validation message
3139
+ *
3140
+ * @param {string} error
3141
+ * @this {SweetAlert}
3142
+ */
3143
+ function showValidationMessage(error) {
3144
+ const domCache = privateProps.domCache.get(this);
3145
+ const params = privateProps.innerParams.get(this);
3146
+ setInnerHtml(domCache.validationMessage, error);
3147
+ domCache.validationMessage.className = swalClasses['validation-message'];
3148
+ if (params.customClass && params.customClass.validationMessage) {
3149
+ addClass(domCache.validationMessage, params.customClass.validationMessage);
3150
+ }
3151
+ show(domCache.validationMessage);
3152
+ const input = this.getInput();
3153
+ if (input) {
3154
+ input.setAttribute('aria-invalid', 'true');
3155
+ input.setAttribute('aria-describedby', swalClasses['validation-message']);
3156
+ focusInput(input);
3157
+ addClass(input, swalClasses.inputerror);
3158
+ }
3159
+ }
3160
+
3161
+ /**
3162
+ * Hide block with validation message
3163
+ *
3164
+ * @this {SweetAlert}
3165
+ */
3166
+ function resetValidationMessage() {
3167
+ const domCache = privateProps.domCache.get(this);
3168
+ if (domCache.validationMessage) {
3169
+ hide(domCache.validationMessage);
3170
+ }
3171
+ const input = this.getInput();
3172
+ if (input) {
3173
+ input.removeAttribute('aria-invalid');
3174
+ input.removeAttribute('aria-describedby');
3175
+ removeClass(input, swalClasses.inputerror);
3176
+ }
3177
+ }
3178
+
3179
+ const defaultParams = {
3180
+ title: '',
3181
+ titleText: '',
3182
+ text: '',
3183
+ html: '',
3184
+ footer: '',
3185
+ icon: undefined,
3186
+ iconColor: undefined,
3187
+ iconHtml: undefined,
3188
+ template: undefined,
3189
+ toast: false,
3190
+ draggable: false,
3191
+ animation: true,
3192
+ theme: 'light',
3193
+ showClass: {
3194
+ popup: 'swal2-show',
3195
+ backdrop: 'swal2-backdrop-show',
3196
+ icon: 'swal2-icon-show'
3197
+ },
3198
+ hideClass: {
3199
+ popup: 'swal2-hide',
3200
+ backdrop: 'swal2-backdrop-hide',
3201
+ icon: 'swal2-icon-hide'
3202
+ },
3203
+ customClass: {},
3204
+ target: 'body',
3205
+ color: undefined,
3206
+ backdrop: true,
3207
+ heightAuto: true,
3208
+ allowOutsideClick: true,
3209
+ allowEscapeKey: true,
3210
+ allowEnterKey: true,
3211
+ stopKeydownPropagation: true,
3212
+ keydownListenerCapture: false,
3213
+ showConfirmButton: true,
3214
+ showDenyButton: false,
3215
+ showCancelButton: false,
3216
+ preConfirm: undefined,
3217
+ preDeny: undefined,
3218
+ confirmButtonText: 'OK',
3219
+ confirmButtonAriaLabel: '',
3220
+ confirmButtonColor: undefined,
3221
+ denyButtonText: 'No',
3222
+ denyButtonAriaLabel: '',
3223
+ denyButtonColor: undefined,
3224
+ cancelButtonText: 'Cancel',
3225
+ cancelButtonAriaLabel: '',
3226
+ cancelButtonColor: undefined,
3227
+ buttonsStyling: true,
3228
+ reverseButtons: false,
3229
+ focusConfirm: true,
3230
+ focusDeny: false,
3231
+ focusCancel: false,
3232
+ returnFocus: true,
3233
+ showCloseButton: false,
3234
+ closeButtonHtml: '&times;',
3235
+ closeButtonAriaLabel: 'Close this dialog',
3236
+ loaderHtml: '',
3237
+ showLoaderOnConfirm: false,
3238
+ showLoaderOnDeny: false,
3239
+ imageUrl: undefined,
3240
+ imageWidth: undefined,
3241
+ imageHeight: undefined,
3242
+ imageAlt: '',
3243
+ timer: undefined,
3244
+ timerProgressBar: false,
3245
+ width: undefined,
3246
+ padding: undefined,
3247
+ background: undefined,
3248
+ input: undefined,
3249
+ inputPlaceholder: '',
3250
+ inputLabel: '',
3251
+ inputValue: '',
3252
+ inputOptions: {},
3253
+ inputAutoFocus: true,
3254
+ inputAutoTrim: true,
3255
+ inputAttributes: {},
3256
+ inputValidator: undefined,
3257
+ returnInputValueOnDeny: false,
3258
+ validationMessage: undefined,
3259
+ grow: false,
3260
+ position: 'center',
3261
+ progressSteps: [],
3262
+ currentProgressStep: undefined,
3263
+ progressStepsDistance: undefined,
3264
+ willOpen: undefined,
3265
+ didOpen: undefined,
3266
+ didRender: undefined,
3267
+ willClose: undefined,
3268
+ didClose: undefined,
3269
+ didDestroy: undefined,
3270
+ scrollbarPadding: true,
3271
+ topLayer: false
3272
+ };
3273
+ const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'draggable', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'theme', 'willClose'];
3274
+
3275
+ /** @type {Record<string, string | undefined>} */
3276
+ const deprecatedParams = {
3277
+ allowEnterKey: undefined
3278
+ };
3279
+ const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
3280
+
3281
+ /**
3282
+ * Is valid parameter
3283
+ *
3284
+ * @param {string} paramName
3285
+ * @returns {boolean}
3286
+ */
3287
+ const isValidParameter = paramName => {
3288
+ return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
3289
+ };
3290
+
3291
+ /**
3292
+ * Is valid parameter for Swal.update() method
3293
+ *
3294
+ * @param {string} paramName
3295
+ * @returns {boolean}
3296
+ */
3297
+ const isUpdatableParameter = paramName => {
3298
+ return updatableParams.indexOf(paramName) !== -1;
3299
+ };
3300
+
3301
+ /**
3302
+ * Is deprecated parameter
3303
+ *
3304
+ * @param {string} paramName
3305
+ * @returns {string | undefined}
3306
+ */
3307
+ const isDeprecatedParameter = paramName => {
3308
+ return deprecatedParams[paramName];
3309
+ };
3310
+
3311
+ /**
3312
+ * @param {string} param
3313
+ */
3314
+ const checkIfParamIsValid = param => {
3315
+ if (!isValidParameter(param)) {
3316
+ warn(`Unknown parameter "${param}"`);
3317
+ }
3318
+ };
3319
+
3320
+ /**
3321
+ * @param {string} param
3322
+ */
3323
+ const checkIfToastParamIsValid = param => {
3324
+ if (toastIncompatibleParams.includes(param)) {
3325
+ warn(`The parameter "${param}" is incompatible with toasts`);
3326
+ }
3327
+ };
3328
+
3329
+ /**
3330
+ * @param {string} param
3331
+ */
3332
+ const checkIfParamIsDeprecated = param => {
3333
+ const isDeprecated = isDeprecatedParameter(param);
3334
+ if (isDeprecated) {
3335
+ warnAboutDeprecation(param, isDeprecated);
3336
+ }
3337
+ };
3338
+
3339
+ /**
3340
+ * Show relevant warnings for given params
3341
+ *
3342
+ * @param {SweetAlertOptions} params
3343
+ */
3344
+ const showWarningsForParams = params => {
3345
+ if (params.backdrop === false && params.allowOutsideClick) {
3346
+ warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
3347
+ }
3348
+ if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'bootstrap-4', 'bootstrap-4-light', 'bootstrap-4-dark', 'bootstrap-5', 'bootstrap-5-light', 'bootstrap-5-dark', 'material-ui', 'material-ui-light', 'material-ui-dark', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
3349
+ warn(`Invalid theme "${params.theme}"`);
3350
+ }
3351
+ for (const param in params) {
3352
+ checkIfParamIsValid(param);
3353
+ if (params.toast) {
3354
+ checkIfToastParamIsValid(param);
3355
+ }
3356
+ checkIfParamIsDeprecated(param);
3357
+ }
3358
+ };
3359
+
3360
+ /**
3361
+ * Updates popup parameters.
3362
+ *
3363
+ * @this {any}
3364
+ * @param {SweetAlertOptions} params
3365
+ */
3366
+ function update(params) {
3367
+ const container = getContainer();
3368
+ const popup = getPopup();
3369
+ const innerParams = privateProps.innerParams.get(this);
3370
+ if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
3371
+ warn(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`);
3372
+ return;
3373
+ }
3374
+ const validUpdatableParams = filterValidParams(params);
3375
+ const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
3376
+ showWarningsForParams(updatedParams);
3377
+ if (container) {
3378
+ container.dataset['swal2Theme'] = updatedParams.theme;
3379
+ }
3380
+ render(this, updatedParams);
3381
+ privateProps.innerParams.set(this, updatedParams);
3382
+ Object.defineProperties(this, {
3383
+ params: {
3384
+ value: Object.assign({}, this.params, params),
3385
+ writable: false,
3386
+ enumerable: true
3387
+ }
3388
+ });
3389
+ }
3390
+
3391
+ /**
3392
+ * @param {SweetAlertOptions} params
3393
+ * @returns {SweetAlertOptions}
3394
+ */
3395
+ const filterValidParams = params => {
3396
+ /** @type {Record<string, any>} */
3397
+ const validUpdatableParams = {};
3398
+ Object.keys(params).forEach(param => {
3399
+ if (isUpdatableParameter(param)) {
3400
+ const typedParams = /** @type {Record<string, any>} */params;
3401
+ validUpdatableParams[param] = typedParams[param];
3402
+ } else {
3403
+ warn(`Invalid parameter to update: ${param}`);
3404
+ }
3405
+ });
3406
+ return validUpdatableParams;
3407
+ };
3408
+
3409
+ /**
3410
+ * Dispose the current SweetAlert2 instance
3411
+ * @this {SweetAlert}
3412
+ */
3413
+ function _destroy() {
3414
+ var _globalState$eventEmi;
3415
+ const domCache = privateProps.domCache.get(this);
3416
+ const innerParams = privateProps.innerParams.get(this);
3417
+ if (!innerParams) {
3418
+ disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
3419
+ return; // This instance has already been destroyed
3420
+ }
3421
+
3422
+ // Check if there is another Swal closing
3423
+ if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
3424
+ globalState.swalCloseEventFinishedCallback();
3425
+ delete globalState.swalCloseEventFinishedCallback;
3426
+ }
3427
+ if (typeof innerParams.didDestroy === 'function') {
3428
+ innerParams.didDestroy();
3429
+ }
3430
+ (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
3431
+ disposeSwal(this);
3432
+ }
3433
+
3434
+ /**
3435
+ * @param {SweetAlert} instance
3436
+ */
3437
+ const disposeSwal = instance => {
3438
+ disposeWeakMaps(instance);
3439
+ // Unset this.params so GC will dispose it (#1569)
3440
+ // @ts-ignore
3441
+ delete instance.params;
3442
+ // Unset globalState props so GC will dispose globalState (#1569)
3443
+ delete globalState.keydownHandler;
3444
+ delete globalState.keydownTarget;
3445
+ // Unset currentInstance
3446
+ delete globalState.currentInstance;
3447
+ };
3448
+
3449
+ /**
3450
+ * @param {SweetAlert} instance
3451
+ */
3452
+ const disposeWeakMaps = instance => {
3453
+ // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
3454
+ if (instance.isAwaitingPromise) {
3455
+ unsetWeakMaps(privateProps, instance);
3456
+ instance.isAwaitingPromise = true;
3457
+ } else {
3458
+ unsetWeakMaps(privateMethods, instance);
3459
+ unsetWeakMaps(privateProps, instance);
3460
+
3461
+ // @ts-ignore
3462
+ delete instance.isAwaitingPromise;
3463
+ // Unset instance methods
3464
+ // @ts-ignore
3465
+ delete instance.disableButtons;
3466
+ // @ts-ignore
3467
+ delete instance.enableButtons;
3468
+ // @ts-ignore
3469
+ delete instance.getInput;
3470
+ // @ts-ignore
3471
+ delete instance.disableInput;
3472
+ // @ts-ignore
3473
+ delete instance.enableInput;
3474
+ // @ts-ignore
3475
+ delete instance.hideLoading;
3476
+ // @ts-ignore
3477
+ delete instance.disableLoading;
3478
+ // @ts-ignore
3479
+ delete instance.showValidationMessage;
3480
+ // @ts-ignore
3481
+ delete instance.resetValidationMessage;
3482
+ // @ts-ignore
3483
+ delete instance.close;
3484
+ // @ts-ignore
3485
+ delete instance.closePopup;
3486
+ // @ts-ignore
3487
+ delete instance.closeModal;
3488
+ // @ts-ignore
3489
+ delete instance.closeToast;
3490
+ // @ts-ignore
3491
+ delete instance.rejectPromise;
3492
+ // @ts-ignore
3493
+ delete instance.update;
3494
+ // @ts-ignore
3495
+ delete instance._destroy;
3496
+ }
3497
+ };
3498
+
3499
+ /**
3500
+ * @param {Record<string, WeakMap<any, any>>} obj
3501
+ * @param {SweetAlert} instance
3502
+ */
3503
+ const unsetWeakMaps = (obj, instance) => {
3504
+ for (const i in obj) {
3505
+ obj[i].delete(instance);
3506
+ }
3507
+ };
3508
+
3509
+ var instanceMethods = /*#__PURE__*/Object.freeze({
3510
+ __proto__: null,
3511
+ _destroy: _destroy,
3512
+ close: close,
3513
+ closeModal: close,
3514
+ closePopup: close,
3515
+ closeToast: close,
3516
+ disableButtons: disableButtons,
3517
+ disableInput: disableInput,
3518
+ disableLoading: hideLoading,
3519
+ enableButtons: enableButtons,
3520
+ enableInput: enableInput,
3521
+ getInput: getInput,
3522
+ handleAwaitingPromise: handleAwaitingPromise,
3523
+ hideLoading: hideLoading,
3524
+ rejectPromise: rejectPromise,
3525
+ resetValidationMessage: resetValidationMessage,
3526
+ showValidationMessage: showValidationMessage,
3527
+ update: update
3528
+ });
3529
+
3530
+ /**
3531
+ * @param {SweetAlertOptions} innerParams
3532
+ * @param {DomCache} domCache
3533
+ * @param {(dismiss: DismissReason) => void} dismissWith
3534
+ */
3535
+ const handlePopupClick = (innerParams, domCache, dismissWith) => {
3536
+ if (innerParams.toast) {
3537
+ handleToastClick(innerParams, domCache, dismissWith);
3538
+ } else {
3539
+ // Ignore click events that had mousedown on the popup but mouseup on the container
3540
+ // This can happen when the user drags a slider
3541
+ handleModalMousedown(domCache);
3542
+
3543
+ // Ignore click events that had mousedown on the container but mouseup on the popup
3544
+ handleContainerMousedown(domCache);
3545
+ handleModalClick(innerParams, domCache, dismissWith);
3546
+ }
3547
+ };
3548
+
3549
+ /**
3550
+ * @param {SweetAlertOptions} innerParams
3551
+ * @param {DomCache} domCache
3552
+ * @param {(dismiss: DismissReason) => void} dismissWith
3553
+ */
3554
+ const handleToastClick = (innerParams, domCache, dismissWith) => {
3555
+ // Closing toast by internal click
3556
+ domCache.popup.onclick = () => {
3557
+ if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
3558
+ return;
3559
+ }
3560
+ dismissWith(DismissReason.close);
3561
+ };
3562
+ };
3563
+
3564
+ /**
3565
+ * @param {SweetAlertOptions} innerParams
3566
+ * @returns {boolean}
3567
+ */
3568
+ const isAnyButtonShown = innerParams => {
3569
+ return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
3570
+ };
3571
+ let ignoreOutsideClick = false;
3572
+
3573
+ /**
3574
+ * @param {DomCache} domCache
3575
+ */
3576
+ const handleModalMousedown = domCache => {
3577
+ domCache.popup.onmousedown = () => {
3578
+ domCache.container.onmouseup = function (e) {
3579
+ domCache.container.onmouseup = () => {};
3580
+ // We only check if the mouseup target is the container because usually it doesn't
3581
+ // have any other direct children aside of the popup
3582
+ if (e.target === domCache.container) {
3583
+ ignoreOutsideClick = true;
3584
+ }
3585
+ };
3586
+ };
3587
+ };
3588
+
3589
+ /**
3590
+ * @param {DomCache} domCache
3591
+ */
3592
+ const handleContainerMousedown = domCache => {
3593
+ domCache.container.onmousedown = e => {
3594
+ // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
3595
+ if (e.target === domCache.container) {
3596
+ e.preventDefault();
3597
+ }
3598
+ domCache.popup.onmouseup = function (e) {
3599
+ domCache.popup.onmouseup = () => {};
3600
+ // We also need to check if the mouseup target is a child of the popup
3601
+ if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
3602
+ ignoreOutsideClick = true;
3603
+ }
3604
+ };
3605
+ };
3606
+ };
3607
+
3608
+ /**
3609
+ * @param {SweetAlertOptions} innerParams
3610
+ * @param {DomCache} domCache
3611
+ * @param {(dismiss: DismissReason) => void} dismissWith
3612
+ */
3613
+ const handleModalClick = (innerParams, domCache, dismissWith) => {
3614
+ domCache.container.onclick = e => {
3615
+ if (ignoreOutsideClick) {
3616
+ ignoreOutsideClick = false;
3617
+ return;
3618
+ }
3619
+ if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
3620
+ dismissWith(DismissReason.backdrop);
3621
+ }
3622
+ };
3623
+ };
3624
+
3625
+ /**
3626
+ * @param {unknown} elem
3627
+ * @returns {boolean}
3628
+ */
3629
+ const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
3630
+
3631
+ /**
3632
+ * @param {unknown} elem
3633
+ * @returns {boolean}
3634
+ */
3635
+ const isElement = elem => elem instanceof Element || isJqueryElement(elem);
3636
+
3637
+ /**
3638
+ * @param {ReadonlyArray<unknown>} args
3639
+ * @returns {SweetAlertOptions}
3640
+ */
3641
+ const argsToParams = args => {
3642
+ /** @type {Record<string, unknown>} */
3643
+ const params = {};
3644
+ if (typeof args[0] === 'object' && !isElement(args[0])) {
3645
+ Object.assign(params, args[0]);
3646
+ } else {
3647
+ ['title', 'html', 'icon'].forEach((name, index) => {
3648
+ const arg = args[index];
3649
+ if (typeof arg === 'string' || isElement(arg)) {
3650
+ params[name] = arg;
3651
+ } else if (arg !== undefined) {
3652
+ error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
3653
+ }
3654
+ });
3655
+ }
3656
+ return /** @type {SweetAlertOptions} */params;
3657
+ };
3658
+
3659
+ /**
3660
+ * Main method to create a new SweetAlert2 popup
3661
+ *
3662
+ * @this {new (...args: any[]) => any}
3663
+ * @param {...SweetAlertOptions} args
3664
+ * @returns {Promise<SweetAlertResult>}
3665
+ */
3666
+ function fire(...args) {
3667
+ return new this(...args);
3668
+ }
3669
+
3670
+ /**
3671
+ * Returns an extended version of `Swal` containing `params` as defaults.
3672
+ * Useful for reusing Swal configuration.
3673
+ *
3674
+ * For example:
3675
+ *
3676
+ * Before:
3677
+ * const textPromptOptions = { input: 'text', showCancelButton: true }
3678
+ * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
3679
+ * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
3680
+ *
3681
+ * After:
3682
+ * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
3683
+ * const {value: firstName} = await TextPrompt('What is your first name?')
3684
+ * const {value: lastName} = await TextPrompt('What is your last name?')
3685
+ *
3686
+ * @param {SweetAlertOptions} mixinParams
3687
+ * @returns {SweetAlert}
3688
+ * @this {typeof import('../SweetAlert.js').SweetAlert}
3689
+ */
3690
+ function mixin(mixinParams) {
3691
+ // @ts-ignore: 'this' refers to the SweetAlert constructor
3692
+ class MixinSwal extends this {
3693
+ /**
3694
+ * @param {any} params
3695
+ * @param {any} priorityMixinParams
3696
+ */
3697
+ _main(params, priorityMixinParams) {
3698
+ return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
3699
+ }
3700
+ }
3701
+ // @ts-ignore
3702
+ return MixinSwal;
3703
+ }
3704
+
3705
+ /**
3706
+ * If `timer` parameter is set, returns number of milliseconds of timer remained.
3707
+ * Otherwise, returns undefined.
3708
+ *
3709
+ * @returns {number | undefined}
3710
+ */
3711
+ const getTimerLeft = () => {
3712
+ return globalState.timeout && globalState.timeout.getTimerLeft();
3713
+ };
3714
+
3715
+ /**
3716
+ * Stop timer. Returns number of milliseconds of timer remained.
3717
+ * If `timer` parameter isn't set, returns undefined.
3718
+ *
3719
+ * @returns {number | undefined}
3720
+ */
3721
+ const stopTimer = () => {
3722
+ if (globalState.timeout) {
3723
+ stopTimerProgressBar();
3724
+ return globalState.timeout.stop();
3725
+ }
3726
+ };
3727
+
3728
+ /**
3729
+ * Resume timer. Returns number of milliseconds of timer remained.
3730
+ * If `timer` parameter isn't set, returns undefined.
3731
+ *
3732
+ * @returns {number | undefined}
3733
+ */
3734
+ const resumeTimer = () => {
3735
+ if (globalState.timeout) {
3736
+ const remaining = globalState.timeout.start();
3737
+ animateTimerProgressBar(remaining);
3738
+ return remaining;
3739
+ }
3740
+ };
3741
+
3742
+ /**
3743
+ * Resume timer. Returns number of milliseconds of timer remained.
3744
+ * If `timer` parameter isn't set, returns undefined.
3745
+ *
3746
+ * @returns {number | undefined}
3747
+ */
3748
+ const toggleTimer = () => {
3749
+ const timer = globalState.timeout;
3750
+ return timer && (timer.running ? stopTimer() : resumeTimer());
3751
+ };
3752
+
3753
+ /**
3754
+ * Increase timer. Returns number of milliseconds of an updated timer.
3755
+ * If `timer` parameter isn't set, returns undefined.
3756
+ *
3757
+ * @param {number} ms
3758
+ * @returns {number | undefined}
3759
+ */
3760
+ const increaseTimer = ms => {
3761
+ if (globalState.timeout) {
3762
+ const remaining = globalState.timeout.increase(ms);
3763
+ animateTimerProgressBar(remaining, true);
3764
+ return remaining;
3765
+ }
3766
+ };
3767
+
3768
+ /**
3769
+ * Check if timer is running. Returns true if timer is running
3770
+ * or false if timer is paused or stopped.
3771
+ * If `timer` parameter isn't set, returns undefined
3772
+ *
3773
+ * @returns {boolean}
3774
+ */
3775
+ const isTimerRunning = () => {
3776
+ return Boolean(globalState.timeout && globalState.timeout.isRunning());
3777
+ };
3778
+
3779
+ let bodyClickListenerAdded = false;
3780
+ /** @type {Record<string, any>} */
3781
+ const clickHandlers = {};
3782
+
3783
+ /**
3784
+ * @this {any}
3785
+ * @param {string} attr
3786
+ */
3787
+ function bindClickHandler(attr = 'data-swal-template') {
3788
+ clickHandlers[attr] = this;
3789
+ if (!bodyClickListenerAdded) {
3790
+ document.body.addEventListener('click', bodyClickListener);
3791
+ bodyClickListenerAdded = true;
3792
+ }
3793
+ }
3794
+
3795
+ /**
3796
+ * @param {MouseEvent} event
3797
+ */
3798
+ const bodyClickListener = event => {
3799
+ for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
3800
+ for (const attr in clickHandlers) {
3801
+ const template = el.getAttribute && el.getAttribute(attr);
3802
+ if (template) {
3803
+ clickHandlers[attr].fire({
3804
+ template
3805
+ });
3806
+ return;
3807
+ }
3808
+ }
3809
+ }
3810
+ };
3811
+
3812
+ // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
3813
+
3814
+ class EventEmitter {
3815
+ constructor() {
3816
+ /** @type {Events} */
3817
+ this.events = {};
3818
+ }
3819
+
3820
+ /**
3821
+ * @param {string} eventName
3822
+ * @returns {EventHandlers}
3823
+ */
3824
+ _getHandlersByEventName(eventName) {
3825
+ if (typeof this.events[eventName] === 'undefined') {
3826
+ // not Set because we need to keep the FIFO order
3827
+ // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
3828
+ this.events[eventName] = [];
3829
+ }
3830
+ return this.events[eventName];
3831
+ }
3832
+
3833
+ /**
3834
+ * @param {string} eventName
3835
+ * @param {EventHandler} eventHandler
3836
+ */
3837
+ on(eventName, eventHandler) {
3838
+ const currentHandlers = this._getHandlersByEventName(eventName);
3839
+ if (!currentHandlers.includes(eventHandler)) {
3840
+ currentHandlers.push(eventHandler);
3841
+ }
3842
+ }
3843
+
3844
+ /**
3845
+ * @param {string} eventName
3846
+ * @param {EventHandler} eventHandler
3847
+ */
3848
+ once(eventName, eventHandler) {
3849
+ /**
3850
+ * @param {...any} args
3851
+ */
3852
+ const onceFn = (...args) => {
3853
+ this.removeListener(eventName, onceFn);
3854
+ // @ts-ignore
3855
+ eventHandler.apply(this, args);
3856
+ };
3857
+ this.on(eventName, onceFn);
3858
+ }
3859
+
3860
+ /**
3861
+ * @param {string} eventName
3862
+ * @param {...any} args
3863
+ */
3864
+ emit(eventName, ...args) {
3865
+ this._getHandlersByEventName(eventName).forEach(
3866
+ /**
3867
+ * @param {EventHandler} eventHandler
3868
+ */
3869
+ eventHandler => {
3870
+ try {
3871
+ // @ts-ignore
3872
+ eventHandler.apply(this, args);
3873
+ } catch (error) {
3874
+ console.error(error);
3875
+ }
3876
+ });
3877
+ }
3878
+
3879
+ /**
3880
+ * @param {string} eventName
3881
+ * @param {EventHandler} eventHandler
3882
+ */
3883
+ removeListener(eventName, eventHandler) {
3884
+ const currentHandlers = this._getHandlersByEventName(eventName);
3885
+ const index = currentHandlers.indexOf(eventHandler);
3886
+ if (index > -1) {
3887
+ currentHandlers.splice(index, 1);
3888
+ }
3889
+ }
3890
+
3891
+ /**
3892
+ * @param {string} eventName
3893
+ */
3894
+ removeAllListeners(eventName) {
3895
+ if (this.events[eventName] !== undefined) {
3896
+ // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
3897
+ this.events[eventName].length = 0;
3898
+ }
3899
+ }
3900
+ reset() {
3901
+ this.events = {};
3902
+ }
3903
+ }
3904
+
3905
+ globalState.eventEmitter = new EventEmitter();
3906
+
3907
+ /**
3908
+ * @param {string} eventName
3909
+ * @param {EventHandler} eventHandler
3910
+ */
3911
+ const on = (eventName, eventHandler) => {
3912
+ if (globalState.eventEmitter) {
3913
+ globalState.eventEmitter.on(eventName, eventHandler);
3914
+ }
3915
+ };
3916
+
3917
+ /**
3918
+ * @param {string} eventName
3919
+ * @param {EventHandler} eventHandler
3920
+ */
3921
+ const once = (eventName, eventHandler) => {
3922
+ if (globalState.eventEmitter) {
3923
+ globalState.eventEmitter.once(eventName, eventHandler);
3924
+ }
3925
+ };
3926
+
3927
+ /**
3928
+ * @param {string} [eventName]
3929
+ * @param {EventHandler} [eventHandler]
3930
+ */
3931
+ const off = (eventName, eventHandler) => {
3932
+ if (!globalState.eventEmitter) {
3933
+ return;
3934
+ }
3935
+
3936
+ // Remove all handlers for all events
3937
+ if (!eventName) {
3938
+ globalState.eventEmitter.reset();
3939
+ return;
3940
+ }
3941
+ if (eventHandler) {
3942
+ // Remove a specific handler
3943
+ globalState.eventEmitter.removeListener(eventName, eventHandler);
3944
+ } else {
3945
+ // Remove all handlers for a specific event
3946
+ globalState.eventEmitter.removeAllListeners(eventName);
3947
+ }
3948
+ };
3949
+
3950
+ var staticMethods = /*#__PURE__*/Object.freeze({
3951
+ __proto__: null,
3952
+ argsToParams: argsToParams,
3953
+ bindClickHandler: bindClickHandler,
3954
+ clickCancel: clickCancel,
3955
+ clickConfirm: clickConfirm,
3956
+ clickDeny: clickDeny,
3957
+ enableLoading: showLoading,
3958
+ fire: fire,
3959
+ getActions: getActions,
3960
+ getCancelButton: getCancelButton,
3961
+ getCloseButton: getCloseButton,
3962
+ getConfirmButton: getConfirmButton,
3963
+ getContainer: getContainer,
3964
+ getDenyButton: getDenyButton,
3965
+ getFocusableElements: getFocusableElements,
3966
+ getFooter: getFooter,
3967
+ getHtmlContainer: getHtmlContainer,
3968
+ getIcon: getIcon,
3969
+ getIconContent: getIconContent,
3970
+ getImage: getImage,
3971
+ getInputLabel: getInputLabel,
3972
+ getLoader: getLoader,
3973
+ getPopup: getPopup,
3974
+ getProgressSteps: getProgressSteps,
3975
+ getTimerLeft: getTimerLeft,
3976
+ getTimerProgressBar: getTimerProgressBar,
3977
+ getTitle: getTitle,
3978
+ getValidationMessage: getValidationMessage,
3979
+ increaseTimer: increaseTimer,
3980
+ isDeprecatedParameter: isDeprecatedParameter,
3981
+ isLoading: isLoading,
3982
+ isTimerRunning: isTimerRunning,
3983
+ isUpdatableParameter: isUpdatableParameter,
3984
+ isValidParameter: isValidParameter,
3985
+ isVisible: isVisible,
3986
+ mixin: mixin,
3987
+ off: off,
3988
+ on: on,
3989
+ once: once,
3990
+ resumeTimer: resumeTimer,
3991
+ showLoading: showLoading,
3992
+ stopTimer: stopTimer,
3993
+ toggleTimer: toggleTimer
3994
+ });
3995
+
3996
+ class Timer {
3997
+ /**
3998
+ * @param {() => void} callback
3999
+ * @param {number} delay
4000
+ */
4001
+ constructor(callback, delay) {
4002
+ this.callback = callback;
4003
+ this.remaining = delay;
4004
+ this.running = false;
4005
+ this.start();
4006
+ }
4007
+
4008
+ /**
4009
+ * @returns {number}
4010
+ */
4011
+ start() {
4012
+ if (!this.running) {
4013
+ this.running = true;
4014
+ this.started = new Date();
4015
+ this.id = setTimeout(this.callback, this.remaining);
4016
+ }
4017
+ return this.remaining;
4018
+ }
4019
+
4020
+ /**
4021
+ * @returns {number}
4022
+ */
4023
+ stop() {
4024
+ if (this.started && this.running) {
4025
+ this.running = false;
4026
+ clearTimeout(this.id);
4027
+ this.remaining -= new Date().getTime() - this.started.getTime();
4028
+ }
4029
+ return this.remaining;
4030
+ }
4031
+
4032
+ /**
4033
+ * @param {number} n
4034
+ * @returns {number}
4035
+ */
4036
+ increase(n) {
4037
+ const running = this.running;
4038
+ if (running) {
4039
+ this.stop();
4040
+ }
4041
+ this.remaining += n;
4042
+ if (running) {
4043
+ this.start();
4044
+ }
4045
+ return this.remaining;
4046
+ }
4047
+
4048
+ /**
4049
+ * @returns {number}
4050
+ */
4051
+ getTimerLeft() {
4052
+ if (this.running) {
4053
+ this.stop();
4054
+ this.start();
4055
+ }
4056
+ return this.remaining;
4057
+ }
4058
+
4059
+ /**
4060
+ * @returns {boolean}
4061
+ */
4062
+ isRunning() {
4063
+ return this.running;
4064
+ }
4065
+ }
4066
+
4067
+ const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
4068
+
4069
+ /**
4070
+ * @param {SweetAlertOptions} params
4071
+ * @returns {SweetAlertOptions}
4072
+ */
4073
+ const getTemplateParams = params => {
4074
+ const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
4075
+ if (!template) {
4076
+ return {};
4077
+ }
4078
+ /** @type {DocumentFragment} */
4079
+ const templateContent = template.content;
4080
+ showWarningsForElements(templateContent);
4081
+ const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
4082
+ return result;
4083
+ };
4084
+
4085
+ /**
4086
+ * @param {DocumentFragment} templateContent
4087
+ * @returns {Record<string, string | boolean | number>}
4088
+ */
4089
+ const getSwalParams = templateContent => {
4090
+ /** @type {Record<string, string | boolean | number>} */
4091
+ const result = {};
4092
+ /** @type {HTMLElement[]} */
4093
+ const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
4094
+ swalParams.forEach(param => {
4095
+ showWarningsForAttributes(param, ['name', 'value']);
4096
+ const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
4097
+ const value = param.getAttribute('value');
4098
+ if (!paramName || !value) {
4099
+ return;
4100
+ }
4101
+ if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
4102
+ result[paramName] = value !== 'false';
4103
+ } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
4104
+ result[paramName] = JSON.parse(value);
4105
+ } else {
4106
+ result[paramName] = value;
4107
+ }
4108
+ });
4109
+ return result;
4110
+ };
4111
+
4112
+ /**
4113
+ * @param {DocumentFragment} templateContent
4114
+ * @returns {Record<string, () => void>}
4115
+ */
4116
+ const getSwalFunctionParams = templateContent => {
4117
+ /** @type {Record<string, () => void>} */
4118
+ const result = {};
4119
+ /** @type {HTMLElement[]} */
4120
+ const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
4121
+ swalFunctions.forEach(param => {
4122
+ const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
4123
+ const value = param.getAttribute('value');
4124
+ if (!paramName || !value) {
4125
+ return;
4126
+ }
4127
+ result[paramName] = new Function(`return ${value}`)();
4128
+ });
4129
+ return result;
4130
+ };
4131
+
4132
+ /**
4133
+ * @param {DocumentFragment} templateContent
4134
+ * @returns {Record<string, string | boolean>}
4135
+ */
4136
+ const getSwalButtons = templateContent => {
4137
+ /** @type {Record<string, string | boolean>} */
4138
+ const result = {};
4139
+ /** @type {HTMLElement[]} */
4140
+ const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
4141
+ swalButtons.forEach(button => {
4142
+ showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
4143
+ const type = button.getAttribute('type');
4144
+ if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
4145
+ return;
4146
+ }
4147
+ result[`${type}ButtonText`] = button.innerHTML;
4148
+ result[`show${capitalizeFirstLetter(type)}Button`] = true;
4149
+ const color = button.getAttribute('color');
4150
+ if (color !== null) {
4151
+ result[`${type}ButtonColor`] = color;
4152
+ }
4153
+ const ariaLabel = button.getAttribute('aria-label');
4154
+ if (ariaLabel !== null) {
4155
+ result[`${type}ButtonAriaLabel`] = ariaLabel;
4156
+ }
4157
+ });
4158
+ return result;
4159
+ };
4160
+
4161
+ /**
4162
+ * @param {DocumentFragment} templateContent
4163
+ * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
4164
+ */
4165
+ const getSwalImage = templateContent => {
4166
+ const result = {};
4167
+ /** @type {HTMLElement | null} */
4168
+ const image = templateContent.querySelector('swal-image');
4169
+ if (image) {
4170
+ showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
4171
+ // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
4172
+ const src = image.getAttribute('src');
4173
+ if (src !== null) result.imageUrl = src || undefined;
4174
+ const width = image.getAttribute('width');
4175
+ if (width !== null) result.imageWidth = width || undefined;
4176
+ const height = image.getAttribute('height');
4177
+ if (height !== null) result.imageHeight = height || undefined;
4178
+ const alt = image.getAttribute('alt');
4179
+ if (alt !== null) result.imageAlt = alt || undefined;
4180
+ }
4181
+ return result;
4182
+ };
4183
+
4184
+ /**
4185
+ * @param {DocumentFragment} templateContent
4186
+ * @returns {object}
4187
+ */
4188
+ const getSwalIcon = templateContent => {
4189
+ const result = {};
4190
+ /** @type {HTMLElement | null} */
4191
+ const icon = templateContent.querySelector('swal-icon');
4192
+ if (icon) {
4193
+ showWarningsForAttributes(icon, ['type', 'color']);
4194
+ if (icon.hasAttribute('type')) {
4195
+ result.icon = icon.getAttribute('type');
4196
+ }
4197
+ if (icon.hasAttribute('color')) {
4198
+ result.iconColor = icon.getAttribute('color');
4199
+ }
4200
+ result.iconHtml = icon.innerHTML;
4201
+ }
4202
+ return result;
4203
+ };
4204
+
4205
+ /**
4206
+ * @param {DocumentFragment} templateContent
4207
+ * @returns {object}
4208
+ */
4209
+ const getSwalInput = templateContent => {
4210
+ /** @type {Record<string, any>} */
4211
+ const result = {};
4212
+ /** @type {HTMLElement | null} */
4213
+ const input = templateContent.querySelector('swal-input');
4214
+ if (input) {
4215
+ showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
4216
+ result.input = input.getAttribute('type') || 'text';
4217
+ if (input.hasAttribute('label')) {
4218
+ result.inputLabel = input.getAttribute('label');
4219
+ }
4220
+ if (input.hasAttribute('placeholder')) {
4221
+ result.inputPlaceholder = input.getAttribute('placeholder');
4222
+ }
4223
+ if (input.hasAttribute('value')) {
4224
+ result.inputValue = input.getAttribute('value');
4225
+ }
4226
+ }
4227
+ /** @type {HTMLElement[]} */
4228
+ const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
4229
+ if (inputOptions.length) {
4230
+ result.inputOptions = {};
4231
+ inputOptions.forEach(option => {
4232
+ showWarningsForAttributes(option, ['value']);
4233
+ const optionValue = option.getAttribute('value');
4234
+ if (!optionValue) {
4235
+ return;
4236
+ }
4237
+ const optionName = option.innerHTML;
4238
+ result.inputOptions[optionValue] = optionName;
4239
+ });
4240
+ }
4241
+ return result;
4242
+ };
4243
+
4244
+ /**
4245
+ * @param {DocumentFragment} templateContent
4246
+ * @param {string[]} paramNames
4247
+ * @returns {Record<string, string>}
4248
+ */
4249
+ const getSwalStringParams = (templateContent, paramNames) => {
4250
+ /** @type {Record<string, string>} */
4251
+ const result = {};
4252
+ for (const i in paramNames) {
4253
+ const paramName = paramNames[i];
4254
+ /** @type {HTMLElement | null} */
4255
+ const tag = templateContent.querySelector(paramName);
4256
+ if (tag) {
4257
+ showWarningsForAttributes(tag, []);
4258
+ result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
4259
+ }
4260
+ }
4261
+ return result;
4262
+ };
4263
+
4264
+ /**
4265
+ * @param {DocumentFragment} templateContent
4266
+ */
4267
+ const showWarningsForElements = templateContent => {
4268
+ const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
4269
+ Array.from(templateContent.children).forEach(el => {
4270
+ const tagName = el.tagName.toLowerCase();
4271
+ if (!allowedElements.includes(tagName)) {
4272
+ warn(`Unrecognized element <${tagName}>`);
4273
+ }
4274
+ });
4275
+ };
4276
+
4277
+ /**
4278
+ * @param {HTMLElement} el
4279
+ * @param {string[]} allowedAttributes
4280
+ */
4281
+ const showWarningsForAttributes = (el, allowedAttributes) => {
4282
+ Array.from(el.attributes).forEach(attribute => {
4283
+ if (allowedAttributes.indexOf(attribute.name) === -1) {
4284
+ warn([`Unrecognized attribute "${attribute.name}" on <${el.tagName.toLowerCase()}>.`, `${allowedAttributes.length ? `Allowed attributes are: ${allowedAttributes.join(', ')}` : 'To set the value, use HTML within the element.'}`]);
4285
+ }
4286
+ });
4287
+ };
4288
+
4289
+ const SHOW_CLASS_TIMEOUT = 10;
4290
+
4291
+ /**
4292
+ * Open popup, add necessary classes and styles, fix scrollbar
4293
+ *
4294
+ * @param {SweetAlertOptions} params
4295
+ */
4296
+ const openPopup = params => {
4297
+ var _globalState$eventEmi, _globalState$eventEmi2;
4298
+ const container = getContainer();
4299
+ const popup = getPopup();
4300
+ if (!container || !popup) {
4301
+ return;
4302
+ }
4303
+ if (typeof params.willOpen === 'function') {
4304
+ params.willOpen(popup);
4305
+ }
4306
+ (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
4307
+ const bodyStyles = window.getComputedStyle(document.body);
4308
+ const initialBodyOverflow = bodyStyles.overflowY;
4309
+ addClasses(container, popup, params);
4310
+
4311
+ // scrolling is 'hidden' until animation is done, after that 'auto'
4312
+ setTimeout(() => {
4313
+ setScrollingVisibility(container, popup);
4314
+ }, SHOW_CLASS_TIMEOUT);
4315
+ if (isModal()) {
4316
+ fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
4317
+ setAriaHidden();
4318
+ }
4319
+
4320
+ // https://github.com/sweetalert2/sweetalert2/issues/2923
4321
+ if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
4322
+ // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
4323
+ container.style.pointerEvents = 'auto';
4324
+ }
4325
+ if (!isToast() && !globalState.previousActiveElement) {
4326
+ globalState.previousActiveElement = document.activeElement;
4327
+ }
4328
+ if (typeof params.didOpen === 'function') {
4329
+ const didOpen = params.didOpen;
4330
+ setTimeout(() => didOpen(popup));
4331
+ }
4332
+ (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
4333
+ };
4334
+
4335
+ /**
4336
+ * @param {Event} event
4337
+ */
4338
+ const swalOpenAnimationFinished = event => {
4339
+ const popup = getPopup();
4340
+ if (!popup || event.target !== popup) {
4341
+ return;
4342
+ }
4343
+ const container = getContainer();
4344
+ if (!container) {
4345
+ return;
4346
+ }
4347
+ popup.removeEventListener('animationend', swalOpenAnimationFinished);
4348
+ popup.removeEventListener('transitionend', swalOpenAnimationFinished);
4349
+ container.style.overflowY = 'auto';
4350
+
4351
+ // no-transition is added in init() in case one swal is opened right after another
4352
+ removeClass(container, swalClasses['no-transition']);
4353
+ };
4354
+
4355
+ /**
4356
+ * @param {HTMLElement} container
4357
+ * @param {HTMLElement} popup
4358
+ */
4359
+ const setScrollingVisibility = (container, popup) => {
4360
+ if (hasCssAnimation(popup)) {
4361
+ container.style.overflowY = 'hidden';
4362
+ popup.addEventListener('animationend', swalOpenAnimationFinished);
4363
+ popup.addEventListener('transitionend', swalOpenAnimationFinished);
4364
+ } else {
4365
+ container.style.overflowY = 'auto';
4366
+ }
4367
+ };
4368
+
4369
+ /**
4370
+ * @param {HTMLElement} container
4371
+ * @param {boolean} scrollbarPadding
4372
+ * @param {string} initialBodyOverflow
4373
+ */
4374
+ const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
4375
+ iOSfix();
4376
+ if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
4377
+ replaceScrollbarWithPadding(initialBodyOverflow);
4378
+ }
4379
+
4380
+ // sweetalert2/issues/1247
4381
+ setTimeout(() => {
4382
+ container.scrollTop = 0;
4383
+ });
4384
+ };
4385
+
4386
+ /**
4387
+ * @param {HTMLElement} container
4388
+ * @param {HTMLElement} popup
4389
+ * @param {SweetAlertOptions} params
4390
+ */
4391
+ const addClasses = (container, popup, params) => {
4392
+ var _params$showClass;
4393
+ if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
4394
+ addClass(container, params.showClass.backdrop);
4395
+ }
4396
+ if (params.animation) {
4397
+ // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
4398
+ popup.style.setProperty('opacity', '0', 'important');
4399
+ show(popup, 'grid');
4400
+ setTimeout(() => {
4401
+ var _params$showClass2;
4402
+ // Animate popup right after showing it
4403
+ if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
4404
+ addClass(popup, params.showClass.popup);
4405
+ }
4406
+ // and remove the opacity workaround
4407
+ popup.style.removeProperty('opacity');
4408
+ }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
4409
+ } else {
4410
+ show(popup, 'grid');
4411
+ }
4412
+ addClass([document.documentElement, document.body], swalClasses.shown);
4413
+ if (params.heightAuto && params.backdrop && !params.toast) {
4414
+ addClass([document.documentElement, document.body], swalClasses['height-auto']);
4415
+ }
4416
+ };
4417
+
4418
+ var defaultInputValidators = {
4419
+ /**
4420
+ * @param {string} string
4421
+ * @param {string} [validationMessage]
4422
+ * @returns {Promise<string | void>}
4423
+ */
4424
+ email: (string, validationMessage) => {
4425
+ return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
4426
+ },
4427
+ /**
4428
+ * @param {string} string
4429
+ * @param {string} [validationMessage]
4430
+ * @returns {Promise<string | void>}
4431
+ */
4432
+ url: (string, validationMessage) => {
4433
+ // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
4434
+ return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid URL');
4435
+ }
4436
+ };
4437
+
4438
+ /**
4439
+ * @param {SweetAlertOptions} params
4440
+ */
4441
+ function setDefaultInputValidators(params) {
4442
+ // Use default `inputValidator` for supported input types if not provided
4443
+ if (params.inputValidator) {
4444
+ return;
4445
+ }
4446
+ if (params.input === 'email') {
4447
+ params.inputValidator = defaultInputValidators['email'];
4448
+ }
4449
+ if (params.input === 'url') {
4450
+ params.inputValidator = defaultInputValidators['url'];
4451
+ }
4452
+ }
4453
+
4454
+ /**
4455
+ * @param {SweetAlertOptions} params
4456
+ */
4457
+ function validateCustomTargetElement(params) {
4458
+ // Determine if the custom target element is valid
4459
+ if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
4460
+ warn('Target parameter is not valid, defaulting to "body"');
4461
+ params.target = 'body';
4462
+ }
4463
+ }
4464
+
4465
+ /**
4466
+ * Set type, text and actions on popup
4467
+ *
4468
+ * @param {SweetAlertOptions} params
4469
+ */
4470
+ function setParameters(params) {
4471
+ setDefaultInputValidators(params);
4472
+
4473
+ // showLoaderOnConfirm && preConfirm
4474
+ if (params.showLoaderOnConfirm && !params.preConfirm) {
4475
+ warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request');
4476
+ }
4477
+ validateCustomTargetElement(params);
4478
+
4479
+ // Replace newlines with <br> in title
4480
+ if (typeof params.title === 'string') {
4481
+ params.title = params.title.split('\n').join('<br />');
4482
+ }
4483
+ init(params);
4484
+ }
4485
+
4486
+ /** @type {SweetAlert} */
4487
+ let currentInstance;
4488
+ var _promise = /*#__PURE__*/new WeakMap();
4489
+ class SweetAlert {
4490
+ /**
4491
+ * @param {...(SweetAlertOptions | string)} args
4492
+ * @this {SweetAlert}
4493
+ */
4494
+ constructor(...args) {
4495
+ /**
4496
+ * @type {Promise<SweetAlertResult>}
4497
+ */
4498
+ _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
4499
+ Promise.resolve({
4500
+ isConfirmed: false,
4501
+ isDenied: false,
4502
+ isDismissed: true
4503
+ }));
4504
+ // Prevent run in Node env
4505
+ if (typeof window === 'undefined') {
4506
+ return;
4507
+ }
4508
+ currentInstance = this;
4509
+
4510
+ // @ts-ignore
4511
+ const outerParams = Object.freeze(this.constructor.argsToParams(args));
4512
+
4513
+ /** @type {Readonly<SweetAlertOptions>} */
4514
+ this.params = outerParams;
4515
+
4516
+ /** @type {boolean} */
4517
+ this.isAwaitingPromise = false;
4518
+ _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
4519
+ }
4520
+
4521
+ /**
4522
+ * @param {any} userParams
4523
+ * @param {any} mixinParams
4524
+ */
4525
+ _main(userParams, mixinParams = {}) {
4526
+ showWarningsForParams(Object.assign({}, mixinParams, userParams));
4527
+ if (globalState.currentInstance) {
4528
+ const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
4529
+ const {
4530
+ isAwaitingPromise
4531
+ } = globalState.currentInstance;
4532
+ globalState.currentInstance._destroy();
4533
+ if (!isAwaitingPromise) {
4534
+ swalPromiseResolve({
4535
+ isDismissed: true
4536
+ });
4537
+ }
4538
+ if (isModal()) {
4539
+ unsetAriaHidden();
4540
+ }
4541
+ }
4542
+ globalState.currentInstance = currentInstance;
4543
+ const innerParams = prepareParams(userParams, mixinParams);
4544
+ setParameters(innerParams);
4545
+ Object.freeze(innerParams);
4546
+
4547
+ // clear the previous timer
4548
+ if (globalState.timeout) {
4549
+ globalState.timeout.stop();
4550
+ delete globalState.timeout;
4551
+ }
4552
+
4553
+ // clear the restore focus timeout
4554
+ clearTimeout(globalState.restoreFocusTimeout);
4555
+ const domCache = populateDomCache(currentInstance);
4556
+ render(currentInstance, innerParams);
4557
+ privateProps.innerParams.set(currentInstance, innerParams);
4558
+ return swalPromise(currentInstance, domCache, innerParams);
4559
+ }
4560
+
4561
+ // `catch` cannot be the name of a module export, so we define our thenable methods here instead
4562
+ /**
4563
+ * @param {any} onFulfilled
4564
+ */
4565
+ // oxlint-disable-next-line unicorn/no-thenable
4566
+ then(onFulfilled) {
4567
+ return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
4568
+ }
4569
+
4570
+ /**
4571
+ * @param {any} onFinally
4572
+ */
4573
+ finally(onFinally) {
4574
+ return _classPrivateFieldGet2(_promise, this).finally(onFinally);
4575
+ }
4576
+ }
4577
+
4578
+ /**
4579
+ * @param {SweetAlert} instance
4580
+ * @param {DomCache} domCache
4581
+ * @param {SweetAlertOptions} innerParams
4582
+ * @returns {Promise<SweetAlertResult>}
4583
+ */
4584
+ const swalPromise = (instance, domCache, innerParams) => {
4585
+ return new Promise((resolve, reject) => {
4586
+ // functions to handle all closings/dismissals
4587
+ /**
4588
+ * @param {DismissReason} dismiss
4589
+ */
4590
+ const dismissWith = dismiss => {
4591
+ instance.close({
4592
+ isDismissed: true,
4593
+ dismiss,
4594
+ isConfirmed: false,
4595
+ isDenied: false
4596
+ });
4597
+ };
4598
+ privateMethods.swalPromiseResolve.set(instance, resolve);
4599
+ privateMethods.swalPromiseReject.set(instance, reject);
4600
+ domCache.confirmButton.onclick = () => {
4601
+ handleConfirmButtonClick(instance);
4602
+ };
4603
+ domCache.denyButton.onclick = () => {
4604
+ handleDenyButtonClick(instance);
4605
+ };
4606
+ domCache.cancelButton.onclick = () => {
4607
+ handleCancelButtonClick(instance, dismissWith);
4608
+ };
4609
+ domCache.closeButton.onclick = () => {
4610
+ dismissWith(DismissReason.close);
4611
+ };
4612
+ handlePopupClick(innerParams, domCache, dismissWith);
4613
+ addKeydownHandler(globalState, innerParams, dismissWith);
4614
+ handleInputOptionsAndValue(instance, innerParams);
4615
+ openPopup(innerParams);
4616
+ setupTimer(globalState, innerParams, dismissWith);
4617
+ initFocus(domCache, innerParams);
4618
+
4619
+ // Scroll container to top on open (#1247, #1946)
4620
+ setTimeout(() => {
4621
+ domCache.container.scrollTop = 0;
4622
+ });
4623
+ });
4624
+ };
4625
+
4626
+ /**
4627
+ * @param {SweetAlertOptions} userParams
4628
+ * @param {SweetAlertOptions} mixinParams
4629
+ * @returns {SweetAlertOptions}
4630
+ */
4631
+ const prepareParams = (userParams, mixinParams) => {
4632
+ const templateParams = getTemplateParams(userParams);
4633
+ const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
4634
+ params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
4635
+ params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
4636
+ if (params.animation === false) {
4637
+ params.showClass = {
4638
+ backdrop: 'swal2-noanimation'
4639
+ };
4640
+ params.hideClass = {};
4641
+ }
4642
+ return params;
4643
+ };
4644
+
4645
+ /**
4646
+ * @param {SweetAlert} instance
4647
+ * @returns {DomCache}
4648
+ */
4649
+ const populateDomCache = instance => {
4650
+ const domCache = /** @type {DomCache} */{
4651
+ popup: (/** @type {HTMLElement} */getPopup()),
4652
+ container: (/** @type {HTMLElement} */getContainer()),
4653
+ actions: (/** @type {HTMLElement} */getActions()),
4654
+ confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
4655
+ denyButton: (/** @type {HTMLElement} */getDenyButton()),
4656
+ cancelButton: (/** @type {HTMLElement} */getCancelButton()),
4657
+ loader: (/** @type {HTMLElement} */getLoader()),
4658
+ closeButton: (/** @type {HTMLElement} */getCloseButton()),
4659
+ validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
4660
+ progressSteps: (/** @type {HTMLElement} */getProgressSteps())
4661
+ };
4662
+ privateProps.domCache.set(instance, domCache);
4663
+ return domCache;
4664
+ };
4665
+
4666
+ /**
4667
+ * @param {GlobalState} globalState
4668
+ * @param {SweetAlertOptions} innerParams
4669
+ * @param {(dismiss: DismissReason) => void} dismissWith
4670
+ */
4671
+ const setupTimer = (globalState, innerParams, dismissWith) => {
4672
+ const timerProgressBar = getTimerProgressBar();
4673
+ hide(timerProgressBar);
4674
+ if (innerParams.timer) {
4675
+ globalState.timeout = new Timer(() => {
4676
+ dismissWith('timer');
4677
+ delete globalState.timeout;
4678
+ }, innerParams.timer);
4679
+ if (innerParams.timerProgressBar && timerProgressBar) {
4680
+ show(timerProgressBar);
4681
+ applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
4682
+ setTimeout(() => {
4683
+ if (globalState.timeout && globalState.timeout.running) {
4684
+ // timer can be already stopped or unset at this point
4685
+ animateTimerProgressBar(/** @type {number} */innerParams.timer);
4686
+ }
4687
+ });
4688
+ }
4689
+ }
4690
+ };
4691
+
4692
+ /**
4693
+ * Initialize focus in the popup:
4694
+ *
4695
+ * 1. If `toast` is `true`, don't steal focus from the document.
4696
+ * 2. Else if there is an [autofocus] element, focus it.
4697
+ * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
4698
+ * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
4699
+ * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
4700
+ * 6. Else focus the first focusable element in a popup (if any).
4701
+ *
4702
+ * @param {DomCache} domCache
4703
+ * @param {SweetAlertOptions} innerParams
4704
+ */
4705
+ const initFocus = (domCache, innerParams) => {
4706
+ if (innerParams.toast) {
4707
+ return;
4708
+ }
4709
+ // TODO: this is dumb, remove `allowEnterKey` param in the next major version
4710
+ if (!callIfFunction(innerParams.allowEnterKey)) {
4711
+ warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
4712
+ domCache.popup.focus();
4713
+ return;
4714
+ }
4715
+ if (focusAutofocus(domCache)) {
4716
+ return;
4717
+ }
4718
+ if (focusButton(domCache, innerParams)) {
4719
+ return;
4720
+ }
4721
+ setFocus(-1, 1);
4722
+ };
4723
+
4724
+ /**
4725
+ * @param {DomCache} domCache
4726
+ * @returns {boolean}
4727
+ */
4728
+ const focusAutofocus = domCache => {
4729
+ const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
4730
+ for (const autofocusElement of autofocusElements) {
4731
+ if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
4732
+ autofocusElement.focus();
4733
+ return true;
4734
+ }
4735
+ }
4736
+ return false;
4737
+ };
4738
+
4739
+ /**
4740
+ * @param {DomCache} domCache
4741
+ * @param {SweetAlertOptions} innerParams
4742
+ * @returns {boolean}
4743
+ */
4744
+ const focusButton = (domCache, innerParams) => {
4745
+ if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
4746
+ domCache.denyButton.focus();
4747
+ return true;
4748
+ }
4749
+ if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
4750
+ domCache.cancelButton.focus();
4751
+ return true;
4752
+ }
4753
+ if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
4754
+ domCache.confirmButton.focus();
4755
+ return true;
4756
+ }
4757
+ return false;
4758
+ };
4759
+
4760
+ // Assign instance methods from src/instanceMethods/*.js to prototype
4761
+ SweetAlert.prototype.disableButtons = disableButtons;
4762
+ SweetAlert.prototype.enableButtons = enableButtons;
4763
+ SweetAlert.prototype.getInput = getInput;
4764
+ SweetAlert.prototype.disableInput = disableInput;
4765
+ SweetAlert.prototype.enableInput = enableInput;
4766
+ SweetAlert.prototype.hideLoading = hideLoading;
4767
+ SweetAlert.prototype.disableLoading = hideLoading;
4768
+ SweetAlert.prototype.showValidationMessage = showValidationMessage;
4769
+ SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
4770
+ SweetAlert.prototype.close = close;
4771
+ SweetAlert.prototype.closePopup = close;
4772
+ SweetAlert.prototype.closeModal = close;
4773
+ SweetAlert.prototype.closeToast = close;
4774
+ SweetAlert.prototype.rejectPromise = rejectPromise;
4775
+ SweetAlert.prototype.update = update;
4776
+ SweetAlert.prototype._destroy = _destroy;
4777
+
4778
+ // Assign static methods from src/staticMethods/*.js to constructor
4779
+ Object.assign(SweetAlert, staticMethods);
4780
+
4781
+ // Proxy to instance methods to constructor, for now, for backwards compatibility
4782
+ Object.keys(instanceMethods).forEach(key => {
4783
+ /**
4784
+ * @param {...(SweetAlertOptions | string | undefined)} args
4785
+ * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
4786
+ */
4787
+ // @ts-ignore: Dynamic property assignment for backwards compatibility
4788
+ SweetAlert[key] = function (...args) {
4789
+ // @ts-ignore
4790
+ if (currentInstance && currentInstance[key]) {
4791
+ // @ts-ignore
4792
+ return currentInstance[key](...args);
4793
+ }
4794
+ return undefined;
4795
+ };
4796
+ });
4797
+ SweetAlert.DismissReason = DismissReason;
4798
+ SweetAlert.version = '11.26.24';
4799
+
4800
+ const Swal = SweetAlert;
4801
+ // @ts-ignore
4802
+ Swal.default = Swal;
4803
+
4804
+ export { Swal as default };