PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.4
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.4, at assets/js/dist/admin/webhooks.js

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