sweetalert2 11.7.4 → 11.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sweetalert2 v11.7.4
2
+ * sweetalert2 v11.7.6
3
3
  * Released under the MIT License.
4
4
  */
5
5
  (function (global, factory) {
@@ -8,6 +8,41 @@
8
8
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Sweetalert2 = factory());
9
9
  })(this, (function () { 'use strict';
10
10
 
11
+ const RESTORE_FOCUS_TIMEOUT = 100;
12
+
13
+ /** @type {GlobalState} */
14
+ const globalState = {};
15
+ const focusPreviousActiveElement = () => {
16
+ if (globalState.previousActiveElement instanceof HTMLElement) {
17
+ globalState.previousActiveElement.focus();
18
+ globalState.previousActiveElement = null;
19
+ } else if (document.body) {
20
+ document.body.focus();
21
+ }
22
+ };
23
+
24
+ /**
25
+ * Restore previous active (focused) element
26
+ *
27
+ * @param {boolean} returnFocus
28
+ * @returns {Promise}
29
+ */
30
+ const restoreActiveElement = returnFocus => {
31
+ return new Promise(resolve => {
32
+ if (!returnFocus) {
33
+ return resolve();
34
+ }
35
+ const x = window.scrollX;
36
+ const y = window.scrollY;
37
+ globalState.restoreFocusTimeout = setTimeout(() => {
38
+ focusPreviousActiveElement();
39
+ resolve();
40
+ }, RESTORE_FOCUS_TIMEOUT); // issues/900
41
+
42
+ window.scrollTo(x, y);
43
+ });
44
+ };
45
+
11
46
  /**
12
47
  * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
13
48
  * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
@@ -19,7 +54,6 @@
19
54
  */
20
55
 
21
56
  var privateProps = {
22
- awaitingPromise: new WeakMap(),
23
57
  promise: new WeakMap(),
24
58
  innerParams: new WeakMap(),
25
59
  domCache: new WeakMap()
@@ -597,41 +631,6 @@
597
631
  timerProgressBar.style.width = `${timerProgressBarPercent}%`;
598
632
  };
599
633
 
600
- const RESTORE_FOCUS_TIMEOUT = 100;
601
-
602
- /** @type {GlobalState} */
603
- const globalState = {};
604
- const focusPreviousActiveElement = () => {
605
- if (globalState.previousActiveElement instanceof HTMLElement) {
606
- globalState.previousActiveElement.focus();
607
- globalState.previousActiveElement = null;
608
- } else if (document.body) {
609
- document.body.focus();
610
- }
611
- };
612
-
613
- /**
614
- * Restore previous active (focused) element
615
- *
616
- * @param {boolean} returnFocus
617
- * @returns {Promise}
618
- */
619
- const restoreActiveElement = returnFocus => {
620
- return new Promise(resolve => {
621
- if (!returnFocus) {
622
- return resolve();
623
- }
624
- const x = window.scrollX;
625
- const y = window.scrollY;
626
- globalState.restoreFocusTimeout = setTimeout(() => {
627
- focusPreviousActiveElement();
628
- resolve();
629
- }, RESTORE_FOCUS_TIMEOUT); // issues/900
630
-
631
- window.scrollTo(x, y);
632
- });
633
- };
634
-
635
634
  /**
636
635
  * Detect Node env
637
636
  *
@@ -862,7 +861,7 @@
862
861
  };
863
862
 
864
863
  /**
865
- * @param {SweetAlert2} instance
864
+ * @param {SweetAlert} instance
866
865
  * @param {SweetAlertOptions} params
867
866
  */
868
867
  const renderActions = (instance, params) => {
@@ -959,7 +958,7 @@
959
958
  }
960
959
 
961
960
  /**
962
- * @param {SweetAlert2} instance
961
+ * @param {SweetAlert} instance
963
962
  * @param {SweetAlertOptions} params
964
963
  */
965
964
  const renderCloseButton = (instance, params) => {
@@ -973,7 +972,7 @@
973
972
  };
974
973
 
975
974
  /**
976
- * @param {SweetAlert2} instance
975
+ * @param {SweetAlert} instance
977
976
  * @param {SweetAlertOptions} params
978
977
  */
979
978
  const renderContainer = (instance, params) => {
@@ -1029,11 +1028,12 @@
1029
1028
 
1030
1029
  /// <reference path="../../../../sweetalert2.d.ts"/>
1031
1030
 
1031
+
1032
1032
  /** @type {InputClass[]} */
1033
1033
  const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
1034
1034
 
1035
1035
  /**
1036
- * @param {SweetAlert2} instance
1036
+ * @param {SweetAlert} instance
1037
1037
  * @param {SweetAlertOptions} params
1038
1038
  */
1039
1039
  const renderInput = (instance, params) => {
@@ -1292,7 +1292,7 @@
1292
1292
  };
1293
1293
 
1294
1294
  /**
1295
- * @param {SweetAlert2} instance
1295
+ * @param {SweetAlert} instance
1296
1296
  * @param {SweetAlertOptions} params
1297
1297
  */
1298
1298
  const renderContent = (instance, params) => {
@@ -1319,7 +1319,7 @@
1319
1319
  };
1320
1320
 
1321
1321
  /**
1322
- * @param {SweetAlert2} instance
1322
+ * @param {SweetAlert} instance
1323
1323
  * @param {SweetAlertOptions} params
1324
1324
  */
1325
1325
  const renderFooter = (instance, params) => {
@@ -1334,7 +1334,7 @@
1334
1334
  };
1335
1335
 
1336
1336
  /**
1337
- * @param {SweetAlert2} instance
1337
+ * @param {SweetAlert} instance
1338
1338
  * @param {SweetAlertOptions} params
1339
1339
  */
1340
1340
  const renderIcon = (instance, params) => {
@@ -1462,7 +1462,7 @@
1462
1462
  const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
1463
1463
 
1464
1464
  /**
1465
- * @param {SweetAlert2} instance
1465
+ * @param {SweetAlert} instance
1466
1466
  * @param {SweetAlertOptions} params
1467
1467
  */
1468
1468
  const renderImage = (instance, params) => {
@@ -1487,7 +1487,7 @@
1487
1487
  };
1488
1488
 
1489
1489
  /**
1490
- * @param {SweetAlert2} instance
1490
+ * @param {SweetAlert} instance
1491
1491
  * @param {SweetAlertOptions} params
1492
1492
  */
1493
1493
  const renderPopup = (instance, params) => {
@@ -1549,7 +1549,7 @@
1549
1549
  };
1550
1550
 
1551
1551
  /**
1552
- * @param {SweetAlert2} instance
1552
+ * @param {SweetAlert} instance
1553
1553
  * @param {SweetAlertOptions} params
1554
1554
  */
1555
1555
  const renderProgressSteps = (instance, params) => {
@@ -1601,7 +1601,7 @@
1601
1601
  };
1602
1602
 
1603
1603
  /**
1604
- * @param {SweetAlert2} instance
1604
+ * @param {SweetAlert} instance
1605
1605
  * @param {SweetAlertOptions} params
1606
1606
  */
1607
1607
  const renderTitle = (instance, params) => {
@@ -1619,7 +1619,7 @@
1619
1619
  };
1620
1620
 
1621
1621
  /**
1622
- * @param {SweetAlert2} instance
1622
+ * @param {SweetAlert} instance
1623
1623
  * @param {SweetAlertOptions} params
1624
1624
  */
1625
1625
  const render = (instance, params) => {
@@ -1638,55 +1638,6 @@
1638
1638
  }
1639
1639
  };
1640
1640
 
1641
- /**
1642
- * Hides loader and shows back the button which was hidden by .showLoading()
1643
- */
1644
- function hideLoading() {
1645
- // do nothing if popup is closed
1646
- const innerParams = privateProps.innerParams.get(this);
1647
- if (!innerParams) {
1648
- return;
1649
- }
1650
- const domCache = privateProps.domCache.get(this);
1651
- hide(domCache.loader);
1652
- if (isToast()) {
1653
- if (innerParams.icon) {
1654
- show(getIcon());
1655
- }
1656
- } else {
1657
- showRelatedButton(domCache);
1658
- }
1659
- removeClass([domCache.popup, domCache.actions], swalClasses.loading);
1660
- domCache.popup.removeAttribute('aria-busy');
1661
- domCache.popup.removeAttribute('data-loading');
1662
- domCache.confirmButton.disabled = false;
1663
- domCache.denyButton.disabled = false;
1664
- domCache.cancelButton.disabled = false;
1665
- }
1666
- const showRelatedButton = domCache => {
1667
- const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
1668
- if (buttonToReplace.length) {
1669
- show(buttonToReplace[0], 'inline-block');
1670
- } else if (allButtonsAreHidden()) {
1671
- hide(domCache.actions);
1672
- }
1673
- };
1674
-
1675
- /**
1676
- * Gets the input DOM node, this method works with input parameter.
1677
- *
1678
- * @param {SweetAlert2} instance
1679
- * @returns {HTMLElement | null}
1680
- */
1681
- function getInput(instance) {
1682
- const innerParams = privateProps.innerParams.get(instance || this);
1683
- const domCache = privateProps.domCache.get(instance || this);
1684
- if (!domCache) {
1685
- return null;
1686
- }
1687
- return getInput$1(domCache.popup, innerParams.input);
1688
- }
1689
-
1690
1641
  /*
1691
1642
  * Global function to determine if SweetAlert2 popup is shown
1692
1643
  */
@@ -1730,7 +1681,7 @@
1730
1681
  };
1731
1682
 
1732
1683
  /**
1733
- * @param {SweetAlert2} instance
1684
+ * @param {SweetAlert} instance
1734
1685
  * @param {GlobalState} globalState
1735
1686
  * @param {SweetAlertOptions} innerParams
1736
1687
  * @param {*} dismissWith
@@ -1776,7 +1727,7 @@
1776
1727
  const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
1777
1728
 
1778
1729
  /**
1779
- * @param {SweetAlert2} instance
1730
+ * @param {SweetAlert} instance
1780
1731
  * @param {KeyboardEvent} event
1781
1732
  * @param {Function} dismissWith
1782
1733
  */
@@ -1819,7 +1770,7 @@
1819
1770
  };
1820
1771
 
1821
1772
  /**
1822
- * @param {SweetAlert2} instance
1773
+ * @param {SweetAlert} instance
1823
1774
  * @param {KeyboardEvent} event
1824
1775
  * @param {SweetAlertOptions} innerParams
1825
1776
  */
@@ -2078,7 +2029,7 @@
2078
2029
  };
2079
2030
 
2080
2031
  /**
2081
- * @param {SweetAlert2} instance
2032
+ * @param {SweetAlert} instance
2082
2033
  * @param {HTMLElement} container
2083
2034
  * @param {boolean} returnFocus
2084
2035
  * @param {Function} didClose
@@ -2124,7 +2075,7 @@
2124
2075
  resolveValue = prepareResolveValue(resolveValue);
2125
2076
  const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
2126
2077
  const didClose = triggerClosePopup(this);
2127
- if (this.isAwaitingPromise()) {
2078
+ if (this.isAwaitingPromise) {
2128
2079
  // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
2129
2080
  if (!resolveValue.isDismissed) {
2130
2081
  handleAwaitingPromise(this);
@@ -2135,13 +2086,6 @@
2135
2086
  swalPromiseResolve(resolveValue);
2136
2087
  }
2137
2088
  }
2138
-
2139
- /**
2140
- * @returns {boolean}
2141
- */
2142
- function isAwaitingPromise() {
2143
- return !!privateProps.awaitingPromise.get(this);
2144
- }
2145
2089
  const triggerClosePopup = instance => {
2146
2090
  const popup = getPopup();
2147
2091
  if (!popup) {
@@ -2173,15 +2117,13 @@
2173
2117
  }
2174
2118
 
2175
2119
  /**
2176
- * @param {SweetAlert2} instance
2120
+ * @param {SweetAlert} instance
2177
2121
  */
2178
2122
  const handleAwaitingPromise = instance => {
2179
- // @ts-ignore
2180
- if (instance.isAwaitingPromise()) {
2181
- privateProps.awaitingPromise.delete(instance);
2123
+ if (instance.isAwaitingPromise) {
2124
+ delete instance.isAwaitingPromise;
2182
2125
  // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
2183
2126
  if (!privateProps.innerParams.get(instance)) {
2184
- // @ts-ignore
2185
2127
  instance._destroy();
2186
2128
  }
2187
2129
  }
@@ -2208,7 +2150,7 @@
2208
2150
  };
2209
2151
 
2210
2152
  /**
2211
- * @param {SweetAlert2} instance
2153
+ * @param {SweetAlert} instance
2212
2154
  * @param {HTMLElement} popup
2213
2155
  * @param {SweetAlertOptions} innerParams
2214
2156
  */
@@ -2228,7 +2170,7 @@
2228
2170
  };
2229
2171
 
2230
2172
  /**
2231
- * @param {SweetAlert2} instance
2173
+ * @param {SweetAlert} instance
2232
2174
  * @param {HTMLElement} popup
2233
2175
  * @param {HTMLElement} container
2234
2176
  * @param {boolean} returnFocus
@@ -2245,7 +2187,7 @@
2245
2187
  };
2246
2188
 
2247
2189
  /**
2248
- * @param {SweetAlert2} instance
2190
+ * @param {SweetAlert} instance
2249
2191
  * @param {Function} didClose
2250
2192
  */
2251
2193
  const triggerDidCloseAndDispose = (instance, didClose) => {
@@ -2254,804 +2196,885 @@
2254
2196
  // @ts-ignore
2255
2197
  didClose.bind(instance.params)();
2256
2198
  }
2257
- // @ts-ignore
2258
- instance._destroy();
2199
+ // instance might have been destroyed already
2200
+ if (instance._destroy) {
2201
+ instance._destroy();
2202
+ }
2259
2203
  });
