sweetalert2 11.3.0 → 11.3.4

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 (35) hide show
  1. package/README.md +13 -11
  2. package/dist/sweetalert2.all.js +1334 -1234
  3. package/dist/sweetalert2.all.min.js +2 -2
  4. package/dist/sweetalert2.css +2 -2
  5. package/dist/sweetalert2.js +1333 -1233
  6. package/dist/sweetalert2.min.css +1 -1
  7. package/dist/sweetalert2.min.js +1 -1
  8. package/package.json +15 -13
  9. package/src/SweetAlert.js +169 -1
  10. package/src/{instanceMethods/buttons-handlers.js → buttons-handlers.js} +9 -9
  11. package/src/instanceMethods/_destroy.js +1 -1
  12. package/src/instanceMethods/getInput.js +4 -1
  13. package/src/instanceMethods/update.js +2 -2
  14. package/src/instanceMethods.js +0 -1
  15. package/src/{instanceMethods/keydown-handler.js → keydown-handler.js} +6 -6
  16. package/src/{instanceMethods/popup-click-handler.js → popup-click-handler.js} +15 -11
  17. package/src/staticMethods/showLoading.js +1 -1
  18. package/src/sweetalert2.js +1 -0
  19. package/src/utils/Timer.js +1 -1
  20. package/src/utils/dom/animationEndEvent.js +2 -3
  21. package/src/utils/dom/domUtils.js +66 -13
  22. package/src/utils/dom/getters.js +9 -4
  23. package/src/utils/dom/init.js +7 -9
  24. package/src/utils/dom/inputUtils.js +3 -3
  25. package/src/utils/dom/renderers/renderIcon.js +2 -2
  26. package/src/utils/dom/renderers/renderInput.js +4 -3
  27. package/src/utils/getTemplateParams.js +7 -4
  28. package/src/utils/iosFix.js +18 -5
  29. package/src/utils/openPopup.js +1 -1
  30. package/src/utils/params.js +3 -3
  31. package/src/utils/setParameters.js +0 -1
  32. package/src/utils/utils.js +9 -8
  33. package/src/variables.scss +1 -1
  34. package/sweetalert2.d.ts +2 -2
  35. package/src/instanceMethods/_main.js +0 -168
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sweetalert2 v11.3.0
2
+ * sweetalert2 v11.3.4
3
3
  * Released under the MIT License.
4
4
  */
5
5
  (function (global, factory) {
@@ -8,14 +8,6 @@
8
8
  (global = global || self, global.Sweetalert2 = factory());
9
9
  }(this, function () { 'use strict';
10
10
 
11
- const DismissReason = Object.freeze({
12
- cancel: 'cancel',
13
- backdrop: 'backdrop',
14
- close: 'close',
15
- esc: 'esc',
16
- timer: 'timer'
17
- });
18
-
19
11
  const consolePrefix = 'SweetAlert2:';
20
12
  /**
21
13
  * Filter the unique values into a new array
@@ -35,27 +27,28 @@
35
27
  };
36
28
  /**
37
29
  * Capitalize the first letter of a string
38
- * @param str
30
+ * @param {string} str
31
+ * @returns {string}
39
32
  */
40
33
 
41
34
  const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
42
35
  /**
43
- * Convert NodeList to Array
44
- * @param nodeList
36
+ * @param {NodeList | HTMLCollection | NamedNodeMap} nodeList
37
+ * @returns {array}
45
38
  */
46
39
 
47
40
  const toArray = nodeList => Array.prototype.slice.call(nodeList);
48
41
  /**
49
- * Standardise console warnings
50
- * @param message
42
+ * Standardize console warnings
43
+ * @param {string | array} message
51
44
  */
52
45
 
53
46
  const warn = message => {
54
47
  console.warn("".concat(consolePrefix, " ").concat(typeof message === 'object' ? message.join(' ') : message));
55
48
  };
56
49
  /**
57
- * Standardise console errors
58
- * @param message
50
+ * Standardize console errors
51
+ * @param {string} message
59
52
  */
60
53
 
61
54
  const error = message => {
@@ -70,7 +63,7 @@
70
63
  const previousWarnOnceMessages = [];
71
64
  /**
72
65
  * Show a console warning, but only if it hasn't already been shown
73
- * @param message
66
+ * @param {string} message
74
67
  */
75
68
 
76
69
  const warnOnce = message => {
@@ -97,28 +90,161 @@
97
90
  const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
98
91
  const isPromise = arg => arg && Promise.resolve(arg) === arg;
99
92
 
100
- const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
93
+ const defaultParams = {
94
+ title: '',
95
+ titleText: '',
96
+ text: '',
97
+ html: '',
98
+ footer: '',
99
+ icon: undefined,
100
+ iconColor: undefined,
101
+ iconHtml: undefined,
102
+ template: undefined,
103
+ toast: false,
104
+ showClass: {
105
+ popup: 'swal2-show',
106
+ backdrop: 'swal2-backdrop-show',
107
+ icon: 'swal2-icon-show'
108
+ },
109
+ hideClass: {
110
+ popup: 'swal2-hide',
111
+ backdrop: 'swal2-backdrop-hide',
112
+ icon: 'swal2-icon-hide'
113
+ },
114
+ customClass: {},
115
+ target: 'body',
116
+ color: undefined,
117
+ backdrop: true,
118
+ heightAuto: true,
119
+ allowOutsideClick: true,
120
+ allowEscapeKey: true,
121
+ allowEnterKey: true,
122
+ stopKeydownPropagation: true,
123
+ keydownListenerCapture: false,
124
+ showConfirmButton: true,
125
+ showDenyButton: false,
126
+ showCancelButton: false,
127
+ preConfirm: undefined,
128
+ preDeny: undefined,
129
+ confirmButtonText: 'OK',
130
+ confirmButtonAriaLabel: '',
131
+ confirmButtonColor: undefined,
132
+ denyButtonText: 'No',
133
+ denyButtonAriaLabel: '',
134
+ denyButtonColor: undefined,
135
+ cancelButtonText: 'Cancel',
136
+ cancelButtonAriaLabel: '',
137
+ cancelButtonColor: undefined,
138
+ buttonsStyling: true,
139
+ reverseButtons: false,
140
+ focusConfirm: true,
141
+ focusDeny: false,
142
+ focusCancel: false,
143
+ returnFocus: true,
144
+ showCloseButton: false,
145
+ closeButtonHtml: '×',
146
+ closeButtonAriaLabel: 'Close this dialog',
147
+ loaderHtml: '',
148
+ showLoaderOnConfirm: false,
149
+ showLoaderOnDeny: false,
150
+ imageUrl: undefined,
151
+ imageWidth: undefined,
152
+ imageHeight: undefined,
153
+ imageAlt: '',
154
+ timer: undefined,
155
+ timerProgressBar: false,
156
+ width: undefined,
157
+ padding: undefined,
158
+ background: undefined,
159
+ input: undefined,
160
+ inputPlaceholder: '',
161
+ inputLabel: '',
162
+ inputValue: '',
163
+ inputOptions: {},
164
+ inputAutoTrim: true,
165
+ inputAttributes: {},
166
+ inputValidator: undefined,
167
+ returnInputValueOnDeny: false,
168
+ validationMessage: undefined,
169
+ grow: false,
170
+ position: 'center',
171
+ progressSteps: [],
172
+ currentProgressStep: undefined,
173
+ progressStepsDistance: undefined,
174
+ willOpen: undefined,
175
+ didOpen: undefined,
176
+ didRender: undefined,
177
+ willClose: undefined,
178
+ didClose: undefined,
179
+ didDestroy: undefined,
180
+ scrollbarPadding: true
181
+ };
182
+ 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'];
183
+ const deprecatedParams = {};
184
+ const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
185
+ /**
186
+ * Is valid parameter
187
+ * @param {string} paramName
188
+ */
101
189
 
102
- const isElement = elem => elem instanceof Element || isJqueryElement(elem);
190
+ const isValidParameter = paramName => {
191
+ return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
192
+ };
193
+ /**
194
+ * Is valid parameter for Swal.update() method
195
+ * @param {string} paramName
196
+ */
103
197
 
104
- const argsToParams = args => {
105
- const params = {};
198
+ const isUpdatableParameter = paramName => {
199
+ return updatableParams.indexOf(paramName) !== -1;
200
+ };
201
+ /**
202
+ * Is deprecated parameter
203
+ * @param {string} paramName
204
+ */
106
205
 
107
- if (typeof args[0] === 'object' && !isElement(args[0])) {
108
- Object.assign(params, args[0]);
109
- } else {
110
- ['title', 'html', 'icon'].forEach((name, index) => {
111
- const arg = args[index];
206
+ const isDeprecatedParameter = paramName => {
207
+ return deprecatedParams[paramName];
208
+ };
112
209
 
113
- if (typeof arg === 'string' || isElement(arg)) {
114
- params[name] = arg;
115
- } else if (arg !== undefined) {
116
- error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg));
117
- }
118
- });
210
+ const checkIfParamIsValid = param => {
211
+ if (!isValidParameter(param)) {
212
+ warn("Unknown parameter \"".concat(param, "\""));
119
213
  }
214
+ };
120
215
 
121
- return params;
216
+ const checkIfToastParamIsValid = param => {
217
+ if (toastIncompatibleParams.includes(param)) {
218
+ warn("The parameter \"".concat(param, "\" is incompatible with toasts"));
219
+ }
220
+ };
221
+
222
+ const checkIfParamIsDeprecated = param => {
223
+ if (isDeprecatedParameter(param)) {
224
+ warnAboutDeprecation(param, isDeprecatedParameter(param));
225
+ }
226
+ };
227
+ /**
228
+ * Show relevant warnings for given params
229
+ *
230
+ * @param params
231
+ */
232
+
233
+
234
+ const showWarningsForParams = params => {
235
+ if (!params.backdrop && params.allowOutsideClick) {
236
+ warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
237
+ }
238
+
239
+ for (const param in params) {
240
+ checkIfParamIsValid(param);
241
+
242
+ if (params.toast) {
243
+ checkIfToastParamIsValid(param);
244
+ }
245
+
246
+ checkIfParamIsDeprecated(param);
247
+ }
122
248
  };
123
249
 
124
250
  const swalPrefix = 'swal2-';
@@ -134,6 +260,12 @@
134
260
  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']);
135
261
  const iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']);
136
262
 
263
+ /**
264
+ * Gets the popup container which contains the backdrop and the popup itself.
265
+ *
266
+ * @returns {HTMLElement | null}
267
+ */
268
+
137
269
  const getContainer = () => document.body.querySelector(".".concat(swalClasses.container));
138
270
  const elementBySelector = selectorString => {
139
271
  const container = getContainer();
@@ -165,12 +297,12 @@
165
297
  const getFocusableElements = () => {
166
298
  const focusableElementsWithTabindex = toArray(getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')) // sort according to tabindex
167
299
  .sort((a, b) => {
168
- a = parseInt(a.getAttribute('tabindex'));
169
- b = parseInt(b.getAttribute('tabindex'));
300
+ const tabindexA = parseInt(a.getAttribute('tabindex'));
301
+ const tabindexB = parseInt(b.getAttribute('tabindex'));
170
302
 
171
- if (a > b) {
303
+ if (tabindexA > tabindexB) {
172
304
  return 1;
173
- } else if (a < b) {
305
+ } else if (tabindexA < tabindexB) {
174
306
  return -1;
175
307
  }
176
308
 
@@ -192,8 +324,15 @@
192
324
  const states = {
193
325
  previousBodyPadding: null
194
326
  };
327
+ /**
328
+ * Securely set innerHTML of an element
329
+ * https://github.com/sweetalert2/sweetalert2/issues/1926
330
+ *
331
+ * @param {HTMLElement} elem
332
+ * @param {string} html
333
+ */
334
+
195
335
  const setInnerHtml = (elem, html) => {
196
- // #1926
197
336
  elem.textContent = '';
198
337
 
199
338
  if (html) {
@@ -207,6 +346,12 @@
207
346
  });
208
347
  }
209
348
  };
349
+ /**
350
+ * @param {HTMLElement} elem
351
+ * @param {string} className
352
+ * @returns {boolean}
353
+ */
354
+
210
355
  const hasClass = (elem, className) => {
211
356
  if (!className) {
212
357
  return false;
@@ -242,6 +387,12 @@
242
387
  addClass(elem, params.customClass[className]);
243
388
  }
244
389
  };
390
+ /**
391
+ * @param {HTMLElement} popup
392
+ * @param {string} inputType
393
+ * @returns {HTMLInputElement | null}
394
+ */
395
+
245
396
  const getInput = (popup, inputType) => {
246
397
  if (!inputType) {
247
398
  return null;
@@ -251,21 +402,25 @@
251
402
  case 'select':
252
403
  case 'textarea':
253
404
  case 'file':
254
- return getChildByClass(popup, swalClasses[inputType]);
405
+ return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses[inputType]));
255
406
 
256
407
  case 'checkbox':
257
- return popup.querySelector(".".concat(swalClasses.checkbox, " input"));
408
+ return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.checkbox, " input"));
258
409
 
259
410
  case 'radio':
260
- return popup.querySelector(".".concat(swalClasses.radio, " input:checked")) || popup.querySelector(".".concat(swalClasses.radio, " input:first-child"));
411
+ return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.radio, " input:checked")) || popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.radio, " input:first-child"));
261
412
 
262
413
  case 'range':
263
- return popup.querySelector(".".concat(swalClasses.range, " input"));
414
+ return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.range, " input"));
264
415
 
265
416
  default:
266
- return getChildByClass(popup, swalClasses.input);
417
+ return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.input));
267
418
  }
268
419
  };
420
+ /**
421
+ * @param {HTMLInputElement} input
422
+ */
423
+
269
424
  const focusInput = input => {
270
425
  input.focus(); // place cursor at end of text in text input
271
426
 
@@ -276,6 +431,12 @@
276
431
  input.value = val;
277
432
  }
278
433
  };
