sweetalert2 11.4.28 → 11.4.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +10 -3
  2. package/dist/sweetalert2.all.js +1595 -1574
  3. package/dist/sweetalert2.all.min.js +2 -2
  4. package/dist/sweetalert2.css +1 -0
  5. package/dist/sweetalert2.js +1594 -1573
  6. package/dist/sweetalert2.min.css +1 -1
  7. package/dist/sweetalert2.min.js +1 -1
  8. package/package.json +9 -9
  9. package/src/SweetAlert.js +16 -16
  10. package/src/buttons-handlers.js +5 -5
  11. package/src/instanceMethods/_destroy.js +1 -1
  12. package/src/instanceMethods/close.js +7 -7
  13. package/src/instanceMethods/getInput.js +1 -1
  14. package/src/instanceMethods/hideLoading.js +2 -2
  15. package/src/instanceMethods/update.js +1 -1
  16. package/src/instanceMethods/validation-message.js +2 -2
  17. package/src/keydown-handler.js +3 -3
  18. package/src/popup-click-handler.js +2 -2
  19. package/src/scss/_toasts.scss +1 -0
  20. package/src/staticMethods/dom.js +1 -1
  21. package/src/staticMethods/showLoading.js +1 -1
  22. package/src/staticMethods/timer.js +1 -1
  23. package/src/types.js +21 -19
  24. package/src/utils/Timer.js +4 -0
  25. package/src/utils/dom/domUtils.js +1 -1
  26. package/src/utils/dom/init.js +3 -3
  27. package/src/utils/dom/inputUtils.js +3 -3
  28. package/src/utils/dom/renderers/render.js +2 -2
  29. package/src/utils/dom/renderers/renderContainer.js +1 -1
  30. package/src/utils/dom/renderers/renderIcon.js +2 -2
  31. package/src/utils/dom/renderers/renderInput.js +2 -3
  32. package/src/utils/dom/renderers/renderProgressSteps.js +1 -1
  33. package/src/utils/getTemplateParams.js +16 -1
  34. package/src/utils/iosFix.js +1 -1
  35. package/src/utils/openPopup.js +4 -4
  36. package/src/utils/setParameters.js +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sweetalert2 v11.4.28
2
+ * sweetalert2 v11.4.31
3
3
  * Released under the MIT License.
4
4
  */