2260
2204
  };
2261
2205
 
2262
2206
  /**
2263
- * @param {SweetAlert2} instance
2264
- * @param {string[]} buttons
2265
- * @param {boolean} disabled
2207
+ * Shows loader (spinner), this is useful with AJAX requests.
2208
+ * By default the loader be shown instead of the "Confirm" button.
2209
+ *
2210
+ * @param {HTMLButtonElement} [buttonToReplace]
2266
2211
  */
2267
- function setButtonsDisabled(instance, buttons, disabled) {
2268
- const domCache = privateProps.domCache.get(instance);
2269
- buttons.forEach(button => {
2270
- domCache[button].disabled = disabled;
2271
- });
2272
- }
2212
+ const showLoading = buttonToReplace => {
2213
+ let popup = getPopup();
2214
+ if (!popup) {
2215
+ new Swal(); // eslint-disable-line no-new
2216
+ }
2217
+
2218
+ popup = getPopup();
2219
+ const loader = getLoader();
2220
+ if (isToast()) {
2221
+ hide(getIcon());
2222
+ } else {
2223
+ replaceButton(popup, buttonToReplace);
2224
+ }
2225
+ show(loader);
2226
+ popup.setAttribute('data-loading', 'true');
2227
+ popup.setAttribute('aria-busy', 'true');
2228
+ popup.focus();
2229
+ };
2273
2230
 
2274
2231
  /**
2275
- * @param {HTMLInputElement} input
2276
- * @param {boolean} disabled
2232
+ * @param {HTMLElement} popup
2233
+ * @param {HTMLButtonElement} [buttonToReplace]
2277
2234
  */