434
+ /**
435
+ * @param {HTMLElement | HTMLElement[] | null} target
436
+ * @param {string | string[]} classList
437
+ * @param {boolean} condition
438
+ */
439
+
279
440
  const toggleClass = (target, classList, condition) => {
280
441
  if (!target || !classList) {
281
442
  return;
@@ -286,7 +447,7 @@
286
447
  }
287
448
 
288
449
  classList.forEach(className => {
289
- if (target.forEach) {
450
+ if (Array.isArray(target)) {
290
451
  target.forEach(elem => {
291
452
  condition ? elem.classList.add(className) : elem.classList.remove(className);
292
453
  });
@@ -295,19 +456,45 @@
295
456
  }
296
457
  });
297
458
  };
459
+ /**
460
+ * @param {HTMLElement | HTMLElement[] | null} target
461
+ * @param {string | string[]} classList
462
+ */
463
+
298
464
  const addClass = (target, classList) => {
299
465
  toggleClass(target, classList, true);
300
466
  };
467
+ /**
468
+ * @param {HTMLElement | HTMLElement[] | null} target
469
+ * @param {string | string[]} classList
470
+ */
471
+
301
472
  const removeClass = (target, classList) => {
302
473
  toggleClass(target, classList, false);
303
474
  };
304
- const getChildByClass = (elem, className) => {
305
- for (let i = 0; i < elem.childNodes.length; i++) {
306
- if (hasClass(elem.childNodes[i], className)) {
307
- return elem.childNodes[i];
475
+ /**
476
+ * Get direct child of an element by class name
477
+ *
478
+ * @param {HTMLElement} elem
479
+ * @param {string} className
480
+ * @returns {HTMLElement | null}
481
+ */
482
+
483
+ const getDirectChildByClass = (elem, className) => {
484
+ const childNodes = toArray(elem.childNodes);
485
+
486
+ for (let i = 0; i < childNodes.length; i++) {
487
+ if (hasClass(childNodes[i], className)) {
488
+ return childNodes[i];
308
489
  }
309
490
  }
310
491
  };
492
+ /**
493
+ * @param {HTMLElement} elem
494
+ * @param {string} property
495
+ * @param {*} value
496
+ */
497
+
311
498
  const applyNumericalStyle = (elem, property, value) => {
312
499
  if (value === "".concat(parseInt(value))) {
313
500
  value = parseInt(value);
@@ -319,10 +506,19 @@
319
506
  elem.style.removeProperty(property);
320
507
  }
321
508
  };
509
+ /**
510
+ * @param {HTMLElement} elem
511
+ * @param {string} display
512
+ */
513
+
322
514
  const show = function (elem) {
323
515
  let display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'flex';
324
516
  elem.style.display = display;
325
517
  };
518
+ /**
519
+ * @param {HTMLElement} elem
520
+ */
521
+
326
522
  const hide = elem => {
327
523
  elem.style.display = 'none';
328
524
  };
@@ -369,7 +565,7 @@
369
565
  timerProgressBar.style.removeProperty('transition');
370
566
  timerProgressBar.style.width = '100%';
371
567
  const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
372
- const timerProgressBarPercent = parseInt(timerProgressBarWidth / timerProgressBarFullWidth * 100);
568
+ const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
373
569
  timerProgressBar.style.removeProperty('transition');
374
570
  timerProgressBar.style.width = "".concat(timerProgressBarPercent, "%");
375
571
  };
@@ -377,6 +573,37 @@
377
573
  // Detect Node env
378
574
  const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
379
575
 
576
+ const RESTORE_FOCUS_TIMEOUT = 100;
577
+
578
+ const globalState = {};
579
+
580
+ const focusPreviousActiveElement = () => {
581
+ if (globalState.previousActiveElement && globalState.previousActiveElement.focus) {
582
+ globalState.previousActiveElement.focus();
583
+ globalState.previousActiveElement = null;
584
+ } else if (document.body) {
585
+ document.body.focus();
586
+ }
587
+ }; // Restore previous active (focused) element
588
+
589
+
590
+ const restoreActiveElement = returnFocus => {
591
+ return new Promise(resolve => {
592
+ if (!returnFocus) {
593
+ return resolve();
594
+ }
595
+
596
+ const x = window.scrollX;
597
+ const y = window.scrollY;
598
+ globalState.restoreFocusTimeout = setTimeout(() => {
599
+ focusPreviousActiveElement();
600
+ resolve();
601
+ }, RESTORE_FOCUS_TIMEOUT); // issues/900
602
+
603
+ window.scrollTo(x, y);
604
+ });
605
+ };
606
+
380
607
  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, '');
381
608
 
382
609
  const resetOldContainer = () => {
@@ -392,20 +619,18 @@
392
619
  };
393
620
 
394
621
  const resetValidationMessage = () => {
395
- if (Swal.isVisible()) {
396
- Swal.resetValidationMessage();
397
- }
622
+ globalState.currentInstance.resetValidationMessage();
398
623
  };
399
624
 
400
625
  const addInputChangeListeners = () => {
401
626
  const popup = getPopup();
402
- const input = getChildByClass(popup, swalClasses.input);
403
- const file = getChildByClass(popup, swalClasses.file);
627
+ const input = getDirectChildByClass(popup, swalClasses.input);
628
+ const file = getDirectChildByClass(popup, swalClasses.file);
404
629
  const range = popup.querySelector(".".concat(swalClasses.range, " input"));
405
630
  const rangeOutput = popup.querySelector(".".concat(swalClasses.range, " output"));
406
- const select = getChildByClass(popup, swalClasses.select);
631
+ const select = getDirectChildByClass(popup, swalClasses.select);
407
632
  const checkbox = popup.querySelector(".".concat(swalClasses.checkbox, " input"));
408
- const textarea = getChildByClass(popup, swalClasses.textarea);
633
+ const textarea = getDirectChildByClass(popup, swalClasses.textarea);
409
634
  input.oninput = resetValidationMessage;
410
635
  file.onchange = resetValidationMessage;
411
636
  select.onchange = resetValidationMessage;
@@ -513,8 +738,9 @@
513
738
  const testEl = document.createElement('div');
514
739
  const transEndEventNames = {
515
740
  WebkitAnimation: 'webkitAnimationEnd',
516
- OAnimation: 'oAnimationEnd oanimationend',
517
- animation: 'animationend'
741
+ // Chrome, Safari and Opera
742
+ animation: 'animationend' // Standard syntax
743
+
518
744
  };
519
745
 
520
746
  for (const i in transEndEventNames) {
@@ -677,7 +903,7 @@
677
903
  const rerender = !innerParams || params.input !== innerParams.input;
678
904
  inputTypes.forEach(inputType => {
679
905
  const inputClass = swalClasses[inputType];
680
- const inputContainer = getChildByClass(popup, inputClass); // set attributes
906
+ const inputContainer = getDirectChildByClass(popup, inputClass); // set attributes
681
907
 
682
908
  setAttributes(inputType, params.inputAttributes); // set class
683
909
 
@@ -765,7 +991,7 @@
765
991
 
766
992
  const getInputContainer = inputType => {
767
993
  const inputClass = swalClasses[inputType] ? swalClasses[inputType] : swalClasses.input;
768
- return getChildByClass(getPopup(), inputClass);
994
+ return getDirectChildByClass(getPopup(), inputClass);
769
995
  };
770
996
 
771
997
  const renderInputType = {};
@@ -821,8 +1047,9 @@
821
1047
  };
822
1048
 
823
1049
  renderInputType.checkbox = (checkboxContainer, params) => {
1050
+ /** @type {HTMLInputElement} */
824
1051
  const checkbox = getInput(getPopup(), 'checkbox');
825
- checkbox.value = 1;
1052
+ checkbox.value = '1';
826
1053
  checkbox.id = swalClasses.checkbox;
827
1054
  checkbox.checked = Boolean(params.inputValue);
828
1055
  const label = checkboxContainer.querySelector('span');
@@ -939,13 +1166,13 @@
939
1166
 
940
1167
  setColor(icon, params); // Success icon background color
941
1168
 
942
- adjustSuccessIconBackgoundColor(); // Custom class
1169
+ adjustSuccessIconBackgroundColor(); // Custom class
943
1170
 
944
1171
  applyCustomClass(icon, params, 'icon');
945
1172
  }; // Adjust success icon background color to match the popup background color
946
1173
 
947
1174
 
948
- const adjustSuccessIconBackgoundColor = () => {
1175
+ const adjustSuccessIconBackgroundColor = () => {
949
1176
  const popup = getPopup();
950
1177
  const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
951
1178
  const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
@@ -1144,588 +1371,13 @@
1144
1371
  }
1145
1372
  };
1146
1373
 
1147
- /*
1148
- * Global function to determine if SweetAlert2 popup is shown
1149
- */
1150
-
1151
- const isVisible$1 = () => {
1152
- return isVisible(getPopup());
1153
- };
1154
- /*
1155
- * Global function to click 'Confirm' button
1156
- */
1157
-
1158
- const clickConfirm = () => getConfirmButton() && getConfirmButton().click();
1159
- /*
1160
- * Global function to click 'Deny' button
1161
- */
1162
-
1163
- const clickDeny = () => getDenyButton() && getDenyButton().click();
1164
- /*
1165
- * Global function to click 'Cancel' button
1166
- */
1167
-
1168
- const clickCancel = () => getCancelButton() && getCancelButton().click();
1169
-
1170
- function fire() {
1171
- const Swal = this;
1172
-
1173
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1174
- args[_key] = arguments[_key];
1175
- }
1176
-
1177
- return new Swal(...args);
1178
- }
1179
-
1180
- /**
1181
- * Returns an extended version of `Swal` containing `params` as defaults.
1182
- * Useful for reusing Swal configuration.
1183
- *
1184
- * For example:
1185
- *
1186
- * Before:
1187
- * const textPromptOptions = { input: 'text', showCancelButton: true }
1188
- * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
1189
- * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
1190
- *
1191
- * After:
1192
- * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
1193
- * const {value: firstName} = await TextPrompt('What is your first name?')
1194
- * const {value: lastName} = await TextPrompt('What is your last name?')
1195
- *
1196
- * @param mixinParams
1197
- */
1198
- function mixin(mixinParams) {
1199
- class MixinSwal extends this {
1200
- _main(params, priorityMixinParams) {
1201
- return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
1202
- }
1203
-
1204
- }
1205
-
1206
- return MixinSwal;
1207
- }
1208
-
1209
- /**
1210
- * Shows loader (spinner), this is useful with AJAX requests.
1211
- * By default the loader be shown instead of the "Confirm" button.
1212
- */
1213
-
1214
- const showLoading = buttonToReplace => {
1215
- let popup = getPopup();
1216
-
1217
- if (!popup) {
1218
- Swal.fire();
1219
- }
1220
-
1221
- popup = getPopup();
1222
- const loader = getLoader();
1223
-
1224
- if (isToast()) {
1225
- hide(getIcon());
1226
- } else {
1227
- replaceButton(popup, buttonToReplace);
1228
- }
1229
-
1230
- show(loader);
1231
- popup.setAttribute('data-loading', true);
1232
- popup.setAttribute('aria-busy', true);
1233
- popup.focus();
1234
- };
1235
-
1236
- const replaceButton = (popup, buttonToReplace) => {
1237
- const actions = getActions();
1238
- const loader = getLoader();
1239
-
1240
- if (!buttonToReplace && isVisible(getConfirmButton())) {
1241
- buttonToReplace = getConfirmButton();
1242
- }
1243
-
1244
- show(actions);
1245
-
1246
- if (buttonToReplace) {
1247
- hide(buttonToReplace);
1248
- loader.setAttribute('data-button-to-replace', buttonToReplace.className);
1249
- }
1250
-
1251
- loader.parentNode.insertBefore(loader, buttonToReplace);
1252
- addClass([popup, actions], swalClasses.loading);
1253
- };
1254
-
1255
- const RESTORE_FOCUS_TIMEOUT = 100;
1256
-
1257
- const globalState = {};
1258
-
1259
- const focusPreviousActiveElement = () => {
1260
- if (globalState.previousActiveElement && globalState.previousActiveElement.focus) {
1261
- globalState.previousActiveElement.focus();
1262
- globalState.previousActiveElement = null;
1263
- } else if (document.body) {
1264
- document.body.focus();
1265
- }
1266
- }; // Restore previous active (focused) element
1267
-
1268
-
1269
- const restoreActiveElement = returnFocus => {
1270
- return new Promise(resolve => {
1271
- if (!returnFocus) {
1272
- return resolve();
1273
- }
1274
-
1275
- const x = window.scrollX;
1276
- const y = window.scrollY;
1277
- globalState.restoreFocusTimeout = setTimeout(() => {
1278
- focusPreviousActiveElement();
1279
- resolve();
1280
- }, RESTORE_FOCUS_TIMEOUT); // issues/900
1281
-
1282
- window.scrollTo(x, y);
1283
- });
1284
- };
1285
-
1286
- /**
1287
- * If `timer` parameter is set, returns number of milliseconds of timer remained.
1288
- * Otherwise, returns undefined.
1289
- */
1290
-
1291
- const getTimerLeft = () => {
1292
- return globalState.timeout && globalState.timeout.getTimerLeft();
1293
- };
1294
- /**
1295
- * Stop timer. Returns number of milliseconds of timer remained.
1296
- * If `timer` parameter isn't set, returns undefined.
1297
- */
1298
-
1299
- const stopTimer = () => {
1300
- if (globalState.timeout) {
1301
- stopTimerProgressBar();
1302
- return globalState.timeout.stop();
1303
- }
1304
- };
1305
- /**
1306
- * Resume timer. Returns number of milliseconds of timer remained.
1307
- * If `timer` parameter isn't set, returns undefined.
1308
- */
1309
-
1310
- const resumeTimer = () => {
1311
- if (globalState.timeout) {
1312
- const remaining = globalState.timeout.start();
1313
- animateTimerProgressBar(remaining);
1314
- return remaining;
1315
- }
1316
- };
1317
- /**
1318
- * Resume timer. Returns number of milliseconds of timer remained.
1319
- * If `timer` parameter isn't set, returns undefined.
1320
- */
1321
-
1322
- const toggleTimer = () => {
1323
- const timer = globalState.timeout;
1324
- return timer && (timer.running ? stopTimer() : resumeTimer());
1325
- };
1326
- /**
1327
- * Increase timer. Returns number of milliseconds of an updated timer.
1328
- * If `timer` parameter isn't set, returns undefined.
1329
- */
1330
-
1331
- const increaseTimer = n => {
1332
- if (globalState.timeout) {
1333
- const remaining = globalState.timeout.increase(n);
1334
- animateTimerProgressBar(remaining, true);
1335
- return remaining;
1336
- }
1337
- };
1338
- /**
1339
- * Check if timer is running. Returns true if timer is running
1340
- * or false if timer is paused or stopped.
1341
- * If `timer` parameter isn't set, returns undefined
1342
- */
1343
-
1344
- const isTimerRunning = () => {
1345
- return globalState.timeout && globalState.timeout.isRunning();
1346
- };
1347
-
1348
- let bodyClickListenerAdded = false;
1349
- const clickHandlers = {};
1350
- function bindClickHandler() {
1351
- let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template';
1352
- clickHandlers[attr] = this;
1353
-
1354
- if (!bodyClickListenerAdded) {
1355
- document.body.addEventListener('click', bodyClickListener);
1356
- bodyClickListenerAdded = true;
1357
- }
1358
- }
1359
-
1360
- const bodyClickListener = event => {
1361
- for (let el = event.target; el && el !== document; el = el.parentNode) {
1362
- for (const attr in clickHandlers) {
1363
- const template = el.getAttribute(attr);
1364
-
1365
- if (template) {
1366
- clickHandlers[attr].fire({
1367
- template
1368
- });
1369
- return;
1370
- }
1371
- }
1372
- }
1373
- };
1374
-
1375
- const defaultParams = {
1376
- title: '',
1377
- titleText: '',
1378
- text: '',
1379
- html: '',
1380
- footer: '',
1381
- icon: undefined,
1382
- iconColor: undefined,
1383
- iconHtml: undefined,
1384
- template: undefined,
1385
- toast: false,
1386
- showClass: {
1387
- popup: 'swal2-show',
1388
- backdrop: 'swal2-backdrop-show',
1389
- icon: 'swal2-icon-show'
1390
- },
1391
- hideClass: {
1392
- popup: 'swal2-hide',
1393
- backdrop: 'swal2-backdrop-hide',
1394
- icon: 'swal2-icon-hide'
1395
- },
1396
- customClass: {},
1397
- target: 'body',
1398
- color: undefined,
1399
- backdrop: true,
1400
- heightAuto: true,
1401
- allowOutsideClick: true,
1402
- allowEscapeKey: true,
1403
- allowEnterKey: true,
1404
- stopKeydownPropagation: true,
1405
- keydownListenerCapture: false,
1406
- showConfirmButton: true,
1407
- showDenyButton: false,
1408
- showCancelButton: false,
1409
- preConfirm: undefined,
1410
- preDeny: undefined,
1411
- confirmButtonText: 'OK',
1412
- confirmButtonAriaLabel: '',
1413
- confirmButtonColor: undefined,
1414
- denyButtonText: 'No',
1415
- denyButtonAriaLabel: '',
1416
- denyButtonColor: undefined,
1417
- cancelButtonText: 'Cancel',
1418
- cancelButtonAriaLabel: '',
1419
- cancelButtonColor: undefined,
1420
- buttonsStyling: true,
1421
- reverseButtons: false,
1422
- focusConfirm: true,
1423
- focusDeny: false,
1424
- focusCancel: false,
1425
- returnFocus: true,
1426
- showCloseButton: false,
1427
- closeButtonHtml: '&times;',
1428
- closeButtonAriaLabel: 'Close this dialog',
1429
- loaderHtml: '',
1430
- showLoaderOnConfirm: false,
1431
- showLoaderOnDeny: false,
1432
- imageUrl: undefined,
1433
- imageWidth: undefined,
1434
- imageHeight: undefined,
1435
- imageAlt: '',
1436
- timer: undefined,
1437
- timerProgressBar: false,
1438
- width: undefined,
1439
- padding: undefined,
1440
- background: undefined,
1441
- input: undefined,
1442
- inputPlaceholder: '',
1443
- inputLabel: '',
1444
- inputValue: '',
1445
- inputOptions: {},
1446
- inputAutoTrim: true,
1447
- inputAttributes: {},
1448
- inputValidator: undefined,
1449
- returnInputValueOnDeny: false,
1450
- validationMessage: undefined,
1451
- grow: false,
1452
- position: 'center',
1453
- progressSteps: [],
1454
- currentProgressStep: undefined,
1455
- progressStepsDistance: undefined,
1456
- willOpen: undefined,
1457
- didOpen: undefined,
1458
- didRender: undefined,
1459
- willClose: undefined,
1460
- didClose: undefined,
1461
- didDestroy: undefined,
1462
- scrollbarPadding: true
1463
- };
1464
- 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'];
1465
- const deprecatedParams = {};
1466
- const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
1467
- /**
1468
- * Is valid parameter
1469
- * @param {String} paramName
1470
- */
1471
-
1472
- const isValidParameter = paramName => {
1473
- return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
1474
- };
1475
- /**
1476
- * Is valid parameter for Swal.update() method
1477
- * @param {String} paramName
1478
- */
1479
-
1480
- const isUpdatableParameter = paramName => {
1481
- return updatableParams.indexOf(paramName) !== -1;
1482
- };
1483
- /**
1484
- * Is deprecated parameter
1485
- * @param {String} paramName
1486
- */
1487
-
1488
- const isDeprecatedParameter = paramName => {
1489
- return deprecatedParams[paramName];
1490
- };
1491
-
1492
- const checkIfParamIsValid = param => {
1493
- if (!isValidParameter(param)) {
1494
- warn("Unknown parameter \"".concat(param, "\""));
1495
- }
1496
- };
1497
-
1498
- const checkIfToastParamIsValid = param => {
1499
- if (toastIncompatibleParams.includes(param)) {
1500
- warn("The parameter \"".concat(param, "\" is incompatible with toasts"));
1501
- }
1502
- };
1503
-
1504
- const checkIfParamIsDeprecated = param => {
1505
- if (isDeprecatedParameter(param)) {
1506
- warnAboutDeprecation(param, isDeprecatedParameter(param));
1507
- }
1508
- };
1509
- /**
1510
- * Show relevant warnings for given params
1511
- *
1512
- * @param params
1513
- */
1514
-
1515
-
1516
- const showWarningsForParams = params => {
1517
- if (!params.backdrop && params.allowOutsideClick) {
1518
- warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
1519
- }
1520
-
1521
- for (const param in params) {
1522
- checkIfParamIsValid(param);
1523
-
1524
- if (params.toast) {
1525
- checkIfToastParamIsValid(param);
1526
- }
1527
-
1528
- checkIfParamIsDeprecated(param);
1529
- }
1530
- };
1531
-
1532
-
1533
-
1534
- var staticMethods = /*#__PURE__*/Object.freeze({
1535
- isValidParameter: isValidParameter,
1536
- isUpdatableParameter: isUpdatableParameter,
1537
- isDeprecatedParameter: isDeprecatedParameter,
1538
- argsToParams: argsToParams,
1539
- isVisible: isVisible$1,
1540
- clickConfirm: clickConfirm,
1541
- clickDeny: clickDeny,
1542
- clickCancel: clickCancel,
1543
- getContainer: getContainer,
1544
- getPopup: getPopup,
1545
- getTitle: getTitle,
1546
- getHtmlContainer: getHtmlContainer,
1547
- getImage: getImage,
1548
- getIcon: getIcon,
1549
- getInputLabel: getInputLabel,
1550
- getCloseButton: getCloseButton,
1551
- getActions: getActions,
1552
- getConfirmButton: getConfirmButton,
1553
- getDenyButton: getDenyButton,
1554
- getCancelButton: getCancelButton,
1555
- getLoader: getLoader,
1556
- getFooter: getFooter,
1557
- getTimerProgressBar: getTimerProgressBar,
1558
- getFocusableElements: getFocusableElements,
1559
- getValidationMessage: getValidationMessage,
1560
- isLoading: isLoading,
1561
- fire: fire,
1562
- mixin: mixin,
1563
- showLoading: showLoading,
1564
- enableLoading: showLoading,
1565
- getTimerLeft: getTimerLeft,
1566
- stopTimer: stopTimer,
1567
- resumeTimer: resumeTimer,
1568
- toggleTimer: toggleTimer,
1569
- increaseTimer: increaseTimer,
1570
- isTimerRunning: isTimerRunning,
1571
- bindClickHandler: bindClickHandler
1572
- });
1573
-
1574
- /**
1575
- * Hides loader and shows back the button which was hidden by .showLoading()
1576
- */
1577
-
1578
- function hideLoading() {
1579
- // do nothing if popup is closed
1580
- const innerParams = privateProps.innerParams.get(this);
1581
-
1582
- if (!innerParams) {
1583
- return;
1584
- }
1585
-
1586
- const domCache = privateProps.domCache.get(this);
1587
- hide(domCache.loader);
1588
-
1589
- if (isToast()) {
1590
- if (innerParams.icon) {
1591
- show(getIcon());
1592
- }
1593
- } else {
1594
- showRelatedButton(domCache);
1595
- }
1596
-
1597
- removeClass([domCache.popup, domCache.actions], swalClasses.loading);
1598
- domCache.popup.removeAttribute('aria-busy');
1599
- domCache.popup.removeAttribute('data-loading');
1600
- domCache.confirmButton.disabled = false;
1601
- domCache.denyButton.disabled = false;
1602
- domCache.cancelButton.disabled = false;
1603
- }
1604
-
1605
- const showRelatedButton = domCache => {
1606
- const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
1607
-
1608
- if (buttonToReplace.length) {
1609
- show(buttonToReplace[0], 'inline-block');
1610
- } else if (allButtonsAreHidden()) {
1611
- hide(domCache.actions);
1612
- }
1613
- };
1614
-
1615
- function getInput$1(instance) {
1616
- const innerParams = privateProps.innerParams.get(instance || this);
1617
- const domCache = privateProps.domCache.get(instance || this);
1618
-
1619
- if (!domCache) {
1620
- return null;
1621
- }
1622
-
1623
- return getInput(domCache.popup, innerParams.input);
1624
- }
1625
-
1626
- const fixScrollbar = () => {
1627
- // for queues, do not do this more than once
1628
- if (states.previousBodyPadding !== null) {
1629
- return;
1630
- } // if the body has overflow
1631
-
1632
-
1633
- if (document.body.scrollHeight > window.innerHeight) {
1634
- // add padding so the content doesn't shift after removal of scrollbar
1635
- states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
1636
- document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px");
1637
- }
1638
- };
1639
- const undoScrollbar = () => {
1640
- if (states.previousBodyPadding !== null) {
1641
- document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px");
1642
- states.previousBodyPadding = null;
1643
- }
1644
- };
1645
-
1646
- /* istanbul ignore file */
1647
-
1648
- const iOSfix = () => {
1649
- const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream || navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
1650
-
1651
- if (iOS && !hasClass(document.body, swalClasses.iosfix)) {
1652
- const offset = document.body.scrollTop;
1653
- document.body.style.top = "".concat(offset * -1, "px");
1654
- addClass(document.body, swalClasses.iosfix);
1655
- lockBodyScroll();
1656
- addBottomPaddingForTallPopups(); // #1948
1657
- }
1658
- };
1659
-
1660
- const addBottomPaddingForTallPopups = () => {
1661
- const safari = !navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i);
1662
-
1663
- if (safari) {
1664
- const bottomPanelHeight = 44;
1665
-
1666
- if (getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) {
1667
- getContainer().style.paddingBottom = "".concat(bottomPanelHeight, "px");
1668
- }
1669
- }
1670
- };
1671
-
1672
- const lockBodyScroll = () => {
1673
- // #1246
1674
- const container = getContainer();
1675
- let preventTouchMove;
1676
-
1677
- container.ontouchstart = e => {
1678
- preventTouchMove = shouldPreventTouchMove(e);
1679
- };
1680
-
1681
- container.ontouchmove = e => {
1682
- if (preventTouchMove) {
1683
- e.preventDefault();
1684
- e.stopPropagation();
1685
- }
1686
- };
1687
- };
1688
-
1689
- const shouldPreventTouchMove = event => {
1690
- const target = event.target;
1691
- const container = getContainer();
1692
-
1693
- if (isStylys(event) || isZoom(event)) {
1694
- return false;
1695
- }
1696
-
1697
- if (target === container) {
1698
- return true;
1699
- }
1700
-
1701
- if (!isScrollable(container) && target.tagName !== 'INPUT' && // #1603
1702
- target.tagName !== 'TEXTAREA' && // #2266
1703
- !(isScrollable(getHtmlContainer()) && // #1944
1704
- getHtmlContainer().contains(target))) {
1705
- return true;
1706
- }
1707
-
1708
- return false;
1709
- };
1710
-
1711
- const isStylys = event => {
1712
- // #1786
1713
- return event.touches && event.touches.length && event.touches[0].touchType === 'stylus';
1714
- };
1715
-
1716
- const isZoom = event => {
1717
- // #1891
1718
- return event.touches && event.touches.length > 1;
1719
- };
1720
-
1721
- const undoIOSfix = () => {
1722
- if (hasClass(document.body, swalClasses.iosfix)) {
1723
- const offset = parseInt(document.body.style.top, 10);
1724
- removeClass(document.body, swalClasses.iosfix);
1725
- document.body.style.top = '';
1726
- document.body.scrollTop = offset * -1;
1727
- }
1728
- };
1374
+ const DismissReason = Object.freeze({
1375
+ cancel: 'cancel',
1376
+ backdrop: 'backdrop',
1377
+ close: 'close',
1378
+ esc: 'esc',
1379
+ timer: 'timer'
1380
+ });
1729
1381
 
1730
1382
  // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
1731
1383
  // elements not within the active modal dialog will not be surfaced if a user opens a screen
@@ -1757,312 +1409,180 @@
1757
1409
  });
1758
1410
  };