5
5
  (function (global, factory) {
@@ -8,6 +8,40 @@
8
8
  (global = global || self, global.Sweetalert2 = factory());
9
9
  }(this, function () { 'use strict';
10
10
 
11
+ /**
12
+ * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
13
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
14
+ * This is the approach that Babel will probably take to implement private methods/fields
15
+ * https://github.com/tc39/proposal-private-methods
16
+ * https://github.com/babel/babel/pull/7555
17
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
18
+ * then we can use that language feature.
19
+ */
20
+ var privateProps = {
21
+ awaitingPromise: new WeakMap(),
22
+ promise: new WeakMap(),
23
+ innerParams: new WeakMap(),
24
+ domCache: new WeakMap()
25
+ };
26
+
27
+ const swalPrefix = 'swal2-';
28
+ /**
29
+ * @param {string[]} items
30
+ * @returns {object}
31
+ */
32
+
33
+ const prefix = items => {
34
+ const result = {};
35
+
36
+ for (const i in items) {
37
+ result[items[i]] = swalPrefix + items[i];
38
+ }
39
+
40
+ return result;
41
+ };
42
+ const swalClasses = prefix(['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'default-outline', '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', 'no-war']);
43
+ const iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']);
44
+
11
45
  const consolePrefix = 'SweetAlert2:';
12
46
  /**
13
47
  * Filter the unique values into a new array
@@ -117,198 +151,6 @@
117
151
 
118
152
  const getRandomElement = arr => arr[Math.floor(Math.random() * arr.length)];
119
153
 
120
- const defaultParams = {
121
- title: '',
122
- titleText: '',
123
- text: '',
124
- html: '',
125
- footer: '',
126
- icon: undefined,
127
- iconColor: undefined,
128
- iconHtml: undefined,
129
- template: undefined,
130
- toast: false,
131
- showClass: {
132
- popup: 'swal2-show',
133
- backdrop: 'swal2-backdrop-show',
134
- icon: 'swal2-icon-show'
135
- },
136
- hideClass: {
137
- popup: 'swal2-hide',
138
- backdrop: 'swal2-backdrop-hide',
139
- icon: 'swal2-icon-hide'
140
- },
141
- customClass: {},
142
- target: 'body',
143
- color: undefined,
144
- backdrop: true,
145
- heightAuto: true,
146
- allowOutsideClick: true,
147
- allowEscapeKey: true,
148
- allowEnterKey: true,
149
- stopKeydownPropagation: true,
150
- keydownListenerCapture: false,
151
- showConfirmButton: true,
152
- showDenyButton: false,
153
- showCancelButton: false,
154
- preConfirm: undefined,
155
- preDeny: undefined,
156
- confirmButtonText: 'OK',
157
- confirmButtonAriaLabel: '',
158
- confirmButtonColor: undefined,
159
- denyButtonText: 'No',
160
- denyButtonAriaLabel: '',
161
- denyButtonColor: undefined,
162
- cancelButtonText: 'Cancel',
163
- cancelButtonAriaLabel: '',
164
- cancelButtonColor: undefined,
165
- buttonsStyling: true,
166
- reverseButtons: false,
167
- focusConfirm: true,
168
- focusDeny: false,
169
- focusCancel: false,
170
- returnFocus: true,
171
- showCloseButton: false,
172
- closeButtonHtml: '×',
173
- closeButtonAriaLabel: 'Close this dialog',
174
- loaderHtml: '',
175
- showLoaderOnConfirm: false,
176
- showLoaderOnDeny: false,
177
- imageUrl: undefined,
178
- imageWidth: undefined,
179
- imageHeight: undefined,
180
- imageAlt: '',
181
- timer: undefined,
182
- timerProgressBar: false,
183
- width: undefined,
184
- padding: undefined,
185
- background: undefined,
186
- input: undefined,
187
- inputPlaceholder: '',
188
- inputLabel: '',
189
- inputValue: '',
190
- inputOptions: {},
191
- inputAutoTrim: true,
192
- inputAttributes: {},
193
- inputValidator: undefined,
194
- returnInputValueOnDeny: false,
195
- validationMessage: undefined,
196
- grow: false,
197
- position: 'center',
198
- progressSteps: [],
199
- currentProgressStep: undefined,
200
- progressStepsDistance: undefined,
201
- willOpen: undefined,
202
- didOpen: undefined,
203
- didRender: undefined,
204
- willClose: undefined,
205
- didClose: undefined,
206
- didDestroy: undefined,
207
- scrollbarPadding: true
208
- };
209
- 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'];
210
- const deprecatedParams = {};
211
- const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
212
- /**
213
- * Is valid parameter
214
- *
215
- * @param {string} paramName
216
- * @returns {boolean}
217
- */
218
-
219
- const isValidParameter = paramName => {
220
- return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
221
- };
222
- /**
223
- * Is valid parameter for Swal.update() method
224
- *
225
- * @param {string} paramName
226
- * @returns {boolean}
227
- */
228
-
229
- const isUpdatableParameter = paramName => {
230
- return updatableParams.indexOf(paramName) !== -1;
231
- };
232
- /**
233
- * Is deprecated parameter
234
- *
235
- * @param {string} paramName
236
- * @returns {string | undefined}
237
- */
238
-
239
- const isDeprecatedParameter = paramName => {
240
- return deprecatedParams[paramName];
241
- };
242
- /**
243
- * @param {string} param
244
- */
245
-
246
- const checkIfParamIsValid = param => {
247
- if (!isValidParameter(param)) {
248
- warn("Unknown parameter \"".concat(param, "\""));
249
- }
250
- };
251
- /**
252
- * @param {string} param
253
- */
254
-
255
-
256
- const checkIfToastParamIsValid = param => {
257
- if (toastIncompatibleParams.includes(param)) {
258
- warn("The parameter \"".concat(param, "\" is incompatible with toasts"));
259
- }
260
- };
261
- /**
262
- * @param {string} param
263
- */
264
-
265
-
266
- const checkIfParamIsDeprecated = param => {
267
- if (isDeprecatedParameter(param)) {
268
- warnAboutDeprecation(param, isDeprecatedParameter(param));
269
- }
270
- };
271
- /**
272
- * Show relevant warnings for given params
273
- *
274
- * @param {SweetAlertOptions} params
275
- */
276
-
277
-
278
- const showWarningsForParams = params => {
279
- if (!params.backdrop && params.allowOutsideClick) {
280
- warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
281
- }
282
-
283
- for (const param in params) {
284
- checkIfParamIsValid(param);
285
-
286
- if (params.toast) {
287
- checkIfToastParamIsValid(param);
288
- }
289
-
290
- checkIfParamIsDeprecated(param);
291
- }
292
- };
293
-
294
- const swalPrefix = 'swal2-';
295
- /**
296
- * @param {string[]} items
297
- * @returns {object}
298
- */
299
-
300
- const prefix = items => {
301
- const result = {};
302
-
303
- for (const i in items) {
304
- result[items[i]] = swalPrefix + items[i];
305
- }
306
-
307
- return result;
308
- };
309
- const swalClasses = prefix(['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'default-outline', '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', 'no-war']);
310
- const iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']);
311
-
312
154
  /**
313
155
  * Gets the popup container which contains the backdrop and the popup itself.
314
156
  *
@@ -760,13 +602,6 @@
760
602
  timerProgressBar.style.width = "".concat(timerProgressBarPercent, "%");
761
603
  };
762
604
 
763
- /**
764
- * Detect Node env
765
- *
766
- * @returns {boolean}
767
- */
768
- const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
769
-
770
605
  const RESTORE_FOCUS_TIMEOUT = 100;
771
606
 
772
607
  /** @type {GlobalState} */
@@ -806,6 +641,13 @@
806
641
  });
807
642
  };
808
643
 
644
+ /**
645
+ * Detect Node env
646
+ *
647
+ * @returns {boolean}
648
+ */
649
+ const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
650
+
809
651
  const sweetHTML = "\n <div aria-labelledby=\"".concat(swalClasses.title, "\" aria-describedby=\"").concat(swalClasses['html-container'], "\" class=\"").concat(swalClasses.popup, "\" tabindex=\"-1\">\n <button type=\"button\" class=\"").concat(swalClasses.close, "\"></button>\n <ul class=\"").concat(swalClasses['progress-steps'], "\"></ul>\n <div class=\"").concat(swalClasses.icon, "\"></div>\n <img class=\"").concat(swalClasses.image, "\" />\n <h2 class=\"").concat(swalClasses.title, "\" id=\"").concat(swalClasses.title, "\"></h2>\n <div class=\"").concat(swalClasses['html-container'], "\" id=\"").concat(swalClasses['html-container'], "\"></div>\n <input class=\"").concat(swalClasses.input, "\" />\n <input type=\"file\" class=\"").concat(swalClasses.file, "\" />\n <div class=\"").concat(swalClasses.range, "\">\n <input type=\"range\" />\n <output></output>\n </div>\n <select class=\"").concat(swalClasses.select, "\"></select>\n <div class=\"").concat(swalClasses.radio, "\"></div>\n <label for=\"").concat(swalClasses.checkbox, "\" class=\"").concat(swalClasses.checkbox, "\">\n <input type=\"checkbox\" />\n <span class=\"").concat(swalClasses.label, "\"></span>\n </label>\n <textarea class=\"").concat(swalClasses.textarea, "\"></textarea>\n <div class=\"").concat(swalClasses['validation-message'], "\" id=\"").concat(swalClasses['validation-message'], "\"></div>\n <div class=\"").concat(swalClasses.actions, "\">\n <div class=\"").concat(swalClasses.loader, "\"></div>\n <button type=\"button\" class=\"").concat(swalClasses.confirm, "\"></button>\n <button type=\"button\" class=\"").concat(swalClasses.deny, "\"></button>\n <button type=\"button\" class=\"").concat(swalClasses.cancel, "\"></button>\n </div>\n <div class=\"").concat(swalClasses.footer, "\"></div>\n <div class=\"").concat(swalClasses['timer-progress-bar-container'], "\">\n <div class=\"").concat(swalClasses['timer-progress-bar'], "\"></div>\n </div>\n </div>\n").replace(/(^|\n)\s*/g, '');
810
652
  /**
811
653
  * @returns {boolean}
@@ -1114,6 +956,20 @@
1114
956
  addClass(button, params["".concat(buttonType, "ButtonClass")]);
1115
957
  }
1116
958
 
959
+ /**
960
+ * @param {SweetAlert2} instance
961
+ * @param {SweetAlertOptions} params
962
+ */
963
+
964
+ const renderCloseButton = (instance, params) => {
965
+ const closeButton = getCloseButton();
966
+ setInnerHtml(closeButton, params.closeButtonHtml); // Custom class
967
+
968
+ applyCustomClass(closeButton, params, 'closeButton');
969
+ toggle(closeButton, params.showCloseButton);
970
+ closeButton.setAttribute('aria-label', params.closeButtonAriaLabel);
971
+ };
972
+
1117
973
  /**
1118
974
  * @param {SweetAlert2} instance
1119
975
  * @param {SweetAlertOptions} params
@@ -1174,22 +1030,6 @@
1174
1030
  }
1175
1031
  }
1176
1032
 
1177
- /**
1178
- * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
1179
- * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
1180
- * This is the approach that Babel will probably take to implement private methods/fields
1181
- * https://github.com/tc39/proposal-private-methods
1182
- * https://github.com/babel/babel/pull/7555
1183
- * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
1184
- * then we can use that language feature.
1185
- */
1186
- var privateProps = {
1187
- awaitingPromise: new WeakMap(),
1188
- promise: new WeakMap(),
1189
- innerParams: new WeakMap(),
1190
- domCache: new WeakMap()
1191
- };
1192
-
1193
1033
  /// <reference path="../../../../sweetalert2.d.ts"/>
1194
1034
  /** @type {InputClass[]} */
1195
1035
 
@@ -1519,20 +1359,6 @@
1519
1359
  applyCustomClass(footer, params, 'footer');
1520
1360
  };
1521
1361
 
1522
- /**
1523
- * @param {SweetAlert2} instance
1524
- * @param {SweetAlertOptions} params
1525
- */
1526
-
1527
- const renderCloseButton = (instance, params) => {
1528
- const closeButton = getCloseButton();
1529
- setInnerHtml(closeButton, params.closeButtonHtml); // Custom class
1530
-
1531
- applyCustomClass(closeButton, params, 'closeButton');
1532
- toggle(closeButton, params.showCloseButton);
1533
- closeButton.setAttribute('aria-label', params.closeButtonAriaLabel);
1534
- };
1535
-
1536
1362
  /**
1537
1363
  * @param {SweetAlert2} instance
1538
1364
  * @param {SweetAlertOptions} params
@@ -1684,6 +1510,69 @@
1684
1510
  applyCustomClass(image, params, 'image');
1685
1511
  };
1686
1512
 
1513
+ /**
1514
+ * @param {SweetAlert2} instance
1515
+ * @param {SweetAlertOptions} params
1516
+ */
1517
+
1518
+ const renderPopup = (instance, params) => {
1519
+ const container = getContainer();
1520
+ const popup = getPopup(); // Width
1521
+ // https://github.com/sweetalert2/sweetalert2/issues/2170
1522
+
1523
+ if (params.toast) {
1524
+ applyNumericalStyle(container, 'width', params.width);
1525
+ popup.style.width = '100%';
1526
+ popup.insertBefore(getLoader(), getIcon());
1527
+ } else {
1528
+ applyNumericalStyle(popup, 'width', params.width);
1529
+ } // Padding
1530
+
1531
+
1532
+ applyNumericalStyle(popup, 'padding', params.padding); // Color
1533
+
1534
+ if (params.color) {
1535
+ popup.style.color = params.color;
1536
+ } // Background
1537
+
1538
+
1539
+ if (params.background) {
1540
+ popup.style.background = params.background;
1541
+ }
1542
+
1543
+ hide(getValidationMessage()); // Classes
1544
+
1545
+ addClasses(popup, params);
1546
+ };
1547
+ /**
1548
+ * @param {HTMLElement} popup
1549
+ * @param {SweetAlertOptions} params
1550
+ */
1551
+
1552
+ const addClasses = (popup, params) => {
1553
+ // Default Class + showClass when updating Swal.update({})
1554
+ popup.className = "".concat(swalClasses.popup, " ").concat(isVisible(popup) ? params.showClass.popup : '');
1555
+
1556
+ if (params.toast) {
1557
+ addClass([document.documentElement, document.body], swalClasses['toast-shown']);
1558
+ addClass(popup, swalClasses.toast);
1559
+ } else {
1560
+ addClass(popup, swalClasses.modal);
1561
+ } // Custom class
1562
+
1563
+
1564
+ applyCustomClass(popup, params, 'popup');
1565
+
1566
+ if (typeof params.customClass === 'string') {
1567
+ addClass(popup, params.customClass);
1568
+ } // Icon class (#1842)
1569
+
1570
+
1571
+ if (params.icon) {
1572
+ addClass(popup, swalClasses["icon-".concat(params.icon)]);
1573
+ }
1574
+ };
1575
+
1687
1576
  /**
1688
1577
  * @param {SweetAlert2} instance
1689
1578
  * @param {SweetAlertOptions} params
@@ -1771,85 +1660,102 @@
1771
1660
  * @param {SweetAlertOptions} params
1772
1661
  */
1773
1662
 
1774
- const renderPopup = (instance, params) => {
1775
- const container = getContainer();
1776
- const popup = getPopup(); // Width
1777
- // https://github.com/sweetalert2/sweetalert2/issues/2170
1663
+ const render = (instance, params) => {
1664
+ renderPopup(instance, params);
1665
+ renderContainer(instance, params);
1666
+ renderProgressSteps(instance, params);
1667
+ renderIcon(instance, params);
1668
+ renderImage(instance, params);
1669
+ renderTitle(instance, params);
1670
+ renderCloseButton(instance, params);
1671
+ renderContent(instance, params);
1672
+ renderActions(instance, params);
1673
+ renderFooter(instance, params);
1778
1674
 
1779
- if (params.toast) {
1780
- applyNumericalStyle(container, 'width', params.width);
1781
- popup.style.width = '100%';
1782
- popup.insertBefore(getLoader(), getIcon());
1783
- } else {
1784
- applyNumericalStyle(popup, 'width', params.width);
1785
- } // Padding
1675
+ if (typeof params.didRender === 'function') {
1676
+ params.didRender(getPopup());
1677
+ }
1678
+ };
1786
1679
 
1680
+ /**
1681
+ * Hides loader and shows back the button which was hidden by .showLoading()
1682
+ */
1787
1683
 
1788
- applyNumericalStyle(popup, 'padding', params.padding); // Color
1684
+ function hideLoading() {
1685
+ // do nothing if popup is closed
1686
+ const innerParams = privateProps.innerParams.get(this);
1789
1687
 
1790
- if (params.color) {
1791
- popup.style.color = params.color;
1792
- } // Background
1688
+ if (!innerParams) {
1689
+ return;
1690
+ }
1793
1691
 
1692
+ const domCache = privateProps.domCache.get(this);
1693
+ hide(domCache.loader);
1794
1694
 
1795
- if (params.background) {
1796
- popup.style.background = params.background;
1695
+ if (isToast()) {
1696
+ if (innerParams.icon) {
1697
+ show(getIcon());
1698
+ }
1699
+ } else {
1700
+ showRelatedButton(domCache);
1797
1701
  }
1798
1702
 
1799
- hide(getValidationMessage()); // Classes
1703
+ removeClass([domCache.popup, domCache.actions], swalClasses.loading);
1704
+ domCache.popup.removeAttribute('aria-busy');
1705
+ domCache.popup.removeAttribute('data-loading');
1706
+ domCache.confirmButton.disabled = false;
1707
+ domCache.denyButton.disabled = false;
1708
+ domCache.cancelButton.disabled = false;
1709
+ }
1800
1710
 
1801
- addClasses(popup, params);
1711
+ const showRelatedButton = domCache => {
1712
+ const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
1713
+
1714
+ if (buttonToReplace.length) {
1715
+ show(buttonToReplace[0], 'inline-block');
1716
+ } else if (allButtonsAreHidden()) {
1717
+ hide(domCache.actions);
1718
+ }
1802
1719
  };
1720
+
1803
1721
  /**
1804
- * @param {HTMLElement} popup
1805
- * @param {SweetAlertOptions} params
1722
+ * Gets the input DOM node, this method works with input parameter.
1723
+ * @returns {HTMLElement | null}
1806
1724
  */
1807
1725
 
1808
- const addClasses = (popup, params) => {
1809
- // Default Class + showClass when updating Swal.update({})
1810
- popup.className = "".concat(swalClasses.popup, " ").concat(isVisible(popup) ? params.showClass.popup : '');
1811
-
1812
- if (params.toast) {
1813
- addClass([document.documentElement, document.body], swalClasses['toast-shown']);
1814
- addClass(popup, swalClasses.toast);
1815
- } else {
1816
- addClass(popup, swalClasses.modal);
1817
- } // Custom class
1818
-
1726
+ function getInput$1(instance) {
1727
+ const innerParams = privateProps.innerParams.get(instance || this);
1728
+ const domCache = privateProps.domCache.get(instance || this);
1819
1729
 
1820
- applyCustomClass(popup, params, 'popup');
1730
+ if (!domCache) {
1731
+ return null;
1732
+ }
1821
1733
 
1822
- if (typeof params.customClass === 'string') {
1823
- addClass(popup, params.customClass);
1824
- } // Icon class (#1842)
1734
+ return getInput(domCache.popup, innerParams.input);
1735
+ }
1825
1736
 
1737
+ /*
1738
+ * Global function to determine if SweetAlert2 popup is shown
1739
+ */
1826
1740
 
1827
- if (params.icon) {
1828
- addClass(popup, swalClasses["icon-".concat(params.icon)]);
1829
- }
1741
+ const isVisible$1 = () => {
1742
+ return isVisible(getPopup());
1830
1743
  };
1744
+ /*
1745
+ * Global function to click 'Confirm' button
1746
+ */
1831
1747
 
1832
- /**
1833
- * @param {SweetAlert2} instance
1834
- * @param {SweetAlertOptions} params
1748
+ const clickConfirm = () => getConfirmButton() && getConfirmButton().click();
1749
+ /*
1750
+ * Global function to click 'Deny' button
1835
1751
  */
1836
1752
 
1837
- const render = (instance, params) => {
1838
- renderPopup(instance, params);
1839
- renderContainer(instance, params);
1840
- renderProgressSteps(instance, params);
1841
- renderIcon(instance, params);
1842
- renderImage(instance, params);
1843
- renderTitle(instance, params);
1844
- renderCloseButton(instance, params);
1845
- renderContent(instance, params);
1846
- renderActions(instance, params);
1847
- renderFooter(instance, params);
1753
+ const clickDeny = () => getDenyButton() && getDenyButton().click();
1754
+ /*
1755
+ * Global function to click 'Cancel' button
1756
+ */
1848
1757
 
1849
- if (typeof params.didRender === 'function') {
1850
- params.didRender(getPopup());
1851
- }
1852
- };
1758
+ const clickCancel = () => getCancelButton() && getCancelButton().click();
1853
1759
 
1854
1760
  const DismissReason = Object.freeze({
1855
1761
  cancel: 'cancel',
@@ -1859,404 +1765,244 @@
1859
1765
  timer: 'timer'
1860
1766
  });
1861
1767
 
1862
- // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
1863
- // elements not within the active modal dialog will not be surfaced if a user opens a screen
1864
- // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
1768
+ /**
1769
+ * @param {GlobalState} globalState
1770
+ */
1865
1771
 
1866
- const setAriaHidden = () => {
1867
- const bodyChildren = Array.from(document.body.children);
1868
- bodyChildren.forEach(el => {
1869
- if (el === getContainer() || el.contains(getContainer())) {
1870
- return;
1871
- }
1772
+ const removeKeydownHandler = globalState => {
1773
+ if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
1774
+ globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
1775
+ capture: globalState.keydownListenerCapture
1776
+ });
1777
+ globalState.keydownHandlerAdded = false;
1778
+ }
1779
+ };
1780
+ /**
1781
+ * @param {SweetAlert2} instance
1782
+ * @param {GlobalState} globalState
1783
+ * @param {SweetAlertOptions} innerParams
1784
+ * @param {*} dismissWith
1785
+ */
1872
1786
 
1873
- if (el.hasAttribute('aria-hidden')) {
1874
- el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden'));
1875
- }
1787
+ const addKeydownHandler = (instance, globalState, innerParams, dismissWith) => {
1788
+ removeKeydownHandler(globalState);
1876
1789
 
1877
- el.setAttribute('aria-hidden', 'true');
1878
- });
1879
- };
1880
- const unsetAriaHidden = () => {
1881
- const bodyChildren = Array.from(document.body.children);
1882
- bodyChildren.forEach(el => {
1883
- if (el.hasAttribute('data-previous-aria-hidden')) {
1884
- el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden'));
1885
- el.removeAttribute('data-previous-aria-hidden');
1886
- } else {
1887
- el.removeAttribute('aria-hidden');
1888
- }
1889
- });
1890
- };
1891
-
1892
- const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
1893
- const getTemplateParams = params => {
1894
- const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template;
1790
+ if (!innerParams.toast) {
1791
+ globalState.keydownHandler = e => keydownHandler(instance, e, dismissWith);
1895
1792
 
1896
- if (!template) {
1897
- return {};
1793
+ globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup();
1794
+ globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
1795
+ globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, {
1796
+ capture: globalState.keydownListenerCapture
1797
+ });
1798
+ globalState.keydownHandlerAdded = true;
1898
1799
  }
1899
- /** @type {DocumentFragment} */
1900
-
1901
-
1902
- const templateContent = template.content;
1903
- showWarningsForElements(templateContent);
1904
- const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
1905
- return result;
1906
1800
  };
1907
1801
  /**
1908
- * @param {DocumentFragment} templateContent
1802
+ * @param {SweetAlertOptions} innerParams
1803
+ * @param {number} index
1804
+ * @param {number} increment
1909
1805
  */
1910
1806
 
1911
- const getSwalParams = templateContent => {
1912
- const result = {};
1913
- /** @type {HTMLElement[]} */
1807
+ const setFocus = (innerParams, index, increment) => {
1808
+ const focusableElements = getFocusableElements(); // search for visible elements and select the next possible match
1914
1809
 
1915
- const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
1916
- swalParams.forEach(param => {
1917
- showWarningsForAttributes(param, ['name', 'value']);
1918
- const paramName = param.getAttribute('name');
1919
- const value = param.getAttribute('value');
1810
+ if (focusableElements.length) {
1811
+ index = index + increment; // rollover to first item
1920
1812
 
1921
- if (typeof defaultParams[paramName] === 'boolean' && value === 'false') {
1922
- result[paramName] = false;
1813
+ if (index === focusableElements.length) {
1814
+ index = 0; // go to last item
1815
+ } else if (index === -1) {
1816
+ index = focusableElements.length - 1;
1923
1817
  }
1924
1818
 
1925
- if (typeof defaultParams[paramName] === 'object') {
1926
- result[paramName] = JSON.parse(value);
1927
- }
1928
- });
1929
- return result;
1819
+ return focusableElements[index].focus();
1820
+ } // no visible focusable elements, focus the popup
1821
+
1822
+
1823
+ getPopup().focus();
1930
1824
  };
1825
+ const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
1826
+ const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
1931
1827
  /**
1932
- * @param {DocumentFragment} templateContent
1828
+ * @param {SweetAlert2} instance
1829
+ * @param {KeyboardEvent} e
1830
+ * @param {function} dismissWith
1933
1831
  */
1934
1832
 
1833
+ const keydownHandler = (instance, e, dismissWith) => {
1834
+ const innerParams = privateProps.innerParams.get(instance);
1935
1835
 
1936
- const getSwalButtons = templateContent => {
1937
- const result = {};
1938
- /** @type {HTMLElement[]} */
1836
+ if (!innerParams) {
1837
+ return; // This instance has already been destroyed
1838
+ } // Ignore keydown during IME composition
1839
+ // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
1840
+ // https://github.com/sweetalert2/sweetalert2/issues/720
1841
+ // https://github.com/sweetalert2/sweetalert2/issues/2406
1939
1842
 
1940
- const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
1941
- swalButtons.forEach(button => {
1942
- showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
1943
- const type = button.getAttribute('type');
1944
- result["".concat(type, "ButtonText")] = button.innerHTML;
1945
- result["show".concat(capitalizeFirstLetter(type), "Button")] = true;
1946
1843
 
1947
- if (button.hasAttribute('color')) {
1948
- result["".concat(type, "ButtonColor")] = button.getAttribute('color');
1949
- }
1844
+ if (e.isComposing || e.keyCode === 229) {
1845
+ return;
1846
+ }
1950
1847
 
1951
- if (button.hasAttribute('aria-label')) {
1952
- result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label');
1953
- }
1954
- });
1955
- return result;
1848
+ if (innerParams.stopKeydownPropagation) {
1849
+ e.stopPropagation();
1850
+ } // ENTER
1851
+
1852
+
1853
+ if (e.key === 'Enter') {
1854
+ handleEnter(instance, e, innerParams);
1855
+ } // TAB
1856
+ else if (e.key === 'Tab') {
1857
+ handleTab(e, innerParams);
1858
+ } // ARROWS - switch focus between buttons
1859
+ else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(e.key)) {
1860
+ handleArrows(e.key);
1861
+ } // ESC
1862
+ else if (e.key === 'Escape') {
1863
+ handleEsc(e, innerParams, dismissWith);
1864
+ }
1956
1865
  };
1957
1866
  /**
1958
- * @param {DocumentFragment} templateContent
1867
+ * @param {SweetAlert2} instance
1868
+ * @param {KeyboardEvent} e
1869
+ * @param {SweetAlertOptions} innerParams
1959
1870
  */
1960
1871
 
1961
1872
 
1962
- const getSwalImage = templateContent => {
1963
- const result = {};
1964
- /** @type {HTMLElement} */
1965
-
1966
- const image = templateContent.querySelector('swal-image');
1967
-
1968
- if (image) {
1969
- showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
1970
-
1971
- if (image.hasAttribute('src')) {
1972
- result.imageUrl = image.getAttribute('src');
1973
- }
1974
-
1975
- if (image.hasAttribute('width')) {
1976
- result.imageWidth = image.getAttribute('width');
1977
- }
1873
+ const handleEnter = (instance, e, innerParams) => {
1874
+ // https://github.com/sweetalert2/sweetalert2/issues/2386
1875
+ if (!callIfFunction(innerParams.allowEnterKey)) {
1876
+ return;
1877
+ }
1978
1878
 
1979
- if (image.hasAttribute('height')) {
1980
- result.imageHeight = image.getAttribute('height');
1879
+ if (e.target && instance.getInput() && e.target instanceof HTMLElement && e.target.outerHTML === instance.getInput().outerHTML) {
1880
+ if (['textarea', 'file'].includes(innerParams.input)) {
1881
+ return; // do not submit
1981
1882
  }
1982
1883
 
1983
- if (image.hasAttribute('alt')) {
1984
- result.imageAlt = image.getAttribute('alt');
1985
- }
1884
+ clickConfirm();
1885
+ e.preventDefault();
1986
1886
  }
1987
-
1988
- return result;
1989
1887
  };
1990
1888
  /**
1991
- * @param {DocumentFragment} templateContent
1889
+ * @param {KeyboardEvent} e
1890
+ * @param {SweetAlertOptions} innerParams
1992
1891
  */
1993
1892
 
1994
1893
 
1995
- const getSwalIcon = templateContent => {
1996
- const result = {};
1997
- /** @type {HTMLElement} */
1998
-
1999
- const icon = templateContent.querySelector('swal-icon');
2000
-
2001
- if (icon) {
2002
- showWarningsForAttributes(icon, ['type', 'color']);
1894
+ const handleTab = (e, innerParams) => {
1895
+ const targetElement = e.target;
1896
+ const focusableElements = getFocusableElements();
1897
+ let btnIndex = -1;
2003
1898
 
2004
- if (icon.hasAttribute('type')) {
2005
- result.icon = icon.getAttribute('type');
1899
+ for (let i = 0; i < focusableElements.length; i++) {
1900
+ if (targetElement === focusableElements[i]) {
1901
+ btnIndex = i;
1902
+ break;
2006
1903
  }
1904
+ } // Cycle to the next button
2007
1905
 
2008
- if (icon.hasAttribute('color')) {
2009
- result.iconColor = icon.getAttribute('color');
2010
- }
2011
1906
 
2012
- result.iconHtml = icon.innerHTML;
1907
+ if (!e.shiftKey) {
1908
+ setFocus(innerParams, btnIndex, 1);
1909
+ } // Cycle to the prev button
1910
+ else {
1911
+ setFocus(innerParams, btnIndex, -1);
2013
1912
  }
2014
1913
 
2015
- return result;
1914
+ e.stopPropagation();
1915
+ e.preventDefault();
2016
1916
  };
2017
1917
  /**
2018
- * @param {DocumentFragment} templateContent
1918
+ * @param {string} key
2019
1919
  */
2020
1920
 
2021
1921
 
2022
- const getSwalInput = templateContent => {
2023
- const result = {};
2024
- /** @type {HTMLElement} */
1922
+ const handleArrows = key => {
1923
+ const confirmButton = getConfirmButton();
1924
+ const denyButton = getDenyButton();
1925
+ const cancelButton = getCancelButton();
2025
1926
 
2026
- const input = templateContent.querySelector('swal-input');
1927
+ if (document.activeElement instanceof HTMLElement && ![confirmButton, denyButton, cancelButton].includes(document.activeElement)) {
1928
+ return;
1929
+ }
2027
1930
 
2028
- if (input) {
2029
- showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
2030
- result.input = input.getAttribute('type') || 'text';
1931
+ const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
1932
+ let buttonToFocus = document.activeElement;
2031
1933
 
2032
- if (input.hasAttribute('label')) {
2033
- result.inputLabel = input.getAttribute('label');
2034
- }
1934
+ for (let i = 0; i < getActions().children.length; i++) {
1935
+ buttonToFocus = buttonToFocus[sibling];
2035
1936
 
2036
- if (input.hasAttribute('placeholder')) {
2037
- result.inputPlaceholder = input.getAttribute('placeholder');
1937
+ if (!buttonToFocus) {
1938
+ return;
2038
1939
  }
2039
1940
 
2040
- if (input.hasAttribute('value')) {
2041
- result.inputValue = input.getAttribute('value');
1941
+ if (buttonToFocus instanceof HTMLButtonElement && isVisible(buttonToFocus)) {
1942
+ break;
2042
1943
  }
2043
1944
  }
2044
- /** @type {HTMLElement[]} */
2045
-
2046
-
2047
- const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
2048
1945
 
2049
- if (inputOptions.length) {
2050
- result.inputOptions = {};
2051
- inputOptions.forEach(option => {
2052
- showWarningsForAttributes(option, ['value']);
2053
- const optionValue = option.getAttribute('value');
2054
- const optionName = option.innerHTML;
2055
- result.inputOptions[optionValue] = optionName;
2056
- });
1946
+ if (buttonToFocus instanceof HTMLButtonElement) {
1947
+ buttonToFocus.focus();
2057
1948
  }
2058
-
2059
- return result;
2060
1949
  };
2061
1950
  /**
2062
- * @param {DocumentFragment} templateContent
2063
- * @param {string[]} paramNames
1951
+ * @param {KeyboardEvent} e
1952
+ * @param {SweetAlertOptions} innerParams
1953
+ * @param {function} dismissWith
2064
1954
  */
2065
1955
 
2066
1956
 
2067
- const getSwalStringParams = (templateContent, paramNames) => {
2068
- const result = {};
2069
-
2070
- for (const i in paramNames) {
2071
- const paramName = paramNames[i];
2072
- /** @type {HTMLElement} */
2073
-
2074
- const tag = templateContent.querySelector(paramName);
2075
-
2076
- if (tag) {
2077
- showWarningsForAttributes(tag, []);
2078
- result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
2079
- }
1957
+ const handleEsc = (e, innerParams, dismissWith) => {
1958
+ if (callIfFunction(innerParams.allowEscapeKey)) {
1959
+ e.preventDefault();
1960
+ dismissWith(DismissReason.esc);
2080
1961
  }
1962
+ };
2081
1963
 
2082
- return result;
2083
- };
2084
- /**
2085
- * @param {DocumentFragment} templateContent
2086
- */
2087
-
2088
-
2089
- const showWarningsForElements = templateContent => {
2090
- const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
2091
- Array.from(templateContent.children).forEach(el => {
2092
- const tagName = el.tagName.toLowerCase();
2093
-
2094
- if (allowedElements.indexOf(tagName) === -1) {
2095
- warn("Unrecognized element <".concat(tagName, ">"));
2096
- }
2097
- });
2098
- };
2099
1964
  /**
2100
- * @param {HTMLElement} el
2101
- * @param {string[]} allowedAttributes
1965
+ * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
1966
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
1967
+ * This is the approach that Babel will probably take to implement private methods/fields
1968
+ * https://github.com/tc39/proposal-private-methods
1969
+ * https://github.com/babel/babel/pull/7555
1970
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
1971
+ * then we can use that language feature.
2102
1972
  */
2103
-
2104
-
2105
- const showWarningsForAttributes = (el, allowedAttributes) => {
2106
- Array.from(el.attributes).forEach(attribute => {
2107
- if (allowedAttributes.indexOf(attribute.name) === -1) {
2108
- warn(["Unrecognized attribute \"".concat(attribute.name, "\" on <").concat(el.tagName.toLowerCase(), ">."), "".concat(allowedAttributes.length ? "Allowed attributes are: ".concat(allowedAttributes.join(', ')) : 'To set the value, use HTML within the element.')]);
2109
- }
2110
- });
2111
- };
2112
-
2113
- var defaultInputValidators = {
2114
- /**
2115
- * @param {string} string
2116
- * @param {string} validationMessage
2117
- * @returns {Promise<void | string>}
2118
- */
2119
- email: (string, validationMessage) => {
2120
- return /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
2121
- },
2122
-
2123
- /**
2124
- * @param {string} string
2125
- * @param {string} validationMessage
2126
- * @returns {Promise<void | string>}
2127
- */
2128
- url: (string, validationMessage) => {
2129
- // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
2130
- 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');
2131
- }
1973
+ var privateMethods = {
1974
+ swalPromiseResolve: new WeakMap(),
1975
+ swalPromiseReject: new WeakMap()
2132
1976
  };
2133
1977
 
2134
- /**
2135
- * @param {SweetAlertOptions} params
2136
- */
2137
-
2138
- function setDefaultInputValidators(params) {
2139
- // Use default `inputValidator` for supported input types if not provided
2140
- if (!params.inputValidator) {
2141
- Object.keys(defaultInputValidators).forEach(key => {
2142
- if (params.input === key) {
2143
- params.inputValidator = defaultInputValidators[key];
2144
- }
2145
- });
2146
- }
2147
- }
2148
- /**
2149
- * @param {SweetAlertOptions} params
2150
- */
2151
-
2152
-
2153
- function validateCustomTargetElement(params) {
2154
- // Determine if the custom target element is valid
2155
- if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
2156
- warn('Target parameter is not valid, defaulting to "body"');
2157
- params.target = 'body';
2158
- }
2159
- }
2160
- /**
2161
- * Set type, text and actions on popup
2162
- *
2163
- * @param {SweetAlertOptions} params
2164
- */
2165
-
2166
-
2167
- function setParameters(params) {
2168
- setDefaultInputValidators(params); // showLoaderOnConfirm && preConfirm
2169
-
2170
- if (params.showLoaderOnConfirm && !params.preConfirm) {
2171
- 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');
2172
- }
2173
-
2174
- validateCustomTargetElement(params); // Replace newlines with <br> in title
2175
-
2176
- if (typeof params.title === 'string') {
2177
- params.title = params.title.split('\n').join('<br />');
2178
- }
2179
-
2180
- init(params);
2181
- }
2182
-
2183
- class Timer {
2184
- constructor(callback, delay) {
2185
- this.callback = callback;
2186
- this.remaining = delay;
2187
- this.running = false;
2188
- this.start();
2189
- }
2190
-
2191
- start() {
2192
- if (!this.running) {
2193
- this.running = true;
2194
- this.started = new Date();
2195
- this.id = setTimeout(this.callback, this.remaining);
2196
- }
2197
-
2198
- return this.remaining;
2199
- }
2200
-
2201
- stop() {
2202
- if (this.running) {
2203
- this.running = false;
2204
- clearTimeout(this.id);
2205
- this.remaining -= new Date().getTime() - this.started.getTime();
2206
- }
2207
-
2208
- return this.remaining;
2209
- }
2210
-
2211
- increase(n) {
2212
- const running = this.running;
2213
-
2214
- if (running) {
2215
- this.stop();
2216
- }
2217
-
2218
- this.remaining += n;
1978
+ // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
1979
+ // elements not within the active modal dialog will not be surfaced if a user opens a screen
1980
+ // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
2219
1981
 
2220
- if (running) {
2221
- this.start();
1982
+ const setAriaHidden = () => {
1983
+ const bodyChildren = Array.from(document.body.children);
1984
+ bodyChildren.forEach(el => {
1985
+ if (el === getContainer() || el.contains(getContainer())) {
1986
+ return;
2222
1987
  }
2223
1988
 
2224
- return this.remaining;
2225
- }
2226
-
2227
- getTimerLeft() {
2228
- if (this.running) {
2229
- this.stop();
2230
- this.start();
1989
+ if (el.hasAttribute('aria-hidden')) {
1990
+ el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden'));
2231
1991
  }
2232
1992
 
2233
- return this.remaining;
2234
- }
2235
-
2236
- isRunning() {
2237
- return this.running;
2238
- }
2239
-
2240
- }
2241
-
2242
- const fixScrollbar = () => {
2243
- // for queues, do not do this more than once
2244
- if (states.previousBodyPadding !== null) {
2245
- return;
2246
- } // if the body has overflow
2247
-
2248
-
2249
- if (document.body.scrollHeight > window.innerHeight) {
2250
- // add padding so the content doesn't shift after removal of scrollbar
2251
- states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
2252
- document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px");
2253
- }
1993
+ el.setAttribute('aria-hidden', 'true');
1994
+ });
2254
1995
  };
2255
- const undoScrollbar = () => {
2256
- if (states.previousBodyPadding !== null) {
2257
- document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px");
2258
- states.previousBodyPadding = null;
2259
- }
1996
+ const unsetAriaHidden = () => {
1997
+ const bodyChildren = Array.from(document.body.children);
1998
+ bodyChildren.forEach(el => {
1999
+ if (el.hasAttribute('data-previous-aria-hidden')) {
2000
+ el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden'));
2001
+ el.removeAttribute('data-previous-aria-hidden');
2002
+ } else {
2003
+ el.removeAttribute('aria-hidden');
2004
+ }
2005
+ });
2260
2006
  };
2261
2007
 
2262
2008
  /* istanbul ignore file */
@@ -2377,182 +2123,620 @@
2377
2123
  }
2378
2124
  };
2379
2125
 
2380
- const SHOW_CLASS_TIMEOUT = 10;
2381
- /**
2382
- * Open popup, add necessary classes and styles, fix scrollbar
2383
- *
2384
- * @param {SweetAlertOptions} params
2385
- */
2126
+ const fixScrollbar = () => {
2127
+ // for queues, do not do this more than once
2128
+ if (states.previousBodyPadding !== null) {
2129
+ return;
2130
+ } // if the body has overflow
2386
2131
 
2387
- const openPopup = params => {
2388
- const container = getContainer();
2389
- const popup = getPopup();
2390
2132
 
2391
- if (typeof params.willOpen === 'function') {
2392
- params.willOpen(popup);
2133
+ if (document.body.scrollHeight > window.innerHeight) {
2134
+ // add padding so the content doesn't shift after removal of scrollbar
2135
+ states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
2136
+ document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px");
2393
2137
  }
2138
+ };
2139
+ const undoScrollbar = () => {
2140
+ if (states.previousBodyPadding !== null) {
2141
+ document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px");
2142
+ states.previousBodyPadding = null;
2143
+ }
2144
+ };
2394
2145
 
2395
- const bodyStyles = window.getComputedStyle(document.body);
2396
- const initialBodyOverflow = bodyStyles.overflowY;
2397
- addClasses$1(container, popup, params); // scrolling is 'hidden' until animation is done, after that 'auto'
2398
-
2399
- setTimeout(() => {
2400
- setScrollingVisibility(container, popup);
2401
- }, SHOW_CLASS_TIMEOUT);
2146
+ /*
2147
+ * Instance method to close sweetAlert
2148
+ */
2402
2149
 
2403
- if (isModal()) {
2404
- fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow);
2405
- setAriaHidden();
2150
+ function removePopupAndResetState(instance, container, returnFocus, didClose) {
2151
+ if (isToast()) {
2152
+ triggerDidCloseAndDispose(instance, didClose);
2153
+ } else {
2154
+ restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
2155
+ removeKeydownHandler(globalState);
2406
2156
  }
2407
2157
 
2408
- if (!isToast() && !globalState.previousActiveElement) {
2409
- globalState.previousActiveElement = document.activeElement;
2158
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088
2159
+ // for some reason removing the container in Safari will scroll the document to bottom
2160
+
2161
+ if (isSafari) {
2162
+ container.setAttribute('style', 'display:none !important');
2163
+ container.removeAttribute('class');
2164
+ container.innerHTML = '';
2165
+ } else {
2166
+ container.remove();
2410
2167
  }
2411
2168
 
2412
- if (typeof params.didOpen === 'function') {
2413
- setTimeout(() => params.didOpen(popup));
2169
+ if (isModal()) {
2170
+ undoScrollbar();
2171
+ undoIOSfix();
2172
+ unsetAriaHidden();
2414
2173
  }
2415
2174
 
2416
- removeClass(container, swalClasses['no-transition']);
2417
- };
2418
- /**
2419
- * @param {AnimationEvent} event
2420
- */
2175
+ removeBodyClasses();
2176
+ }
2421
2177
 
2422
- const swalOpenAnimationFinished = event => {
2423
- const popup = getPopup();
2178
+ function removeBodyClasses() {
2179
+ removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
2180
+ }
2424
2181
 
2425
- if (event.target !== popup) {
2426
- return;
2427
- }
2182
+ function close(resolveValue) {
2183
+ resolveValue = prepareResolveValue(resolveValue);
2184
+ const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
2185
+ const didClose = triggerClosePopup(this);
2428
2186
 
2429
- const container = getContainer();
2430
- popup.removeEventListener(animationEndEvent, swalOpenAnimationFinished);
2431
- container.style.overflowY = 'auto';
2432
- };
2433
- /**
2434
- * @param {HTMLElement} container
2435
- * @param {HTMLElement} popup
2436
- */
2187
+ if (this.isAwaitingPromise()) {
2188
+ // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
2189
+ if (!resolveValue.isDismissed) {
2190
+ handleAwaitingPromise(this);
2191
+ swalPromiseResolve(resolveValue);
2192
+ }
2193
+ } else if (didClose) {
2194
+ // Resolve Swal promise
2195
+ swalPromiseResolve(resolveValue);
2196
+ }
2197
+ }
2198
+ function isAwaitingPromise() {
2199
+ return !!privateProps.awaitingPromise.get(this);
2200
+ }
2437
2201
 
2202
+ const triggerClosePopup = instance => {
2203
+ const popup = getPopup();
2438
2204
 
2439
- const setScrollingVisibility = (container, popup) => {
2440
- if (animationEndEvent && hasCssAnimation(popup)) {
2441
- container.style.overflowY = 'hidden';
2442
- popup.addEventListener(animationEndEvent, swalOpenAnimationFinished);
2443
- } else {
2444
- container.style.overflowY = 'auto';
2205
+ if (!popup) {
2206
+ return false;
2445
2207
  }
2446
- };
2447
- /**
2448
- * @param {HTMLElement} container
2449
- * @param {boolean} scrollbarPadding
2450
- * @param {string} initialBodyOverflow
2451
- */
2452
2208
 
2209
+ const innerParams = privateProps.innerParams.get(instance);
2210
+
2211
+ if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
2212
+ return false;
2213
+ }
2453
2214
 
2454
- const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
2455
- iOSfix();
2215
+ removeClass(popup, innerParams.showClass.popup);
2216
+ addClass(popup, innerParams.hideClass.popup);
2217
+ const backdrop = getContainer();
2218
+ removeClass(backdrop, innerParams.showClass.backdrop);
2219
+ addClass(backdrop, innerParams.hideClass.backdrop);
2220
+ handlePopupAnimation(instance, popup, innerParams);
2221
+ return true;
2222
+ };
2456
2223
 
2457
- if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
2458
- fixScrollbar();
2459
- } // sweetalert2/issues/1247
2224
+ function rejectPromise(error) {
2225
+ const rejectPromise = privateMethods.swalPromiseReject.get(this);
2226
+ handleAwaitingPromise(this);
2460
2227
 
2228
+ if (rejectPromise) {
2229
+ // Reject Swal promise
2230
+ rejectPromise(error);
2231
+ }
2232
+ }
2233
+ const handleAwaitingPromise = instance => {
2234
+ if (instance.isAwaitingPromise()) {
2235
+ privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
2461
2236
 
2462
- setTimeout(() => {
2463
- container.scrollTop = 0;
2464
- });
2237
+ if (!privateProps.innerParams.get(instance)) {
2238
+ instance._destroy();
2239
+ }
2240
+ }
2465
2241
  };
2466
- /**
2467
- * @param {HTMLElement} container
2468
- * @param {HTMLElement} popup
2469
- * @param {SweetAlertOptions} params
2470
- */
2471
2242
 
2243
+ const prepareResolveValue = resolveValue => {
2244
+ // When user calls Swal.close()
2245
+ if (typeof resolveValue === 'undefined') {
2246
+ return {
2247
+ isConfirmed: false,
2248
+ isDenied: false,
2249
+ isDismissed: true
2250
+ };
2251
+ }
2472
2252
 
2473
- const addClasses$1 = (container, popup, params) => {
2474
- addClass(container, params.showClass.backdrop); // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
2253
+ return Object.assign({
2254
+ isConfirmed: false,
2255
+ isDenied: false,
2256
+ isDismissed: false
2257
+ }, resolveValue);
2258
+ };
2475
2259
 
2476
- popup.style.setProperty('opacity', '0', 'important');
2477
- show(popup, 'grid');
2478
- setTimeout(() => {
2479
- // Animate popup right after showing it
2480
- addClass(popup, params.showClass.popup); // and remove the opacity workaround
2260
+ const handlePopupAnimation = (instance, popup, innerParams) => {
2261
+ const container = getContainer(); // If animation is supported, animate
2481
2262
 
2482
- popup.style.removeProperty('opacity');
2483
- }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
2263
+ const animationIsSupported = animationEndEvent && hasCssAnimation(popup);
2484
2264
 
2485
- addClass([document.documentElement, document.body], swalClasses.shown);
2265
+ if (typeof innerParams.willClose === 'function') {
2266
+ innerParams.willClose(popup);
2267
+ }
2486
2268
 
2487
- if (params.heightAuto && params.backdrop && !params.toast) {
2488
- addClass([document.documentElement, document.body], swalClasses['height-auto']);
2269
+ if (animationIsSupported) {
2270
+ animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
2271
+ } else {
2272
+ // Otherwise, remove immediately
2273
+ removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
2489
2274
  }
2490
2275
  };
2491
2276
 
2492
- /**
2493
- * Shows loader (spinner), this is useful with AJAX requests.
2494
- * By default the loader be shown instead of the "Confirm" button.
2495
- */
2277
+ const animatePopup = (instance, popup, container, returnFocus, didClose) => {
2278
+ globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
2279
+ popup.addEventListener(animationEndEvent, function (e) {
2280
+ if (e.target === popup) {
2281
+ globalState.swalCloseEventFinishedCallback();
2282
+ delete globalState.swalCloseEventFinishedCallback;
2283
+ }
2284
+ });
2285
+ };
2496
2286
 
2497
- const showLoading = buttonToReplace => {
2498
- let popup = getPopup();
2287
+ const triggerDidCloseAndDispose = (instance, didClose) => {
2288
+ setTimeout(() => {
2289
+ if (typeof didClose === 'function') {
2290
+ didClose.bind(instance.params)();
2291
+ }
2499
2292
 
2500
- if (!popup) {
2501
- new Swal(); // eslint-disable-line no-new
2293
+ instance._destroy();
2294
+ });
2295
+ };
2296
+
2297
+ function setButtonsDisabled(instance, buttons, disabled) {
2298
+ const domCache = privateProps.domCache.get(instance);
2299
+ buttons.forEach(button => {
2300
+ domCache[button].disabled = disabled;
2301
+ });
2302
+ }
2303
+
2304
+ function setInputDisabled(input, disabled) {
2305
+ if (!input) {
2306
+ return false;
2502
2307
  }
2503
2308
 
2504
- popup = getPopup();
2505
- const loader = getLoader();
2309
+ if (input.type === 'radio') {
2310
+ const radiosContainer = input.parentNode.parentNode;
2311
+ const radios = radiosContainer.querySelectorAll('input');
2506
2312
 
2507
- if (isToast()) {
2508
- hide(getIcon());
2313
+ for (let i = 0; i < radios.length; i++) {
2314
+ radios[i].disabled = disabled;
2315
+ }
2509
2316
  } else {
2510
- replaceButton(popup, buttonToReplace);
2317
+ input.disabled = disabled;
2511
2318
  }
2319
+ }
2512
2320
 
2513
- show(loader);
2514
- popup.setAttribute('data-loading', 'true');
2515
- popup.setAttribute('aria-busy', 'true');
2516
- popup.focus();
2517
- };
2321
+ function enableButtons() {
2322
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
2323
+ }
2324
+ function disableButtons() {
2325
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
2326
+ }
2327
+ function enableInput() {
2328
+ return setInputDisabled(this.getInput(), false);
2329
+ }
2330
+ function disableInput() {
2331
+ return setInputDisabled(this.getInput(), true);
2332
+ }
2518
2333
 
2519
- const replaceButton = (popup, buttonToReplace) => {
2520
- const actions = getActions();
2521
- const loader = getLoader();
2334
+ function showValidationMessage(error) {
2335
+ const domCache = privateProps.domCache.get(this);
2336
+ const params = privateProps.innerParams.get(this);
2337
+ setInnerHtml(domCache.validationMessage, error);
2338
+ domCache.validationMessage.className = swalClasses['validation-message'];
2522
2339
 
2523
- if (!buttonToReplace && isVisible(getConfirmButton())) {
2524
- buttonToReplace = getConfirmButton();
2340
+ if (params.customClass && params.customClass.validationMessage) {
2341
+ addClass(domCache.validationMessage, params.customClass.validationMessage);
2525
2342
  }
2526
2343
 
2527
- show(actions);
2344
+ show(domCache.validationMessage);
2345
+ const input = this.getInput();
2528
2346
 
2529
- if (buttonToReplace) {
2530
- hide(buttonToReplace);
2531
- loader.setAttribute('data-button-to-replace', buttonToReplace.className);
2347
+ if (input) {
2348
+ input.setAttribute('aria-invalid', true);
2349
+ input.setAttribute('aria-describedby', swalClasses['validation-message']);
2350
+ focusInput(input);
2351
+ addClass(input, swalClasses.inputerror);
2532
2352
  }
2353
+ } // Hide block with validation message
2533
2354
 
2534
- loader.parentNode.insertBefore(loader, buttonToReplace);
2535
- addClass([popup, actions], swalClasses.loading);
2536
- };
2537
-
2538
- const handleInputOptionsAndValue = (instance, params) => {
2539
- if (params.input === 'select' || params.input === 'radio') {
2540
- handleInputOptions(instance, params);
2541
- } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
2542
- showLoading(getConfirmButton());
2543
- handleInputValue(instance, params);
2544
- }
2545
- };
2546
- const getInputValue = (instance, innerParams) => {
2547
- const input = instance.getInput();
2355
+ function resetValidationMessage$1() {
2356
+ const domCache = privateProps.domCache.get(this);
2548
2357
 
2549
- if (!input) {
2550
- return null;
2358
+ if (domCache.validationMessage) {
2359
+ hide(domCache.validationMessage);
2551
2360
  }
2552
2361
 
2553
- switch (innerParams.input) {
2554
- case 'checkbox':
2555
- return getCheckboxValue(input);
2362
+ const input = this.getInput();
2363
+
2364
+ if (input) {
2365
+ input.removeAttribute('aria-invalid');
2366
+ input.removeAttribute('aria-describedby');
2367
+ removeClass(input, swalClasses.inputerror);
2368
+ }
2369
+ }
2370
+
2371
+ function getProgressSteps$1() {
2372
+ const domCache = privateProps.domCache.get(this);
2373
+ return domCache.progressSteps;
2374
+ }
2375
+
2376
+ const defaultParams = {
2377
+ title: '',
2378
+ titleText: '',
2379
+ text: '',
2380
+ html: '',
2381
+ footer: '',
2382
+ icon: undefined,
2383
+ iconColor: undefined,
2384
+ iconHtml: undefined,
2385
+ template: undefined,
2386
+ toast: false,
2387
+ showClass: {
2388
+ popup: 'swal2-show',
2389
+ backdrop: 'swal2-backdrop-show',
2390
+ icon: 'swal2-icon-show'
2391
+ },
2392
+ hideClass: {
2393
+ popup: 'swal2-hide',
2394
+ backdrop: 'swal2-backdrop-hide',
2395
+ icon: 'swal2-icon-hide'
2396
+ },
2397
+ customClass: {},
2398
+ target: 'body',
2399
+ color: undefined,
2400
+ backdrop: true,
2401
+ heightAuto: true,
2402
+ allowOutsideClick: true,
2403
+ allowEscapeKey: true,
2404
+ allowEnterKey: true,
2405
+ stopKeydownPropagation: true,
2406
+ keydownListenerCapture: false,
2407
+ showConfirmButton: true,
2408
+ showDenyButton: false,
2409
+ showCancelButton: false,
2410
+ preConfirm: undefined,
2411
+ preDeny: undefined,
2412
+ confirmButtonText: 'OK',
2413
+ confirmButtonAriaLabel: '',
2414
+ confirmButtonColor: undefined,
2415
+ denyButtonText: 'No',
2416
+ denyButtonAriaLabel: '',
2417
+ denyButtonColor: undefined,
2418
+ cancelButtonText: 'Cancel',
2419
+ cancelButtonAriaLabel: '',
2420
+ cancelButtonColor: undefined,
2421
+ buttonsStyling: true,
2422
+ reverseButtons: false,
2423
+ focusConfirm: true,
2424
+ focusDeny: false,
2425
+ focusCancel: false,
2426
+ returnFocus: true,
2427
+ showCloseButton: false,
2428
+ closeButtonHtml: '&times;',
2429
+ closeButtonAriaLabel: 'Close this dialog',
2430
+ loaderHtml: '',
2431
+ showLoaderOnConfirm: false,
2432
+ showLoaderOnDeny: false,
2433
+ imageUrl: undefined,
2434
+ imageWidth: undefined,
2435
+ imageHeight: undefined,
2436
+ imageAlt: '',
2437
+ timer: undefined,
2438
+ timerProgressBar: false,
2439
+ width: undefined,
2440
+ padding: undefined,
2441
+ background: undefined,
2442
+ input: undefined,
2443
+ inputPlaceholder: '',
2444
+ inputLabel: '',
2445
+ inputValue: '',
2446
+ inputOptions: {},
2447
+ inputAutoTrim: true,
2448
+ inputAttributes: {},
2449
+ inputValidator: undefined,
2450
+ returnInputValueOnDeny: false,
2451
+ validationMessage: undefined,
2452
+ grow: false,
2453
+ position: 'center',
2454
+ progressSteps: [],
2455
+ currentProgressStep: undefined,
2456
+ progressStepsDistance: undefined,
2457
+ willOpen: undefined,
2458
+ didOpen: undefined,
2459
+ didRender: undefined,
2460
+ willClose: undefined,
2461
+ didClose: undefined,
2462
+ didDestroy: undefined,
2463
+ scrollbarPadding: true
2464
+ };
2465
+ 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'];
2466
+ const deprecatedParams = {};
2467
+ const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
2468
+ /**
2469
+ * Is valid parameter
2470
+ *
2471
+ * @param {string} paramName
2472
+ * @returns {boolean}
2473
+ */
2474
+
2475
+ const isValidParameter = paramName => {
2476
+ return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
2477
+ };
2478
+ /**
2479
+ * Is valid parameter for Swal.update() method
2480
+ *
2481
+ * @param {string} paramName
2482
+ * @returns {boolean}
2483
+ */
2484
+
2485
+ const isUpdatableParameter = paramName => {
2486
+ return updatableParams.indexOf(paramName) !== -1;
2487
+ };
2488
+ /**
2489
+ * Is deprecated parameter
2490
+ *
2491
+ * @param {string} paramName
2492
+ * @returns {string | undefined}
2493
+ */
2494
+
2495
+ const isDeprecatedParameter = paramName => {
2496
+ return deprecatedParams[paramName];
2497
+ };
2498
+ /**
2499
+ * @param {string} param
2500
+ */
2501
+
2502
+ const checkIfParamIsValid = param => {
2503
+ if (!isValidParameter(param)) {
2504
+ warn("Unknown parameter \"".concat(param, "\""));
2505
+ }
2506
+ };
2507
+ /**
2508
+ * @param {string} param
2509
+ */
2510
+
2511
+
2512
+ const checkIfToastParamIsValid = param => {
2513
+ if (toastIncompatibleParams.includes(param)) {
2514
+ warn("The parameter \"".concat(param, "\" is incompatible with toasts"));
2515
+ }
2516
+ };
2517
+ /**
2518
+ * @param {string} param
2519
+ */
2520
+
2521
+
2522
+ const checkIfParamIsDeprecated = param => {
2523
+ if (isDeprecatedParameter(param)) {
2524
+ warnAboutDeprecation(param, isDeprecatedParameter(param));
2525
+ }
2526
+ };
2527
+ /**
2528
+ * Show relevant warnings for given params
2529
+ *
2530
+ * @param {SweetAlertOptions} params
2531
+ */
2532
+
2533
+
2534
+ const showWarningsForParams = params => {
2535
+ if (!params.backdrop && params.allowOutsideClick) {
2536
+ warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
2537
+ }
2538
+
2539
+ for (const param in params) {
2540
+ checkIfParamIsValid(param);
2541
+
2542
+ if (params.toast) {
2543
+ checkIfToastParamIsValid(param);
2544
+ }
2545
+
2546
+ checkIfParamIsDeprecated(param);
2547
+ }
2548
+ };
2549
+
2550
+ /**
2551
+ * Updates popup parameters.
2552
+ */
2553
+
2554
+ function update(params) {
2555
+ const popup = getPopup();
2556
+ const innerParams = privateProps.innerParams.get(this);
2557
+
2558
+ if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
2559
+ return 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.");
2560
+ }
2561
+
2562
+ const validUpdatableParams = filterValidParams(params);
2563
+ const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
2564
+ render(this, updatedParams);
2565
+ privateProps.innerParams.set(this, updatedParams);
2566
+ Object.defineProperties(this, {
2567
+ params: {
2568
+ value: Object.assign({}, this.params, params),
2569
+ writable: false,
2570
+ enumerable: true
2571
+ }
2572
+ });
2573
+ }
2574
+
2575
+ const filterValidParams = params => {
2576
+ const validUpdatableParams = {};
2577
+ Object.keys(params).forEach(param => {
2578
+ if (isUpdatableParameter(param)) {
2579
+ validUpdatableParams[param] = params[param];
2580
+ } else {
2581
+ warn("Invalid parameter to update: ".concat(param));
2582
+ }
2583
+ });
2584
+ return validUpdatableParams;
2585
+ };
2586
+
2587
+ function _destroy() {
2588
+ const domCache = privateProps.domCache.get(this);
2589
+ const innerParams = privateProps.innerParams.get(this);
2590
+
2591
+ if (!innerParams) {
2592
+ disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
2593
+
2594
+ return; // This instance has already been destroyed
2595
+ } // Check if there is another Swal closing
2596
+
2597
+
2598
+ if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
2599
+ globalState.swalCloseEventFinishedCallback();
2600
+ delete globalState.swalCloseEventFinishedCallback;
2601
+ }
2602
+
2603
+ if (typeof innerParams.didDestroy === 'function') {
2604
+ innerParams.didDestroy();
2605
+ }
2606
+
2607
+ disposeSwal(this);
2608
+ }
2609
+ /**
2610
+ * @param {SweetAlert2} instance
2611
+ */
2612
+
2613
+ const disposeSwal = instance => {
2614
+ disposeWeakMaps(instance); // Unset this.params so GC will dispose it (#1569)
2615
+ // @ts-ignore
2616
+
2617
+ delete instance.params; // Unset globalState props so GC will dispose globalState (#1569)
2618
+
2619
+ delete globalState.keydownHandler;
2620
+ delete globalState.keydownTarget; // Unset currentInstance
2621
+
2622
+ delete globalState.currentInstance;
2623
+ };
2624
+ /**
2625
+ * @param {SweetAlert2} instance
2626
+ */
2627
+
2628
+
2629
+ const disposeWeakMaps = instance => {
2630
+ // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
2631
+ // @ts-ignore
2632
+ if (instance.isAwaitingPromise()) {
2633
+ unsetWeakMaps(privateProps, instance);
2634
+ privateProps.awaitingPromise.set(instance, true);
2635
+ } else {
2636
+ unsetWeakMaps(privateMethods, instance);
2637
+ unsetWeakMaps(privateProps, instance);
2638
+ }
2639
+ };
2640
+ /**
2641
+ * @param {object} obj
2642
+ * @param {SweetAlert2} instance
2643
+ */
2644
+
2645
+
2646
+ const unsetWeakMaps = (obj, instance) => {
2647
+ for (const i in obj) {
2648
+ obj[i].delete(instance);
2649
+ }
2650
+ };
2651
+
2652
+
2653
+
2654
+ var instanceMethods = /*#__PURE__*/Object.freeze({
2655
+ hideLoading: hideLoading,
2656
+ disableLoading: hideLoading,
2657
+ getInput: getInput$1,
2658
+ close: close,
2659
+ isAwaitingPromise: isAwaitingPromise,
2660
+ rejectPromise: rejectPromise,
2661
+ handleAwaitingPromise: handleAwaitingPromise,
2662
+ closePopup: close,
2663
+ closeModal: close,
2664
+ closeToast: close,
2665
+ enableButtons: enableButtons,
2666
+ disableButtons: disableButtons,
2667
+ enableInput: enableInput,
2668
+ disableInput: disableInput,
2669
+ showValidationMessage: showValidationMessage,
2670
+ resetValidationMessage: resetValidationMessage$1,
2671
+ getProgressSteps: getProgressSteps$1,
2672
+ update: update,
2673
+ _destroy: _destroy
2674
+ });
2675
+
2676
+ /**
2677
+ * Shows loader (spinner), this is useful with AJAX requests.
2678
+ * By default the loader be shown instead of the "Confirm" button.
2679
+ */
2680
+
2681
+ const showLoading = buttonToReplace => {
2682
+ let popup = getPopup();
2683
+
2684
+ if (!popup) {
2685
+ new Swal(); // eslint-disable-line no-new
2686
+ }
2687
+
2688
+ popup = getPopup();
2689
+ const loader = getLoader();
2690
+
2691
+ if (isToast()) {
2692
+ hide(getIcon());
2693
+ } else {
2694
+ replaceButton(popup, buttonToReplace);
2695
+ }
2696
+
2697
+ show(loader);
2698
+ popup.setAttribute('data-loading', 'true');
2699
+ popup.setAttribute('aria-busy', 'true');
2700
+ popup.focus();
2701
+ };
2702
+
2703
+ const replaceButton = (popup, buttonToReplace) => {
2704
+ const actions = getActions();
2705
+ const loader = getLoader();
2706
+
2707
+ if (!buttonToReplace && isVisible(getConfirmButton())) {
2708
+ buttonToReplace = getConfirmButton();
2709
+ }
2710
+
2711
+ show(actions);
2712
+
2713
+ if (buttonToReplace) {
2714
+ hide(buttonToReplace);
2715
+ loader.setAttribute('data-button-to-replace', buttonToReplace.className);
2716
+ }
2717
+
2718
+ loader.parentNode.insertBefore(loader, buttonToReplace);
2719
+ addClass([popup, actions], swalClasses.loading);
2720
+ };
2721
+
2722
+ const handleInputOptionsAndValue = (instance, params) => {
2723
+ if (params.input === 'select' || params.input === 'radio') {
2724
+ handleInputOptions(instance, params);
2725
+ } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
2726
+ showLoading(getConfirmButton());
2727
+ handleInputValue(instance, params);
2728
+ }
2729
+ };
2730
+ const getInputValue = (instance, innerParams) => {
2731
+ const input = instance.getInput();
2732
+
2733
+ if (!input) {
2734
+ return null;
2735
+ }
2736
+
2737
+ switch (innerParams.input) {
2738
+ case 'checkbox':
2739
+ return getCheckboxValue(input);
2556
2740
 
2557
2741
  case 'radio':
2558
2742
  return getRadioValue(input);
@@ -2709,1100 +2893,937 @@
2709
2893
  };
2710
2894
 
2711
2895
  /**
2712
- * Hides loader and shows back the button which was hidden by .showLoading()
2896
+ * @param {SweetAlert2} instance
2713
2897
  */
2714
2898
 
2715
- function hideLoading() {
2716
- // do nothing if popup is closed
2717
- const innerParams = privateProps.innerParams.get(this);
2718
-
2719
- if (!innerParams) {
2720
- return;
2721
- }
2722
-
2723
- const domCache = privateProps.domCache.get(this);
2724
- hide(domCache.loader);
2899
+ const handleConfirmButtonClick = instance => {
2900
+ const innerParams = privateProps.innerParams.get(instance);
2901
+ instance.disableButtons();
2725
2902
 
2726
- if (isToast()) {
2727
- if (innerParams.icon) {
2728
- show(getIcon());
2729
- }
2903
+ if (innerParams.input) {
2904
+ handleConfirmOrDenyWithInput(instance, 'confirm');
2730
2905
  } else {
2731
- showRelatedButton(domCache);
2732
- }
2733
-
2734
- removeClass([domCache.popup, domCache.actions], swalClasses.loading);
2735
- domCache.popup.removeAttribute('aria-busy');
2736
- domCache.popup.removeAttribute('data-loading');
2737
- domCache.confirmButton.disabled = false;
2738
- domCache.denyButton.disabled = false;
2739
- domCache.cancelButton.disabled = false;
2740
- }
2741
-
2742
- const showRelatedButton = domCache => {
2743
- const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
2744
-
2745
- if (buttonToReplace.length) {
2746
- show(buttonToReplace[0], 'inline-block');
2747
- } else if (allButtonsAreHidden()) {
2748
- hide(domCache.actions);
2906
+ confirm(instance, true);
2749
2907
  }
2750
2908
  };
2751
-
2752
2909
  /**
2753
- * Gets the input DOM node, this method works with input parameter.
2754
- * @returns {HTMLElement | null}
2910
+ * @param {SweetAlert2} instance
2755
2911
  */
2756
2912
 
2757
- function getInput$1(instance) {
2758
- const innerParams = privateProps.innerParams.get(instance || this);
2759
- const domCache = privateProps.domCache.get(instance || this);
2913
+ const handleDenyButtonClick = instance => {
2914
+ const innerParams = privateProps.innerParams.get(instance);
2915
+ instance.disableButtons();
2760
2916
 
2761
- if (!domCache) {
2762
- return null;
2917
+ if (innerParams.returnInputValueOnDeny) {
2918
+ handleConfirmOrDenyWithInput(instance, 'deny');
2919
+ } else {
2920
+ deny(instance, false);
2763
2921
  }
2764
-
2765
- return getInput(domCache.popup, innerParams.input);
2766
- }
2767
-
2768
- /**
2769
- * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
2770
- * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
2771
- * This is the approach that Babel will probably take to implement private methods/fields
2772
- * https://github.com/tc39/proposal-private-methods
2773
- * https://github.com/babel/babel/pull/7555
2774
- * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
2775
- * then we can use that language feature.
2776
- */
2777
- var privateMethods = {
2778
- swalPromiseResolve: new WeakMap(),
2779
- swalPromiseReject: new WeakMap()
2780
- };
2781
-
2782
- /*
2783
- * Global function to determine if SweetAlert2 popup is shown
2784
- */
2785
-
2786
- const isVisible$1 = () => {
2787
- return isVisible(getPopup());
2788
2922
  };
2789
- /*
2790
- * Global function to click 'Confirm' button
2791
- */
2792
-
2793
- const clickConfirm = () => getConfirmButton() && getConfirmButton().click();
2794
- /*
2795
- * Global function to click 'Deny' button
2796
- */
2797
-
2798
- const clickDeny = () => getDenyButton() && getDenyButton().click();
2799
- /*
2800
- * Global function to click 'Cancel' button
2801
- */
2802
-
2803
- const clickCancel = () => getCancelButton() && getCancelButton().click();
2804
-
2805
2923
  /**
2806
- * @param {GlobalState} globalState
2924
+ * @param {SweetAlert2} instance
2925
+ * @param {Function} dismissWith
2807
2926
  */
2808
2927
 
2809
- const removeKeydownHandler = globalState => {
2810
- if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
2811
- globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
2812
- capture: globalState.keydownListenerCapture
2813
- });
2814
- globalState.keydownHandlerAdded = false;
2815
- }
2928
+ const handleCancelButtonClick = (instance, dismissWith) => {
2929
+ instance.disableButtons();
2930
+ dismissWith(DismissReason.cancel);
2816
2931
  };
2817
2932
  /**
2818
2933
  * @param {SweetAlert2} instance
2819
- * @param {GlobalState} globalState
2820
- * @param {SweetAlertOptions} innerParams
2821
- * @param {*} dismissWith
2934
+ * @param {'confirm' | 'deny'} type
2822
2935
  */
2823
2936
 
2824
- const addKeydownHandler = (instance, globalState, innerParams, dismissWith) => {
2825
- removeKeydownHandler(globalState);
2937
+ const handleConfirmOrDenyWithInput = (instance, type) => {
2938
+ const innerParams = privateProps.innerParams.get(instance);
2826
2939
 
2827
- if (!innerParams.toast) {
2828
- globalState.keydownHandler = e => keydownHandler(instance, e, dismissWith);
2940
+ if (!innerParams.input) {
2941
+ error("The \"input\" parameter is needed to be set when using returnInputValueOn".concat(capitalizeFirstLetter(type)));
2942
+ return;
2943
+ }
2829
2944
 
2830
- globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup();
2831
- globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
2832
- globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, {
2833
- capture: globalState.keydownListenerCapture
2834
- });
2835
- globalState.keydownHandlerAdded = true;
2945
+ const inputValue = getInputValue(instance, innerParams);
2946
+
2947
+ if (innerParams.inputValidator) {
2948
+ handleInputValidator(instance, inputValue, type);
2949
+ } else if (!instance.getInput().checkValidity()) {
2950
+ instance.enableButtons();
2951
+ instance.showValidationMessage(innerParams.validationMessage);
2952
+ } else if (type === 'deny') {
2953
+ deny(instance, inputValue);
2954
+ } else {
2955
+ confirm(instance, inputValue);
2836
2956
  }
2837
2957
  };
2838
2958
  /**
2839
- * @param {SweetAlertOptions} innerParams
2840
- * @param {number} index
2841
- * @param {number} increment
2959
+ * @param {SweetAlert2} instance
2960
+ * @param {string} inputValue
2961
+ * @param {'confirm' | 'deny'} type
2842
2962
  */
2843
2963
 
2844
- const setFocus = (innerParams, index, increment) => {
2845
- const focusableElements = getFocusableElements(); // search for visible elements and select the next possible match
2846
2964
 
2847
- if (focusableElements.length) {
2848
- index = index + increment; // rollover to first item
2965
+ const handleInputValidator = (instance, inputValue, type) => {
2966
+ const innerParams = privateProps.innerParams.get(instance);
2967
+ instance.disableInput();
2968
+ const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
2969
+ validationPromise.then(validationMessage => {
2970
+ instance.enableButtons();
2971
+ instance.enableInput();
2849
2972
 
2850
- if (index === focusableElements.length) {
2851
- index = 0; // go to last item
2852
- } else if (index === -1) {
2853
- index = focusableElements.length - 1;
2973
+ if (validationMessage) {
2974
+ instance.showValidationMessage(validationMessage);
2975
+ } else if (type === 'deny') {
2976
+ deny(instance, inputValue);
2977
+ } else {
2978
+ confirm(instance, inputValue);
2854
2979
  }
2855
-
2856
- return focusableElements[index].focus();
2857
- } // no visible focusable elements, focus the popup
2858
-
2859
-
2860
- getPopup().focus();
2980
+ });
2861
2981
  };
2862
- const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
2863
- const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
2864
2982
  /**
2865
2983
  * @param {SweetAlert2} instance
2866
- * @param {KeyboardEvent} e
2867
- * @param {function} dismissWith
2984
+ * @param {any} value
2868
2985
  */
2869
2986
 
2870
- const keydownHandler = (instance, e, dismissWith) => {
2871
- const innerParams = privateProps.innerParams.get(instance);
2872
-
2873
- if (!innerParams) {
2874
- return; // This instance has already been destroyed
2875
- } // Ignore keydown during IME composition
2876
- // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
2877
- // https://github.com/sweetalert2/sweetalert2/issues/720
2878
- // https://github.com/sweetalert2/sweetalert2/issues/2406
2879
2987
 
2988
+ const deny = (instance, value) => {
2989
+ const innerParams = privateProps.innerParams.get(instance || undefined);
2880
2990
 
2881
- if (e.isComposing || e.keyCode === 229) {
2882
- return;
2991
+ if (innerParams.showLoaderOnDeny) {
2992
+ showLoading(getDenyButton());
2883
2993
  }
2884
2994
 
2885
- if (innerParams.stopKeydownPropagation) {
2886
- e.stopPropagation();
2887
- } // ENTER
2888
-
2995
+ if (innerParams.preDeny) {
2996
+ 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
2889
2997
 
2890
- if (e.key === 'Enter') {
2891
- handleEnter(instance, e, innerParams);
2892
- } // TAB
2893
- else if (e.key === 'Tab') {
2894
- handleTab(e, innerParams);
2895
- } // ARROWS - switch focus between buttons
2896
- else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(e.key)) {
2897
- handleArrows(e.key);
2898
- } // ESC
2899
- else if (e.key === 'Escape') {
2900
- handleEsc(e, innerParams, dismissWith);
2998
+ const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
2999
+ preDenyPromise.then(preDenyValue => {
3000
+ if (preDenyValue === false) {
3001
+ instance.hideLoading();
3002
+ handleAwaitingPromise(instance);
3003
+ } else {
3004
+ instance.close({
3005
+ isDenied: true,
3006
+ value: typeof preDenyValue === 'undefined' ? value : preDenyValue
3007
+ });
3008
+ }
3009
+ }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
3010
+ } else {
3011
+ instance.close({
3012
+ isDenied: true,
3013
+ value
3014
+ });
2901
3015
  }
2902
3016
  };
2903
3017
  /**
2904
3018
  * @param {SweetAlert2} instance
2905
- * @param {KeyboardEvent} e
2906
- * @param {SweetAlertOptions} innerParams
3019
+ * @param {any} value
2907
3020
  */
2908
3021
 
2909
3022
 
2910
- const handleEnter = (instance, e, innerParams) => {
2911
- // https://github.com/sweetalert2/sweetalert2/issues/2386
2912
- if (!callIfFunction(innerParams.allowEnterKey)) {
2913
- return;
2914
- }
3023
+ const succeedWith = (instance, value) => {
3024
+ instance.close({
3025
+ isConfirmed: true,
3026
+ value
3027
+ });
3028
+ };
3029
+ /**
3030
+ *
3031
+ * @param {SweetAlert2} instance
3032
+ * @param {string} error
3033
+ */
2915
3034
 
2916
- if (e.target && instance.getInput() && e.target instanceof HTMLElement && e.target.outerHTML === instance.getInput().outerHTML) {
2917
- if (['textarea', 'file'].includes(innerParams.input)) {
2918
- return; // do not submit
2919
- }
2920
3035
 
2921
- clickConfirm();
2922
- e.preventDefault();
2923
- }
3036
+ const rejectWith = (instance, error$$1) => {
3037
+ // @ts-ignore
3038
+ instance.rejectPromise(error$$1);
2924
3039
  };
2925
3040
  /**
2926
- * @param {KeyboardEvent} e
2927
- * @param {SweetAlertOptions} innerParams
3041
+ *
3042
+ * @param {SweetAlert2} instance
3043
+ * @param {any} value
2928
3044
  */
2929
3045
 
2930
3046
 
2931
- const handleTab = (e, innerParams) => {
2932
- const targetElement = e.target;
2933
- const focusableElements = getFocusableElements();
2934
- let btnIndex = -1;
3047
+ const confirm = (instance, value) => {
3048
+ const innerParams = privateProps.innerParams.get(instance || undefined);
2935
3049
 
2936
- for (let i = 0; i < focusableElements.length; i++) {
2937
- if (targetElement === focusableElements[i]) {
2938
- btnIndex = i;
2939
- break;
2940
- }
2941
- } // Cycle to the next button
3050
+ if (innerParams.showLoaderOnConfirm) {
3051
+ showLoading();
3052
+ }
2942
3053
 
3054
+ if (innerParams.preConfirm) {
3055
+ instance.resetValidationMessage();
3056
+ 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
2943
3057
 
2944
- if (!e.shiftKey) {
2945
- setFocus(innerParams, btnIndex, 1);
2946
- } // Cycle to the prev button
2947
- else {
2948
- setFocus(innerParams, btnIndex, -1);
3058
+ const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
3059
+ preConfirmPromise.then(preConfirmValue => {
3060
+ if (isVisible(getValidationMessage()) || preConfirmValue === false) {
3061
+ instance.hideLoading();
3062
+ handleAwaitingPromise(instance);
3063
+ } else {
3064
+ succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
3065
+ }
3066
+ }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
3067
+ } else {
3068
+ succeedWith(instance, value);
2949
3069
  }
2950
-
2951
- e.stopPropagation();
2952
- e.preventDefault();
2953
3070
  };
2954
- /**
2955
- * @param {string} key
2956
- */
2957
3071
 
3072
+ const handlePopupClick = (instance, domCache, dismissWith) => {
3073
+ const innerParams = privateProps.innerParams.get(instance);
2958
3074
 
2959
- const handleArrows = key => {
2960
- const confirmButton = getConfirmButton();
2961
- const denyButton = getDenyButton();
2962
- const cancelButton = getCancelButton();
3075
+ if (innerParams.toast) {
3076
+ handleToastClick(instance, domCache, dismissWith);
3077
+ } else {
3078
+ // Ignore click events that had mousedown on the popup but mouseup on the container
3079
+ // This can happen when the user drags a slider
3080
+ handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup
2963
3081
 
2964
- if (document.activeElement instanceof HTMLElement && ![confirmButton, denyButton, cancelButton].includes(document.activeElement)) {
2965
- return;
3082
+ handleContainerMousedown(domCache);
3083
+ handleModalClick(instance, domCache, dismissWith);
2966
3084
  }
3085
+ };
2967
3086
 
2968
- const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
2969
- let buttonToFocus = document.activeElement;
2970
-
2971
- for (let i = 0; i < getActions().children.length; i++) {
2972
- buttonToFocus = buttonToFocus[sibling];
3087
+ const handleToastClick = (instance, domCache, dismissWith) => {
3088
+ // Closing toast by internal click
3089
+ domCache.popup.onclick = () => {
3090
+ const innerParams = privateProps.innerParams.get(instance);
2973
3091
 
2974
- if (!buttonToFocus) {
3092
+ if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
2975
3093
  return;
2976
3094
  }
2977
3095
 
2978
- if (buttonToFocus instanceof HTMLButtonElement && isVisible(buttonToFocus)) {
2979
- break;
2980
- }
2981
- }
2982
-
2983
- if (buttonToFocus instanceof HTMLButtonElement) {
2984
- buttonToFocus.focus();
2985
- }
3096
+ dismissWith(DismissReason.close);
3097
+ };
2986
3098
  };
2987
3099
  /**
2988
- * @param {KeyboardEvent} e
2989
- * @param {SweetAlertOptions} innerParams
2990
- * @param {function} dismissWith
3100
+ * @param {*} innerParams
3101
+ * @returns {boolean}
2991
3102
  */
2992
3103
 
2993
3104
 
2994
- const handleEsc = (e, innerParams, dismissWith) => {
2995
- if (callIfFunction(innerParams.allowEscapeKey)) {
2996
- e.preventDefault();
2997
- dismissWith(DismissReason.esc);
2998
- }
3105
+ const isAnyButtonShown = innerParams => {
3106
+ return innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton;
2999
3107
  };
3000
3108
 
3001
- /*
3002
- * Instance method to close sweetAlert
3003
- */
3004
-
3005
- function removePopupAndResetState(instance, container, returnFocus, didClose) {
3006
- if (isToast()) {
3007
- triggerDidCloseAndDispose(instance, didClose);
3008
- } else {
3009
- restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
3010
- removeKeydownHandler(globalState);
3011
- }
3109
+ let ignoreOutsideClick = false;
3012
3110
 
3013
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088
3014
- // for some reason removing the container in Safari will scroll the document to bottom
3111
+ const handleModalMousedown = domCache => {
3112
+ domCache.popup.onmousedown = () => {
3113
+ domCache.container.onmouseup = function (e) {
3114
+ domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't
3115
+ // have any other direct children aside of the popup
3015
3116
 
3016
- if (isSafari) {
3017
- container.setAttribute('style', 'display:none !important');
3018
- container.removeAttribute('class');
3019
- container.innerHTML = '';
3020
- } else {
3021
- container.remove();
3022
- }
3117
+ if (e.target === domCache.container) {
3118
+ ignoreOutsideClick = true;
3119
+ }
3120
+ };
3121
+ };
3122
+ };
3023
3123
 
3024
- if (isModal()) {
3025
- undoScrollbar();
3026
- undoIOSfix();
3027
- unsetAriaHidden();
3028
- }
3124
+ const handleContainerMousedown = domCache => {
3125
+ domCache.container.onmousedown = () => {
3126
+ domCache.popup.onmouseup = function (e) {
3127
+ domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup
3029
3128
 
3030
- removeBodyClasses();
3031
- }
3129
+ if (e.target === domCache.popup || domCache.popup.contains(e.target)) {
3130
+ ignoreOutsideClick = true;
3131
+ }
3132
+ };
3133
+ };
3134
+ };
3032
3135
 
3033
- function removeBodyClasses() {
3034
- removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
3035
- }
3136
+ const handleModalClick = (instance, domCache, dismissWith) => {
3137
+ domCache.container.onclick = e => {
3138
+ const innerParams = privateProps.innerParams.get(instance);
3036
3139
 
3037
- function close(resolveValue) {
3038
- resolveValue = prepareResolveValue(resolveValue);
3039
- const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
3040
- const didClose = triggerClosePopup(this);
3140
+ if (ignoreOutsideClick) {
3141
+ ignoreOutsideClick = false;
3142
+ return;
3143
+ }
3041
3144
 
3042
- if (this.isAwaitingPromise()) {
3043
- // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
3044
- if (!resolveValue.isDismissed) {
3045
- handleAwaitingPromise(this);
3046
- swalPromiseResolve(resolveValue);
3145
+ if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
3146
+ dismissWith(DismissReason.backdrop);
3047
3147
  }
3048
- } else if (didClose) {
3049
- // Resolve Swal promise
3050
- swalPromiseResolve(resolveValue);
3051
- }
3052
- }
3053
- function isAwaitingPromise() {
3054
- return !!privateProps.awaitingPromise.get(this);
3055
- }
3148
+ };
3149
+ };
3056
3150
 
3057
- const triggerClosePopup = instance => {
3058
- const popup = getPopup();
3151
+ const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
3059
3152
 
3060
- if (!popup) {
3061
- return false;
3062
- }
3153
+ const isElement = elem => elem instanceof Element || isJqueryElement(elem);
3063
3154
 
3064
- const innerParams = privateProps.innerParams.get(instance);
3155
+ const argsToParams = args => {
3156
+ const params = {};
3065
3157
 
3066
- if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
3067
- return false;
3158
+ if (typeof args[0] === 'object' && !isElement(args[0])) {
3159
+ Object.assign(params, args[0]);
3160
+ } else {
3161
+ ['title', 'html', 'icon'].forEach((name, index) => {
3162
+ const arg = args[index];
3163
+
3164
+ if (typeof arg === 'string' || isElement(arg)) {
3165
+ params[name] = arg;
3166
+ } else if (arg !== undefined) {
3167
+ error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg));
3168
+ }
3169
+ });
3068
3170
  }
3069
3171
 
3070
- removeClass(popup, innerParams.showClass.popup);
3071
- addClass(popup, innerParams.hideClass.popup);
3072
- const backdrop = getContainer();
3073
- removeClass(backdrop, innerParams.showClass.backdrop);
3074
- addClass(backdrop, innerParams.hideClass.backdrop);
3075
- handlePopupAnimation(instance, popup, innerParams);
3076
- return true;
3172
+ return params;
3077
3173
  };
3078
3174
 
3079
- function rejectPromise(error) {
3080
- const rejectPromise = privateMethods.swalPromiseReject.get(this);
3081
- handleAwaitingPromise(this);
3175
+ function fire() {
3176
+ const Swal = this; // eslint-disable-line @typescript-eslint/no-this-alias
3082
3177
 
3083
- if (rejectPromise) {
3084
- // Reject Swal promise
3085
- rejectPromise(error);
3178
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3179
+ args[_key] = arguments[_key];
3086
3180
  }
3181
+
3182
+ return new Swal(...args);
3087
3183
  }
3088
- const handleAwaitingPromise = instance => {
3089
- if (instance.isAwaitingPromise()) {
3090
- privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
3091
3184
 
3092
- if (!privateProps.innerParams.get(instance)) {
3093
- instance._destroy();
3185
+ /**
3186
+ * Returns an extended version of `Swal` containing `params` as defaults.
3187
+ * Useful for reusing Swal configuration.
3188
+ *
3189
+ * For example:
3190
+ *
3191
+ * Before:
3192
+ * const textPromptOptions = { input: 'text', showCancelButton: true }
3193
+ * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
3194
+ * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
3195
+ *
3196
+ * After:
3197
+ * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
3198
+ * const {value: firstName} = await TextPrompt('What is your first name?')
3199
+ * const {value: lastName} = await TextPrompt('What is your last name?')
3200
+ *
3201
+ * @param mixinParams
3202
+ */
3203
+ function mixin(mixinParams) {
3204
+ class MixinSwal extends this {
3205
+ _main(params, priorityMixinParams) {
3206
+ return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
3094
3207
  }
3095
- }
3096
- };
3097
3208
 
3098
- const prepareResolveValue = resolveValue => {
3099
- // When user calls Swal.close()
3100
- if (typeof resolveValue === 'undefined') {
3101
- return {
3102
- isConfirmed: false,
3103
- isDenied: false,
3104
- isDismissed: true
3105
- };
3106
3209
  }
3107
3210
 
3108
- return Object.assign({
3109
- isConfirmed: false,
3110
- isDenied: false,
3111
- isDismissed: false
3112
- }, resolveValue);
3113
- };
3211
+ return MixinSwal;
3212
+ }
3114
3213
 
3115
- const handlePopupAnimation = (instance, popup, innerParams) => {
3116
- const container = getContainer(); // If animation is supported, animate
3214
+ /**
3215
+ * If `timer` parameter is set, returns number of milliseconds of timer remained.
3216
+ * Otherwise, returns undefined.
3217
+ */
3117
3218
 
3118
- const animationIsSupported = animationEndEvent && hasCssAnimation(popup);
3219
+ const getTimerLeft = () => {
3220
+ return globalState.timeout && globalState.timeout.getTimerLeft();
3221
+ };
3222
+ /**
3223
+ * Stop timer. Returns number of milliseconds of timer remained.
3224
+ * If `timer` parameter isn't set, returns undefined.
3225
+ */
3119
3226
 
3120
- if (typeof innerParams.willClose === 'function') {
3121
- innerParams.willClose(popup);
3227
+ const stopTimer = () => {
3228
+ if (globalState.timeout) {
3229
+ stopTimerProgressBar();
3230
+ return globalState.timeout.stop();
3122
3231
  }
3232
+ };
3233
+ /**
3234
+ * Resume timer. Returns number of milliseconds of timer remained.
3235
+ * If `timer` parameter isn't set, returns undefined.
3236
+ */
3123
3237
 
3124
- if (animationIsSupported) {
3125
- animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
3126
- } else {
3127
- // Otherwise, remove immediately
3128
- removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
3238
+ const resumeTimer = () => {
3239
+ if (globalState.timeout) {
3240
+ const remaining = globalState.timeout.start();
3241
+ animateTimerProgressBar(remaining);
3242
+ return remaining;
3129
3243
  }
3130
3244
  };
3245
+ /**
3246
+ * Resume timer. Returns number of milliseconds of timer remained.
3247
+ * If `timer` parameter isn't set, returns undefined.
3248
+ */
3131
3249
 
3132
- const animatePopup = (instance, popup, container, returnFocus, didClose) => {
3133
- globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
3134
- popup.addEventListener(animationEndEvent, function (e) {
3135
- if (e.target === popup) {
3136
- globalState.swalCloseEventFinishedCallback();
3137
- delete globalState.swalCloseEventFinishedCallback;
3138
- }
3139
- });
3250
+ const toggleTimer = () => {
3251
+ const timer = globalState.timeout;
3252
+ return timer && (timer.running ? stopTimer() : resumeTimer());
3140
3253
  };
3254
+ /**
3255
+ * Increase timer. Returns number of milliseconds of an updated timer.
3256
+ * If `timer` parameter isn't set, returns undefined.
3257
+ */
3141
3258
 
3142
- const triggerDidCloseAndDispose = (instance, didClose) => {
3143
- setTimeout(() => {
3144
- if (typeof didClose === 'function') {
3145
- didClose.bind(instance.params)();
3146
- }
3147
-
3148
- instance._destroy();
3149
- });
3259
+ const increaseTimer = n => {
3260
+ if (globalState.timeout) {
3261
+ const remaining = globalState.timeout.increase(n);
3262
+ animateTimerProgressBar(remaining, true);
3263
+ return remaining;
3264
+ }
3150
3265
  };
3266
+ /**
3267
+ * Check if timer is running. Returns true if timer is running
3268
+ * or false if timer is paused or stopped.
3269
+ * If `timer` parameter isn't set, returns undefined
3270
+ */
3151
3271
 
3152
- function setButtonsDisabled(instance, buttons, disabled) {
3153
- const domCache = privateProps.domCache.get(instance);
3154
- buttons.forEach(button => {
3155
- domCache[button].disabled = disabled;
3156
- });
3157
- }
3158
-
3159
- function setInputDisabled(input, disabled) {
3160
- if (!input) {
3161
- return false;
3162
- }
3272
+ const isTimerRunning = () => {
3273
+ return globalState.timeout && globalState.timeout.isRunning();
3274
+ };
3163
3275
 
3164
- if (input.type === 'radio') {
3165
- const radiosContainer = input.parentNode.parentNode;
3166
- const radios = radiosContainer.querySelectorAll('input');
3276
+ let bodyClickListenerAdded = false;
3277
+ const clickHandlers = {};
3278
+ function bindClickHandler() {
3279
+ let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template';
3280
+ clickHandlers[attr] = this;
3167
3281
 
3168
- for (let i = 0; i < radios.length; i++) {
3169
- radios[i].disabled = disabled;
3170
- }
3171
- } else {
3172
- input.disabled = disabled;
3282
+ if (!bodyClickListenerAdded) {
3283
+ document.body.addEventListener('click', bodyClickListener);
3284
+ bodyClickListenerAdded = true;
3173
3285
  }
3174
3286
  }
3175
3287
 
3176
- function enableButtons() {
3177
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
3178
- }
3179
- function disableButtons() {
3180
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
3181
- }
3182
- function enableInput() {
3183
- return setInputDisabled(this.getInput(), false);
3184
- }
3185
- function disableInput() {
3186
- return setInputDisabled(this.getInput(), true);
3187
- }
3188
-
3189
- function showValidationMessage(error) {
3190
- const domCache = privateProps.domCache.get(this);
3191
- const params = privateProps.innerParams.get(this);
3192
- setInnerHtml(domCache.validationMessage, error);
3193
- domCache.validationMessage.className = swalClasses['validation-message'];
3194
-
3195
- if (params.customClass && params.customClass.validationMessage) {
3196
- addClass(domCache.validationMessage, params.customClass.validationMessage);
3197
- }
3198
-
3199
- show(domCache.validationMessage);
3200
- const input = this.getInput();
3288
+ const bodyClickListener = event => {
3289
+ for (let el = event.target; el && el !== document; el = el.parentNode) {
3290
+ for (const attr in clickHandlers) {
3291
+ const template = el.getAttribute(attr);
3201
3292
 
3202
- if (input) {
3203
- input.setAttribute('aria-invalid', true);
3204
- input.setAttribute('aria-describedby', swalClasses['validation-message']);
3205
- focusInput(input);
3206
- addClass(input, swalClasses.inputerror);
3293
+ if (template) {
3294
+ clickHandlers[attr].fire({
3295
+ template
3296
+ });
3297
+ return;
3298
+ }
3299
+ }
3207
3300
  }
3208
- } // Hide block with validation message
3301
+ };
3209
3302
 
3210
- function resetValidationMessage$1() {
3211
- const domCache = privateProps.domCache.get(this);
3212
3303
 
3213
- if (domCache.validationMessage) {
3214
- hide(domCache.validationMessage);
3215
- }
3216
3304
 
3217
- const input = this.getInput();
3305
+ var staticMethods = /*#__PURE__*/Object.freeze({
3306
+ isValidParameter: isValidParameter,
3307
+ isUpdatableParameter: isUpdatableParameter,
3308
+ isDeprecatedParameter: isDeprecatedParameter,
3309
+ argsToParams: argsToParams,
3310
+ isVisible: isVisible$1,
3311
+ clickConfirm: clickConfirm,
3312
+ clickDeny: clickDeny,
3313
+ clickCancel: clickCancel,
3314
+ getContainer: getContainer,
3315
+ getPopup: getPopup,
3316
+ getTitle: getTitle,
3317
+ getHtmlContainer: getHtmlContainer,
3318
+ getImage: getImage,
3319
+ getIcon: getIcon,
3320
+ getInputLabel: getInputLabel,
3321
+ getCloseButton: getCloseButton,
3322
+ getActions: getActions,
3323
+ getConfirmButton: getConfirmButton,
3324
+ getDenyButton: getDenyButton,
3325
+ getCancelButton: getCancelButton,
3326
+ getLoader: getLoader,
3327
+ getFooter: getFooter,
3328
+ getTimerProgressBar: getTimerProgressBar,
3329
+ getFocusableElements: getFocusableElements,
3330
+ getValidationMessage: getValidationMessage,
3331
+ isLoading: isLoading,
3332
+ fire: fire,
3333
+ mixin: mixin,
3334
+ showLoading: showLoading,
3335
+ enableLoading: showLoading,
3336
+ getTimerLeft: getTimerLeft,
3337
+ stopTimer: stopTimer,
3338
+ resumeTimer: resumeTimer,
3339
+ toggleTimer: toggleTimer,
3340
+ increaseTimer: increaseTimer,
3341
+ isTimerRunning: isTimerRunning,
3342
+ bindClickHandler: bindClickHandler
3343
+ });
3218
3344
 
3219
- if (input) {
3220
- input.removeAttribute('aria-invalid');
3221
- input.removeAttribute('aria-describedby');
3222
- removeClass(input, swalClasses.inputerror);
3345
+ class Timer {
3346
+ /**
3347
+ * @param {Function} callback
3348
+ * @param {number} delay
3349
+ */
3350
+ constructor(callback, delay) {
3351
+ this.callback = callback;
3352
+ this.remaining = delay;
3353
+ this.running = false;
3354
+ this.start();
3223
3355
  }
3224
- }
3225
3356
 
3226
- function getProgressSteps$1() {
3227
- const domCache = privateProps.domCache.get(this);
3228
- return domCache.progressSteps;
3229
- }
3357
+ start() {
3358
+ if (!this.running) {
3359
+ this.running = true;
3360
+ this.started = new Date();
3361
+ this.id = setTimeout(this.callback, this.remaining);
3362
+ }
3230
3363
 
3231
- /**
3232
- * Updates popup parameters.
3233
- */
3364
+ return this.remaining;
3365
+ }
3234
3366
 
3235
- function update(params) {
3236
- const popup = getPopup();
3237
- const innerParams = privateProps.innerParams.get(this);
3367
+ stop() {
3368
+ if (this.running) {
3369
+ this.running = false;
3370
+ clearTimeout(this.id);
3371
+ this.remaining -= new Date().getTime() - this.started.getTime();
3372
+ }
3238
3373
 
3239
- if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
3240
- return 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.");
3374
+ return this.remaining;
3241
3375
  }
3242
3376
 
3243
- const validUpdatableParams = filterValidParams(params);
3244
- const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
3245
- render(this, updatedParams);
3246
- privateProps.innerParams.set(this, updatedParams);
3247
- Object.defineProperties(this, {
3248
- params: {
3249
- value: Object.assign({}, this.params, params),
3250
- writable: false,
3251
- enumerable: true
3252
- }
3253
- });
3254
- }
3377
+ increase(n) {
3378
+ const running = this.running;
3255
3379
 
3256
- const filterValidParams = params => {
3257
- const validUpdatableParams = {};
3258
- Object.keys(params).forEach(param => {
3259
- if (isUpdatableParameter(param)) {
3260
- validUpdatableParams[param] = params[param];
3261
- } else {
3262
- warn("Invalid parameter to update: ".concat(param));
3380
+ if (running) {
3381
+ this.stop();
3263
3382
  }
3264
- });
3265
- return validUpdatableParams;
3266
- };
3267
3383
 
3268
- function _destroy() {
3269
- const domCache = privateProps.domCache.get(this);
3270
- const innerParams = privateProps.innerParams.get(this);
3384
+ this.remaining += n;
3271
3385
 
3272
- if (!innerParams) {
3273
- disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
3386
+ if (running) {
3387
+ this.start();
3388
+ }
3274
3389
 
3275
- return; // This instance has already been destroyed
3276
- } // Check if there is another Swal closing
3390
+ return this.remaining;
3391
+ }
3277
3392
 
3393
+ getTimerLeft() {
3394
+ if (this.running) {
3395
+ this.stop();
3396
+ this.start();
3397
+ }
3278
3398
 
3279
- if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
3280
- globalState.swalCloseEventFinishedCallback();
3281
- delete globalState.swalCloseEventFinishedCallback;
3399
+ return this.remaining;
3282
3400
  }
3283
3401
 
3284
- if (typeof innerParams.didDestroy === 'function') {
3285
- innerParams.didDestroy();
3402
+ isRunning() {
3403
+ return this.running;
3286
3404
  }
3287
3405
 
3288
- disposeSwal(this);
3289
3406
  }
3290
- /**
3291
- * @param {SweetAlert2} instance
3292
- */
3293
-
3294
- const disposeSwal = instance => {
3295
- disposeWeakMaps(instance); // Unset this.params so GC will dispose it (#1569)
3296
- // @ts-ignore
3297
-
3298
- delete instance.params; // Unset globalState props so GC will dispose globalState (#1569)
3299
-
3300
- delete globalState.keydownHandler;
3301
- delete globalState.keydownTarget; // Unset currentInstance
3302
3407
 
3303
- delete globalState.currentInstance;
3304
- };
3408
+ const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
3305
3409
  /**
3306
- * @param {SweetAlert2} instance
3410
+ * @param {SweetAlertOptions} params
3411
+ * @returns {SweetAlertOptions}
3307
3412
  */
3308
3413
 
3414
+ const getTemplateParams = params => {
3415
+ /** @type {HTMLTemplateElement} */
3416
+ const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template;
3309
3417
 
3310
- const disposeWeakMaps = instance => {
3311
- // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
3312
- // @ts-ignore
3313
- if (instance.isAwaitingPromise()) {
3314
- unsetWeakMaps(privateProps, instance);
3315
- privateProps.awaitingPromise.set(instance, true);
3316
- } else {
3317
- unsetWeakMaps(privateMethods, instance);
3318
- unsetWeakMaps(privateProps, instance);
3418
+ if (!template) {
3419
+ return {};
3319
3420
  }
3320
- };
3321
- /**
3322
- * @param {object} obj
3323
- * @param {SweetAlert2} instance
3324
- */
3421
+ /** @type {DocumentFragment} */
3325
3422
 
3326
3423
 
3327
- const unsetWeakMaps = (obj, instance) => {
3328
- for (const i in obj) {
3329
- obj[i].delete(instance);
3330
- }
3424
+ const templateContent = template.content;
3425
+ showWarningsForElements(templateContent);
3426
+ const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
3427
+ return result;
3331
3428
  };
3332
-
3333
-
3334
-
3335
- var instanceMethods = /*#__PURE__*/Object.freeze({
3336
- hideLoading: hideLoading,
3337
- disableLoading: hideLoading,
3338
- getInput: getInput$1,
3339
- close: close,
3340
- isAwaitingPromise: isAwaitingPromise,
3341
- rejectPromise: rejectPromise,
3342
- handleAwaitingPromise: handleAwaitingPromise,
3343
- closePopup: close,
3344
- closeModal: close,
3345
- closeToast: close,
3346
- enableButtons: enableButtons,
3347
- disableButtons: disableButtons,
3348
- enableInput: enableInput,
3349
- disableInput: disableInput,
3350
- showValidationMessage: showValidationMessage,
3351
- resetValidationMessage: resetValidationMessage$1,
3352
- getProgressSteps: getProgressSteps$1,
3353
- update: update,
3354
- _destroy: _destroy
3355
- });
3356
-
3357
3429
  /**
3358
- * @param {SweetAlert2} instance
3430
+ * @param {DocumentFragment} templateContent
3431
+ * @returns {SweetAlertOptions}
3359
3432
  */
3360
3433
 
3361
- const handleConfirmButtonClick = instance => {
3362
- const innerParams = privateProps.innerParams.get(instance);
3363
- instance.disableButtons();
3364
-
3365
- if (innerParams.input) {
3366
- handleConfirmOrDenyWithInput(instance, 'confirm');
3367
- } else {
3368
- confirm(instance, true);
3369
- }
3370
- };
3371
- /**
3372
- * @param {SweetAlert2} instance
3373
- */
3434
+ const getSwalParams = templateContent => {
3435
+ const result = {};
3436
+ /** @type {HTMLElement[]} */
3374
3437
 
3375
- const handleDenyButtonClick = instance => {
3376
- const innerParams = privateProps.innerParams.get(instance);
3377
- instance.disableButtons();
3438
+ const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
3439
+ swalParams.forEach(param => {
3440
+ showWarningsForAttributes(param, ['name', 'value']);
3441
+ const paramName = param.getAttribute('name');
3442
+ const value = param.getAttribute('value');
3378
3443
 
3379
- if (innerParams.returnInputValueOnDeny) {
3380
- handleConfirmOrDenyWithInput(instance, 'deny');
3381
- } else {
3382
- deny(instance, false);
3383
- }
3384
- };
3385
- /**
3386
- * @param {SweetAlert2} instance
3387
- * @param {Function} dismissWith
3388
- */
3444
+ if (typeof defaultParams[paramName] === 'boolean' && value === 'false') {
3445
+ result[paramName] = false;
3446
+ }
3389
3447
 
3390
- const handleCancelButtonClick = (instance, dismissWith) => {
3391
- instance.disableButtons();
3392
- dismissWith(DismissReason.cancel);
3448
+ if (typeof defaultParams[paramName] === 'object') {
3449
+ result[paramName] = JSON.parse(value);
3450
+ }
3451
+ });
3452
+ return result;
3393
3453
  };
3394
3454
  /**
3395
- * @param {SweetAlert2} instance
3396
- * @param {'confirm' | 'deny'} type
3455
+ * @param {DocumentFragment} templateContent
3456
+ * @returns {SweetAlertOptions}
3397
3457
  */
3398
3458
 
3399
- const handleConfirmOrDenyWithInput = (instance, type) => {
3400
- const innerParams = privateProps.innerParams.get(instance);
3401
-
3402
- if (!innerParams.input) {
3403
- error("The \"input\" parameter is needed to be set when using returnInputValueOn".concat(capitalizeFirstLetter(type)));
3404
- return;
3405
- }
3406
-
3407
- const inputValue = getInputValue(instance, innerParams);
3408
3459
 
3409
- if (innerParams.inputValidator) {
3410
- handleInputValidator(instance, inputValue, type);
3411
- } else if (!instance.getInput().checkValidity()) {
3412
- instance.enableButtons();
3413
- instance.showValidationMessage(innerParams.validationMessage);
3414
- } else if (type === 'deny') {
3415
- deny(instance, inputValue);
3416
- } else {
3417
- confirm(instance, inputValue);
3418
- }
3419
- };
3420
- /**
3421
- * @param {SweetAlert2} instance
3422
- * @param {string} inputValue
3423
- * @param {'confirm' | 'deny'} type
3424
- */
3460
+ const getSwalButtons = templateContent => {
3461
+ const result = {};
3462
+ /** @type {HTMLElement[]} */
3425
3463
 
3464
+ const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
3465
+ swalButtons.forEach(button => {
3466
+ showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
3467
+ const type = button.getAttribute('type');
3468
+ result["".concat(type, "ButtonText")] = button.innerHTML;
3469
+ result["show".concat(capitalizeFirstLetter(type), "Button")] = true;
3426
3470
 
3427
- const handleInputValidator = (instance, inputValue, type) => {
3428
- const innerParams = privateProps.innerParams.get(instance);
3429
- instance.disableInput();
3430
- const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
3431
- validationPromise.then(validationMessage => {
3432
- instance.enableButtons();
3433
- instance.enableInput();
3471
+ if (button.hasAttribute('color')) {
3472
+ result["".concat(type, "ButtonColor")] = button.getAttribute('color');
3473
+ }
3434
3474
 
3435
- if (validationMessage) {
3436
- instance.showValidationMessage(validationMessage);
3437
- } else if (type === 'deny') {
3438
- deny(instance, inputValue);
3439
- } else {
3440
- confirm(instance, inputValue);
3475
+ if (button.hasAttribute('aria-label')) {
3476
+ result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label');
3441
3477
  }
3442
3478
  });
3479
+ return result;
3443
3480
  };
3444
3481
  /**
3445
- * @param {SweetAlert2} instance
3446
- * @param {any} value
3482
+ * @param {DocumentFragment} templateContent
3483
+ * @returns {SweetAlertOptions}
3447
3484
  */
3448
3485
 
3449
3486
 
3450
- const deny = (instance, value) => {
3451
- const innerParams = privateProps.innerParams.get(instance || undefined);
3487
+ const getSwalImage = templateContent => {
3488
+ const result = {};
3489
+ /** @type {HTMLElement} */
3452
3490
 
3453
- if (innerParams.showLoaderOnDeny) {
3454
- showLoading(getDenyButton());
3455
- }
3491
+ const image = templateContent.querySelector('swal-image');
3456
3492
 
3457
- if (innerParams.preDeny) {
3458
- 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
3493
+ if (image) {
3494
+ showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
3459
3495
 
3460
- const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
3461
- preDenyPromise.then(preDenyValue => {
3462
- if (preDenyValue === false) {
3463
- instance.hideLoading();
3464
- handleAwaitingPromise(instance);
3465
- } else {
3466
- instance.close({
3467
- isDenied: true,
3468
- value: typeof preDenyValue === 'undefined' ? value : preDenyValue
3469
- });
3470
- }
3471
- }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
3472
- } else {
3473
- instance.close({
3474
- isDenied: true,
3475
- value
3476
- });
3496
+ if (image.hasAttribute('src')) {
3497
+ result.imageUrl = image.getAttribute('src');
3498
+ }
3499
+
3500
+ if (image.hasAttribute('width')) {
3501
+ result.imageWidth = image.getAttribute('width');
3502
+ }
3503
+
3504
+ if (image.hasAttribute('height')) {
3505
+ result.imageHeight = image.getAttribute('height');
3506
+ }
3507
+
3508
+ if (image.hasAttribute('alt')) {
3509
+ result.imageAlt = image.getAttribute('alt');
3510
+ }
3477
3511
  }
3512
+
3513
+ return result;
3478
3514
  };
3479
3515
  /**
3480
- * @param {SweetAlert2} instance
3481
- * @param {any} value
3516
+ * @param {DocumentFragment} templateContent
3517
+ * @returns {SweetAlertOptions}
3482
3518
  */
3483
3519
 
3484
3520
 
3485
- const succeedWith = (instance, value) => {
3486
- instance.close({
3487
- isConfirmed: true,
3488
- value
3489
- });
3490
- };
3491
- /**
3492
- *
3493
- * @param {SweetAlert2} instance
3494
- * @param {string} error
3495
- */
3521
+ const getSwalIcon = templateContent => {
3522
+ const result = {};
3523
+ /** @type {HTMLElement} */
3496
3524
 
3525
+ const icon = templateContent.querySelector('swal-icon');
3497
3526
 
3498
- const rejectWith = (instance, error$$1) => {
3499
- // @ts-ignore
3500
- instance.rejectPromise(error$$1);
3527
+ if (icon) {
3528
+ showWarningsForAttributes(icon, ['type', 'color']);
3529
+
3530
+ if (icon.hasAttribute('type')) {
3531
+ /** @type {SweetAlertIcon} */
3532
+ // @ts-ignore
3533
+ result.icon = icon.getAttribute('type');
3534
+ }
3535
+
3536
+ if (icon.hasAttribute('color')) {
3537
+ result.iconColor = icon.getAttribute('color');
3538
+ }
3539
+
3540
+ result.iconHtml = icon.innerHTML;
3541
+ }
3542
+
3543
+ return result;
3501
3544
  };
3502
3545
  /**
3503
- *
3504
- * @param {SweetAlert2} instance
3505
- * @param {any} value
3546
+ * @param {DocumentFragment} templateContent
3547
+ * @returns {SweetAlertOptions}
3506
3548
  */
3507
3549
 
3508
3550
 
3509
- const confirm = (instance, value) => {
3510
- const innerParams = privateProps.innerParams.get(instance || undefined);
3551
+ const getSwalInput = templateContent => {
3552
+ const result = {};
3553
+ /** @type {HTMLElement} */
3511
3554
 
3512
- if (innerParams.showLoaderOnConfirm) {
3513
- showLoading();
3514
- }
3555
+ const input = templateContent.querySelector('swal-input');
3515
3556
 
3516
- if (innerParams.preConfirm) {
3517
- instance.resetValidationMessage();
3518
- 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
3557
+ if (input) {
3558
+ showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
3559
+ /** @type {SweetAlertInput} */
3560
+ // @ts-ignore
3519
3561
 
3520
- const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
3521
- preConfirmPromise.then(preConfirmValue => {
3522
- if (isVisible(getValidationMessage()) || preConfirmValue === false) {
3523
- instance.hideLoading();
3524
- handleAwaitingPromise(instance);
3525
- } else {
3526
- succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
3527
- }
3528
- }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
3529
- } else {
3530
- succeedWith(instance, value);
3531
- }
3532
- };
3562
+ result.input = input.getAttribute('type') || 'text';
3533
3563
 
3534
- const handlePopupClick = (instance, domCache, dismissWith) => {
3535
- const innerParams = privateProps.innerParams.get(instance);
3564
+ if (input.hasAttribute('label')) {
3565
+ result.inputLabel = input.getAttribute('label');
3566
+ }
3536
3567
 
3537
- if (innerParams.toast) {
3538
- handleToastClick(instance, domCache, dismissWith);
3539
- } else {
3540
- // Ignore click events that had mousedown on the popup but mouseup on the container
3541
- // This can happen when the user drags a slider
3542
- handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup
3568
+ if (input.hasAttribute('placeholder')) {
3569
+ result.inputPlaceholder = input.getAttribute('placeholder');
3570
+ }
3543
3571
 
3544
- handleContainerMousedown(domCache);
3545
- handleModalClick(instance, domCache, dismissWith);
3572
+ if (input.hasAttribute('value')) {
3573
+ result.inputValue = input.getAttribute('value');
3574
+ }
3546
3575
  }
3547
- };
3576
+ /** @type {HTMLElement[]} */
3548
3577
 
3549
- const handleToastClick = (instance, domCache, dismissWith) => {
3550
- // Closing toast by internal click
3551
- domCache.popup.onclick = () => {
3552
- const innerParams = privateProps.innerParams.get(instance);
3553
3578
 
3554
- if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
3555
- return;
3556
- }
3579
+ const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
3557
3580
 
3558
- dismissWith(DismissReason.close);
3559
- };
3581
+ if (inputOptions.length) {
3582
+ result.inputOptions = {};
3583
+ inputOptions.forEach(option => {
3584
+ showWarningsForAttributes(option, ['value']);
3585
+ const optionValue = option.getAttribute('value');
3586
+ const optionName = option.innerHTML;
3587
+ result.inputOptions[optionValue] = optionName;
3588
+ });
3589
+ }
3590
+
3591
+ return result;
3560
3592
  };
3561
3593
  /**
3562
- * @param {*} innerParams
3563
- * @returns {boolean}
3594
+ * @param {DocumentFragment} templateContent
3595
+ * @param {string[]} paramNames
3596
+ * @returns {SweetAlertOptions}
3564
3597
  */
3565
3598
 
3566
3599
 
3567
- const isAnyButtonShown = innerParams => {
3568
- return innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton;
3569
- };
3570
-
3571
- let ignoreOutsideClick = false;
3600
+ const getSwalStringParams = (templateContent, paramNames) => {
3601
+ const result = {};
3572
3602
 
3573
- const handleModalMousedown = domCache => {
3574
- domCache.popup.onmousedown = () => {
3575
- domCache.container.onmouseup = function (e) {
3576
- domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't
3577
- // have any other direct children aside of the popup
3603
+ for (const i in paramNames) {
3604
+ const paramName = paramNames[i];
3605
+ /** @type {HTMLElement} */
3578
3606
 
3579
- if (e.target === domCache.container) {
3580
- ignoreOutsideClick = true;
3581
- }
3582
- };
3583
- };
3584
- };
3607
+ const tag = templateContent.querySelector(paramName);
3585
3608
 
3586
- const handleContainerMousedown = domCache => {
3587
- domCache.container.onmousedown = () => {
3588
- domCache.popup.onmouseup = function (e) {
3589
- domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup
3609
+ if (tag) {
3610
+ showWarningsForAttributes(tag, []);
3611
+ result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
3612
+ }
3613
+ }
3590
3614
 
3591
- if (e.target === domCache.popup || domCache.popup.contains(e.target)) {
3592
- ignoreOutsideClick = true;
3593
- }
3594
- };
3595
- };
3615
+ return result;
3596
3616
  };
3617
+ /**
3618
+ * @param {DocumentFragment} templateContent
3619
+ */
3597
3620
 
3598
- const handleModalClick = (instance, domCache, dismissWith) => {
3599
- domCache.container.onclick = e => {
3600
- const innerParams = privateProps.innerParams.get(instance);
3601
3621
 
3602
- if (ignoreOutsideClick) {
3603
- ignoreOutsideClick = false;
3604
- return;
3605
- }
3622
+ const showWarningsForElements = templateContent => {
3623
+ const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
3624
+ Array.from(templateContent.children).forEach(el => {
3625
+ const tagName = el.tagName.toLowerCase();
3606
3626
 
3607
- if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
3608
- dismissWith(DismissReason.backdrop);
3627
+ if (!allowedElements.includes(tagName)) {
3628
+ warn("Unrecognized element <".concat(tagName, ">"));
3609
3629
  }
3610
- };
3630
+ });
3611
3631
  };
3632
+ /**
3633
+ * @param {HTMLElement} el
3634
+ * @param {string[]} allowedAttributes
3635
+ */
3612
3636
 
3613
- const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
3614
3637
 
3615
- const isElement = elem => elem instanceof Element || isJqueryElement(elem);
3638
+ const showWarningsForAttributes = (el, allowedAttributes) => {
3639
+ Array.from(el.attributes).forEach(attribute => {
3640
+ if (allowedAttributes.indexOf(attribute.name) === -1) {
3641
+ warn(["Unrecognized attribute \"".concat(attribute.name, "\" on <").concat(el.tagName.toLowerCase(), ">."), "".concat(allowedAttributes.length ? "Allowed attributes are: ".concat(allowedAttributes.join(', ')) : 'To set the value, use HTML within the element.')]);
3642
+ }
3643
+ });
3644
+ };
3616
3645
 
3617
- const argsToParams = args => {
3618
- const params = {};
3646
+ const SHOW_CLASS_TIMEOUT = 10;
3647
+ /**
3648
+ * Open popup, add necessary classes and styles, fix scrollbar
3649
+ *
3650
+ * @param {SweetAlertOptions} params
3651
+ */
3619
3652
 
3620
- if (typeof args[0] === 'object' && !isElement(args[0])) {
3621
- Object.assign(params, args[0]);
3622
- } else {
3623
- ['title', 'html', 'icon'].forEach((name, index) => {
3624
- const arg = args[index];
3653
+ const openPopup = params => {
3654
+ const container = getContainer();
3655
+ const popup = getPopup();
3625
3656
 
3626
- if (typeof arg === 'string' || isElement(arg)) {
3627
- params[name] = arg;
3628
- } else if (arg !== undefined) {
3629
- error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg));
3630
- }
3631
- });
3657
+ if (typeof params.willOpen === 'function') {
3658
+ params.willOpen(popup);
3632
3659
  }
3633
3660
 
3634
- return params;
3635
- };
3661
+ const bodyStyles = window.getComputedStyle(document.body);
3662
+ const initialBodyOverflow = bodyStyles.overflowY;
3663
+ addClasses$1(container, popup, params); // scrolling is 'hidden' until animation is done, after that 'auto'
3636
3664
 
3637
- function fire() {
3638
- const Swal = this; // eslint-disable-line @typescript-eslint/no-this-alias
3665
+ setTimeout(() => {
3666
+ setScrollingVisibility(container, popup);
3667
+ }, SHOW_CLASS_TIMEOUT);
3639
3668
 
3640
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3641
- args[_key] = arguments[_key];
3669
+ if (isModal()) {
3670
+ fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow);
3671
+ setAriaHidden();
3642
3672
  }
3643
3673
 
3644
- return new Swal(...args);
3645
- }
3674
+ if (!isToast() && !globalState.previousActiveElement) {
3675
+ globalState.previousActiveElement = document.activeElement;
3676
+ }
3677
+
3678
+ if (typeof params.didOpen === 'function') {
3679
+ setTimeout(() => params.didOpen(popup));
3680
+ }
3646
3681
 
3682
+ removeClass(container, swalClasses['no-transition']);
3683
+ };
3647
3684
  /**
3648
- * Returns an extended version of `Swal` containing `params` as defaults.
3649
- * Useful for reusing Swal configuration.
3650
- *
3651
- * For example:
3652
- *
3653
- * Before:
3654
- * const textPromptOptions = { input: 'text', showCancelButton: true }
3655
- * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
3656
- * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
3657
- *
3658
- * After:
3659
- * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
3660
- * const {value: firstName} = await TextPrompt('What is your first name?')
3661
- * const {value: lastName} = await TextPrompt('What is your last name?')
3662
- *
3663
- * @param mixinParams
3685
+ * @param {AnimationEvent} event
3664
3686
  */
3665
- function mixin(mixinParams) {
3666
- class MixinSwal extends this {
3667
- _main(params, priorityMixinParams) {
3668
- return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
3669
- }
3670
3687
 
3671
- }
3688
+ const swalOpenAnimationFinished = event => {
3689
+ const popup = getPopup();
3672
3690
 
3673
- return MixinSwal;
3674
- }
3691
+ if (event.target !== popup) {
3692
+ return;
3693
+ }
3675
3694
 
3695
+ const container = getContainer();
3696
+ popup.removeEventListener(animationEndEvent, swalOpenAnimationFinished);
3697
+ container.style.overflowY = 'auto';
3698
+ };
3676
3699
  /**
3677
- * If `timer` parameter is set, returns number of milliseconds of timer remained.
3678
- * Otherwise, returns undefined.
3700
+ * @param {HTMLElement} container
3701
+ * @param {HTMLElement} popup
3679
3702
  */
3680
3703
 
3681
- const getTimerLeft = () => {
3682
- return globalState.timeout && globalState.timeout.getTimerLeft();
3704
+
3705
+ const setScrollingVisibility = (container, popup) => {
3706
+ if (animationEndEvent && hasCssAnimation(popup)) {
3707
+ container.style.overflowY = 'hidden';
3708
+ popup.addEventListener(animationEndEvent, swalOpenAnimationFinished);
3709
+ } else {
3710
+ container.style.overflowY = 'auto';
3711
+ }
3683
3712
  };
3684
3713
  /**
3685
- * Stop timer. Returns number of milliseconds of timer remained.
3686
- * If `timer` parameter isn't set, returns undefined.
3714
+ * @param {HTMLElement} container
3715
+ * @param {boolean} scrollbarPadding
3716
+ * @param {string} initialBodyOverflow
3687
3717
  */
3688
3718
 
3689
- const stopTimer = () => {
3690
- if (globalState.timeout) {
3691
- stopTimerProgressBar();
3692
- return globalState.timeout.stop();
3693
- }
3719
+
3720
+ const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
3721
+ iOSfix();
3722
+
3723
+ if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
3724
+ fixScrollbar();
3725
+ } // sweetalert2/issues/1247
3726
+
3727
+
3728
+ setTimeout(() => {
3729
+ container.scrollTop = 0;
3730
+ });
3694
3731
  };
3695
3732
  /**
3696
- * Resume timer. Returns number of milliseconds of timer remained.
3697
- * If `timer` parameter isn't set, returns undefined.
3733
+ * @param {HTMLElement} container
3734
+ * @param {HTMLElement} popup
3735
+ * @param {SweetAlertOptions} params
3698
3736
  */
3699
3737
 
3700
- const resumeTimer = () => {
3701
- if (globalState.timeout) {
3702
- const remaining = globalState.timeout.start();
3703
- animateTimerProgressBar(remaining);
3704
- return remaining;
3738
+
3739
+ const addClasses$1 = (container, popup, params) => {
3740
+ addClass(container, params.showClass.backdrop); // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
3741
+
3742
+ popup.style.setProperty('opacity', '0', 'important');
3743
+ show(popup, 'grid');
3744
+ setTimeout(() => {
3745
+ // Animate popup right after showing it
3746
+ addClass(popup, params.showClass.popup); // and remove the opacity workaround
3747
+
3748
+ popup.style.removeProperty('opacity');
3749
+ }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
3750
+
3751
+ addClass([document.documentElement, document.body], swalClasses.shown);
3752
+
3753
+ if (params.heightAuto && params.backdrop && !params.toast) {
3754
+ addClass([document.documentElement, document.body], swalClasses['height-auto']);
3705
3755
  }
3706
3756
  };
3707
- /**
3708
- * Resume timer. Returns number of milliseconds of timer remained.
3709
- * If `timer` parameter isn't set, returns undefined.
3710
- */
3711
3757
 
3712
- const toggleTimer = () => {
3713
- const timer = globalState.timeout;
3714
- return timer && (timer.running ? stopTimer() : resumeTimer());
3758
+ var defaultInputValidators = {
3759
+ /**
3760
+ * @param {string} string
3761
+ * @param {string} validationMessage
3762
+ * @returns {Promise<void | string>}
3763
+ */
3764
+ email: (string, validationMessage) => {
3765
+ return /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
3766
+ },
3767
+
3768
+ /**
3769
+ * @param {string} string
3770
+ * @param {string} validationMessage
3771
+ * @returns {Promise<void | string>}
3772
+ */
3773
+ url: (string, validationMessage) => {
3774
+ // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
3775
+ 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');
3776
+ }
3715
3777
  };
3778
+
3716
3779
  /**
3717
- * Increase timer. Returns number of milliseconds of an updated timer.
3718
- * If `timer` parameter isn't set, returns undefined.
3780
+ * @param {SweetAlertOptions} params
3719
3781
  */
3720
3782
 
3721
- const increaseTimer = n => {
3722
- if (globalState.timeout) {
3723
- const remaining = globalState.timeout.increase(n);
3724
- animateTimerProgressBar(remaining, true);
3725
- return remaining;
3783
+ function setDefaultInputValidators(params) {
3784
+ // Use default `inputValidator` for supported input types if not provided
3785
+ if (!params.inputValidator) {
3786
+ Object.keys(defaultInputValidators).forEach(key => {
3787
+ if (params.input === key) {
3788
+ params.inputValidator = defaultInputValidators[key];
3789
+ }
3790
+ });
3726
3791
  }
3727
- };
3792
+ }
3728
3793
  /**
3729
- * Check if timer is running. Returns true if timer is running
3730
- * or false if timer is paused or stopped.
3731
- * If `timer` parameter isn't set, returns undefined
3794
+ * @param {SweetAlertOptions} params
3732
3795
  */
3733
3796
 
3734
- const isTimerRunning = () => {
3735
- return globalState.timeout && globalState.timeout.isRunning();
3736
- };
3737
-
3738
- let bodyClickListenerAdded = false;
3739
- const clickHandlers = {};
3740
- function bindClickHandler() {
3741
- let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template';
3742
- clickHandlers[attr] = this;
3743
3797
 
3744
- if (!bodyClickListenerAdded) {
3745
- document.body.addEventListener('click', bodyClickListener);
3746
- bodyClickListenerAdded = true;
3798
+ function validateCustomTargetElement(params) {
3799
+ // Determine if the custom target element is valid
3800
+ if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
3801
+ warn('Target parameter is not valid, defaulting to "body"');
3802
+ params.target = 'body';
3747
3803
  }
3748
3804
  }
3805
+ /**
3806
+ * Set type, text and actions on popup
3807
+ *
3808
+ * @param {SweetAlertOptions} params
3809
+ */
3749
3810
 
3750
- const bodyClickListener = event => {
3751
- for (let el = event.target; el && el !== document; el = el.parentNode) {
3752
- for (const attr in clickHandlers) {
3753
- const template = el.getAttribute(attr);
3754
3811
 
3755
- if (template) {
3756
- clickHandlers[attr].fire({
3757
- template
3758
- });
3759
- return;
3760
- }
3761
- }
3812
+ function setParameters(params) {
3813
+ setDefaultInputValidators(params); // showLoaderOnConfirm && preConfirm
3814
+
3815
+ if (params.showLoaderOnConfirm && !params.preConfirm) {
3816
+ 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');
3762
3817
  }
3763
- };
3764
3818
 
3819
+ validateCustomTargetElement(params); // Replace newlines with <br> in title
3765
3820
 
3821
+ if (typeof params.title === 'string') {
3822
+ params.title = params.title.split('\n').join('<br />');
3823
+ }
3766
3824
 
3767
- var staticMethods = /*#__PURE__*/Object.freeze({
3768
- isValidParameter: isValidParameter,
3769
- isUpdatableParameter: isUpdatableParameter,
3770
- isDeprecatedParameter: isDeprecatedParameter,
3771
- argsToParams: argsToParams,
3772
- isVisible: isVisible$1,
3773
- clickConfirm: clickConfirm,
3774
- clickDeny: clickDeny,
3775
- clickCancel: clickCancel,
3776
- getContainer: getContainer,
3777
- getPopup: getPopup,
3778
- getTitle: getTitle,
3779
- getHtmlContainer: getHtmlContainer,
3780
- getImage: getImage,
3781
- getIcon: getIcon,
3782
- getInputLabel: getInputLabel,
3783
- getCloseButton: getCloseButton,
3784
- getActions: getActions,
3785
- getConfirmButton: getConfirmButton,
3786
- getDenyButton: getDenyButton,
3787
- getCancelButton: getCancelButton,
3788
- getLoader: getLoader,
3789
- getFooter: getFooter,
3790
- getTimerProgressBar: getTimerProgressBar,
3791
- getFocusableElements: getFocusableElements,
3792
- getValidationMessage: getValidationMessage,
3793
- isLoading: isLoading,
3794
- fire: fire,
3795
- mixin: mixin,
3796
- showLoading: showLoading,
3797
- enableLoading: showLoading,
3798
- getTimerLeft: getTimerLeft,
3799
- stopTimer: stopTimer,
3800
- resumeTimer: resumeTimer,
3801
- toggleTimer: toggleTimer,
3802
- increaseTimer: increaseTimer,
3803
- isTimerRunning: isTimerRunning,
3804
- bindClickHandler: bindClickHandler
3805
- });
3825
+ init(params);
3826
+ }
3806
3827
 
3807
3828
  let currentInstance;
3808
3829
 
@@ -4062,7 +4083,7 @@
4062
4083
  };
4063
4084
  });
4064
4085
  SweetAlert.DismissReason = DismissReason;
4065
- SweetAlert.version = '11.4.28';
4086
+ SweetAlert.version = '11.4.31';
4066
4087
 
4067
4088
  const Swal = SweetAlert; // @ts-ignore
4068
4089
 
@@ -4073,4 +4094,4 @@
4073
4094
  }));
4074
4095
  if (typeof this !== 'undefined' && this.Sweetalert2){ this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
4075
4096
 
4076
- "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,".swal2-popup.swal2-toast{box-sizing:border-box;grid-column:1/4!important;grid-row:1/4!important;grid-template-columns:1fr 99fr 1fr;padding:1em;overflow-y:hidden;background:#fff;box-shadow:0 0 1px hsla(0deg,0%,0%,.075),0 1px 2px hsla(0deg,0%,0%,.075),1px 2px 4px hsla(0deg,0%,0%,.075),1px 3px 8px hsla(0deg,0%,0%,.075),2px 4px 16px hsla(0deg,0%,0%,.075);pointer-events:all}.swal2-popup.swal2-toast>*{grid-column:2}.swal2-popup.swal2-toast .swal2-title{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.5em;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-popup.swal2-toast .swal2-html-container{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-popup.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-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-popup.swal2-toast .swal2-styled{margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}.swal2-container{display:grid;position:fixed;z-index:1060;top:0;right:0;bottom:0;left: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(-webkit-min-content,auto) minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto);grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);height:100%;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:0 0!important}.swal2-container.swal2-bottom-start,.swal2-container.swal2-center-start,.swal2-container.swal2-top-start{grid-template-columns:minmax(0,1fr) auto auto}.swal2-container.swal2-bottom,.swal2-container.swal2-center,.swal2-container.swal2-top{grid-template-columns:auto minmax(0,1fr) auto}.swal2-container.swal2-bottom-end,.swal2-container.swal2-center-end,.swal2-container.swal2-top-end{grid-template-columns:auto auto minmax(0,1fr)}.swal2-container.swal2-top-start>.swal2-popup{align-self:start}.swal2-container.swal2-top>.swal2-popup{grid-column:2;align-self:start;justify-self:center}.swal2-container.swal2-top-end>.swal2-popup,.swal2-container.swal2-top-right>.swal2-popup{grid-column:3;align-self:start;justify-self:end}.swal2-container.swal2-center-left>.swal2-popup,.swal2-container.swal2-center-start>.swal2-popup{grid-row:2;align-self:center}.swal2-container.swal2-center>.swal2-popup{grid-column:2;grid-row:2;align-self:center;justify-self:center}.swal2-container.swal2-center-end>.swal2-popup,.swal2-container.swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;align-self:center;justify-self:end}.swal2-container.swal2-bottom-left>.swal2-popup,.swal2-container.swal2-bottom-start>.swal2-popup{grid-column:1;grid-row:3;align-self:end}.swal2-container.swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;justify-self:center;align-self:end}.swal2-container.swal2-bottom-end>.swal2-popup,.swal2-container.swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;align-self:end;justify-self:end}.swal2-container.swal2-grow-fullscreen>.swal2-popup,.swal2-container.swal2-grow-row>.swal2-popup{grid-column:1/4;width:100%}.swal2-container.swal2-grow-column>.swal2-popup,.swal2-container.swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}.swal2-container.swal2-no-transition{transition:none!important}.swal2-popup{display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0,100%);width:32em;max-width:100%;padding:0 0 1.25em;border:none;border-radius:5px;background:#fff;color:#545454;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-title{position:relative;max-width:100%;margin:0;padding:.8em 1em 0;color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px transparent;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}.swal2-styled.swal2-confirm:focus{box-shadow:0 0 0 3px rgba(112,102,224,.5)}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}.swal2-styled.swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}.swal2-styled.swal2-cancel:focus{box-shadow:0 0 0 3px rgba(110,120,129,.5)}.swal2-styled.swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled:focus{outline:0}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1em 0 0;padding:1em 1em 0;border-top:1px solid #eee;color:inherit;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto!important;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:2em auto 1em}.swal2-close{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:color .1s,box-shadow .1s;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-family:monospace;font-size:2.5em;cursor:pointer;justify-self:end}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-html-container{z-index:1;justify-content:center;margin:1em 1.6em .3em;padding:0;overflow:auto;color:inherit;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em 2em 3px}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:0 0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em 2em 3px;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-file{width:75%;margin-right:auto;margin-left:auto;background:0 0;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:0 0;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{flex-shrink:0;margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto 0}.swal2-validation-message{align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.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}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.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}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-warning.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-warning.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .5s;animation:swal2-animate-i-mark .5s}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-info.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-info.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .8s;animation:swal2-animate-i-mark .8s}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-question.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-question.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-question-mark .8s;animation:swal2-animate-question-mark .8s}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.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)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:0 0;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.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}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.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}.leave-russia-now-and-apply-your-skills-to-the-world{display:flex;position:fixed;z-index:1939;top:0;right:0;bottom:0;left:0;flex-direction:column;align-items:center;justify-content:center;padding:25px 0 20px;background:#20232a;color:#fff;text-align:center}.leave-russia-now-and-apply-your-skills-to-the-world div{max-width:560px;margin:10px;line-height:146%}.leave-russia-now-and-apply-your-skills-to-the-world iframe{max-width:100%;max-height:55.5555555556vmin;margin:16px auto}.leave-russia-now-and-apply-your-skills-to-the-world strong{border-bottom:2px dashed #fff}.leave-russia-now-and-apply-your-skills-to-the-world button{display:flex;position:fixed;z-index:1940;top:0;right:0;align-items:center;justify-content:center;width:48px;height:48px;margin-right:10px;margin-bottom:-10px;border:none;background:0 0;color:#aaa;font-size:48px;font-weight:700;cursor:pointer}.leave-russia-now-and-apply-your-skills-to-the-world button:hover{color:#fff}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-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:-.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-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-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}}@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}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-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:-.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-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-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-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}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-webkit-keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@-webkit-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-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}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{background-color:transparent!important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:transparent;pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}");
4097
+ "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,".swal2-popup.swal2-toast{box-sizing:border-box;grid-column:1/4!important;grid-row:1/4!important;grid-template-columns:1fr 99fr 1fr;padding:1em;overflow-y:hidden;background:#fff;box-shadow:0 0 1px hsla(0deg,0%,0%,.075),0 1px 2px hsla(0deg,0%,0%,.075),1px 2px 4px hsla(0deg,0%,0%,.075),1px 3px 8px hsla(0deg,0%,0%,.075),2px 4px 16px hsla(0deg,0%,0%,.075);pointer-events:all}.swal2-popup.swal2-toast>*{grid-column:2}.swal2-popup.swal2-toast .swal2-title{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.5em;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-popup.swal2-toast .swal2-html-container{margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-popup.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-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-popup.swal2-toast .swal2-styled{margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}.swal2-container{display:grid;position:fixed;z-index:1060;top:0;right:0;bottom:0;left: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(-webkit-min-content,auto) minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto);grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);height:100%;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:0 0!important}.swal2-container.swal2-bottom-start,.swal2-container.swal2-center-start,.swal2-container.swal2-top-start{grid-template-columns:minmax(0,1fr) auto auto}.swal2-container.swal2-bottom,.swal2-container.swal2-center,.swal2-container.swal2-top{grid-template-columns:auto minmax(0,1fr) auto}.swal2-container.swal2-bottom-end,.swal2-container.swal2-center-end,.swal2-container.swal2-top-end{grid-template-columns:auto auto minmax(0,1fr)}.swal2-container.swal2-top-start>.swal2-popup{align-self:start}.swal2-container.swal2-top>.swal2-popup{grid-column:2;align-self:start;justify-self:center}.swal2-container.swal2-top-end>.swal2-popup,.swal2-container.swal2-top-right>.swal2-popup{grid-column:3;align-self:start;justify-self:end}.swal2-container.swal2-center-left>.swal2-popup,.swal2-container.swal2-center-start>.swal2-popup{grid-row:2;align-self:center}.swal2-container.swal2-center>.swal2-popup{grid-column:2;grid-row:2;align-self:center;justify-self:center}.swal2-container.swal2-center-end>.swal2-popup,.swal2-container.swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;align-self:center;justify-self:end}.swal2-container.swal2-bottom-left>.swal2-popup,.swal2-container.swal2-bottom-start>.swal2-popup{grid-column:1;grid-row:3;align-self:end}.swal2-container.swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;justify-self:center;align-self:end}.swal2-container.swal2-bottom-end>.swal2-popup,.swal2-container.swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;align-self:end;justify-self:end}.swal2-container.swal2-grow-fullscreen>.swal2-popup,.swal2-container.swal2-grow-row>.swal2-popup{grid-column:1/4;width:100%}.swal2-container.swal2-grow-column>.swal2-popup,.swal2-container.swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}.swal2-container.swal2-no-transition{transition:none!important}.swal2-popup{display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0,100%);width:32em;max-width:100%;padding:0 0 1.25em;border:none;border-radius:5px;background:#fff;color:#545454;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-title{position:relative;max-width:100%;margin:0;padding:.8em 1em 0;color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px transparent;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}.swal2-styled.swal2-confirm:focus{box-shadow:0 0 0 3px rgba(112,102,224,.5)}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}.swal2-styled.swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}.swal2-styled.swal2-cancel:focus{box-shadow:0 0 0 3px rgba(110,120,129,.5)}.swal2-styled.swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled:focus{outline:0}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1em 0 0;padding:1em 1em 0;border-top:1px solid #eee;color:inherit;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto!important;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:2em auto 1em}.swal2-close{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:color .1s,box-shadow .1s;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-family:monospace;font-size:2.5em;cursor:pointer;justify-self:end}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-html-container{z-index:1;justify-content:center;margin:1em 1.6em .3em;padding:0;overflow:auto;color:inherit;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em 2em 3px}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:0 0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em 2em 3px;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-file{width:75%;margin-right:auto;margin-left:auto;background:0 0;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:0 0;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{flex-shrink:0;margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto 0}.swal2-validation-message{align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.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}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.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}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-warning.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-warning.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .5s;animation:swal2-animate-i-mark .5s}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-info.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-info.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .8s;animation:swal2-animate-i-mark .8s}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-question.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-question.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-question-mark .8s;animation:swal2-animate-question-mark .8s}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.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)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:0 0;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.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}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.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}.leave-russia-now-and-apply-your-skills-to-the-world{display:flex;position:fixed;z-index:1939;top:0;right:0;bottom:0;left:0;flex-direction:column;align-items:center;justify-content:center;padding:25px 0 20px;background:#20232a;color:#fff;text-align:center}.leave-russia-now-and-apply-your-skills-to-the-world div{max-width:560px;margin:10px;line-height:146%}.leave-russia-now-and-apply-your-skills-to-the-world iframe{max-width:100%;max-height:55.5555555556vmin;margin:16px auto}.leave-russia-now-and-apply-your-skills-to-the-world strong{border-bottom:2px dashed #fff}.leave-russia-now-and-apply-your-skills-to-the-world button{display:flex;position:fixed;z-index:1940;top:0;right:0;align-items:center;justify-content:center;width:48px;height:48px;margin-right:10px;margin-bottom:-10px;border:none;background:0 0;color:#aaa;font-size:48px;font-weight:700;cursor:pointer}.leave-russia-now-and-apply-your-skills-to-the-world button:hover{color:#fff}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-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:-.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-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-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}}@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}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-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:-.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-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-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-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}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-webkit-keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@-webkit-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-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}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{background-color:transparent!important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:transparent;pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}");