2278
- function setInputDisabled(input, disabled) {
2279
- if (!input) {
2280
- return;
2235
+ const replaceButton = (popup, buttonToReplace) => {
2236
+ const actions = getActions();
2237
+ const loader = getLoader();
2238
+ if (!buttonToReplace && isVisible$1(getConfirmButton())) {
2239
+ buttonToReplace = getConfirmButton();
2281
2240
  }
2282
- if (input.type === 'radio') {
2283
- const radiosContainer = input.parentNode.parentNode;
2284
- const radios = radiosContainer.querySelectorAll('input');
2285
- for (let i = 0; i < radios.length; i++) {
2286
- radios[i].disabled = disabled;
2287
- }
2288
- } else {
2289
- input.disabled = disabled;
2241
+ show(actions);
2242
+ if (buttonToReplace) {
2243
+ hide(buttonToReplace);
2244
+ loader.setAttribute('data-button-to-replace', buttonToReplace.className);
2290
2245
  }
2291
- }
2292
- function enableButtons() {
2293
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
2294
- }
2295
- function disableButtons() {
2296
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
2297
- }
2298
- function enableInput() {
2299
- setInputDisabled(this.getInput(), false);
2300
- }
2301
- function disableInput() {
2302
- setInputDisabled(this.getInput(), true);
2303
- }
2246
+ loader.parentNode.insertBefore(loader, buttonToReplace);
2247
+ addClass([popup, actions], swalClasses.loading);
2248
+ };
2304
2249
 
2305
2250
  /**
2306
- * Show block with validation message
2307
- *
2308
- * @param {string} error
2251
+ * @typedef { string | number | boolean } InputValue
2309
2252
  */
2310
- function showValidationMessage(error) {
2311
- const domCache = privateProps.domCache.get(this);
2312
- const params = privateProps.innerParams.get(this);
2313
- setInnerHtml(domCache.validationMessage, error);
2314
- domCache.validationMessage.className = swalClasses['validation-message'];
2315
- if (params.customClass && params.customClass.validationMessage) {
2316
- addClass(domCache.validationMessage, params.customClass.validationMessage);
2317
- }
2318
- show(domCache.validationMessage);
2319
- const input = this.getInput();
2320
- if (input) {
2321
- input.setAttribute('aria-invalid', true);
2322
- input.setAttribute('aria-describedby', swalClasses['validation-message']);
2323
- focusInput(input);
2324
- addClass(input, swalClasses.inputerror);
2253
+
2254
+ /**
2255
+ * @param {SweetAlert} instance
2256
+ * @param {SweetAlertOptions} params
2257
+ */
2258
+ const handleInputOptionsAndValue = (instance, params) => {
2259
+ if (params.input === 'select' || params.input === 'radio') {
2260
+ handleInputOptions(instance, params);
2261
+ } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
2262
+ showLoading(getConfirmButton());
2263
+ handleInputValue(instance, params);
2325
2264
  }
2326
- }
2265
+ };
2327
2266
 
2328
2267
  /**
2329
- * Hide block with validation message
2268
+ * @param {SweetAlert} instance
2269
+ * @param {SweetAlertOptions} innerParams
2270
+ * @returns {string | number | File | FileList | null}
2330
2271
  */
2331
- function resetValidationMessage() {
2332
- const domCache = privateProps.domCache.get(this);
2333
- if (domCache.validationMessage) {
2334
- hide(domCache.validationMessage);
2272
+ const getInputValue = (instance, innerParams) => {
2273
+ const input = instance.getInput();
2274
+ if (!input) {
2275
+ return null;
2335
2276
  }
2336
- const input = this.getInput();
2337
- if (input) {
2338
- input.removeAttribute('aria-invalid');
2339
- input.removeAttribute('aria-describedby');
2340
- removeClass(input, swalClasses.inputerror);
2277
+ switch (innerParams.input) {
2278
+ case 'checkbox':
2279
+ return getCheckboxValue(input);
2280
+ case 'radio':
2281
+ return getRadioValue(input);
2282
+ case 'file':
2283
+ return getFileValue(input);
2284
+ default:
2285
+ return innerParams.inputAutoTrim ? input.value.trim() : input.value;
2341
2286
  }
2342
- }
2343
-
2344
- const defaultParams = {
2345
- title: '',
2346
- titleText: '',
2347
- text: '',
2348
- html: '',
2349
- footer: '',
2350
- icon: undefined,
2351
- iconColor: undefined,
2352
- iconHtml: undefined,
2353
- template: undefined,
2354
- toast: false,
2355
- showClass: {
2356
- popup: 'swal2-show',
2357
- backdrop: 'swal2-backdrop-show',
2358
- icon: 'swal2-icon-show'
2359
- },
2360
- hideClass: {
2361
- popup: 'swal2-hide',
2362
- backdrop: 'swal2-backdrop-hide',
2363
- icon: 'swal2-icon-hide'
2364
- },
2365
- customClass: {},
2366
- target: 'body',
2367
- color: undefined,
2368
- backdrop: true,
2369
- heightAuto: true,
2370
- allowOutsideClick: true,
2371
- allowEscapeKey: true,
2372
- allowEnterKey: true,
2373
- stopKeydownPropagation: true,
2374
- keydownListenerCapture: false,
2375
- showConfirmButton: true,
2376
- showDenyButton: false,
2377
- showCancelButton: false,
2378
- preConfirm: undefined,
2379
- preDeny: undefined,
2380
- confirmButtonText: 'OK',
2381
- confirmButtonAriaLabel: '',
2382
- confirmButtonColor: undefined,
2383
- denyButtonText: 'No',
2384
- denyButtonAriaLabel: '',
2385
- denyButtonColor: undefined,
2386
- cancelButtonText: 'Cancel',
2387
- cancelButtonAriaLabel: '',
2388
- cancelButtonColor: undefined,
2389
- buttonsStyling: true,
2390
- reverseButtons: false,
2391
- focusConfirm: true,
2392
- focusDeny: false,
2393
- focusCancel: false,
2394
- returnFocus: true,
2395
- showCloseButton: false,
2396
- closeButtonHtml: '&times;',
2397
- closeButtonAriaLabel: 'Close this dialog',
2398
- loaderHtml: '',
2399
- showLoaderOnConfirm: false,
2400
- showLoaderOnDeny: false,
2401
- imageUrl: undefined,
2402
- imageWidth: undefined,
2403
- imageHeight: undefined,
2404
- imageAlt: '',
2405
- timer: undefined,
2406
- timerProgressBar: false,
2407
- width: undefined,
2408
- padding: undefined,
2409
- background: undefined,
2410
- input: undefined,
2411
- inputPlaceholder: '',
2412
- inputLabel: '',
2413
- inputValue: '',
2414
- inputOptions: {},
2415
- inputAutoFocus: true,
2416
- inputAutoTrim: true,
2417
- inputAttributes: {},
2418
- inputValidator: undefined,
2419
- returnInputValueOnDeny: false,
2420
- validationMessage: undefined,
2421
- grow: false,
2422
- position: 'center',
2423
- progressSteps: [],
2424
- currentProgressStep: undefined,
2425
- progressStepsDistance: undefined,
2426
- willOpen: undefined,
2427
- didOpen: undefined,
2428
- didRender: undefined,
2429
- willClose: undefined,
2430
- didClose: undefined,
2431
- didDestroy: undefined,
2432
- scrollbarPadding: true
2433
- };
2434
- const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'willClose'];
2435
- const deprecatedParams = {};
2436
- const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
2287
+ };
2437
2288
 
2438
2289
  /**
2439
- * Is valid parameter
2440
- *
2441
- * @param {string} paramName
2442
- * @returns {boolean}
2290
+ * @param {HTMLInputElement} input
2291
+ * @returns {number}
2443
2292
  */
2444
- const isValidParameter = paramName => {
2445
- return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
2446
- };
2293
+ const getCheckboxValue = input => input.checked ? 1 : 0;
2447
2294
 
2448
2295
  /**
2449
- * Is valid parameter for Swal.update() method
2450
- *
2451
- * @param {string} paramName
2452
- * @returns {boolean}
2296
+ * @param {HTMLInputElement} input
2297
+ * @returns {string | null}
2453
2298
  */
2454
- const isUpdatableParameter = paramName => {
2455
- return updatableParams.indexOf(paramName) !== -1;
2456
- };
2299
+ const getRadioValue = input => input.checked ? input.value : null;
2457
2300
 
2458
2301
  /**
2459
- * Is deprecated parameter
2460
- *
2461
- * @param {string} paramName
2462
- * @returns {string | undefined}
2302
+ * @param {HTMLInputElement} input
2303
+ * @returns {FileList | File | null}
2463
2304
  */
2464
- const isDeprecatedParameter = paramName => {
2465
- return deprecatedParams[paramName];
2466
- };
2305
+ const getFileValue = input => input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
2467
2306
 
2468
2307
  /**
2469
- * @param {string} param
2308
+ * @param {SweetAlert} instance
2309
+ * @param {SweetAlertOptions} params
2470
2310
  */
2471
- const checkIfParamIsValid = param => {
2472
- if (!isValidParameter(param)) {
2473
- warn(`Unknown parameter "${param}"`);
2311
+ const handleInputOptions = (instance, params) => {
2312
+ const popup = getPopup();
2313
+ /**
2314
+ * @param {Record<string, any>} inputOptions
2315
+ */
2316
+ const processInputOptions = inputOptions => {
2317
+ populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params);
2318
+ };
2319
+ if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
2320
+ showLoading(getConfirmButton());
2321
+ asPromise(params.inputOptions).then(inputOptions => {
2322
+ instance.hideLoading();
2323
+ processInputOptions(inputOptions);
2324
+ });
2325
+ } else if (typeof params.inputOptions === 'object') {
2326
+ processInputOptions(params.inputOptions);
2327
+ } else {
2328
+ error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
2474
2329
  }
2475
2330
  };
2476
2331
 
2477
2332
  /**
2478
- * @param {string} param
2333
+ * @param {SweetAlert} instance
2334
+ * @param {SweetAlertOptions} params
2479
2335
  */
2480
- const checkIfToastParamIsValid = param => {
2481
- if (toastIncompatibleParams.includes(param)) {
2482
- warn(`The parameter "${param}" is incompatible with toasts`);
2483
- }
2336
+ const handleInputValue = (instance, params) => {
2337
+ const input = instance.getInput();
2338
+ hide(input);
2339
+ asPromise(params.inputValue).then(inputValue => {
2340
+ input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
2341
+ show(input);
2342
+ input.focus();
2343
+ instance.hideLoading();
2344
+ }).catch(err => {
2345
+ error(`Error in inputValue promise: ${err}`);
2346
+ input.value = '';
2347
+ show(input);
2348
+ input.focus();
2349
+ instance.hideLoading();
2350
+ });
2484
2351
  };
2485
-
2486
- /**
2487
- * @param {string} param
2488
- */
2489
- const checkIfParamIsDeprecated = param => {
2490
- if (isDeprecatedParameter(param)) {
2491
- warnAboutDeprecation(param, isDeprecatedParameter(param));
2352
+ const populateInputOptions = {
2353
+ /**
2354
+ * @param {HTMLElement} popup
2355
+ * @param {Record<string, any>} inputOptions
2356
+ * @param {SweetAlertOptions} params
2357
+ */
2358
+ select: (popup, inputOptions, params) => {
2359
+ const select = getDirectChildByClass(popup, swalClasses.select);
2360
+ /**
2361
+ * @param {HTMLElement} parent
2362
+ * @param {string} optionLabel
2363
+ * @param {string} optionValue
2364
+ */
2365
+ const renderOption = (parent, optionLabel, optionValue) => {
2366
+ const option = document.createElement('option');
2367
+ option.value = optionValue;
2368
+ setInnerHtml(option, optionLabel);
2369
+ option.selected = isSelected(optionValue, params.inputValue);
2370
+ parent.appendChild(option);
2371
+ };
2372
+ inputOptions.forEach(inputOption => {
2373
+ const optionValue = inputOption[0];
2374
+ const optionLabel = inputOption[1];
2375
+ // <optgroup> spec:
2376
+ // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
2377
+ // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
2378
+ // check whether this is a <optgroup>
2379
+ if (Array.isArray(optionLabel)) {
2380
+ // if it is an array, then it is an <optgroup>
2381
+ const optgroup = document.createElement('optgroup');
2382
+ optgroup.label = optionValue;
2383
+ optgroup.disabled = false; // not configurable for now
2384
+ select.appendChild(optgroup);
2385
+ optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
2386
+ } else {
2387
+ // case of <option>
2388
+ renderOption(select, optionLabel, optionValue);
2389
+ }
2390
+ });
2391
+ select.focus();
2392
+ },
2393
+ /**
2394
+ * @param {HTMLElement} popup
2395
+ * @param {Record<string, any>} inputOptions
2396
+ * @param {SweetAlertOptions} params
2397
+ */
2398
+ radio: (popup, inputOptions, params) => {
2399
+ const radio = getDirectChildByClass(popup, swalClasses.radio);
2400
+ inputOptions.forEach(inputOption => {
2401
+ const radioValue = inputOption[0];
2402
+ const radioLabel = inputOption[1];
2403
+ const radioInput = document.createElement('input');
2404
+ const radioLabelElement = document.createElement('label');
2405
+ radioInput.type = 'radio';
2406
+ radioInput.name = swalClasses.radio;
2407
+ radioInput.value = radioValue;
2408
+ if (isSelected(radioValue, params.inputValue)) {
2409
+ radioInput.checked = true;
2410
+ }
2411
+ const label = document.createElement('span');
2412
+ setInnerHtml(label, radioLabel);
2413
+ label.className = swalClasses.label;
2414
+ radioLabelElement.appendChild(radioInput);
2415
+ radioLabelElement.appendChild(label);
2416
+ radio.appendChild(radioLabelElement);
2417
+ });
2418
+ const radios = radio.querySelectorAll('input');
2419
+ if (radios.length) {
2420
+ radios[0].focus();
2421
+ }
2492
2422
  }
2493
2423
  };
2494
2424
 
2495
2425
  /**
2496
- * Show relevant warnings for given params
2426
+ * Converts `inputOptions` into an array of `[value, label]`s
2497
2427
  *
2498
- * @param {SweetAlertOptions} params
2428
+ * @param {Record<string, any>} inputOptions
2429
+ * @returns {Array<Array<string>>}
2499
2430
  */
2500
- const showWarningsForParams = params => {
2501
- if (params.backdrop === false && params.allowOutsideClick) {
2502
- warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
2503
- }
2504
- for (const param in params) {
2505
- checkIfParamIsValid(param);
2506
- if (params.toast) {
2507
- checkIfToastParamIsValid(param);
2508
- }
2509
- checkIfParamIsDeprecated(param);
2431
+ const formatInputOptions = inputOptions => {
2432
+ const result = [];
2433
+ if (typeof Map !== 'undefined' && inputOptions instanceof Map) {
2434
+ inputOptions.forEach((value, key) => {
2435
+ let valueFormatted = value;
2436
+ if (typeof valueFormatted === 'object') {
2437
+ // case of <optgroup>
2438
+ valueFormatted = formatInputOptions(valueFormatted);
2439
+ }
2440
+ result.push([key, valueFormatted]);
2441
+ });
2442
+ } else {
2443
+ Object.keys(inputOptions).forEach(key => {
2444
+ let valueFormatted = inputOptions[key];
2445
+ if (typeof valueFormatted === 'object') {
2446
+ // case of <optgroup>
2447
+ valueFormatted = formatInputOptions(valueFormatted);
2448
+ }
2449
+ result.push([key, valueFormatted]);
2450
+ });
2510
2451
  }
2452
+ return result;
2511
2453
  };
2512
2454
 
2513
2455
  /**
2514
- * Updates popup parameters.
2515
- *
2516
- * @param {SweetAlertOptions} params
2456
+ * @param {string} optionValue
2457
+ * @param {InputValue | Promise<InputValue> | { toPromise: () => InputValue }} inputValue
2458
+ * @returns {boolean}
2517
2459
  */
2518
- function update(params) {
2519
- const popup = getPopup();
2520
- const innerParams = privateProps.innerParams.get(this);
2521
- if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
2522
- 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.`);
2523
- return;
2524
- }
2525
- const validUpdatableParams = filterValidParams(params);
2526
- const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
2527
- render(this, updatedParams);
2528
- privateProps.innerParams.set(this, updatedParams);
2529
- Object.defineProperties(this, {
2530
- params: {
2531
- value: Object.assign({}, this.params, params),
2532
- writable: false,
2533
- enumerable: true
2534
- }
2535
- });
2536
- }
2460
+ const isSelected = (optionValue, inputValue) => {
2461
+ return inputValue && inputValue.toString() === optionValue.toString();
2462
+ };
2537
2463
 
2538
2464
  /**
2539
- * @param {SweetAlertOptions} params
2540
- * @returns {SweetAlertOptions}
2465
+ * @param {SweetAlert} instance
2541
2466
  */
2542
- const filterValidParams = params => {
2543
- const validUpdatableParams = {};
2544
- Object.keys(params).forEach(param => {
2545
- if (isUpdatableParameter(param)) {
2546
- validUpdatableParams[param] = params[param];
2547
- } else {
2548
- warn(`Invalid parameter to update: ${param}`);
2549
- }
2550
- });
2551
- return validUpdatableParams;
2467
+ const handleConfirmButtonClick = instance => {
2468
+ const innerParams = privateProps.innerParams.get(instance);
2469
+ instance.disableButtons();
2470
+ if (innerParams.input) {
2471
+ handleConfirmOrDenyWithInput(instance, 'confirm');
2472
+ } else {
2473
+ confirm(instance, true);
2474
+ }
2552
2475
  };
2553
2476
 
2554
2477
  /**
2555
- * Dispose the current SweetAlert2 instance
2478
+ * @param {SweetAlert} instance
2556
2479
  */
2557
- function _destroy() {
2558
- const domCache = privateProps.domCache.get(this);
2559
- const innerParams = privateProps.innerParams.get(this);
2560
- if (!innerParams) {
2561
- disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
2562
- return; // This instance has already been destroyed
2563
- }
2564
-
2565
- // Check if there is another Swal closing
2566
- if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
2567
- globalState.swalCloseEventFinishedCallback();
2568
- delete globalState.swalCloseEventFinishedCallback;
2569
- }
2570
- if (typeof innerParams.didDestroy === 'function') {
2571
- innerParams.didDestroy();
2480
+ const handleDenyButtonClick = instance => {
2481
+ const innerParams = privateProps.innerParams.get(instance);
2482
+ instance.disableButtons();
2483
+ if (innerParams.returnInputValueOnDeny) {
2484
+ handleConfirmOrDenyWithInput(instance, 'deny');
2485
+ } else {
2486
+ deny(instance, false);
2572
2487
  }
2573
- disposeSwal(this);
2574
- }
2488
+ };
2575
2489
 
2576
2490
  /**
2577
- * @param {SweetAlert2} instance
2491
+ * @param {SweetAlert} instance
2492
+ * @param {Function} dismissWith
2578
2493
  */
2579
- const disposeSwal = instance => {
2580
- disposeWeakMaps(instance);
2581
- // Unset this.params so GC will dispose it (#1569)
2582
- // @ts-ignore
2583
- delete instance.params;
2584
- // Unset globalState props so GC will dispose globalState (#1569)
2585
- delete globalState.keydownHandler;
2586
- delete globalState.keydownTarget;
2587
- // Unset currentInstance
2588
- delete globalState.currentInstance;
2494
+ const handleCancelButtonClick = (instance, dismissWith) => {
2495
+ instance.disableButtons();
2496
+ dismissWith(DismissReason.cancel);
2589
2497
  };
2590
2498
 
2591
2499
  /**
2592
- * @param {SweetAlert2} instance
2500
+ * @param {SweetAlert} instance
2501
+ * @param {'confirm' | 'deny'} type
2593
2502
  */
2594
- const disposeWeakMaps = instance => {
2595
- // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
2596
- // @ts-ignore
2597
- if (instance.isAwaitingPromise()) {
2598
- unsetWeakMaps(privateProps, instance);
2599
- privateProps.awaitingPromise.set(instance, true);
2503
+ const handleConfirmOrDenyWithInput = (instance, type) => {
2504
+ const innerParams = privateProps.innerParams.get(instance);
2505
+ if (!innerParams.input) {
2506
+ error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
2507
+ return;
2508
+ }
2509
+ const inputValue = getInputValue(instance, innerParams);
2510
+ if (innerParams.inputValidator) {
2511
+ handleInputValidator(instance, inputValue, type);
2512
+ } else if (!instance.getInput().checkValidity()) {
2513
+ instance.enableButtons();
2514
+ instance.showValidationMessage(innerParams.validationMessage);
2515
+ } else if (type === 'deny') {
2516
+ deny(instance, inputValue);
2600
2517
  } else {
2601
- unsetWeakMaps(privateMethods, instance);
2602
- unsetWeakMaps(privateProps, instance);
2518
+ confirm(instance, inputValue);
2603
2519
  }
2604
2520
  };
2605
2521
 
2606
2522
  /**
2607
- * @param {object} obj
2608
- * @param {SweetAlert2} instance
2523
+ * @param {SweetAlert} instance
2524
+ * @param {string | number | File | FileList | null} inputValue
2525
+ * @param {'confirm' | 'deny'} type
2609
2526
  */
2610
- const unsetWeakMaps = (obj, instance) => {
2611
- for (const i in obj) {
2612
- obj[i].delete(instance);
2613
- }
2527
+ const handleInputValidator = (instance, inputValue, type) => {
2528
+ const innerParams = privateProps.innerParams.get(instance);
2529
+ instance.disableInput();
2530
+ const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
2531
+ validationPromise.then(validationMessage => {
2532
+ instance.enableButtons();
2533
+ instance.enableInput();
2534
+ if (validationMessage) {
2535
+ instance.showValidationMessage(validationMessage);
2536
+ } else if (type === 'deny') {
2537
+ deny(instance, inputValue);
2538
+ } else {
2539
+ confirm(instance, inputValue);
2540
+ }
2541
+ });
2614
2542
  };
2615
2543
 
2616
- var instanceMethods = /*#__PURE__*/Object.freeze({
2617
- __proto__: null,
2618
- _destroy: _destroy,
2619
- close: close,
2620
- closeModal: close,
2621
- closePopup: close,
2622
- closeToast: close,
2623
- disableButtons: disableButtons,
2624
- disableInput: disableInput,
2625
- disableLoading: hideLoading,
2626
- enableButtons: enableButtons,
2627
- enableInput: enableInput,
2628
- getInput: getInput,
2629
- handleAwaitingPromise: handleAwaitingPromise,
2630
- hideLoading: hideLoading,
2631
- isAwaitingPromise: isAwaitingPromise,
2632
- rejectPromise: rejectPromise,
2633
- resetValidationMessage: resetValidationMessage,
2634
- showValidationMessage: showValidationMessage,
2635
- update: update
2636
- });
2637
-
2638
2544
  /**
2639
- * Shows loader (spinner), this is useful with AJAX requests.
2640
- * By default the loader be shown instead of the "Confirm" button.
2641
- *
2642
- * @param {HTMLButtonElement} [buttonToReplace]
2545
+ * @param {SweetAlert} instance
2546
+ * @param {any} value
2643
2547
  */
2644
- const showLoading = buttonToReplace => {
2645
- let popup = getPopup();
2646
- if (!popup) {
2647
- new Swal(); // eslint-disable-line no-new
2548
+ const deny = (instance, value) => {
2549
+ const innerParams = privateProps.innerParams.get(instance || undefined);
2550
+ if (innerParams.showLoaderOnDeny) {
2551
+ showLoading(getDenyButton());
2648
2552
  }
2649
-
2650
- popup = getPopup();
2651
- const loader = getLoader();
2652
- if (isToast()) {
2653
- hide(getIcon());
2553
+ if (innerParams.preDeny) {
2554
+ 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
2555
+ const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
2556
+ preDenyPromise.then(preDenyValue => {
2557
+ if (preDenyValue === false) {
2558
+ instance.hideLoading();
2559
+ handleAwaitingPromise(instance);
2560
+ } else {
2561
+ instance.close({
2562
+ isDenied: true,
2563
+ value: typeof preDenyValue === 'undefined' ? value : preDenyValue
2564
+ });
2565
+ }
2566
+ }).catch(error => rejectWith(instance || undefined, error));
2654
2567
  } else {
2655
- replaceButton(popup, buttonToReplace);
2568
+ instance.close({
2569
+ isDenied: true,
2570
+ value
2571
+ });
2656
2572
  }
2657
- show(loader);
2658
- popup.setAttribute('data-loading', 'true');
2659
- popup.setAttribute('aria-busy', 'true');
2660
- popup.focus();
2661
2573
  };
2662
2574
 
2663
2575
  /**
2664
- * @param {HTMLElement} popup
2665
- * @param {HTMLButtonElement} [buttonToReplace]
2576
+ * @param {SweetAlert} instance
2577
+ * @param {any} value
2666
2578
  */
2667
- const replaceButton = (popup, buttonToReplace) => {
2668
- const actions = getActions();
2669
- const loader = getLoader();
2670
- if (!buttonToReplace && isVisible$1(getConfirmButton())) {
2671
- buttonToReplace = getConfirmButton();
2672
- }
2673
- show(actions);
2674
- if (buttonToReplace) {
2675
- hide(buttonToReplace);
2676
- loader.setAttribute('data-button-to-replace', buttonToReplace.className);
2677
- }
2678
- loader.parentNode.insertBefore(loader, buttonToReplace);
2679
- addClass([popup, actions], swalClasses.loading);
2579
+ const succeedWith = (instance, value) => {
2580
+ instance.close({
2581
+ isConfirmed: true,
2582
+ value
2583
+ });
2680
2584
  };
2681
2585
 
2682
2586
  /**
2683
- * @typedef { string | number | boolean } InputValue
2587
+ *
2588
+ * @param {SweetAlert} instance
2589
+ * @param {string} error
2684
2590
  */
2591
+ const rejectWith = (instance, error) => {
2592
+ instance.rejectPromise(error);
2593
+ };
2685
2594
 
2686
2595
  /**
2687
- * @param {SweetAlert2} instance
2688
- * @param {SweetAlertOptions} params
2596
+ *
2597
+ * @param {SweetAlert} instance
2598
+ * @param {any} value
2689
2599
  */
2690
- const handleInputOptionsAndValue = (instance, params) => {
2691
- if (params.input === 'select' || params.input === 'radio') {
2692
- handleInputOptions(instance, params);
2693
- } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
2694
- showLoading(getConfirmButton());
2695
- handleInputValue(instance, params);
2600
+ const confirm = (instance, value) => {
2601
+ const innerParams = privateProps.innerParams.get(instance || undefined);
2602
+ if (innerParams.showLoaderOnConfirm) {
2603
+ showLoading();
2604
+ }
2605
+ if (innerParams.preConfirm) {
2606
+ instance.resetValidationMessage();
2607
+ 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
2608
+ const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
2609
+ preConfirmPromise.then(preConfirmValue => {
2610
+ if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
2611
+ instance.hideLoading();
2612
+ handleAwaitingPromise(instance);
2613
+ } else {
2614
+ succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
2615
+ }
2616
+ }).catch(error => rejectWith(instance || undefined, error));
2617
+ } else {
2618
+ succeedWith(instance, value);
2696
2619
  }
2697
2620
  };
2698
2621
 
2699
2622
  /**
2700
- * @param {SweetAlert2} instance
2701
- * @param {SweetAlertOptions} innerParams
2702
- * @returns {string | number | File | FileList | null}
2623
+ * Hides loader and shows back the button which was hidden by .showLoading()
2703
2624
  */
2704
- const getInputValue = (instance, innerParams) => {
2705
- const input = instance.getInput();
2706
- if (!input) {
2707
- return null;
2625
+ function hideLoading() {
2626
+ // do nothing if popup is closed
2627
+ const innerParams = privateProps.innerParams.get(this);
2628
+ if (!innerParams) {
2629
+ return;
2708
2630
  }
2709
- switch (innerParams.input) {
2710
- case 'checkbox':
2711
- return getCheckboxValue(input);
2712
- case 'radio':
2713
- return getRadioValue(input);
2714
- case 'file':
2715
- return getFileValue(input);
2716
- default:
2717
- return innerParams.inputAutoTrim ? input.value.trim() : input.value;
2631
+ const domCache = privateProps.domCache.get(this);
2632
+ hide(domCache.loader);
2633
+ if (isToast()) {
2634
+ if (innerParams.icon) {
2635
+ show(getIcon());
2636
+ }
2637
+ } else {
2638
+ showRelatedButton(domCache);
2639
+ }
2640
+ removeClass([domCache.popup, domCache.actions], swalClasses.loading);
2641
+ domCache.popup.removeAttribute('aria-busy');
2642
+ domCache.popup.removeAttribute('data-loading');
2643
+ domCache.confirmButton.disabled = false;
2644
+ domCache.denyButton.disabled = false;
2645
+ domCache.cancelButton.disabled = false;
2646
+ }
2647
+ const showRelatedButton = domCache => {
2648
+ const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
2649
+ if (buttonToReplace.length) {
2650
+ show(buttonToReplace[0], 'inline-block');
2651
+ } else if (allButtonsAreHidden()) {
2652
+ hide(domCache.actions);
2718
2653
  }
2719
2654
  };
2720
2655
 
2721
2656
  /**
2722
- * @param {HTMLInputElement} input
2723
- * @returns {number}
2657
+ * Gets the input DOM node, this method works with input parameter.
2658
+ *
2659
+ * @returns {HTMLInputElement | null}
2724
2660
  */
2725
- const getCheckboxValue = input => input.checked ? 1 : 0;
2661
+ function getInput() {
2662
+ const innerParams = privateProps.innerParams.get(this);
2663
+ const domCache = privateProps.domCache.get(this);
2664
+ if (!domCache) {
2665
+ return null;
2666
+ }
2667
+ return getInput$1(domCache.popup, innerParams.input);
2668
+ }
2726
2669
 
2727
2670
  /**
2728
- * @param {HTMLInputElement} input
2729
- * @returns {string | null}
2671
+ * @param {SweetAlert} instance
2672
+ * @param {string[]} buttons
2673
+ * @param {boolean} disabled
2730
2674
  */
2731
- const getRadioValue = input => input.checked ? input.value : null;
2675
+ function setButtonsDisabled(instance, buttons, disabled) {
2676
+ const domCache = privateProps.domCache.get(instance);
2677
+ buttons.forEach(button => {
2678
+ domCache[button].disabled = disabled;
2679
+ });
2680
+ }
2732
2681
 
2733
2682
  /**
2734
2683
  * @param {HTMLInputElement} input
2735
- * @returns {FileList | File | null}
2684
+ * @param {boolean} disabled
2736
2685
  */
2737
- const getFileValue = input => input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
2686
+ function setInputDisabled(input, disabled) {
2687
+ if (!input) {
2688
+ return;
2689
+ }
2690
+ if (input.type === 'radio') {
2691
+ const radiosContainer = input.parentNode.parentNode;
2692
+ const radios = radiosContainer.querySelectorAll('input');
2693
+ for (let i = 0; i < radios.length; i++) {
2694
+ radios[i].disabled = disabled;
2695
+ }
2696
+ } else {
2697
+ input.disabled = disabled;
2698
+ }
2699
+ }
2738
2700
 
2739
2701
  /**
2740
- * @param {SweetAlert2} instance
2741
- * @param {SweetAlertOptions} params
2702
+ * Enable all the buttons
2742
2703
  */
2743
- const handleInputOptions = (instance, params) => {
2744
- const popup = getPopup();
2745
- /**
2746
- * @param {Record<string, any>} inputOptions
2747
- */
2748
- const processInputOptions = inputOptions => {
2749
- populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params);
2750
- };
2751
- if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
2752
- showLoading(getConfirmButton());
2753
- asPromise(params.inputOptions).then(inputOptions => {
2754
- instance.hideLoading();
2755
- processInputOptions(inputOptions);
2756
- });
2757
- } else if (typeof params.inputOptions === 'object') {
2758
- processInputOptions(params.inputOptions);
2759
- } else {
2760
- error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
2761
- }
2762
- };
2704
+ function enableButtons() {
2705
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
2706
+ }
2763
2707
 
2764
2708
  /**
2765
- * @param {SweetAlert2} instance
2766
- * @param {SweetAlertOptions} params
2709
+ * Disable all the buttons
2767
2710
  */
2768
- const handleInputValue = (instance, params) => {
2769
- const input = instance.getInput();
2770
- hide(input);
2771
- asPromise(params.inputValue).then(inputValue => {
2772
- input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
2773
- show(input);
2774
- input.focus();
2775
- instance.hideLoading();
2776
- }).catch(err => {
2777
- error(`Error in inputValue promise: ${err}`);
2778
- input.value = '';
2779
- show(input);
2780
- input.focus();
2781
- instance.hideLoading();
2782
- });
2783
- };
2784
- const populateInputOptions = {
2785
- /**
2786
- * @param {HTMLElement} popup
2787
- * @param {Record<string, any>} inputOptions
2788
- * @param {SweetAlertOptions} params
2789
- */
2790
- select: (popup, inputOptions, params) => {
2791
- const select = getDirectChildByClass(popup, swalClasses.select);
2792
- /**
2793
- * @param {HTMLElement} parent
2794
- * @param {string} optionLabel
2795
- * @param {string} optionValue
2796
- */
2797
- const renderOption = (parent, optionLabel, optionValue) => {
2798
- const option = document.createElement('option');
2799
- option.value = optionValue;
2800
- setInnerHtml(option, optionLabel);
2801
- option.selected = isSelected(optionValue, params.inputValue);
2802
- parent.appendChild(option);
2803
- };
2804
- inputOptions.forEach(inputOption => {
2805
- const optionValue = inputOption[0];
2806
- const optionLabel = inputOption[1];
2807
- // <optgroup> spec:
2808
- // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
2809
- // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
2810
- // check whether this is a <optgroup>
2811
- if (Array.isArray(optionLabel)) {
2812
- // if it is an array, then it is an <optgroup>
2813
- const optgroup = document.createElement('optgroup');
2814
- optgroup.label = optionValue;
2815
- optgroup.disabled = false; // not configurable for now
2816
- select.appendChild(optgroup);
2817
- optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
2818
- } else {
2819
- // case of <option>
2820
- renderOption(select, optionLabel, optionValue);
2821
- }
2822
- });
2823
- select.focus();
2824
- },
2825
- /**
2826
- * @param {HTMLElement} popup
2827
- * @param {Record<string, any>} inputOptions
2828
- * @param {SweetAlertOptions} params
2829
- */
2830
- radio: (popup, inputOptions, params) => {
2831
- const radio = getDirectChildByClass(popup, swalClasses.radio);
2832
- inputOptions.forEach(inputOption => {
2833
- const radioValue = inputOption[0];
2834
- const radioLabel = inputOption[1];
2835
- const radioInput = document.createElement('input');
2836
- const radioLabelElement = document.createElement('label');
2837
- radioInput.type = 'radio';
2838
- radioInput.name = swalClasses.radio;
2839
- radioInput.value = radioValue;
2840
- if (isSelected(radioValue, params.inputValue)) {
2841
- radioInput.checked = true;
2842
- }
2843
- const label = document.createElement('span');
2844
- setInnerHtml(label, radioLabel);
2845
- label.className = swalClasses.label;
2846
- radioLabelElement.appendChild(radioInput);
2847
- radioLabelElement.appendChild(label);
2848
- radio.appendChild(radioLabelElement);
2849
- });
2850
- const radios = radio.querySelectorAll('input');
2851
- if (radios.length) {
2852
- radios[0].focus();
2853
- }
2854
- }
2855
- };
2711
+ function disableButtons() {
2712
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
2713
+ }
2856
2714
 
2857
2715
  /**
2858
- * Converts `inputOptions` into an array of `[value, label]`s
2716
+ * Enable the input field
2717
+ */
2718
+ function enableInput() {
2719
+ setInputDisabled(this.getInput(), false);
2720
+ }
2721
+
2722
+ /**
2723
+ * Disable the input field
2724
+ */
2725
+ function disableInput() {
2726
+ setInputDisabled(this.getInput(), true);
2727
+ }
2728
+
2729
+ /**
2730
+ * Show block with validation message
2859
2731
  *
2860
- * @param {Record<string, any>} inputOptions
2861
- * @returns {Array<Array<string>>}
2732
+ * @param {string} error
2862
2733
  */
2863
- const formatInputOptions = inputOptions => {
2864
- const result = [];
2865
- if (typeof Map !== 'undefined' && inputOptions instanceof Map) {
2866
- inputOptions.forEach((value, key) => {
2867
- let valueFormatted = value;
2868
- if (typeof valueFormatted === 'object') {
2869
- // case of <optgroup>
2870
- valueFormatted = formatInputOptions(valueFormatted);
2871
- }
2872
- result.push([key, valueFormatted]);
2873
- });
2874
- } else {
2875
- Object.keys(inputOptions).forEach(key => {
2876
- let valueFormatted = inputOptions[key];
2877
- if (typeof valueFormatted === 'object') {
2878
- // case of <optgroup>
2879
- valueFormatted = formatInputOptions(valueFormatted);
2880
- }
2881
- result.push([key, valueFormatted]);
2882
- });
2734
+ function showValidationMessage(error) {
2735
+ const domCache = privateProps.domCache.get(this);
2736
+ const params = privateProps.innerParams.get(this);
2737
+ setInnerHtml(domCache.validationMessage, error);
2738
+ domCache.validationMessage.className = swalClasses['validation-message'];
2739
+ if (params.customClass && params.customClass.validationMessage) {
2740
+ addClass(domCache.validationMessage, params.customClass.validationMessage);
2883
2741
  }
2884
- return result;
2742
+ show(domCache.validationMessage);
2743
+ const input = this.getInput();
2744
+ if (input) {
2745
+ input.setAttribute('aria-invalid', true);
2746
+ input.setAttribute('aria-describedby', swalClasses['validation-message']);
2747
+ focusInput(input);
2748
+ addClass(input, swalClasses.inputerror);
2749
+ }
2750
+ }
2751
+
2752
+ /**
2753
+ * Hide block with validation message
2754
+ */
2755
+ function resetValidationMessage() {
2756
+ const domCache = privateProps.domCache.get(this);
2757
+ if (domCache.validationMessage) {
2758
+ hide(domCache.validationMessage);
2759
+ }
2760
+ const input = this.getInput();
2761
+ if (input) {
2762
+ input.removeAttribute('aria-invalid');
2763
+ input.removeAttribute('aria-describedby');
2764
+ removeClass(input, swalClasses.inputerror);
2765
+ }
2766
+ }
2767
+
2768
+ const defaultParams = {
2769
+ title: '',
2770
+ titleText: '',
2771
+ text: '',
2772
+ html: '',
2773
+ footer: '',
2774
+ icon: undefined,
2775
+ iconColor: undefined,
2776
+ iconHtml: undefined,
2777
+ template: undefined,
2778
+ toast: false,
2779
+ showClass: {
2780
+ popup: 'swal2-show',
2781
+ backdrop: 'swal2-backdrop-show',
2782
+ icon: 'swal2-icon-show'
2783
+ },
2784
+ hideClass: {
2785
+ popup: 'swal2-hide',
2786
+ backdrop: 'swal2-backdrop-hide',
2787
+ icon: 'swal2-icon-hide'
2788
+ },
2789
+ customClass: {},
2790
+ target: 'body',
2791
+ color: undefined,
2792
+ backdrop: true,
2793
+ heightAuto: true,
2794
+ allowOutsideClick: true,
2795
+ allowEscapeKey: true,
2796
+ allowEnterKey: true,
2797
+ stopKeydownPropagation: true,
2798
+ keydownListenerCapture: false,
2799
+ showConfirmButton: true,
2800
+ showDenyButton: false,
2801
+ showCancelButton: false,
2802
+ preConfirm: undefined,
2803
+ preDeny: undefined,
2804
+ confirmButtonText: 'OK',
2805
+ confirmButtonAriaLabel: '',
2806
+ confirmButtonColor: undefined,
2807
+ denyButtonText: 'No',
2808
+ denyButtonAriaLabel: '',
2809
+ denyButtonColor: undefined,
2810
+ cancelButtonText: 'Cancel',
2811
+ cancelButtonAriaLabel: '',
2812
+ cancelButtonColor: undefined,
2813
+ buttonsStyling: true,
2814
+ reverseButtons: false,
2815
+ focusConfirm: true,
2816
+ focusDeny: false,
2817
+ focusCancel: false,
2818
+ returnFocus: true,
2819
+ showCloseButton: false,
2820
+ closeButtonHtml: '&times;',
2821
+ closeButtonAriaLabel: 'Close this dialog',
2822
+ loaderHtml: '',
2823
+ showLoaderOnConfirm: false,
2824
+ showLoaderOnDeny: false,
2825
+ imageUrl: undefined,
2826
+ imageWidth: undefined,
2827
+ imageHeight: undefined,
2828
+ imageAlt: '',
2829
+ timer: undefined,
2830
+ timerProgressBar: false,
2831
+ width: undefined,
2832
+ padding: undefined,
2833
+ background: undefined,
2834
+ input: undefined,
2835
+ inputPlaceholder: '',
2836
+ inputLabel: '',
2837
+ inputValue: '',
2838
+ inputOptions: {},
2839
+ inputAutoFocus: true,
2840
+ inputAutoTrim: true,
2841
+ inputAttributes: {},
2842
+ inputValidator: undefined,
2843
+ returnInputValueOnDeny: false,
2844
+ validationMessage: undefined,
2845
+ grow: false,
2846
+ position: 'center',
2847
+ progressSteps: [],
2848
+ currentProgressStep: undefined,
2849
+ progressStepsDistance: undefined,
2850
+ willOpen: undefined,
2851
+ didOpen: undefined,
2852
+ didRender: undefined,
2853
+ willClose: undefined,
2854
+ didClose: undefined,
2855
+ didDestroy: undefined,
2856
+ scrollbarPadding: true
2857
+ };
2858
+ const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'willClose'];
2859
+ const deprecatedParams = {};
2860
+ const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
2861
+
2862
+ /**
2863
+ * Is valid parameter
2864
+ *
2865
+ * @param {string} paramName
2866
+ * @returns {boolean}
2867
+ */
2868
+ const isValidParameter = paramName => {
2869
+ return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
2885
2870
  };
2886
2871
 
2887
2872
  /**
2888
- * @param {string} optionValue
2889
- * @param {InputValue | Promise<InputValue> | { toPromise: () => InputValue }} inputValue
2873
+ * Is valid parameter for Swal.update() method
2874
+ *
2875
+ * @param {string} paramName
2890
2876
  * @returns {boolean}
2891
2877
  */
2892
- const isSelected = (optionValue, inputValue) => {
2893
- return inputValue && inputValue.toString() === optionValue.toString();
2878
+ const isUpdatableParameter = paramName => {
2879
+ return updatableParams.indexOf(paramName) !== -1;
2894
2880
  };
2895
2881
 
2896
2882
  /**
2897
- * @param {SweetAlert2} instance
2883
+ * Is deprecated parameter
2884
+ *
2885
+ * @param {string} paramName
2886
+ * @returns {string | undefined}
2898
2887
  */
2899
- const handleConfirmButtonClick = instance => {
2900
- const innerParams = privateProps.innerParams.get(instance);
2901
- instance.disableButtons();
2902
- if (innerParams.input) {
2903
- handleConfirmOrDenyWithInput(instance, 'confirm');
2904
- } else {
2905
- confirm(instance, true);
2888
+ const isDeprecatedParameter = paramName => {
2889
+ return deprecatedParams[paramName];
2890
+ };
2891
+
2892
+ /**
2893
+ * @param {string} param
2894
+ */
2895
+ const checkIfParamIsValid = param => {
2896
+ if (!isValidParameter(param)) {
2897
+ warn(`Unknown parameter "${param}"`);
2906
2898
  }
2907
2899
  };
2908
2900
 
2909
2901
  /**
2910
- * @param {SweetAlert2} instance
2902
+ * @param {string} param
2911
2903
  */
2912
- const handleDenyButtonClick = instance => {
2913
- const innerParams = privateProps.innerParams.get(instance);
2914
- instance.disableButtons();
2915
- if (innerParams.returnInputValueOnDeny) {
2916
- handleConfirmOrDenyWithInput(instance, 'deny');
2917
- } else {
2918
- deny(instance, false);
2904
+ const checkIfToastParamIsValid = param => {
2905
+ if (toastIncompatibleParams.includes(param)) {
2906
+ warn(`The parameter "${param}" is incompatible with toasts`);
2919
2907
  }
2920
2908
  };
2921
2909
 
2922
2910
  /**
2923
- * @param {SweetAlert2} instance
2924
- * @param {Function} dismissWith
2911
+ * @param {string} param
2925
2912
  */
2926
- const handleCancelButtonClick = (instance, dismissWith) => {
2927
- instance.disableButtons();
2928
- dismissWith(DismissReason.cancel);
2913
+ const checkIfParamIsDeprecated = param => {
2914
+ if (isDeprecatedParameter(param)) {
2915
+ warnAboutDeprecation(param, isDeprecatedParameter(param));
2916
+ }
2929
2917
  };
2930
2918
 
2931
2919
  /**
2932
- * @param {SweetAlert2} instance
2933
- * @param {'confirm' | 'deny'} type
2920
+ * Show relevant warnings for given params
2921
+ *
2922
+ * @param {SweetAlertOptions} params
2934
2923
  */
2935
- const handleConfirmOrDenyWithInput = (instance, type) => {
2936
- const innerParams = privateProps.innerParams.get(instance);
2937
- if (!innerParams.input) {
2938
- error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
2939
- return;
2924
+ const showWarningsForParams = params => {
2925
+ if (params.backdrop === false && params.allowOutsideClick) {
2926
+ warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
2940
2927
  }
2941
- const inputValue = getInputValue(instance, innerParams);
2942
- if (innerParams.inputValidator) {
2943
- handleInputValidator(instance, inputValue, type);
2944
- } else if (!instance.getInput().checkValidity()) {
2945
- instance.enableButtons();
2946
- instance.showValidationMessage(innerParams.validationMessage);
2947
- } else if (type === 'deny') {
2948
- deny(instance, inputValue);
2949
- } else {
2950
- confirm(instance, inputValue);
2928
+ for (const param in params) {
2929
+ checkIfParamIsValid(param);
2930
+ if (params.toast) {
2931
+ checkIfToastParamIsValid(param);
2932
+ }
2933
+ checkIfParamIsDeprecated(param);
2951
2934
  }
2952
2935
  };
2953
2936
 
2954
2937
  /**
2955
- * @param {SweetAlert2} instance
2956
- * @param {string | number | File | FileList | null} inputValue
2957
- * @param {'confirm' | 'deny'} type
2938
+ * Updates popup parameters.
2939
+ *
2940
+ * @param {SweetAlertOptions} params
2958
2941
  */
2959
- const handleInputValidator = (instance, inputValue, type) => {
2960
- const innerParams = privateProps.innerParams.get(instance);
2961
- instance.disableInput();
2962
- const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
2963
- validationPromise.then(validationMessage => {
2964
- instance.enableButtons();
2965
- instance.enableInput();
2966
- if (validationMessage) {
2967
- instance.showValidationMessage(validationMessage);
2968
- } else if (type === 'deny') {
2969
- deny(instance, inputValue);
2942
+ function update(params) {
2943
+ const popup = getPopup();
2944
+ const innerParams = privateProps.innerParams.get(this);
2945
+ if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
2946
+ 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.`);
2947
+ return;
2948
+ }
2949
+ const validUpdatableParams = filterValidParams(params);
2950
+ const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
2951
+ render(this, updatedParams);
2952
+ privateProps.innerParams.set(this, updatedParams);
2953
+ Object.defineProperties(this, {
2954
+ params: {
2955
+ value: Object.assign({}, this.params, params),
2956
+ writable: false,
2957
+ enumerable: true
2958
+ }
2959
+ });
2960
+ }
2961
+
2962
+ /**
2963
+ * @param {SweetAlertOptions} params
2964
+ * @returns {SweetAlertOptions}
2965
+ */
2966
+ const filterValidParams = params => {
2967
+ const validUpdatableParams = {};
2968
+ Object.keys(params).forEach(param => {
2969
+ if (isUpdatableParameter(param)) {
2970
+ validUpdatableParams[param] = params[param];
2970
2971
  } else {
2971
- confirm(instance, inputValue);
2972
+ warn(`Invalid parameter to update: ${param}`);
2972
2973
  }
2973
2974
  });
2975
+ return validUpdatableParams;
2974
2976
  };
2975
2977
 
2976
2978
  /**
2977
- * @param {SweetAlert2} instance
2978
- * @param {any} value
2979
+ * Dispose the current SweetAlert2 instance
2979
2980
  */
2980
- const deny = (instance, value) => {
2981
- const innerParams = privateProps.innerParams.get(instance || undefined);
2982
- if (innerParams.showLoaderOnDeny) {
2983
- showLoading(getDenyButton());
2981
+ function _destroy() {
2982
+ const domCache = privateProps.domCache.get(this);
2983
+ const innerParams = privateProps.innerParams.get(this);
2984
+ if (!innerParams) {
2985
+ disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
2986
+ return; // This instance has already been destroyed
2984
2987
  }
2985
- if (innerParams.preDeny) {
2986
- privateProps.awaitingPromise.set(instance || undefined, 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
2987
- const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
2988
- preDenyPromise.then(preDenyValue => {
2989
- if (preDenyValue === false) {
2990
- instance.hideLoading();
2991
- handleAwaitingPromise(instance);
2992
- } else {
2993
- instance.close({
2994
- isDenied: true,
2995
- value: typeof preDenyValue === 'undefined' ? value : preDenyValue
2996
- });
2997
- }
2998
- }).catch(error => rejectWith(instance || undefined, error));
2999
- } else {
3000
- instance.close({
3001
- isDenied: true,
3002
- value
3003
- });
2988
+
2989
+ // Check if there is another Swal closing
2990
+ if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
2991
+ globalState.swalCloseEventFinishedCallback();
2992
+ delete globalState.swalCloseEventFinishedCallback;
3004
2993
  }
3005
- };
2994
+ if (typeof innerParams.didDestroy === 'function') {
2995
+ innerParams.didDestroy();
2996
+ }
2997
+ disposeSwal(this);
2998
+ }
3006
2999
 
3007
3000
  /**
3008
- * @param {SweetAlert2} instance
3009
- * @param {any} value
3001
+ * @param {SweetAlert} instance
3010
3002
  */
3011
- const succeedWith = (instance, value) => {
3012
- instance.close({
3013
- isConfirmed: true,
3014
- value
3015
- });
3003
+ const disposeSwal = instance => {
3004
+ disposeWeakMaps(instance);
3005
+ // Unset this.params so GC will dispose it (#1569)
3006
+ // @ts-ignore
3007
+ delete instance.params;
3008
+ // Unset globalState props so GC will dispose globalState (#1569)
3009
+ delete globalState.keydownHandler;
3010
+ delete globalState.keydownTarget;
3011
+ // Unset currentInstance
3012
+ delete globalState.currentInstance;
3016
3013
  };
3017
3014
 
3018
3015
  /**
3019
- *
3020
- * @param {SweetAlert2} instance
3021
- * @param {string} error
3016
+ * @param {SweetAlert} instance
3022
3017
  */
3023
- const rejectWith = (instance, error) => {
3024
- // @ts-ignore
3025
- instance.rejectPromise(error);
3018
+ const disposeWeakMaps = instance => {
3019
+ // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
3020
+ if (instance.isAwaitingPromise) {
3021
+ unsetWeakMaps(privateProps, instance);
3022
+ instance.isAwaitingPromise = true;
3023
+ } else {
3024
+ unsetWeakMaps(privateMethods, instance);
3025
+ unsetWeakMaps(privateProps, instance);
3026
+ delete instance.isAwaitingPromise;
3027
+ // Unset instance methods
3028
+ delete instance.disableButtons;
3029
+ delete instance.enableButtons;
3030
+ delete instance.getInput;
3031
+ delete instance.disableInput;
3032
+ delete instance.enableInput;
3033
+ delete instance.hideLoading;
3034
+ delete instance.disableLoading;
3035
+ delete instance.showValidationMessage;
3036
+ delete instance.resetValidationMessage;
3037
+ delete instance.close;
3038
+ delete instance.closePopup;
3039
+ delete instance.closeModal;
3040
+ delete instance.closeToast;
3041
+ delete instance.rejectPromise;
3042
+ delete instance.update;
3043
+ delete instance._destroy;
3044
+ }
3026
3045
  };
3027
3046
 
3028
3047
  /**
3029
- *
3030
- * @param {SweetAlert2} instance
3031
- * @param {any} value
3048
+ * @param {object} obj
3049
+ * @param {SweetAlert} instance
3032
3050
  */
3033
- const confirm = (instance, value) => {
3034
- const innerParams = privateProps.innerParams.get(instance || undefined);
3035
- if (innerParams.showLoaderOnConfirm) {
3036
- showLoading();
3037
- }
3038
- if (innerParams.preConfirm) {
3039
- instance.resetValidationMessage();
3040
- privateProps.awaitingPromise.set(instance || undefined, 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
3041
- const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
3042
- preConfirmPromise.then(preConfirmValue => {
3043
- if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
3044
- instance.hideLoading();
3045
- handleAwaitingPromise(instance);
3046
- } else {
3047
- succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
3048
- }
3049
- }).catch(error => rejectWith(instance || undefined, error));
3050
- } else {
3051
- succeedWith(instance, value);
3051
+ const unsetWeakMaps = (obj, instance) => {
3052
+ for (const i in obj) {
3053
+ obj[i].delete(instance);
3052
3054
  }
3053
3055
  };
3054
3056
 
3057
+ var instanceMethods = /*#__PURE__*/Object.freeze({
3058
+ __proto__: null,
3059
+ _destroy: _destroy,
3060
+ close: close,
3061
+ closeModal: close,
3062
+ closePopup: close,
3063
+ closeToast: close,
3064
+ disableButtons: disableButtons,
3065
+ disableInput: disableInput,
3066
+ disableLoading: hideLoading,
3067
+ enableButtons: enableButtons,
3068
+ enableInput: enableInput,
3069
+ getInput: getInput,
3070
+ handleAwaitingPromise: handleAwaitingPromise,
3071
+ hideLoading: hideLoading,
3072
+ rejectPromise: rejectPromise,
3073
+ resetValidationMessage: resetValidationMessage,
3074
+ showValidationMessage: showValidationMessage,
3075
+ update: update
3076
+ });
3077
+
3055
3078
  const handlePopupClick = (instance, domCache, dismissWith) => {
3056
3079
  const innerParams = privateProps.innerParams.get(instance);
3057
3080
  if (innerParams.toast) {
@@ -3170,7 +3193,8 @@
3170
3193
  * const {value: firstName} = await TextPrompt('What is your first name?')
3171
3194
  * const {value: lastName} = await TextPrompt('What is your last name?')
3172
3195
  *
3173
- * @param mixinParams
3196
+ * @param {SweetAlertOptions} mixinParams
3197
+ * @returns {SweetAlert}
3174
3198
  */
3175
3199
  function mixin(mixinParams) {
3176
3200
  class MixinSwal extends this {
@@ -3178,6 +3202,7 @@
3178
3202
  return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
3179
3203
  }
3180
3204
  }
3205
+ // @ts-ignore
3181
3206
  return MixinSwal;
3182
3207
  }
3183
3208
 
@@ -3753,8 +3778,13 @@
3753
3778
  init(params);
3754
3779
  }
3755
3780
 
3781
+ /** @type {SweetAlert} */
3756
3782
  let currentInstance;
3757
3783
  class SweetAlert {
3784
+ /**
3785
+ * @param {...any} args
3786
+ * @this {SweetAlert}
3787
+ */
3758
3788
  constructor() {
3759
3789
  // Prevent run in Node env
3760
3790
  if (typeof window === 'undefined') {
@@ -3776,6 +3806,9 @@
3776
3806
  }
3777
3807
  });
3778
3808
 
3809
+ /** @type {boolean} */
3810
+ this.isAwaitingPromise = false;
3811
+
3779
3812
  // @ts-ignore
3780
3813
  const promise = currentInstance._main(currentInstance.params);
3781
3814
  privateProps.promise.set(this, promise);
@@ -3784,7 +3817,6 @@
3784
3817
  let mixinParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3785
3818
  showWarningsForParams(Object.assign({}, mixinParams, userParams));
3786
3819
  if (globalState.currentInstance) {
3787
- // @ts-ignore
3788
3820
  globalState.currentInstance._destroy();
3789
3821
  if (isModal()) {
3790
3822
  unsetAriaHidden();
@@ -3808,6 +3840,22 @@
3808
3840
  privateProps.innerParams.set(currentInstance, innerParams);
3809
3841
  return swalPromise(currentInstance, domCache, innerParams);
3810
3842
  }
3843
+ disableButtons = disableButtons;
3844
+ enableButtons = enableButtons;
3845
+ getInput = getInput;
3846
+ disableInput = disableInput;
3847
+ enableInput = enableInput;
3848
+ hideLoading = hideLoading;
3849
+ disableLoading = hideLoading;
3850
+ showValidationMessage = showValidationMessage;
3851
+ resetValidationMessage = resetValidationMessage;
3852
+ close = close;
3853
+ closePopup = close;
3854
+ closeModal = close;
3855
+ closeToast = close;
3856
+ rejectPromise = rejectPromise;
3857
+ update = update;
3858
+ _destroy = _destroy;
3811
3859
 
3812
3860
  // `catch` cannot be the name of a module export, so we define our thenable methods here instead
3813
3861
  then(onFulfilled) {
@@ -3821,7 +3869,7 @@
3821
3869
  }
3822
3870
 
3823
3871
  /**
3824
- * @param {SweetAlert2} instance
3872
+ * @param {SweetAlert} instance
3825
3873
  * @param {DomCache} domCache
3826
3874
  * @param {SweetAlertOptions} innerParams
3827
3875
  * @returns {Promise}
@@ -3833,7 +3881,6 @@
3833
3881
  * @param {DismissReason} dismiss
3834
3882
  */
3835
3883
  const dismissWith = dismiss => {
3836
- // @ts-ignore
3837
3884
  instance.close({
3838
3885
  isDismissed: true,
3839
3886
  dismiss
@@ -3882,7 +3929,7 @@
3882
3929
  };
3883
3930
 
3884
3931
  /**
3885
- * @param {SweetAlert2} instance
3932
+ * @param {SweetAlert} instance
3886
3933
  * @returns {DomCache}
3887
3934
  */
3888
3935
  const populateDomCache = instance => {
@@ -3993,9 +4040,6 @@
3993
4040
  }
3994
4041
  }
3995
4042
 
3996
- // Assign instance methods from src/instanceMethods/*.js to prototype
3997
- Object.assign(SweetAlert.prototype, instanceMethods);
3998
-
3999
4043
  // Assign static methods from src/staticMethods/*.js to constructor
4000
4044
  Object.assign(SweetAlert, staticMethods);
4001
4045
 
@@ -4006,13 +4050,14 @@
4006
4050
  * @returns {any | undefined}
4007
4051
  */
4008
4052
  SweetAlert[key] = function () {
4009
- if (currentInstance) {
4053
+ if (currentInstance && currentInstance[key]) {
4010
4054
  return currentInstance[key](...arguments);
4011
4055
  }
4056
+ return null;
4012
4057
  };
4013
4058
  });
4014
4059
  SweetAlert.DismissReason = DismissReason;
4015
- SweetAlert.version = '11.7.4';
4060
+ SweetAlert.version = '11.7.6';
4016
4061
 
4017
4062
  const Swal = SweetAlert;
4018
4063
  // @ts-ignore