1759
1411
 
1760
- /**
1761
- * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
1762
- * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
1763
- * This is the approach that Babel will probably take to implement private methods/fields
1764
- * https://github.com/tc39/proposal-private-methods
1765
- * https://github.com/babel/babel/pull/7555
1766
- * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
1767
- * then we can use that language feature.
1768
- */
1769
- var privateMethods = {
1770
- swalPromiseResolve: new WeakMap(),
1771
- swalPromiseReject: new WeakMap()
1772
- };
1773
-
1774
- /*
1775
- * Instance method to close sweetAlert
1776
- */
1777
-
1778
- function removePopupAndResetState(instance, container, returnFocus, didClose) {
1779
- if (isToast()) {
1780
- triggerDidCloseAndDispose(instance, didClose);
1781
- } else {
1782
- restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
1783
- globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
1784
- capture: globalState.keydownListenerCapture
1785
- });
1786
- globalState.keydownHandlerAdded = false;
1787
- }
1788
-
1789
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088
1790
- // for some reason removing the container in Safari will scroll the document to bottom
1791
-
1792
- if (isSafari) {
1793
- container.setAttribute('style', 'display:none !important');
1794
- container.removeAttribute('class');
1795
- container.innerHTML = '';
1796
- } else {
1797
- container.remove();
1798
- }
1799
-
1800
- if (isModal()) {
1801
- undoScrollbar();
1802
- undoIOSfix();
1803
- unsetAriaHidden();
1804
- }
1805
-
1806
- removeBodyClasses();
1807
- }
1808
-
1809
- function removeBodyClasses() {
1810
- removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
1811
- }
1812
-
1813
- function close(resolveValue) {
1814
- resolveValue = prepareResolveValue(resolveValue);
1815
- const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
1816
- const didClose = triggerClosePopup(this);
1817
-
1818
- if (this.isAwaitingPromise()) {
1819
- // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
1820
- if (!resolveValue.isDismissed) {
1821
- handleAwaitingPromise(this);
1822
- swalPromiseResolve(resolveValue);
1823
- }
1824
- } else if (didClose) {
1825
- // Resolve Swal promise
1826
- swalPromiseResolve(resolveValue);
1827
- }
1828
- }
1829
- function isAwaitingPromise() {
1830
- return !!privateProps.awaitingPromise.get(this);
1831
- }
1832
-
1833
- const triggerClosePopup = instance => {
1834
- const popup = getPopup();
1835
-
1836
- if (!popup) {
1837
- return false;
1838
- }
1839
-
1840
- const innerParams = privateProps.innerParams.get(instance);
1412
+ const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
1413
+ const getTemplateParams = params => {
1414
+ const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template;
1841
1415
 
1842
- if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
1843
- return false;
1416
+ if (!template) {
1417
+ return {};
1844
1418
  }
1845
1419
 
1846
- removeClass(popup, innerParams.showClass.popup);
1847
- addClass(popup, innerParams.hideClass.popup);
1848
- const backdrop = getContainer();
1849
- removeClass(backdrop, innerParams.showClass.backdrop);
1850
- addClass(backdrop, innerParams.hideClass.backdrop);
1851
- handlePopupAnimation(instance, popup, innerParams);
1852
- return true;
1420
+ const templateContent = template.content;
1421
+ showWarningsForElements(templateContent);
1422
+ const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
1423
+ return result;
1853
1424
  };
1854
1425
 
1855
- function rejectPromise(error) {
1856
- const rejectPromise = privateMethods.swalPromiseReject.get(this);
1857
- handleAwaitingPromise(this);
1858
-
1859
- if (rejectPromise) {
1860
- // Reject Swal promise
1861
- rejectPromise(error);
1862
- }
1863
- }
1864
-
1865
- const handleAwaitingPromise = instance => {
1866
- if (instance.isAwaitingPromise()) {
1867
- privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
1426
+ const getSwalParams = templateContent => {
1427
+ const result = {};
1428
+ toArray(templateContent.querySelectorAll('swal-param')).forEach(param => {
1429
+ showWarningsForAttributes(param, ['name', 'value']);
1430
+ const paramName = param.getAttribute('name');
1431
+ const value = param.getAttribute('value');
1868
1432
 
1869
- if (!privateProps.innerParams.get(instance)) {
1870
- instance._destroy();
1433
+ if (typeof defaultParams[paramName] === 'boolean' && value === 'false') {
1434
+ result[paramName] = false;
1871
1435
  }
1872
- }
1873
- };
1874
-
1875
- const prepareResolveValue = resolveValue => {
1876
- // When user calls Swal.close()
1877
- if (typeof resolveValue === 'undefined') {
1878
- return {
1879
- isConfirmed: false,
1880
- isDenied: false,
1881
- isDismissed: true
1882
- };
1883
- }
1884
1436
 
1885
- return Object.assign({
1886
- isConfirmed: false,
1887
- isDenied: false,
1888
- isDismissed: false
1889
- }, resolveValue);
1437
+ if (typeof defaultParams[paramName] === 'object') {
1438
+ result[paramName] = JSON.parse(value);
1439
+ }
1440
+ });
1441
+ return result;
1890
1442
  };
1891
1443
 
1892
- const handlePopupAnimation = (instance, popup, innerParams) => {
1893
- const container = getContainer(); // If animation is supported, animate
1894
-
1895
- const animationIsSupported = animationEndEvent && hasCssAnimation(popup);
1896
-
1897
- if (typeof innerParams.willClose === 'function') {
1898
- innerParams.willClose(popup);
1899
- }
1444
+ const getSwalButtons = templateContent => {
1445
+ const result = {};
1446
+ toArray(templateContent.querySelectorAll('swal-button')).forEach(button => {
1447
+ showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
1448
+ const type = button.getAttribute('type');
1449
+ result["".concat(type, "ButtonText")] = button.innerHTML;
1450
+ result["show".concat(capitalizeFirstLetter(type), "Button")] = true;
1900
1451
 
1901
- if (animationIsSupported) {
1902
- animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
1903
- } else {
1904
- // Otherwise, remove immediately
1905
- removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
1906
- }
1907
- };
1452
+ if (button.hasAttribute('color')) {
1453
+ result["".concat(type, "ButtonColor")] = button.getAttribute('color');
1454
+ }
1908
1455
 
1909
- const animatePopup = (instance, popup, container, returnFocus, didClose) => {
1910
- globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
1911
- popup.addEventListener(animationEndEvent, function (e) {
1912
- if (e.target === popup) {
1913
- globalState.swalCloseEventFinishedCallback();
1914
- delete globalState.swalCloseEventFinishedCallback;
1456
+ if (button.hasAttribute('aria-label')) {
1457
+ result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label');
1915
1458
  }
1916
1459
  });
1460
+ return result;
1917
1461
  };
1918
1462
 
1919
- const triggerDidCloseAndDispose = (instance, didClose) => {
1920
- setTimeout(() => {
1921
- if (typeof didClose === 'function') {
1922
- didClose.bind(instance.params)();
1923
- }
1463
+ const getSwalImage = templateContent => {
1464
+ const result = {};
1465
+ const image = templateContent.querySelector('swal-image');
1924
1466
 
1925
- instance._destroy();
1926
- });
1927
- };
1467
+ if (image) {
1468
+ showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
1928
1469
 
1929
- function setButtonsDisabled(instance, buttons, disabled) {
1930
- const domCache = privateProps.domCache.get(instance);
1931
- buttons.forEach(button => {
1932
- domCache[button].disabled = disabled;
1933
- });
1934
- }
1470
+ if (image.hasAttribute('src')) {
1471
+ result.imageUrl = image.getAttribute('src');
1472
+ }
1935
1473
 
1936
- function setInputDisabled(input, disabled) {
1937
- if (!input) {
1938
- return false;
1939
- }
1474
+ if (image.hasAttribute('width')) {
1475
+ result.imageWidth = image.getAttribute('width');
1476
+ }
1940
1477
 
1941
- if (input.type === 'radio') {
1942
- const radiosContainer = input.parentNode.parentNode;
1943
- const radios = radiosContainer.querySelectorAll('input');
1478
+ if (image.hasAttribute('height')) {
1479
+ result.imageHeight = image.getAttribute('height');
1480
+ }
1944
1481
 
1945
- for (let i = 0; i < radios.length; i++) {
1946
- radios[i].disabled = disabled;
1482
+ if (image.hasAttribute('alt')) {
1483
+ result.imageAlt = image.getAttribute('alt');
1947
1484
  }
1948
- } else {
1949
- input.disabled = disabled;
1950
1485
  }
1951
- }
1952
-
1953
- function enableButtons() {
1954
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
1955
- }
1956
- function disableButtons() {
1957
- setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
1958
- }
1959
- function enableInput() {
1960
- return setInputDisabled(this.getInput(), false);
1961
- }
1962
- function disableInput() {
1963
- return setInputDisabled(this.getInput(), true);
1964
- }
1965
1486
 
1966
- function showValidationMessage(error) {
1967
- const domCache = privateProps.domCache.get(this);
1968
- const params = privateProps.innerParams.get(this);
1969
- setInnerHtml(domCache.validationMessage, error);
1970
- domCache.validationMessage.className = swalClasses['validation-message'];
1487
+ return result;
1488
+ };
1971
1489
 
1972
- if (params.customClass && params.customClass.validationMessage) {
1973
- addClass(domCache.validationMessage, params.customClass.validationMessage);
1974
- }
1490
+ const getSwalIcon = templateContent => {
1491
+ const result = {};
1492
+ const icon = templateContent.querySelector('swal-icon');
1975
1493
 
1976
- show(domCache.validationMessage);
1977
- const input = this.getInput();
1494
+ if (icon) {
1495
+ showWarningsForAttributes(icon, ['type', 'color']);
1978
1496
 
1979
- if (input) {
1980
- input.setAttribute('aria-invalid', true);
1981
- input.setAttribute('aria-describedby', swalClasses['validation-message']);
1982
- focusInput(input);
1983
- addClass(input, swalClasses.inputerror);
1984
- }
1985
- } // Hide block with validation message
1497
+ if (icon.hasAttribute('type')) {
1498
+ result.icon = icon.getAttribute('type');
1499
+ }
1986
1500
 
1987
- function resetValidationMessage$1() {
1988
- const domCache = privateProps.domCache.get(this);
1501
+ if (icon.hasAttribute('color')) {
1502
+ result.iconColor = icon.getAttribute('color');
1503
+ }
1989
1504
 
1990
- if (domCache.validationMessage) {
1991
- hide(domCache.validationMessage);
1505
+ result.iconHtml = icon.innerHTML;
1992
1506
  }
1993
1507
 
1994
- const input = this.getInput();
1508
+ return result;
1509
+ };
1995
1510
 
1996
- if (input) {
1997
- input.removeAttribute('aria-invalid');
1998
- input.removeAttribute('aria-describedby');
1999
- removeClass(input, swalClasses.inputerror);
2000
- }
2001
- }
1511
+ const getSwalInput = templateContent => {
1512
+ const result = {};
1513
+ const input = templateContent.querySelector('swal-input');
2002
1514
 
2003
- function getProgressSteps$1() {
2004
- const domCache = privateProps.domCache.get(this);
2005
- return domCache.progressSteps;
2006
- }
1515
+ if (input) {
1516
+ showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
1517
+ result.input = input.getAttribute('type') || 'text';
2007
1518
 
2008
- class Timer {
2009
- constructor(callback, delay) {
2010
- this.callback = callback;
2011
- this.remaining = delay;
2012
- this.running = false;
2013
- this.start();
2014
- }
1519
+ if (input.hasAttribute('label')) {
1520
+ result.inputLabel = input.getAttribute('label');
1521
+ }
2015
1522
 
2016
- start() {
2017
- if (!this.running) {
2018
- this.running = true;
2019
- this.started = new Date();
2020
- this.id = setTimeout(this.callback, this.remaining);
1523
+ if (input.hasAttribute('placeholder')) {
1524
+ result.inputPlaceholder = input.getAttribute('placeholder');
2021
1525
  }
2022
1526
 
2023
- return this.remaining;
1527
+ if (input.hasAttribute('value')) {
1528
+ result.inputValue = input.getAttribute('value');
1529
+ }
2024
1530
  }
2025
1531
 
2026
- stop() {
2027
- if (this.running) {
2028
- this.running = false;
2029
- clearTimeout(this.id);
2030
- this.remaining -= new Date() - this.started;
2031
- }
1532
+ const inputOptions = templateContent.querySelectorAll('swal-input-option');
2032
1533
 
2033
- return this.remaining;
1534
+ if (inputOptions.length) {
1535
+ result.inputOptions = {};
1536
+ toArray(inputOptions).forEach(option => {
1537
+ showWarningsForAttributes(option, ['value']);
1538
+ const optionValue = option.getAttribute('value');
1539
+ const optionName = option.innerHTML;
1540
+ result.inputOptions[optionValue] = optionName;
1541
+ });
2034
1542
  }
2035
1543
 
2036
- increase(n) {
2037
- const running = this.running;
1544
+ return result;
1545
+ };
2038
1546
 
2039
- if (running) {
2040
- this.stop();
2041
- }
1547
+ const getSwalStringParams = (templateContent, paramNames) => {
1548
+ const result = {};
2042
1549
 
2043
- this.remaining += n;
1550
+ for (const i in paramNames) {
1551
+ const paramName = paramNames[i];
1552
+ const tag = templateContent.querySelector(paramName);
2044
1553
 
2045
- if (running) {
2046
- this.start();
1554
+ if (tag) {
1555
+ showWarningsForAttributes(tag, []);
1556
+ result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
2047
1557
  }
2048
-
2049
- return this.remaining;
2050
1558
  }
2051
1559
 
2052
- getTimerLeft() {
2053
- if (this.running) {
2054
- this.stop();
2055
- this.start();
2056
- }
1560
+ return result;
1561
+ };
2057
1562
 
2058
- return this.remaining;
2059
- }
1563
+ const showWarningsForElements = template => {
1564
+ const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
1565
+ toArray(template.children).forEach(el => {
1566
+ const tagName = el.tagName.toLowerCase();
2060
1567
 
2061
- isRunning() {
2062
- return this.running;
2063
- }
1568
+ if (allowedElements.indexOf(tagName) === -1) {
1569
+ warn("Unrecognized element <".concat(tagName, ">"));
1570
+ }
1571
+ });
1572
+ };
1573
+ /**
1574
+ * @param {HTMLElement} el
1575
+ * @param {string[]} allowedAttributes
1576
+ */
2064
1577
 
2065
- }
1578
+
1579
+ const showWarningsForAttributes = (el, allowedAttributes) => {
1580
+ toArray(el.attributes).forEach(attribute => {
1581
+ if (allowedAttributes.indexOf(attribute.name) === -1) {
1582
+ 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.')]);
1583
+ }
1584
+ });
1585
+ };
2066
1586
 
2067
1587
  var defaultInputValidators = {
2068
1588
  email: (string, validationMessage) => {
@@ -2096,7 +1616,6 @@
2096
1616
  * Set type, text and actions on popup
2097
1617
  *
2098
1618
  * @param params
2099
- * @returns {boolean}
2100
1619
  */
2101
1620
 
2102
1621
 
@@ -2116,176 +1635,180 @@
2116
1635
  init(params);
2117
1636
  }
2118
1637
 
2119
- const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
2120
- const getTemplateParams = params => {
2121
- const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template;
2122
-
2123
- if (!template) {
2124
- return {};
1638
+ class Timer {
1639
+ constructor(callback, delay) {
1640
+ this.callback = callback;
1641
+ this.remaining = delay;
1642
+ this.running = false;
1643
+ this.start();
2125
1644
  }
2126
1645
 
2127
- const templateContent = template.content;
2128
- showWarningsForElements(templateContent);
2129
- const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
2130
- return result;
2131
- };
1646
+ start() {
1647
+ if (!this.running) {
1648
+ this.running = true;
1649
+ this.started = new Date();
1650
+ this.id = setTimeout(this.callback, this.remaining);
1651
+ }
2132
1652
 
2133
- const getSwalParams = templateContent => {
2134
- const result = {};
2135
- toArray(templateContent.querySelectorAll('swal-param')).forEach(param => {
2136
- showWarningsForAttributes(param, ['name', 'value']);
2137
- const paramName = param.getAttribute('name');
2138
- let value = param.getAttribute('value');
1653
+ return this.remaining;
1654
+ }
2139
1655
 
2140
- if (typeof defaultParams[paramName] === 'boolean' && value === 'false') {
2141
- value = false;
1656
+ stop() {
1657
+ if (this.running) {
1658
+ this.running = false;
1659
+ clearTimeout(this.id);
1660
+ this.remaining -= new Date().getTime() - this.started.getTime();
2142
1661
  }
2143
1662
 
2144
- if (typeof defaultParams[paramName] === 'object') {
2145
- value = JSON.parse(value);
2146
- }
1663
+ return this.remaining;
1664
+ }
2147
1665
 
2148
- result[paramName] = value;
2149
- });
2150
- return result;
2151
- };
1666
+ increase(n) {
1667
+ const running = this.running;
2152
1668
 
2153
- const getSwalButtons = templateContent => {
2154
- const result = {};
2155
- toArray(templateContent.querySelectorAll('swal-button')).forEach(button => {
2156
- showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
2157
- const type = button.getAttribute('type');
2158
- result["".concat(type, "ButtonText")] = button.innerHTML;
2159
- result["show".concat(capitalizeFirstLetter(type), "Button")] = true;
1669
+ if (running) {
1670
+ this.stop();
1671
+ }
2160
1672
 
2161
- if (button.hasAttribute('color')) {
2162
- result["".concat(type, "ButtonColor")] = button.getAttribute('color');
1673
+ this.remaining += n;
1674
+
1675
+ if (running) {
1676
+ this.start();
2163
1677
  }
2164
1678
 
2165
- if (button.hasAttribute('aria-label')) {
2166
- result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label');
1679
+ return this.remaining;
1680
+ }
1681
+
1682
+ getTimerLeft() {
1683
+ if (this.running) {
1684
+ this.stop();
1685
+ this.start();
2167
1686
  }
2168
- });
2169
- return result;
2170
- };
2171
1687
 
2172
- const getSwalImage = templateContent => {
2173
- const result = {};
2174
- const image = templateContent.querySelector('swal-image');
1688
+ return this.remaining;
1689
+ }
2175
1690
 
2176
- if (image) {
2177
- showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
1691
+ isRunning() {
1692
+ return this.running;
1693
+ }
2178
1694
 
2179
- if (image.hasAttribute('src')) {
2180
- result.imageUrl = image.getAttribute('src');
2181
- }
1695
+ }
2182
1696
 
2183
- if (image.hasAttribute('width')) {
2184
- result.imageWidth = image.getAttribute('width');
2185
- }
1697
+ const fixScrollbar = () => {
1698
+ // for queues, do not do this more than once
1699
+ if (states.previousBodyPadding !== null) {
1700
+ return;
1701
+ } // if the body has overflow
2186
1702
 
2187
- if (image.hasAttribute('height')) {
2188
- result.imageHeight = image.getAttribute('height');
2189
- }
2190
1703
 
2191
- if (image.hasAttribute('alt')) {
2192
- result.imageAlt = image.getAttribute('alt');
2193
- }
1704
+ if (document.body.scrollHeight > window.innerHeight) {
1705
+ // add padding so the content doesn't shift after removal of scrollbar
1706
+ states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
1707
+ document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px");
1708
+ }
1709
+ };
1710
+ const undoScrollbar = () => {
1711
+ if (states.previousBodyPadding !== null) {
1712
+ document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px");
1713
+ states.previousBodyPadding = null;
2194
1714
  }
2195
-
2196
- return result;
2197
1715
  };
2198
1716
 
2199
- const getSwalIcon = templateContent => {
2200
- const result = {};
2201
- const icon = templateContent.querySelector('swal-icon');
1717
+ /* istanbul ignore file */
1718
+
1719
+ const iOSfix = () => {
1720
+ // @ts-ignore
1721
+ const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream || navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
1722
+
1723
+ if (iOS && !hasClass(document.body, swalClasses.iosfix)) {
1724
+ const offset = document.body.scrollTop;
1725
+ document.body.style.top = "".concat(offset * -1, "px");
1726
+ addClass(document.body, swalClasses.iosfix);
1727
+ lockBodyScroll();
1728
+ addBottomPaddingForTallPopups();
1729
+ }
1730
+ };
1731
+ /**
1732
+ * https://github.com/sweetalert2/sweetalert2/issues/1948
1733
+ */
2202
1734
 
2203
- if (icon) {
2204
- showWarningsForAttributes(icon, ['type', 'color']);
1735
+ const addBottomPaddingForTallPopups = () => {
1736
+ const ua = navigator.userAgent;
1737
+ const iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
1738
+ const webkit = !!ua.match(/WebKit/i);
1739
+ const iOSSafari = iOS && webkit && !ua.match(/CriOS/i);
2205
1740
 
2206
- if (icon.hasAttribute('type')) {
2207
- result.icon = icon.getAttribute('type');
2208
- }
1741
+ if (iOSSafari) {
1742
+ const bottomPanelHeight = 44;
2209
1743
 
2210
- if (icon.hasAttribute('color')) {
2211
- result.iconColor = icon.getAttribute('color');
1744
+ if (getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) {
1745
+ getContainer().style.paddingBottom = "".concat(bottomPanelHeight, "px");
2212
1746
  }
2213
-
2214
- result.iconHtml = icon.innerHTML;
2215
1747
  }
2216
-
2217
- return result;
2218
1748
  };
2219
1749
 
2220
- const getSwalInput = templateContent => {
2221
- const result = {};
2222
- const input = templateContent.querySelector('swal-input');
1750
+ const lockBodyScroll = () => {
1751
+ // #1246
1752
+ const container = getContainer();
1753
+ let preventTouchMove;
2223
1754
 
2224
- if (input) {
2225
- showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
2226
- result.input = input.getAttribute('type') || 'text';
1755
+ container.ontouchstart = e => {
1756
+ preventTouchMove = shouldPreventTouchMove(e);
1757
+ };
2227
1758
 
2228
- if (input.hasAttribute('label')) {
2229
- result.inputLabel = input.getAttribute('label');
1759
+ container.ontouchmove = e => {
1760
+ if (preventTouchMove) {
1761
+ e.preventDefault();
1762
+ e.stopPropagation();
2230
1763
  }
1764
+ };
1765
+ };
2231
1766
 
2232
- if (input.hasAttribute('placeholder')) {
2233
- result.inputPlaceholder = input.getAttribute('placeholder');
2234
- }
1767
+ const shouldPreventTouchMove = event => {
1768
+ const target = event.target;
1769
+ const container = getContainer();
2235
1770
 
2236
- if (input.hasAttribute('value')) {
2237
- result.inputValue = input.getAttribute('value');
2238
- }
1771
+ if (isStylus(event) || isZoom(event)) {
1772
+ return false;
2239
1773
  }
2240
1774
 
2241
- const inputOptions = templateContent.querySelectorAll('swal-input-option');
1775
+ if (target === container) {
1776
+ return true;
1777
+ }
2242
1778
 
2243
- if (inputOptions.length) {
2244
- result.inputOptions = {};
2245
- toArray(inputOptions).forEach(option => {
2246
- showWarningsForAttributes(option, ['value']);
2247
- const optionValue = option.getAttribute('value');
2248
- const optionName = option.innerHTML;
2249
- result.inputOptions[optionValue] = optionName;
2250
- });
1779
+ if (!isScrollable(container) && target.tagName !== 'INPUT' && // #1603
1780
+ target.tagName !== 'TEXTAREA' && // #2266
1781
+ !(isScrollable(getHtmlContainer()) && // #1944
1782
+ getHtmlContainer().contains(target))) {
1783
+ return true;
2251
1784
  }
2252
1785
 
2253
- return result;
1786
+ return false;
2254
1787
  };
1788
+ /**
1789
+ * https://github.com/sweetalert2/sweetalert2/issues/1786
1790
+ *
1791
+ * @param {*} event
1792
+ * @returns {boolean}
1793
+ */
2255
1794
 
2256
- const getSwalStringParams = (templateContent, paramNames) => {
2257
- const result = {};
2258
-
2259
- for (const i in paramNames) {
2260
- const paramName = paramNames[i];
2261
- const tag = templateContent.querySelector(paramName);
2262
-
2263
- if (tag) {
2264
- showWarningsForAttributes(tag, []);
2265
- result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
2266
- }
2267
- }
2268
1795
 
2269
- return result;
1796
+ const isStylus = event => {
1797
+ return event.touches && event.touches.length && event.touches[0].touchType === 'stylus';
2270
1798
  };
2271
1799
 
2272
- const showWarningsForElements = template => {
2273
- const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
2274
- toArray(template.children).forEach(el => {
2275
- const tagName = el.tagName.toLowerCase();
2276
-
2277
- if (allowedElements.indexOf(tagName) === -1) {
2278
- warn("Unrecognized element <".concat(tagName, ">"));
2279
- }
2280
- });
1800
+ const isZoom = event => {
1801
+ // #1891
1802
+ return event.touches && event.touches.length > 1;
2281
1803
  };
2282
1804
 
2283
- const showWarningsForAttributes = (el, allowedAttributes) => {
2284
- toArray(el.attributes).forEach(attribute => {
2285
- if (allowedAttributes.indexOf(attribute.name) === -1) {
2286
- 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.')]);
2287
- }
2288
- });
1805
+ const undoIOSfix = () => {
1806
+ if (hasClass(document.body, swalClasses.iosfix)) {
1807
+ const offset = parseInt(document.body.style.top, 10);
1808
+ removeClass(document.body, swalClasses.iosfix);
1809
+ document.body.style.top = '';
1810
+ document.body.scrollTop = offset * -1;
1811
+ }
2289
1812
  };
2290
1813
 
2291
1814
  const SHOW_CLASS_TIMEOUT = 10;
@@ -2362,7 +1885,7 @@
2362
1885
  };
2363
1886
 
2364
1887
  const addClasses$1 = (container, popup, params) => {
2365
- addClass(container, params.showClass.backdrop); // the workaround with setting/unsetting opacity is needed for #2019 and 2059
1888
+ addClass(container, params.showClass.backdrop); // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
2366
1889
 
2367
1890
  popup.style.setProperty('opacity', '0', 'important');
2368
1891
  show(popup, 'grid');
@@ -2380,6 +1903,52 @@
2380
1903
  }
2381
1904
  };
2382
1905
 
1906
+ /**
1907
+ * Shows loader (spinner), this is useful with AJAX requests.
1908
+ * By default the loader be shown instead of the "Confirm" button.
1909
+ */
1910
+
1911
+ const showLoading = buttonToReplace => {
1912
+ let popup = getPopup();
1913
+
1914
+ if (!popup) {
1915
+ new Swal(); // eslint-disable-line no-new
1916
+ }
1917
+
1918
+ popup = getPopup();
1919
+ const loader = getLoader();
1920
+
1921
+ if (isToast()) {
1922
+ hide(getIcon());
1923
+ } else {
1924
+ replaceButton(popup, buttonToReplace);
1925
+ }
1926
+
1927
+ show(loader);
1928
+ popup.setAttribute('data-loading', true);
1929
+ popup.setAttribute('aria-busy', true);
1930
+ popup.focus();
1931
+ };
1932
+
1933
+ const replaceButton = (popup, buttonToReplace) => {
1934
+ const actions = getActions();
1935
+ const loader = getLoader();
1936
+
1937
+ if (!buttonToReplace && isVisible(getConfirmButton())) {
1938
+ buttonToReplace = getConfirmButton();
1939
+ }
1940
+
1941
+ show(actions);
1942
+
1943
+ if (buttonToReplace) {
1944
+ hide(buttonToReplace);
1945
+ loader.setAttribute('data-button-to-replace', buttonToReplace.className);
1946
+ }
1947
+
1948
+ loader.parentNode.insertBefore(loader, buttonToReplace);
1949
+ addClass([popup, actions], swalClasses.loading);
1950
+ };
1951
+
2383
1952
  const handleInputOptionsAndValue = (instance, params) => {
2384
1953
  if (params.input === 'select' || params.input === 'radio') {
2385
1954
  handleInputOptions(instance, params);
@@ -2453,7 +2022,7 @@
2453
2022
 
2454
2023
  const populateInputOptions = {
2455
2024
  select: (popup, inputOptions, params) => {
2456
- const select = getChildByClass(popup, swalClasses.select);
2025
+ const select = getDirectChildByClass(popup, swalClasses.select);
2457
2026
 
2458
2027
  const renderOption = (parent, optionLabel, optionValue) => {
2459
2028
  const option = document.createElement('option');
@@ -2486,7 +2055,7 @@
2486
2055
  select.focus();
2487
2056
  },
2488
2057
  radio: (popup, inputOptions, params) => {
2489
- const radio = getChildByClass(popup, swalClasses.radio);
2058
+ const radio = getDirectChildByClass(popup, swalClasses.radio);
2490
2059
  inputOptions.forEach(inputOption => {
2491
2060
  const radioValue = inputOption[0];
2492
2061
  const radioLabel = inputOption[1];
@@ -2624,7 +2193,7 @@
2624
2193
  }
2625
2194
 
2626
2195
  if (innerParams.preDeny) {
2627
- privateProps.awaitingPromise.set(instance || undefined, true); // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesnt get destroyed until the result from this preDeny's promise is received
2196
+ 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
2628
2197
 
2629
2198
  const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
2630
2199
  preDenyPromise.then(preDenyValue => {
@@ -2659,26 +2228,128 @@
2659
2228
  const confirm = (instance, value) => {
2660
2229
  const innerParams = privateProps.innerParams.get(instance || undefined);
2661
2230
 
2662
- if (innerParams.showLoaderOnConfirm) {
2663
- showLoading();
2664
- }
2231
+ if (innerParams.showLoaderOnConfirm) {
2232
+ showLoading();
2233
+ }
2234
+
2235
+ if (innerParams.preConfirm) {
2236
+ instance.resetValidationMessage();
2237
+ 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
2238
+
2239
+ const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
2240
+ preConfirmPromise.then(preConfirmValue => {
2241
+ if (isVisible(getValidationMessage()) || preConfirmValue === false) {
2242
+ instance.hideLoading();
2243
+ } else {
2244
+ succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
2245
+ }
2246
+ }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
2247
+ } else {
2248
+ succeedWith(instance, value);
2249
+ }
2250
+ };
2251
+
2252
+ const handlePopupClick = (instance, domCache, dismissWith) => {
2253
+ const innerParams = privateProps.innerParams.get(instance);
2254
+
2255
+ if (innerParams.toast) {
2256
+ handleToastClick(instance, domCache, dismissWith);
2257
+ } else {
2258
+ // Ignore click events that had mousedown on the popup but mouseup on the container
2259
+ // This can happen when the user drags a slider
2260
+ handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup
2261
+
2262
+ handleContainerMousedown(domCache);
2263
+ handleModalClick(instance, domCache, dismissWith);
2264
+ }
2265
+ };
2266
+
2267
+ const handleToastClick = (instance, domCache, dismissWith) => {
2268
+ // Closing toast by internal click
2269
+ domCache.popup.onclick = () => {
2270
+ const innerParams = privateProps.innerParams.get(instance);
2271
+
2272
+ if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
2273
+ return;
2274
+ }
2275
+
2276
+ dismissWith(DismissReason.close);
2277
+ };
2278
+ };
2279
+ /**
2280
+ * @param {*} innerParams
2281
+ * @returns {boolean}
2282
+ */
2283
+
2284
+
2285
+ const isAnyButtonShown = innerParams => {
2286
+ return innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton;
2287
+ };
2288
+
2289
+ let ignoreOutsideClick = false;
2290
+
2291
+ const handleModalMousedown = domCache => {
2292
+ domCache.popup.onmousedown = () => {
2293
+ domCache.container.onmouseup = function (e) {
2294
+ domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't
2295
+ // have any other direct children aside of the popup
2296
+
2297
+ if (e.target === domCache.container) {
2298
+ ignoreOutsideClick = true;
2299
+ }
2300
+ };
2301
+ };
2302
+ };
2303
+
2304
+ const handleContainerMousedown = domCache => {
2305
+ domCache.container.onmousedown = () => {
2306
+ domCache.popup.onmouseup = function (e) {
2307
+ domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup
2308
+
2309
+ if (e.target === domCache.popup || domCache.popup.contains(e.target)) {
2310
+ ignoreOutsideClick = true;
2311
+ }
2312
+ };
2313
+ };
2314
+ };
2315
+
2316
+ const handleModalClick = (instance, domCache, dismissWith) => {
2317
+ domCache.container.onclick = e => {
2318
+ const innerParams = privateProps.innerParams.get(instance);
2319
+
2320
+ if (ignoreOutsideClick) {
2321
+ ignoreOutsideClick = false;
2322
+ return;
2323
+ }
2324
+
2325
+ if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
2326
+ dismissWith(DismissReason.backdrop);
2327
+ }
2328
+ };
2329
+ };
2330
+
2331
+ /*
2332
+ * Global function to determine if SweetAlert2 popup is shown
2333
+ */
2334
+
2335
+ const isVisible$1 = () => {
2336
+ return isVisible(getPopup());
2337
+ };
2338
+ /*
2339
+ * Global function to click 'Confirm' button
2340
+ */
2341
+
2342
+ const clickConfirm = () => getConfirmButton() && getConfirmButton().click();
2343
+ /*
2344
+ * Global function to click 'Deny' button
2345
+ */
2665
2346
 
2666
- if (innerParams.preConfirm) {
2667
- instance.resetValidationMessage();
2668
- privateProps.awaitingPromise.set(instance || undefined, true); // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesnt get destroyed until the result from this preConfirm's promise is received
2347
+ const clickDeny = () => getDenyButton() && getDenyButton().click();
2348
+ /*
2349
+ * Global function to click 'Cancel' button
2350
+ */
2669
2351
 
2670
- const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
2671
- preConfirmPromise.then(preConfirmValue => {
2672
- if (isVisible(getValidationMessage()) || preConfirmValue === false) {
2673
- instance.hideLoading();
2674
- } else {
2675
- succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
2676
- }
2677
- }).catch(error$$1 => rejectWith(instance || undefined, error$$1));
2678
- } else {
2679
- succeedWith(instance, value);
2680
- }
2681
- };
2352
+ const clickCancel = () => getCancelButton() && getCancelButton().click();
2682
2353
 
2683
2354
  const addKeydownHandler = (instance, globalState, innerParams, dismissWith) => {
2684
2355
  if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
@@ -2789,245 +2460,523 @@
2789
2460
  const denyButton = getDenyButton();
2790
2461
  const cancelButton = getCancelButton();
2791
2462
 
2792
- if (![confirmButton, denyButton, cancelButton].includes(document.activeElement)) {
2793
- return;
2463
+ if (![confirmButton, denyButton, cancelButton].includes(document.activeElement)) {
2464
+ return;
2465
+ }
2466
+
2467
+ const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
2468
+ const buttonToFocus = document.activeElement[sibling];
2469
+
2470
+ if (buttonToFocus instanceof HTMLElement) {
2471
+ buttonToFocus.focus();
2472
+ }
2473
+ };
2474
+
2475
+ const handleEsc = (e, innerParams, dismissWith) => {
2476
+ if (callIfFunction(innerParams.allowEscapeKey)) {
2477
+ e.preventDefault();
2478
+ dismissWith(DismissReason.esc);
2479
+ }
2480
+ };
2481
+
2482
+ const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
2483
+
2484
+ const isElement = elem => elem instanceof Element || isJqueryElement(elem);
2485
+
2486
+ const argsToParams = args => {
2487
+ const params = {};
2488
+
2489
+ if (typeof args[0] === 'object' && !isElement(args[0])) {
2490
+ Object.assign(params, args[0]);
2491
+ } else {
2492
+ ['title', 'html', 'icon'].forEach((name, index) => {
2493
+ const arg = args[index];
2494
+
2495
+ if (typeof arg === 'string' || isElement(arg)) {
2496
+ params[name] = arg;
2497
+ } else if (arg !== undefined) {
2498
+ error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg));
2499
+ }
2500
+ });
2501
+ }
2502
+
2503
+ return params;
2504
+ };
2505
+
2506
+ function fire() {
2507
+ const Swal = this;
2508
+
2509
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2510
+ args[_key] = arguments[_key];
2511
+ }
2512
+
2513
+ return new Swal(...args);
2514
+ }
2515
+
2516
+ /**
2517
+ * Returns an extended version of `Swal` containing `params` as defaults.
2518
+ * Useful for reusing Swal configuration.
2519
+ *
2520
+ * For example:
2521
+ *
2522
+ * Before:
2523
+ * const textPromptOptions = { input: 'text', showCancelButton: true }
2524
+ * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
2525
+ * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
2526
+ *
2527
+ * After:
2528
+ * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
2529
+ * const {value: firstName} = await TextPrompt('What is your first name?')
2530
+ * const {value: lastName} = await TextPrompt('What is your last name?')
2531
+ *
2532
+ * @param mixinParams
2533
+ */
2534
+ function mixin(mixinParams) {
2535
+ class MixinSwal extends this {
2536
+ _main(params, priorityMixinParams) {
2537
+ return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
2538
+ }
2539
+
2540
+ }
2541
+
2542
+ return MixinSwal;
2543
+ }
2544
+
2545
+ /**
2546
+ * If `timer` parameter is set, returns number of milliseconds of timer remained.
2547
+ * Otherwise, returns undefined.
2548
+ */
2549
+
2550
+ const getTimerLeft = () => {
2551
+ return globalState.timeout && globalState.timeout.getTimerLeft();
2552
+ };
2553
+ /**
2554
+ * Stop timer. Returns number of milliseconds of timer remained.
2555
+ * If `timer` parameter isn't set, returns undefined.
2556
+ */
2557
+
2558
+ const stopTimer = () => {
2559
+ if (globalState.timeout) {
2560
+ stopTimerProgressBar();
2561
+ return globalState.timeout.stop();
2562
+ }
2563
+ };
2564
+ /**
2565
+ * Resume timer. Returns number of milliseconds of timer remained.
2566
+ * If `timer` parameter isn't set, returns undefined.
2567
+ */
2568
+
2569
+ const resumeTimer = () => {
2570
+ if (globalState.timeout) {
2571
+ const remaining = globalState.timeout.start();
2572
+ animateTimerProgressBar(remaining);
2573
+ return remaining;
2574
+ }
2575
+ };
2576
+ /**
2577
+ * Resume timer. Returns number of milliseconds of timer remained.
2578
+ * If `timer` parameter isn't set, returns undefined.
2579
+ */
2580
+
2581
+ const toggleTimer = () => {
2582
+ const timer = globalState.timeout;
2583
+ return timer && (timer.running ? stopTimer() : resumeTimer());
2584
+ };
2585
+ /**
2586
+ * Increase timer. Returns number of milliseconds of an updated timer.
2587
+ * If `timer` parameter isn't set, returns undefined.
2588
+ */
2589
+
2590
+ const increaseTimer = n => {
2591
+ if (globalState.timeout) {
2592
+ const remaining = globalState.timeout.increase(n);
2593
+ animateTimerProgressBar(remaining, true);
2594
+ return remaining;
2595
+ }
2596
+ };
2597
+ /**
2598
+ * Check if timer is running. Returns true if timer is running
2599
+ * or false if timer is paused or stopped.
2600
+ * If `timer` parameter isn't set, returns undefined
2601
+ */
2602
+
2603
+ const isTimerRunning = () => {
2604
+ return globalState.timeout && globalState.timeout.isRunning();
2605
+ };
2606
+
2607
+ let bodyClickListenerAdded = false;
2608
+ const clickHandlers = {};
2609
+ function bindClickHandler() {
2610
+ let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template';
2611
+ clickHandlers[attr] = this;
2612
+
2613
+ if (!bodyClickListenerAdded) {
2614
+ document.body.addEventListener('click', bodyClickListener);
2615
+ bodyClickListenerAdded = true;
2616
+ }
2617
+ }
2618
+
2619
+ const bodyClickListener = event => {
2620
+ for (let el = event.target; el && el !== document; el = el.parentNode) {
2621
+ for (const attr in clickHandlers) {
2622
+ const template = el.getAttribute(attr);
2623
+
2624
+ if (template) {
2625
+ clickHandlers[attr].fire({
2626
+ template
2627
+ });
2628
+ return;
2629
+ }
2630
+ }
2631
+ }
2632
+ };
2633
+
2634
+
2635
+
2636
+ var staticMethods = /*#__PURE__*/Object.freeze({
2637
+ isValidParameter: isValidParameter,
2638
+ isUpdatableParameter: isUpdatableParameter,
2639
+ isDeprecatedParameter: isDeprecatedParameter,
2640
+ argsToParams: argsToParams,
2641
+ isVisible: isVisible$1,
2642
+ clickConfirm: clickConfirm,
2643
+ clickDeny: clickDeny,
2644
+ clickCancel: clickCancel,
2645
+ getContainer: getContainer,
2646
+ getPopup: getPopup,
2647
+ getTitle: getTitle,
2648
+ getHtmlContainer: getHtmlContainer,
2649
+ getImage: getImage,
2650
+ getIcon: getIcon,
2651
+ getInputLabel: getInputLabel,
2652
+ getCloseButton: getCloseButton,
2653
+ getActions: getActions,
2654
+ getConfirmButton: getConfirmButton,
2655
+ getDenyButton: getDenyButton,
2656
+ getCancelButton: getCancelButton,
2657
+ getLoader: getLoader,
2658
+ getFooter: getFooter,
2659
+ getTimerProgressBar: getTimerProgressBar,
2660
+ getFocusableElements: getFocusableElements,
2661
+ getValidationMessage: getValidationMessage,
2662
+ isLoading: isLoading,
2663
+ fire: fire,
2664
+ mixin: mixin,
2665
+ showLoading: showLoading,
2666
+ enableLoading: showLoading,
2667
+ getTimerLeft: getTimerLeft,
2668
+ stopTimer: stopTimer,
2669
+ resumeTimer: resumeTimer,
2670
+ toggleTimer: toggleTimer,
2671
+ increaseTimer: increaseTimer,
2672
+ isTimerRunning: isTimerRunning,
2673
+ bindClickHandler: bindClickHandler
2674
+ });
2675
+
2676
+ /**
2677
+ * Hides loader and shows back the button which was hidden by .showLoading()
2678
+ */
2679
+
2680
+ function hideLoading() {
2681
+ // do nothing if popup is closed
2682
+ const innerParams = privateProps.innerParams.get(this);
2683
+
2684
+ if (!innerParams) {
2685
+ return;
2686
+ }
2687
+
2688
+ const domCache = privateProps.domCache.get(this);
2689
+ hide(domCache.loader);
2690
+
2691
+ if (isToast()) {
2692
+ if (innerParams.icon) {
2693
+ show(getIcon());
2694
+ }
2695
+ } else {
2696
+ showRelatedButton(domCache);
2794
2697
  }
2795
2698
 
2796
- const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
2797
- const buttonToFocus = document.activeElement[sibling];
2699
+ removeClass([domCache.popup, domCache.actions], swalClasses.loading);
2700
+ domCache.popup.removeAttribute('aria-busy');
2701
+ domCache.popup.removeAttribute('data-loading');
2702
+ domCache.confirmButton.disabled = false;
2703
+ domCache.denyButton.disabled = false;
2704
+ domCache.cancelButton.disabled = false;
2705
+ }
2798
2706
 
2799
- if (buttonToFocus) {
2800
- buttonToFocus.focus();
2801
- }
2802
- };
2707
+ const showRelatedButton = domCache => {
2708
+ const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
2803
2709
 
2804
- const handleEsc = (e, innerParams, dismissWith) => {
2805
- if (callIfFunction(innerParams.allowEscapeKey)) {
2806
- e.preventDefault();
2807
- dismissWith(DismissReason.esc);
2710
+ if (buttonToReplace.length) {
2711
+ show(buttonToReplace[0], 'inline-block');
2712
+ } else if (allButtonsAreHidden()) {
2713
+ hide(domCache.actions);
2808
2714
  }
2809
2715
  };
2810
2716
 
2811
- const handlePopupClick = (instance, domCache, dismissWith) => {
2812
- const innerParams = privateProps.innerParams.get(instance);
2717
+ /**
2718
+ * Gets the input DOM node, this method works with input parameter.
2719
+ * @returns {HTMLElement | null}
2720
+ */
2813
2721
 
2814
- if (innerParams.toast) {
2815
- handleToastClick(instance, domCache, dismissWith);
2816
- } else {
2817
- // Ignore click events that had mousedown on the popup but mouseup on the container
2818
- // This can happen when the user drags a slider
2819
- handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup
2722
+ function getInput$1(instance) {
2723
+ const innerParams = privateProps.innerParams.get(instance || this);
2724
+ const domCache = privateProps.domCache.get(instance || this);
2820
2725
 
2821
- handleContainerMousedown(domCache);
2822
- handleModalClick(instance, domCache, dismissWith);
2726
+ if (!domCache) {
2727
+ return null;
2823
2728
  }
2824
- };
2825
2729
 
2826
- const handleToastClick = (instance, domCache, dismissWith) => {
2827
- // Closing toast by internal click
2828
- domCache.popup.onclick = () => {
2829
- const innerParams = privateProps.innerParams.get(instance);
2830
-
2831
- if (innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton || innerParams.timer || innerParams.input) {
2832
- return;
2833
- }
2730
+ return getInput(domCache.popup, innerParams.input);
2731
+ }
2834
2732
 
2835
- dismissWith(DismissReason.close);
2836
- };
2733
+ /**
2734
+ * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
2735
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
2736
+ * This is the approach that Babel will probably take to implement private methods/fields
2737
+ * https://github.com/tc39/proposal-private-methods
2738
+ * https://github.com/babel/babel/pull/7555
2739
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
2740
+ * then we can use that language feature.
2741
+ */
2742
+ var privateMethods = {
2743
+ swalPromiseResolve: new WeakMap(),
2744
+ swalPromiseReject: new WeakMap()
2837
2745
  };
2838
2746
 
2839
- let ignoreOutsideClick = false;
2747
+ /*
2748
+ * Instance method to close sweetAlert
2749
+ */
2840
2750
 
2841
- const handleModalMousedown = domCache => {
2842
- domCache.popup.onmousedown = () => {
2843
- domCache.container.onmouseup = function (e) {
2844
- domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't
2845
- // have any other direct children aside of the popup
2751
+ function removePopupAndResetState(instance, container, returnFocus, didClose) {
2752
+ if (isToast()) {
2753
+ triggerDidCloseAndDispose(instance, didClose);
2754
+ } else {
2755
+ restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
2756
+ globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
2757
+ capture: globalState.keydownListenerCapture
2758
+ });
2759
+ globalState.keydownHandlerAdded = false;
2760
+ }
2846
2761
 
2847
- if (e.target === domCache.container) {
2848
- ignoreOutsideClick = true;
2849
- }
2850
- };
2851
- };
2852
- };
2762
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088
2763
+ // for some reason removing the container in Safari will scroll the document to bottom
2853
2764
 
2854
- const handleContainerMousedown = domCache => {
2855
- domCache.container.onmousedown = () => {
2856
- domCache.popup.onmouseup = function (e) {
2857
- domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup
2765
+ if (isSafari) {
2766
+ container.setAttribute('style', 'display:none !important');
2767
+ container.removeAttribute('class');
2768
+ container.innerHTML = '';
2769
+ } else {
2770
+ container.remove();
2771
+ }
2858
2772
 
2859
- if (e.target === domCache.popup || domCache.popup.contains(e.target)) {
2860
- ignoreOutsideClick = true;
2861
- }
2862
- };
2863
- };
2864
- };
2773
+ if (isModal()) {
2774
+ undoScrollbar();
2775
+ undoIOSfix();
2776
+ unsetAriaHidden();
2777
+ }
2865
2778
 
2866
- const handleModalClick = (instance, domCache, dismissWith) => {
2867
- domCache.container.onclick = e => {
2868
- const innerParams = privateProps.innerParams.get(instance);
2779
+ removeBodyClasses();
2780
+ }
2869
2781
 
2870
- if (ignoreOutsideClick) {
2871
- ignoreOutsideClick = false;
2872
- return;
2873
- }
2782
+ function removeBodyClasses() {
2783
+ removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
2784
+ }
2874
2785
 
2875
- if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
2876
- dismissWith(DismissReason.backdrop);
2877
- }
2878
- };
2879
- };
2786
+ function close(resolveValue) {
2787
+ resolveValue = prepareResolveValue(resolveValue);
2788
+ const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
2789
+ const didClose = triggerClosePopup(this);
2880
2790
 
2881
- function _main(userParams) {
2882
- let mixinParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2883
- showWarningsForParams(Object.assign({}, mixinParams, userParams));
2791
+ if (this.isAwaitingPromise()) {
2792
+ // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
2793
+ if (!resolveValue.isDismissed) {
2794
+ handleAwaitingPromise(this);
2795
+ swalPromiseResolve(resolveValue);
2796
+ }
2797
+ } else if (didClose) {
2798
+ // Resolve Swal promise
2799
+ swalPromiseResolve(resolveValue);
2800
+ }
2801
+ }
2802
+ function isAwaitingPromise() {
2803
+ return !!privateProps.awaitingPromise.get(this);
2804
+ }
2884
2805
 
2885
- if (globalState.currentInstance) {
2886
- globalState.currentInstance._destroy();
2806
+ const triggerClosePopup = instance => {
2807
+ const popup = getPopup();
2887
2808
 
2888
- if (isModal()) {
2889
- unsetAriaHidden();
2890
- }
2809
+ if (!popup) {
2810
+ return false;
2891
2811
  }
2892
2812
 
2893
- globalState.currentInstance = this;
2894
- const innerParams = prepareParams(userParams, mixinParams);
2895
- setParameters(innerParams);
2896
- Object.freeze(innerParams); // clear the previous timer
2813
+ const innerParams = privateProps.innerParams.get(instance);
2897
2814
 
2898
- if (globalState.timeout) {
2899
- globalState.timeout.stop();
2900
- delete globalState.timeout;
2901
- } // clear the restore focus timeout
2815
+ if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
2816
+ return false;
2817
+ }
2818
+
2819
+ removeClass(popup, innerParams.showClass.popup);
2820
+ addClass(popup, innerParams.hideClass.popup);
2821
+ const backdrop = getContainer();
2822
+ removeClass(backdrop, innerParams.showClass.backdrop);
2823
+ addClass(backdrop, innerParams.hideClass.backdrop);
2824
+ handlePopupAnimation(instance, popup, innerParams);
2825
+ return true;
2826
+ };
2902
2827
 
2828
+ function rejectPromise(error) {
2829
+ const rejectPromise = privateMethods.swalPromiseReject.get(this);
2830
+ handleAwaitingPromise(this);
2903
2831
 
2904
- clearTimeout(globalState.restoreFocusTimeout);
2905
- const domCache = populateDomCache(this);
2906
- render(this, innerParams);
2907
- privateProps.innerParams.set(this, innerParams);
2908
- return swalPromise(this, domCache, innerParams);
2832
+ if (rejectPromise) {
2833
+ // Reject Swal promise
2834
+ rejectPromise(error);
2835
+ }
2909
2836
  }
2910
2837
 
2911
- const prepareParams = (userParams, mixinParams) => {
2912
- const templateParams = getTemplateParams(userParams);
2913
- const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
2838
+ const handleAwaitingPromise = instance => {
2839
+ if (instance.isAwaitingPromise()) {
2840
+ privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
2914
2841
 
2915
- params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
2916
- params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
2917
- return params;
2842
+ if (!privateProps.innerParams.get(instance)) {
2843
+ instance._destroy();
2844
+ }
2845
+ }
2918
2846
  };
2919
2847
 
2920
- const swalPromise = (instance, domCache, innerParams) => {
2921
- return new Promise((resolve, reject) => {
2922
- // functions to handle all closings/dismissals
2923
- const dismissWith = dismiss => {
2924
- instance.closePopup({
2925
- isDismissed: true,
2926
- dismiss
2927
- });
2848
+ const prepareResolveValue = resolveValue => {
2849
+ // When user calls Swal.close()
2850
+ if (typeof resolveValue === 'undefined') {
2851
+ return {
2852
+ isConfirmed: false,
2853
+ isDenied: false,
2854
+ isDismissed: true
2928
2855
  };
2856
+ }
2929
2857
 
2930
- privateMethods.swalPromiseResolve.set(instance, resolve);
2931
- privateMethods.swalPromiseReject.set(instance, reject);
2858
+ return Object.assign({
2859
+ isConfirmed: false,
2860
+ isDenied: false,
2861
+ isDismissed: false
2862
+ }, resolveValue);
2863
+ };
2932
2864
 
2933
- domCache.confirmButton.onclick = () => handleConfirmButtonClick(instance);
2865
+ const handlePopupAnimation = (instance, popup, innerParams) => {
2866
+ const container = getContainer(); // If animation is supported, animate
2934
2867
 
2935
- domCache.denyButton.onclick = () => handleDenyButtonClick(instance);
2868
+ const animationIsSupported = animationEndEvent && hasCssAnimation(popup);
2936
2869
 
2937
- domCache.cancelButton.onclick = () => handleCancelButtonClick(instance, dismissWith);
2870
+ if (typeof innerParams.willClose === 'function') {
2871
+ innerParams.willClose(popup);
2872
+ }
2938
2873
 
2939
- domCache.closeButton.onclick = () => dismissWith(DismissReason.close);
2874
+ if (animationIsSupported) {
2875
+ animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
2876
+ } else {
2877
+ // Otherwise, remove immediately
2878
+ removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
2879
+ }
2880
+ };
2940
2881
 
2941
- handlePopupClick(instance, domCache, dismissWith);
2942
- addKeydownHandler(instance, globalState, innerParams, dismissWith);
2943
- handleInputOptionsAndValue(instance, innerParams);
2944
- openPopup(innerParams);
2945
- setupTimer(globalState, innerParams, dismissWith);
2946
- initFocus(domCache, innerParams); // Scroll container to top on open (#1247, #1946)
2882
+ const animatePopup = (instance, popup, container, returnFocus, didClose) => {
2883
+ globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
2884
+ popup.addEventListener(animationEndEvent, function (e) {
2885
+ if (e.target === popup) {
2886
+ globalState.swalCloseEventFinishedCallback();
2887
+ delete globalState.swalCloseEventFinishedCallback;
2888
+ }
2889
+ });
2890
+ };
2891
+
2892
+ const triggerDidCloseAndDispose = (instance, didClose) => {
2893
+ setTimeout(() => {
2894
+ if (typeof didClose === 'function') {
2895
+ didClose.bind(instance.params)();
2896
+ }
2947
2897
 
2948
- setTimeout(() => {
2949
- domCache.container.scrollTop = 0;
2950
- });
2898
+ instance._destroy();
2951
2899
  });
2952
2900
  };
2953
2901
 
2954
- const populateDomCache = instance => {
2955
- const domCache = {
2956
- popup: getPopup(),
2957
- container: getContainer(),
2958
- actions: getActions(),
2959
- confirmButton: getConfirmButton(),
2960
- denyButton: getDenyButton(),
2961
- cancelButton: getCancelButton(),
2962
- loader: getLoader(),
2963
- closeButton: getCloseButton(),
2964
- validationMessage: getValidationMessage(),
2965
- progressSteps: getProgressSteps()
2966
- };
2967
- privateProps.domCache.set(instance, domCache);
2968
- return domCache;
2969
- };
2902
+ function setButtonsDisabled(instance, buttons, disabled) {
2903
+ const domCache = privateProps.domCache.get(instance);
2904
+ buttons.forEach(button => {
2905
+ domCache[button].disabled = disabled;
2906
+ });
2907
+ }
2970
2908
 
2971
- const setupTimer = (globalState$$1, innerParams, dismissWith) => {
2972
- const timerProgressBar = getTimerProgressBar();
2973
- hide(timerProgressBar);
2909
+ function setInputDisabled(input, disabled) {
2910
+ if (!input) {
2911
+ return false;
2912
+ }
2974
2913
 
2975
- if (innerParams.timer) {
2976
- globalState$$1.timeout = new Timer(() => {
2977
- dismissWith('timer');
2978
- delete globalState$$1.timeout;
2979
- }, innerParams.timer);
2914
+ if (input.type === 'radio') {
2915
+ const radiosContainer = input.parentNode.parentNode;
2916
+ const radios = radiosContainer.querySelectorAll('input');
2980
2917
 
2981
- if (innerParams.timerProgressBar) {
2982
- show(timerProgressBar);
2983
- setTimeout(() => {
2984
- if (globalState$$1.timeout && globalState$$1.timeout.running) {
2985
- // timer can be already stopped or unset at this point
2986
- animateTimerProgressBar(innerParams.timer);
2987
- }
2988
- });
2918
+ for (let i = 0; i < radios.length; i++) {
2919
+ radios[i].disabled = disabled;
2989
2920
  }
2921
+ } else {
2922
+ input.disabled = disabled;
2990
2923
  }
2991
- };
2924
+ }
2992
2925
 
2993
- const initFocus = (domCache, innerParams) => {
2994
- if (innerParams.toast) {
2995
- return;
2996
- }
2926
+ function enableButtons() {
2927
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
2928
+ }
2929
+ function disableButtons() {
2930
+ setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
2931
+ }
2932
+ function enableInput() {
2933
+ return setInputDisabled(this.getInput(), false);
2934
+ }
2935
+ function disableInput() {
2936
+ return setInputDisabled(this.getInput(), true);
2937
+ }
2997
2938
 
2998
- if (!callIfFunction(innerParams.allowEnterKey)) {
2999
- return blurActiveElement();
3000
- }
2939
+ function showValidationMessage(error) {
2940
+ const domCache = privateProps.domCache.get(this);
2941
+ const params = privateProps.innerParams.get(this);
2942
+ setInnerHtml(domCache.validationMessage, error);
2943
+ domCache.validationMessage.className = swalClasses['validation-message'];
3001
2944
 
3002
- if (!focusButton(domCache, innerParams)) {
3003
- setFocus(innerParams, -1, 1);
2945
+ if (params.customClass && params.customClass.validationMessage) {
2946
+ addClass(domCache.validationMessage, params.customClass.validationMessage);
3004
2947
  }
3005
- };
3006
2948
 
3007
- const focusButton = (domCache, innerParams) => {
3008
- if (innerParams.focusDeny && isVisible(domCache.denyButton)) {
3009
- domCache.denyButton.focus();
3010
- return true;
3011
- }
2949
+ show(domCache.validationMessage);
2950
+ const input = this.getInput();
3012
2951
 
3013
- if (innerParams.focusCancel && isVisible(domCache.cancelButton)) {
3014
- domCache.cancelButton.focus();
3015
- return true;
2952
+ if (input) {
2953
+ input.setAttribute('aria-invalid', true);
2954
+ input.setAttribute('aria-describedby', swalClasses['validation-message']);
2955
+ focusInput(input);
2956
+ addClass(input, swalClasses.inputerror);
3016
2957
  }
2958
+ } // Hide block with validation message
3017
2959
 
3018
- if (innerParams.focusConfirm && isVisible(domCache.confirmButton)) {
3019
- domCache.confirmButton.focus();
3020
- return true;
2960
+ function resetValidationMessage$1() {
2961
+ const domCache = privateProps.domCache.get(this);
2962
+
2963
+ if (domCache.validationMessage) {
2964
+ hide(domCache.validationMessage);
3021
2965
  }
3022
2966
 
3023
- return false;
3024
- };
2967
+ const input = this.getInput();
3025
2968
 
3026
- const blurActiveElement = () => {
3027
- if (document.activeElement && typeof document.activeElement.blur === 'function') {
3028
- document.activeElement.blur();
2969
+ if (input) {
2970
+ input.removeAttribute('aria-invalid');
2971
+ input.removeAttribute('aria-describedby');
2972
+ removeClass(input, swalClasses.inputerror);
3029
2973
  }
3030
- };
2974
+ }
2975
+
2976
+ function getProgressSteps$1() {
2977
+ const domCache = privateProps.domCache.get(this);
2978
+ return domCache.progressSteps;
2979
+ }
3031
2980
 
3032
2981
  /**
3033
2982
  * Updates popup parameters.
@@ -3044,7 +2993,7 @@
3044
2993
  const validUpdatableParams = {}; // assign valid params from `params` to `defaults`
3045
2994
 
3046
2995
  Object.keys(params).forEach(param => {
3047
- if (Swal.isUpdatableParameter(param)) {
2996
+ if (isUpdatableParameter(param)) {
3048
2997
  validUpdatableParams[param] = params[param];
3049
2998
  } else {
3050
2999
  warn("Invalid parameter to update: \"".concat(param, "\". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md"));
@@ -3067,7 +3016,7 @@
3067
3016
  const innerParams = privateProps.innerParams.get(this);
3068
3017
 
3069
3018
  if (!innerParams) {
3070
- disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining weakmaps #2335
3019
+ disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
3071
3020
 
3072
3021
  return; // This instance has already been destroyed
3073
3022
  } // Check if there is another Swal closing
@@ -3138,7 +3087,6 @@
3138
3087
  showValidationMessage: showValidationMessage,
3139
3088
  resetValidationMessage: resetValidationMessage$1,
3140
3089
  getProgressSteps: getProgressSteps$1,
3141
- _main: _main,
3142
3090
  update: update,
3143
3091
  _destroy: _destroy
3144
3092
  });
@@ -3152,7 +3100,7 @@
3152
3100
  return;
3153
3101
  }
3154
3102
 
3155
- currentInstance = this;
3103
+ currentInstance = this; // @ts-ignore
3156
3104
 
3157
3105
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3158
3106
  args[_key] = arguments[_key];
@@ -3166,11 +3114,41 @@
3166
3114
  enumerable: true,
3167
3115
  configurable: true
3168
3116
  }
3169
- });
3117
+ }); // @ts-ignore
3170
3118
 
3171
3119
  const promise = this._main(this.params);
3172
3120
 
3173
3121
  privateProps.promise.set(this, promise);
3122
+ }
3123
+
3124
+ _main(userParams) {
3125
+ let mixinParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3126
+ showWarningsForParams(Object.assign({}, mixinParams, userParams));
3127
+
3128
+ if (globalState.currentInstance) {
3129
+ globalState.currentInstance._destroy();
3130
+
3131
+ if (isModal()) {
3132
+ unsetAriaHidden();
3133
+ }
3134
+ }
3135
+
3136
+ globalState.currentInstance = this;
3137
+ const innerParams = prepareParams(userParams, mixinParams);
3138
+ setParameters(innerParams);
3139
+ Object.freeze(innerParams); // clear the previous timer
3140
+
3141
+ if (globalState.timeout) {
3142
+ globalState.timeout.stop();
3143
+ delete globalState.timeout;
3144
+ } // clear the restore focus timeout
3145
+
3146
+
3147
+ clearTimeout(globalState.restoreFocusTimeout);
3148
+ const domCache = populateDomCache(this);
3149
+ render(this, innerParams);
3150
+ privateProps.innerParams.set(this, innerParams);
3151
+ return swalPromise(this, domCache, innerParams);
3174
3152
  } // `catch` cannot be the name of a module export, so we define our thenable methods here instead
3175
3153
 
3176
3154
 
@@ -3184,7 +3162,128 @@
3184
3162
  return promise.finally(onFinally);
3185
3163
  }
3186
3164
 
3187
- } // Assign instance methods from src/instanceMethods/*.js to prototype
3165
+ }
3166
+
3167
+ const swalPromise = (instance, domCache, innerParams) => {
3168
+ return new Promise((resolve, reject) => {
3169
+ // functions to handle all closings/dismissals
3170
+ const dismissWith = dismiss => {
3171
+ instance.closePopup({
3172
+ isDismissed: true,
3173
+ dismiss
3174
+ });
3175
+ };
3176
+
3177
+ privateMethods.swalPromiseResolve.set(instance, resolve);
3178
+ privateMethods.swalPromiseReject.set(instance, reject);
3179
+
3180
+ domCache.confirmButton.onclick = () => handleConfirmButtonClick(instance);
3181
+
3182
+ domCache.denyButton.onclick = () => handleDenyButtonClick(instance);
3183
+
3184
+ domCache.cancelButton.onclick = () => handleCancelButtonClick(instance, dismissWith);
3185
+
3186
+ domCache.closeButton.onclick = () => dismissWith(DismissReason.close);
3187
+
3188
+ handlePopupClick(instance, domCache, dismissWith);
3189
+ addKeydownHandler(instance, globalState, innerParams, dismissWith);
3190
+ handleInputOptionsAndValue(instance, innerParams);
3191
+ openPopup(innerParams);
3192
+ setupTimer(globalState, innerParams, dismissWith);
3193
+ initFocus(domCache, innerParams); // Scroll container to top on open (#1247, #1946)
3194
+
3195
+ setTimeout(() => {
3196
+ domCache.container.scrollTop = 0;
3197
+ });
3198
+ });
3199
+ };
3200
+
3201
+ const prepareParams = (userParams, mixinParams) => {
3202
+ const templateParams = getTemplateParams(userParams);
3203
+ const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
3204
+
3205
+ params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
3206
+ params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
3207
+ return params;
3208
+ };
3209
+
3210
+ const populateDomCache = instance => {
3211
+ const domCache = {
3212
+ popup: getPopup(),
3213
+ container: getContainer(),
3214
+ actions: getActions(),
3215
+ confirmButton: getConfirmButton(),
3216
+ denyButton: getDenyButton(),
3217
+ cancelButton: getCancelButton(),
3218
+ loader: getLoader(),
3219
+ closeButton: getCloseButton(),
3220
+ validationMessage: getValidationMessage(),
3221
+ progressSteps: getProgressSteps()
3222
+ };
3223
+ privateProps.domCache.set(instance, domCache);
3224
+ return domCache;
3225
+ };
3226
+
3227
+ const setupTimer = (globalState$$1, innerParams, dismissWith) => {
3228
+ const timerProgressBar = getTimerProgressBar();
3229
+ hide(timerProgressBar);
3230
+
3231
+ if (innerParams.timer) {
3232
+ globalState$$1.timeout = new Timer(() => {
3233
+ dismissWith('timer');
3234
+ delete globalState$$1.timeout;
3235
+ }, innerParams.timer);
3236
+
3237
+ if (innerParams.timerProgressBar) {
3238
+ show(timerProgressBar);
3239
+ setTimeout(() => {
3240
+ if (globalState$$1.timeout && globalState$$1.timeout.running) {
3241
+ // timer can be already stopped or unset at this point
3242
+ animateTimerProgressBar(innerParams.timer);
3243
+ }
3244
+ });
3245
+ }
3246
+ }
3247
+ };
3248
+
3249
+ const initFocus = (domCache, innerParams) => {
3250
+ if (innerParams.toast) {
3251
+ return;
3252
+ }
3253
+
3254
+ if (!callIfFunction(innerParams.allowEnterKey)) {
3255
+ return blurActiveElement();
3256
+ }
3257
+
3258
+ if (!focusButton(domCache, innerParams)) {
3259
+ setFocus(innerParams, -1, 1);
3260
+ }
3261
+ };
3262
+
3263
+ const focusButton = (domCache, innerParams) => {
3264
+ if (innerParams.focusDeny && isVisible(domCache.denyButton)) {
3265
+ domCache.denyButton.focus();
3266
+ return true;
3267
+ }
3268
+
3269
+ if (innerParams.focusCancel && isVisible(domCache.cancelButton)) {
3270
+ domCache.cancelButton.focus();
3271
+ return true;
3272
+ }
3273
+
3274
+ if (innerParams.focusConfirm && isVisible(domCache.confirmButton)) {
3275
+ domCache.confirmButton.focus();
3276
+ return true;
3277
+ }
3278
+
3279
+ return false;
3280
+ };
3281
+
3282
+ const blurActiveElement = () => {
3283
+ if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
3284
+ document.activeElement.blur();
3285
+ }
3286
+ }; // Assign instance methods from src/instanceMethods/*.js to prototype
3188
3287
 
3189
3288
 
3190
3289
  Object.assign(SweetAlert.prototype, instanceMethods); // Assign static methods from src/staticMethods/*.js to constructor
@@ -3199,9 +3298,10 @@
3199
3298
  };
3200
3299
  });
3201
3300
  SweetAlert.DismissReason = DismissReason;
3202
- SweetAlert.version = '11.3.0';
3301
+ SweetAlert.version = '11.3.4';
3302
+
3303
+ const Swal = SweetAlert; // @ts-ignore
3203
3304
 
3204
- const Swal = SweetAlert;
3205
3305
  Swal.default = Swal;
3206
3306
 
3207
3307
  return Swal;