PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.3
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.3
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / assets / js / dist / admin / webhooks.js

webhooks.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.3, at assets/js/dist/admin/webhooks.js

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