vendor: 29,464 bytes, lines 1-905
1/*! 2* sweetalert2 v11.4.19 3* Released under the MIT License. 4*/ 5(function (global, factory) { 6 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 7 typeof define === 'function' && define.amd ? define(factory) : 8 (global = global || self, global.Sweetalert2 = factory()); 9}(this, function () { 'use strict'; 10 11 const consolePrefix = 'SweetAlert2:'; 12 /** 13 * Filter the unique values into a new array 14 * @param arr 15 */ 16 17 const uniqueArray = arr => { 18 const result = []; 19 20 for (let i = 0; i < arr.length; i++) { 21 if (result.indexOf(arr[i]) === -1) { 22 result.push(arr[i]); 23 } 24 } 25 26 return result; 27 }; 28 /** 29 * Capitalize the first letter of a string 30 * @param {string} str 31 * @returns {string} 32 */ 33 34 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1); 35 /** 36 * @param {NodeList | HTMLCollection | NamedNodeMap | DOMTokenList} nodeList 37 * @returns {array} 38 */ 39 40 const toArray = nodeList => Array.prototype.slice.call(nodeList); 41 /** 42 * Standardize console warnings 43 * @param {string | array} message 44 */ 45 46 const warn = message => { 47 console.warn("".concat(consolePrefix, " ").concat(typeof message === 'object' ? message.join(' ') : message)); 48 }; 49 /** 50 * Standardize console errors 51 * @param {string} message 52 */ 53 54 const error = message => { 55 console.error("".concat(consolePrefix, " ").concat(message)); 56 }; 57 /** 58 * Private global state for `warnOnce` 59 * @type {Array} 60 * @private 61 */ 62 63 const previousWarnOnceMessages = []; 64 /** 65 * Show a console warning, but only if it hasn't already been shown 66 * @param {string} message 67 */ 68 69 const warnOnce = message => { 70 if (!previousWarnOnceMessages.includes(message)) { 71 previousWarnOnceMessages.push(message); 72 warn(message); 73 } 74 }; 75 /** 76 * Show a one-time console warning about deprecated params/methods 77 */ 78 79 const warnAboutDeprecation = (deprecatedParam, useInstead) => { 80 warnOnce("\"".concat(deprecatedParam, "\" is deprecated and will be removed in the next major release. Please use \"").concat(useInstead, "\" instead.")); 81 }; 82 /** 83 * If `arg` is a function, call it (with no arguments or context) and return the result. 84 * Otherwise, just pass the value through 85 * @param arg 86 */ 87 88 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg; 89 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function'; 90 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg); 91 const isPromise = arg => arg && Promise.resolve(arg) === arg; 92 const getRandomElement = arr => arr[Math.floor(Math.random() * arr.length)]; 93 94 const defaultParams = { 95 title: '', 96 titleText: '', 97 text: '', 98 html: '', 99 footer: '', 100 icon: undefined, 101 iconColor: undefined, 102 iconHtml: undefined, 103 template: undefined, 104 toast: false, 105 showClass: { 106 popup: 'swal2-show', 107 backdrop: 'swal2-backdrop-show', 108 icon: 'swal2-icon-show' 109 }, 110 hideClass: { 111 popup: 'swal2-hide', 112 backdrop: 'swal2-backdrop-hide', 113 icon: 'swal2-icon-hide' 114 }, 115 customClass: {}, 116 target: 'body', 117 color: undefined, 118 backdrop: true, 119 heightAuto: true, 120 allowOutsideClick: true, 121 allowEscapeKey: true, 122 allowEnterKey: true, 123 stopKeydownPropagation: true, 124 keydownListenerCapture: false, 125 showConfirmButton: true, 126 showDenyButton: false, 127 showCancelButton: false, 128 preConfirm: undefined, 129 preDeny: undefined, 130 confirmButtonText: 'OK', 131 confirmButtonAriaLabel: '', 132 confirmButtonColor: undefined, 133 denyButtonText: 'No', 134 denyButtonAriaLabel: '', 135 denyButtonColor: undefined, 136 cancelButtonText: 'Cancel', 137 cancelButtonAriaLabel: '', 138 cancelButtonColor: undefined, 139 buttonsStyling: true, 140 reverseButtons: false, 141 focusConfirm: true, 142 focusDeny: false, 143 focusCancel: false, 144 returnFocus: true, 145 showCloseButton: false, 146 closeButtonHtml: '×', 147 closeButtonAriaLabel: 'Close this dialog', 148 loaderHtml: '', 149 showLoaderOnConfirm: false, 150 showLoaderOnDeny: false, 151 imageUrl: undefined, 152 imageWidth: undefined, 153 imageHeight: undefined, 154 imageAlt: '', 155 timer: undefined, 156 timerProgressBar: false, 157 width: undefined, 158 padding: undefined, 159 background: undefined, 160 input: undefined, 161 inputPlaceholder: '', 162 inputLabel: '', 163 inputValue: '', 164 inputOptions: {}, 165 inputAutoTrim: true, 166 inputAttributes: {}, 167 inputValidator: undefined, 168 returnInputValueOnDeny: false, 169 validationMessage: undefined, 170 grow: false, 171 position: 'center', 172 progressSteps: [], 173 currentProgressStep: undefined, 174 progressStepsDistance: undefined, 175 willOpen: undefined, 176 didOpen: undefined, 177 didRender: undefined, 178 willClose: undefined, 179 didClose: undefined, 180 didDestroy: undefined, 181 scrollbarPadding: true 182 }; 183 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']; 184 const deprecatedParams = {}; 185 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture']; 186 /** 187 * Is valid parameter 188 * @param {string} paramName 189 */ 190 191 const isValidParameter = paramName => { 192 return Object.prototype.hasOwnProperty.call(defaultParams, paramName); 193 }; 194 /** 195 * Is valid parameter for Swal.update() method 196 * @param {string} paramName 197 */ 198 199 const isUpdatableParameter = paramName => { 200 return updatableParams.indexOf(paramName) !== -1; 201 }; 202 /** 203 * Is deprecated parameter 204 * @param {string} paramName 205 */ 206 207 const isDeprecatedParameter = paramName => { 208 return deprecatedParams[paramName]; 209 }; 210 211 const checkIfParamIsValid = param => { 212 if (!isValidParameter(param)) { 213 warn("Unknown parameter \"".concat(param, "\"")); 214 } 215 }; 216 217 const checkIfToastParamIsValid = param => { 218 if (toastIncompatibleParams.includes(param)) { 219 warn("The parameter \"".concat(param, "\" is incompatible with toasts")); 220 } 221 }; 222 223 const checkIfParamIsDeprecated = param => { 224 if (isDeprecatedParameter(param)) { 225 warnAboutDeprecation(param, isDeprecatedParameter(param)); 226 } 227 }; 228 /** 229 * Show relevant warnings for given params 230 * 231 * @param params 232 */ 233 234 235 const showWarningsForParams = params => { 236 if (!params.backdrop && params.allowOutsideClick) { 237 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'); 238 } 239 240 for (const param in params) { 241 checkIfParamIsValid(param); 242 243 if (params.toast) { 244 checkIfToastParamIsValid(param); 245 } 246 247 checkIfParamIsDeprecated(param); 248 } 249 }; 250 251 const swalPrefix = 'swal2-'; 252 /** 253 * @param {string[]} items 254 * @returns {object} 255 */ 256 257 const prefix = items => { 258 const result = {}; 259 260 for (const i in items) { 261 result[items[i]] = swalPrefix + items[i]; 262 } 263 264 return result; 265 }; 266 const swalClasses = prefix(['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'default-outline', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error', 'no-war']); 267 const iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']); 268 269 /** 270 * Gets the popup container which contains the backdrop and the popup itself. 271 * 272 * @returns {HTMLElement | null} 273 */ 274 275 const getContainer = () => document.body.querySelector(".".concat(swalClasses.container)); 276 /** 277 * @param {string} selectorString 278 * @returns {HTMLElement | null} 279 */ 280 281 const elementBySelector = selectorString => { 282 const container = getContainer(); 283 return container ? container.querySelector(selectorString) : null; 284 }; 285 /** 286 * @param {string} className 287 * @returns {HTMLElement | null} 288 */ 289 290 const elementByClass = className => { 291 return elementBySelector(".".concat(className)); 292 }; 293 /** 294 * @returns {HTMLElement | null} 295 */ 296 297 298 const getPopup = () => elementByClass(swalClasses.popup); 299 /** 300 * @returns {HTMLElement | null} 301 */ 302 303 const getIcon = () => elementByClass(swalClasses.icon); 304 /** 305 * @returns {HTMLElement | null} 306 */ 307 308 const getTitle = () => elementByClass(swalClasses.title); 309 /** 310 * @returns {HTMLElement | null} 311 */ 312 313 const getHtmlContainer = () => elementByClass(swalClasses['html-container']); 314 /** 315 * @returns {HTMLElement | null} 316 */ 317 318 const getImage = () => elementByClass(swalClasses.image); 319 /** 320 * @returns {HTMLElement | null} 321 */ 322 323 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']); 324 /** 325 * @returns {HTMLElement | null} 326 */ 327 328 const getValidationMessage = () => elementByClass(swalClasses['validation-message']); 329 /** 330 * @returns {HTMLElement | null} 331 */ 332 333 const getConfirmButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.confirm)); 334 /** 335 * @returns {HTMLElement | null} 336 */ 337 338 const getDenyButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.deny)); 339 /** 340 * @returns {HTMLElement | null} 341 */ 342 343 const getInputLabel = () => elementByClass(swalClasses['input-label']); 344 /** 345 * @returns {HTMLElement | null} 346 */ 347 348 const getLoader = () => elementBySelector(".".concat(swalClasses.loader)); 349 /** 350 * @returns {HTMLElement | null} 351 */ 352 353 const getCancelButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.cancel)); 354 /** 355 * @returns {HTMLElement | null} 356 */ 357 358 const getActions = () => elementByClass(swalClasses.actions); 359 /** 360 * @returns {HTMLElement | null} 361 */ 362 363 const getFooter = () => elementByClass(swalClasses.footer); 364 /** 365 * @returns {HTMLElement | null} 366 */ 367 368 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']); 369 /** 370 * @returns {HTMLElement | null} 371 */ 372 373 const getCloseButton = () => elementByClass(swalClasses.close); // https://github.com/jkup/focusable/blob/master/index.js 374 375 const focusable = "\n a[href],\n area[href],\n input:not([disabled]),\n select:not([disabled]),\n textarea:not([disabled]),\n button:not([disabled]),\n iframe,\n object,\n embed,\n [tabindex=\"0\"],\n [contenteditable],\n audio[controls],\n video[controls],\n summary\n"; 376 /** 377 * @returns {HTMLElement[]} 378 */ 379 380 const getFocusableElements = () => { 381 const focusableElementsWithTabindex = toArray(getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')) // sort according to tabindex 382 .sort((a, b) => { 383 const tabindexA = parseInt(a.getAttribute('tabindex')); 384 const tabindexB = parseInt(b.getAttribute('tabindex')); 385 386 if (tabindexA > tabindexB) { 387 return 1; 388 } else if (tabindexA < tabindexB) { 389 return -1; 390 } 391 392 return 0; 393 }); 394 const otherFocusableElements = toArray(getPopup().querySelectorAll(focusable)).filter(el => el.getAttribute('tabindex') !== '-1'); 395 return uniqueArray(focusableElementsWithTabindex.concat(otherFocusableElements)).filter(el => isVisible(el)); 396 }; 397 /** 398 * @returns {boolean} 399 */ 400 401 const isModal = () => { 402 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']); 403 }; 404 /** 405 * @returns {boolean} 406 */ 407 408 const isToast = () => { 409 return getPopup() && hasClass(getPopup(), swalClasses.toast); 410 }; 411 /** 412 * @returns {boolean} 413 */ 414 415 const isLoading = () => { 416 return getPopup().hasAttribute('data-loading'); 417 }; 418 419 const states = { 420 previousBodyPadding: null 421 }; 422 /** 423 * Securely set innerHTML of an element 424 * https://github.com/sweetalert2/sweetalert2/issues/1926 425 * 426 * @param {HTMLElement} elem 427 * @param {string} html 428 */ 429 430 const setInnerHtml = (elem, html) => { 431 elem.textContent = ''; 432 433 if (html) { 434 const parser = new DOMParser(); 435 const parsed = parser.parseFromString(html, "text/html"); 436 toArray(parsed.querySelector('head').childNodes).forEach(child => { 437 elem.appendChild(child); 438 }); 439 toArray(parsed.querySelector('body').childNodes).forEach(child => { 440 elem.appendChild(child); 441 }); 442 } 443 }; 444 /** 445 * @param {HTMLElement} elem 446 * @param {string} className 447 * @returns {boolean} 448 */ 449 450 const hasClass = (elem, className) => { 451 if (!className) { 452 return false; 453 } 454 455 const classList = className.split(/\s+/); 456 457 for (let i = 0; i < classList.length; i++) { 458 if (!elem.classList.contains(classList[i])) { 459 return false; 460 } 461 } 462 463 return true; 464 }; 465 /** 466 * @param {HTMLElement} elem 467 * @param {SweetAlertOptions} params 468 */ 469 470 const removeCustomClasses = (elem, params) => { 471 toArray(elem.classList).forEach(className => { 472 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass).includes(className)) { 473 elem.classList.remove(className); 474 } 475 }); 476 }; 477 /** 478 * @param {HTMLElement} elem 479 * @param {SweetAlertOptions} params 480 * @param {string} className 481 */ 482 483 484 const applyCustomClass = (elem, params, className) => { 485 removeCustomClasses(elem, params); 486 487 if (params.customClass && params.customClass[className]) { 488 if (typeof params.customClass[className] !== 'string' && !params.customClass[className].forEach) { 489 return warn("Invalid type of customClass.".concat(className, "! Expected string or iterable object, got \"").concat(typeof params.customClass[className], "\"")); 490 } 491 492 addClass(elem, params.customClass[className]); 493 } 494 }; 495 /** 496 * @param {HTMLElement} popup 497 * @param {import('./renderers/renderInput').InputClass} inputClass 498 * @returns {HTMLInputElement | null} 499 */ 500 501 const getInput = (popup, inputClass) => { 502 if (!inputClass) { 503 return null; 504 } 505 506 switch (inputClass) { 507 case 'select': 508 case 'textarea': 509 case 'file': 510 return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses[inputClass])); 511 512 case 'checkbox': 513 return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.checkbox, " input")); 514 515 case 'radio': 516 return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.radio, " input:checked")) || popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.radio, " input:first-child")); 517 518 case 'range': 519 return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.range, " input")); 520 521 default: 522 return popup.querySelector(".".concat(swalClasses.popup, " > .").concat(swalClasses.input)); 523 } 524 }; 525 /** 526 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input 527 */ 528 529 const focusInput = input => { 530 input.focus(); // place cursor at end of text in text input 531 532 if (input.type !== 'file') { 533 // http://stackoverflow.com/a/2345915 534 const val = input.value; 535 input.value = ''; 536 input.value = val; 537 } 538 }; 539 /** 540 * @param {HTMLElement | HTMLElement[] | null} target 541 * @param {string | string[] | readonly string[]} classList 542 * @param {boolean} condition 543 */ 544 545 const toggleClass = (target, classList, condition) => { 546 if (!target || !classList) { 547 return; 548 } 549 550 if (typeof classList === 'string') { 551 classList = classList.split(/\s+/).filter(Boolean); 552 } 553 554 classList.forEach(className => { 555 if (Array.isArray(target)) { 556 target.forEach(elem => { 557 condition ? elem.classList.add(className) : elem.classList.remove(className); 558 }); 559 } else { 560 condition ? target.classList.add(className) : target.classList.remove(className); 561 } 562 }); 563 }; 564 /** 565 * @param {HTMLElement | HTMLElement[] | null} target 566 * @param {string | string[] | readonly string[]} classList 567 */ 568 569 const addClass = (target, classList) => { 570 toggleClass(target, classList, true); 571 }; 572 /** 573 * @param {HTMLElement | HTMLElement[] | null} target 574 * @param {string | string[] | readonly string[]} classList 575 */ 576 577 const removeClass = (target, classList) => { 578 toggleClass(target, classList, false); 579 }; 580 /** 581 * Get direct child of an element by class name 582 * 583 * @param {HTMLElement} elem 584 * @param {string} className 585 * @returns {HTMLElement | null} 586 */ 587 588 const getDirectChildByClass = (elem, className) => { 589 const childNodes = toArray(elem.childNodes); 590 591 for (let i = 0; i < childNodes.length; i++) { 592 if (hasClass(childNodes[i], className)) { 593 return childNodes[i]; 594 } 595 } 596 }; 597 /** 598 * @param {HTMLElement} elem 599 * @param {string} property 600 * @param {*} value 601 */ 602 603 const applyNumericalStyle = (elem, property, value) => { 604 if (value === "".concat(parseInt(value))) { 605 value = parseInt(value); 606 } 607 608 if (value || parseInt(value) === 0) { 609 elem.style[property] = typeof value === 'number' ? "".concat(value, "px") : value; 610 } else { 611 elem.style.removeProperty(property); 612 } 613 }; 614 /** 615 * @param {HTMLElement} elem 616 * @param {string} display 617 */ 618 619 const show = function (elem) { 620 let display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'flex'; 621 elem.style.display = display; 622 }; 623 /** 624 * @param {HTMLElement} elem 625 */ 626 627 const hide = elem => { 628 elem.style.display = 'none'; 629 }; 630 /** 631 * @param {HTMLElement} parent 632 * @param {string} selector 633 * @param {string} property 634 * @param {string} value 635 */ 636 637 const setStyle = (parent, selector, property, value) => { 638 /** @type {HTMLElement} */ 639 const el = parent.querySelector(selector); 640 641 if (el) { 642 el.style[property] = value; 643 } 644 }; 645 /** 646 * @param {HTMLElement} elem 647 * @param {any} condition 648 * @param {string} display 649 */ 650 651 const toggle = function (elem, condition) { 652 let display = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'flex'; 653 condition ? show(elem, display) : hide(elem); 654 }; 655 /** 656 * borrowed from jquery $(elem).is(':visible') implementation 657 * 658 * @param {HTMLElement} elem 659 * @returns {boolean} 660 */ 661 662 const isVisible = elem => !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length)); 663 /** 664 * @returns {boolean} 665 */ 666 667 const allButtonsAreHidden = () => !isVisible(getConfirmButton()) && !isVisible(getDenyButton()) && !isVisible(getCancelButton()); 668 /** 669 * @returns {boolean} 670 */ 671 672 const isScrollable = elem => !!(elem.scrollHeight > elem.clientHeight); 673 /** 674 * borrowed from https://stackoverflow.com/a/46352119 675 * 676 * @param {HTMLElement} elem 677 * @returns {boolean} 678 */ 679 680 const hasCssAnimation = elem => { 681 const style = window.getComputedStyle(elem); 682 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0'); 683 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0'); 684 return animDuration > 0 || transDuration > 0; 685 }; 686 /** 687 * @param {number} timer 688 * @param {boolean} reset 689 */ 690 691 const animateTimerProgressBar = function (timer) { 692 let reset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 693 const timerProgressBar = getTimerProgressBar(); 694 695 if (isVisible(timerProgressBar)) { 696 if (reset) { 697 timerProgressBar.style.transition = 'none'; 698 timerProgressBar.style.width = '100%'; 699 } 700 701 setTimeout(() => { 702 timerProgressBar.style.transition = "width ".concat(timer / 1000, "s linear"); 703 timerProgressBar.style.width = '0%'; 704 }, 10); 705 } 706 }; 707 const stopTimerProgressBar = () => { 708 const timerProgressBar = getTimerProgressBar(); 709 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width); 710 timerProgressBar.style.removeProperty('transition'); 711 timerProgressBar.style.width = '100%'; 712 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width); 713 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100; 714 timerProgressBar.style.removeProperty('transition'); 715 timerProgressBar.style.width = "".concat(timerProgressBarPercent, "%"); 716 }; 717 718 /** 719 * Detect Node env 720 * 721 * @returns {boolean} 722 */ 723 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined'; 724 725 const RESTORE_FOCUS_TIMEOUT = 100; 726 727 /** @type {GlobalState} */ 728 729 const globalState = {}; 730 731 const focusPreviousActiveElement = () => { 732 if (globalState.previousActiveElement instanceof HTMLElement) { 733 globalState.previousActiveElement.focus(); 734 globalState.previousActiveElement = null; 735 } else if (document.body) { 736 document.body.focus(); 737 } 738 }; 739 /** 740 * Restore previous active (focused) element 741 * 742 * @param {boolean} returnFocus 743 * @returns {Promise} 744 */ 745 746 747 const restoreActiveElement = returnFocus => { 748 return new Promise(resolve => { 749 if (!returnFocus) { 750 return resolve(); 751 } 752 753 const x = window.scrollX; 754 const y = window.scrollY; 755 globalState.restoreFocusTimeout = setTimeout(() => { 756 focusPreviousActiveElement(); 757 resolve(); 758 }, RESTORE_FOCUS_TIMEOUT); // issues/900 759 760 window.scrollTo(x, y); 761 }); 762 }; 763 764 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, ''); 765 /** 766 * @returns {boolean} 767 */ 768 769 const resetOldContainer = () => { 770 const oldContainer = getContainer(); 771 772 if (!oldContainer) { 773 return false; 774 } 775 776 oldContainer.remove(); 777 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['has-column']]); 778 return true; 779 }; 780 781 const resetValidationMessage = () => { 782 globalState.currentInstance.resetValidationMessage(); 783 }; 784 785 const addInputChangeListeners = () => { 786 const popup = getPopup(); 787 const input = getDirectChildByClass(popup, swalClasses.input); 788 const file = getDirectChildByClass(popup, swalClasses.file); 789 /** @type {HTMLInputElement} */ 790 791 const range = popup.querySelector(".".concat(swalClasses.range, " input")); 792 /** @type {HTMLOutputElement} */ 793 794 const rangeOutput = popup.querySelector(".".concat(swalClasses.range, " output")); 795 const select = getDirectChildByClass(popup, swalClasses.select); 796 /** @type {HTMLInputElement} */ 797 798 const checkbox = popup.querySelector(".".concat(swalClasses.checkbox, " input")); 799 const textarea = getDirectChildByClass(popup, swalClasses.textarea); 800 input.oninput = resetValidationMessage; 801 file.onchange = resetValidationMessage; 802 select.onchange = resetValidationMessage; 803 checkbox.onchange = resetValidationMessage; 804 textarea.oninput = resetValidationMessage; 805 806 range.oninput = () => { 807 resetValidationMessage(); 808 rangeOutput.value = range.value; 809 }; 810 811 range.onchange = () => { 812 resetValidationMessage(); 813 rangeOutput.value = range.value; 814 }; 815 }; 816 /** 817 * @param {string | HTMLElement} target 818 * @returns {HTMLElement} 819 */ 820 821 822 const getTarget = target => typeof target === 'string' ? document.querySelector(target) : target; 823 /** 824 * @param {SweetAlertOptions} params 825 */ 826 827 828 const setupAccessibility = params => { 829 const popup = getPopup(); 830 popup.setAttribute('role', params.toast ? 'alert' : 'dialog'); 831 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive'); 832 833 if (!params.toast) { 834 popup.setAttribute('aria-modal', 'true'); 835 } 836 }; 837 /** 838 * @param {HTMLElement} targetElement 839 */ 840 841 842 const setupRTL = targetElement => { 843 if (window.getComputedStyle(targetElement).direction === 'rtl') { 844 addClass(getContainer(), swalClasses.rtl); 845 } 846 }; 847 /** 848 * Add modal + backdrop + no-war message for Russians to DOM 849 * 850 * @param {SweetAlertOptions} params 851 */ 852 853 854 const init = params => { 855 // Clean up the old popup container if it exists 856 const oldContainerExisted = resetOldContainer(); 857 /* istanbul ignore if */ 858 859 if (isNodeEnv()) { 860 error('SweetAlert2 requires document to initialize'); 861 return; 862 } 863 864 const container = document.createElement('div'); 865 container.className = swalClasses.container; 866 867 if (oldContainerExisted) { 868 addClass(container, swalClasses['no-transition']); 869 } 870 871 setInnerHtml(container, sweetHTML); 872 const targetElement = getTarget(params.target); 873 targetElement.appendChild(container); 874 setupAccessibility(params); 875 setupRTL(targetElement); 876 addInputChangeListeners(); 877 noWarMessageForRussians(container, params); 878 }; 879 /** 880 * @param {HTMLElement} container 881 * @param {SweetAlertOptions} params 882 */ 883 884 const noWarMessageForRussians = (container, params) => { 885 if (params.toast) { 886 return; 887 } // This message is targeted at people who are corrupted by propaganda, everybody else 888 // is already against war either silently or actively. 889 // 890 // The point is to wrap the truth-bomb into a patriotic title so they will actually click it 891 // and listen to the uncomfortable truth about the war from the people they love or respect. 892 893 894 const message = getRandomElement([{ 895 text: 'ШÐÐРЦÐÐÐÐÐÐРобÑаÑилÑÑ <br> к РУССÐÐÐУ ÐÐÐ ÐÐУ о войне', 896 // Arnold is loved in Russia by all people including those who are for this war 897 // His speech might change the mind of those who are brainwashed by propaganda 898 youtubeId: 'fWClXZd9c78' 899 }, { 900 text: 'РУССÐÐÐ ÐÐТРÐÐТ <br> оÑкÑÑл главнÑÑ ÑÐ°Ð¹Ð½Ñ ÑпеÑопеÑаÑии', 901 // In this video one of the most famous Russian nationalist leaders, Dmitry Demushkin, 902 // explains that this war has no sense and produces the exact opposite result of what 903 // it was intended to do. 904 youtubeId: '_RjBNkn88yA' 905 }, {
vendor: 7,981 bytes, lines 906-1162
906 text: 'ÐÐÐ ÐÐ ÐÐÐÐÐ ÐССÐРСТРÐÐÐÐÐ <br> дал оÑÐµÐ½ÐºÑ Ñ Ð¾Ð´Ñ ÑпеÑопеÑаÑии', 907 // In this video Igor Girkin, who played a key role in the annexation of Crimea, 908 // explains that this war has failed already and all possible outcomes are bad for Russia. 909 youtubeId: 'yUmzQT4C8JY' 910 }, { 911 text: 'ФÐÐСÐÐÐ ÐРУРРÐССÐÐ <br> говоÑÐ¸Ñ ÐÐ-РУССÐРо ÑпеÑопеÑаÑии', 912 youtubeId: 'hkCYb6edUrQ' 913 }, { 914 text: 'ЮРÐÐ ÐÐÐÐÐЯÐÐ ÑеÑÑно <br> о генеÑÐ°Ð»Ð°Ñ Ð Ð£Ð¡Ð¡ÐÐÐ ÐÐ ÐÐÐ', 915 youtubeId: 'w4-_8BJKfpk' 916 }, { 917 text: 'Ðолковник ФСРСТРÐÐÐÐÐ <br> об ÑÑÐ¿ÐµÑ Ð°Ñ Ð ÐССÐРв ÑпеÑопеÑаÑии', 918 youtubeId: 'saK5UTKroDA' 919 }]); // The message will only be shown to Russian users visiting Russian sites 920 921 if (/^ru\b/.test(navigator.language) && location.host.match(/\.(ru|su|xn--p1ai)$/)) { 922 const noWar = document.createElement('div'); 923 noWar.className = swalClasses['no-war']; 924 setInnerHtml(noWar, "<a href=\"https://www.youtube.com/watch?v=".concat(message.youtubeId, "\" target=\"_blank\">").concat(message.text, "</a>")); 925 container.appendChild(noWar); 926 container.style.paddingTop = '4em'; 927 } 928 }; 929 930 /** 931 * @param {HTMLElement | object | string} param 932 * @param {HTMLElement} target 933 */ 934 935 const parseHtmlToContainer = (param, target) => { 936 // DOM element 937 if (param instanceof HTMLElement) { 938 target.appendChild(param); 939 } // Object 940 else if (typeof param === 'object') { 941 handleObject(param, target); 942 } // Plain string 943 else if (param) { 944 setInnerHtml(target, param); 945 } 946 }; 947 /** 948 * @param {object} param 949 * @param {HTMLElement} target 950 */ 951 952 const handleObject = (param, target) => { 953 // JQuery element(s) 954 if (param.jquery) { 955 handleJqueryElem(target, param); 956 } // For other objects use their string representation 957 else { 958 setInnerHtml(target, param.toString()); 959 } 960 }; 961 /** 962 * @param {HTMLElement} target 963 * @param {HTMLElement} elem 964 */ 965 966 967 const handleJqueryElem = (target, elem) => { 968 target.textContent = ''; 969 970 if (0 in elem) { 971 for (let i = 0; (i in elem); i++) { 972 target.appendChild(elem[i].cloneNode(true)); 973 } 974 } else { 975 target.appendChild(elem.cloneNode(true)); 976 } 977 }; 978 979 /** 980 * @returns {'webkitAnimationEnd' | 'animationend' | false} 981 */ 982 983 const animationEndEvent = (() => { 984 // Prevent run in Node env 985 986 /* istanbul ignore if */ 987 if (isNodeEnv()) { 988 return false; 989 } 990 991 const testEl = document.createElement('div'); 992 const transEndEventNames = { 993 WebkitAnimation: 'webkitAnimationEnd', 994 // Chrome, Safari and Opera 995 animation: 'animationend' // Standard syntax 996 997 }; 998 999 for (const i in transEndEventNames) { 1000 if (Object.prototype.hasOwnProperty.call(transEndEventNames, i) && typeof testEl.style[i] !== 'undefined') { 1001 return transEndEventNames[i]; 1002 } 1003 } 1004 1005 return false; 1006 })(); 1007 1008 /** 1009 * Measure scrollbar width for padding body during modal show/hide 1010 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js 1011 * 1012 * @returns {number} 1013 */ 1014 1015 const measureScrollbar = () => { 1016 const scrollDiv = document.createElement('div'); 1017 scrollDiv.className = swalClasses['scrollbar-measure']; 1018 document.body.appendChild(scrollDiv); 1019 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; 1020 document.body.removeChild(scrollDiv); 1021 return scrollbarWidth; 1022 }; 1023 1024 /** 1025 * @param {SweetAlert2} instance 1026 * @param {SweetAlertOptions} params 1027 */ 1028 1029 const renderActions = (instance, params) => { 1030 const actions = getActions(); 1031 const loader = getLoader(); // Actions (buttons) wrapper 1032 1033 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) { 1034 hide(actions); 1035 } else { 1036 show(actions); 1037 } // Custom class 1038 1039 1040 applyCustomClass(actions, params, 'actions'); // Render all the buttons 1041 1042 renderButtons(actions, loader, params); // Loader 1043 1044 setInnerHtml(loader, params.loaderHtml); 1045 applyCustomClass(loader, params, 'loader'); 1046 }; 1047 /** 1048 * @param {HTMLElement} actions 1049 * @param {HTMLElement} loader 1050 * @param {SweetAlertOptions} params 1051 */ 1052 1053 function renderButtons(actions, loader, params) { 1054 const confirmButton = getConfirmButton(); 1055 const denyButton = getDenyButton(); 1056 const cancelButton = getCancelButton(); // Render buttons 1057 1058 renderButton(confirmButton, 'confirm', params); 1059 renderButton(denyButton, 'deny', params); 1060 renderButton(cancelButton, 'cancel', params); 1061 handleButtonsStyling(confirmButton, denyButton, cancelButton, params); 1062 1063 if (params.reverseButtons) { 1064 if (params.toast) { 1065 actions.insertBefore(cancelButton, confirmButton); 1066 actions.insertBefore(denyButton, confirmButton); 1067 } else { 1068 actions.insertBefore(cancelButton, loader); 1069 actions.insertBefore(denyButton, loader); 1070 actions.insertBefore(confirmButton, loader); 1071 } 1072 } 1073 } 1074 /** 1075 * @param {HTMLElement} confirmButton 1076 * @param {HTMLElement} denyButton 1077 * @param {HTMLElement} cancelButton 1078 * @param {SweetAlertOptions} params 1079 */ 1080 1081 1082 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) { 1083 if (!params.buttonsStyling) { 1084 return removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled); 1085 } 1086 1087 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled); // Buttons background colors 1088 1089 if (params.confirmButtonColor) { 1090 confirmButton.style.backgroundColor = params.confirmButtonColor; 1091 addClass(confirmButton, swalClasses['default-outline']); 1092 } 1093 1094 if (params.denyButtonColor) { 1095 denyButton.style.backgroundColor = params.denyButtonColor; 1096 addClass(denyButton, swalClasses['default-outline']); 1097 } 1098 1099 if (params.cancelButtonColor) { 1100 cancelButton.style.backgroundColor = params.cancelButtonColor; 1101 addClass(cancelButton, swalClasses['default-outline']); 1102 } 1103 } 1104 /** 1105 * @param {HTMLElement} button 1106 * @param {'confirm' | 'deny' | 'cancel'} buttonType 1107 * @param {SweetAlertOptions} params 1108 */ 1109 1110 1111 function renderButton(button, buttonType, params) { 1112 toggle(button, params["show".concat(capitalizeFirstLetter(buttonType), "Button")], 'inline-block'); 1113 setInnerHtml(button, params["".concat(buttonType, "ButtonText")]); // Set caption text 1114 1115 button.setAttribute('aria-label', params["".concat(buttonType, "ButtonAriaLabel")]); // ARIA label 1116 // Add buttons custom classes 1117 1118 button.className = swalClasses[buttonType]; 1119 applyCustomClass(button, params, "".concat(buttonType, "Button")); 1120 addClass(button, params["".concat(buttonType, "ButtonClass")]); 1121 } 1122 1123 /** 1124 * @param {SweetAlert2} instance 1125 * @param {SweetAlertOptions} params 1126 */ 1127 1128 const renderContainer = (instance, params) => { 1129 const container = getContainer(); 1130 1131 if (!container) { 1132 return; 1133 } 1134 1135 handleBackdropParam(container, params.backdrop); 1136 handlePositionParam(container, params.position); 1137 handleGrowParam(container, params.grow); // Custom class 1138 1139 applyCustomClass(container, params, 'container'); 1140 }; 1141 /** 1142 * @param {HTMLElement} container 1143 * @param {SweetAlertOptions['backdrop']} backdrop 1144 */ 1145 1146 function handleBackdropParam(container, backdrop) { 1147 if (typeof backdrop === 'string') { 1148 container.style.background = backdrop; 1149 } else if (!backdrop) { 1150 addClass([document.documentElement, document.body], swalClasses['no-backdrop']); 1151 } 1152 } 1153 /** 1154 * @param {HTMLElement} container 1155 * @param {SweetAlertOptions['position']} position 1156 */ 1157 1158 1159 function handlePositionParam(container, position) { 1160 if (position in swalClasses) { 1161 addClass(container, swalClasses[position]); 1162 } else {
vendor: 5,493 bytes, lines 1163-1351
1163 warn('The "position" parameter is not valid, defaulting to "center"'); 1164 addClass(container, swalClasses.center); 1165 } 1166 } 1167 /** 1168 * @param {HTMLElement} container 1169 * @param {SweetAlertOptions['grow']} grow 1170 */ 1171 1172 1173 function handleGrowParam(container, grow) { 1174 if (grow && typeof grow === 'string') { 1175 const growClass = "grow-".concat(grow); 1176 1177 if (growClass in swalClasses) { 1178 addClass(container, swalClasses[growClass]); 1179 } 1180 } 1181 } 1182 1183 /** 1184 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has. 1185 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 1186 * This is the approach that Babel will probably take to implement private methods/fields 1187 * https://github.com/tc39/proposal-private-methods 1188 * https://github.com/babel/babel/pull/7555 1189 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 1190 * then we can use that language feature. 1191 */ 1192 var privateProps = { 1193 awaitingPromise: new WeakMap(), 1194 promise: new WeakMap(), 1195 innerParams: new WeakMap(), 1196 domCache: new WeakMap() 1197 }; 1198 1199 /// <reference path="../../../../sweetalert2.d.ts"/> 1200 /** @type {InputClass[]} */ 1201 1202 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea']; 1203 /** 1204 * @param {SweetAlert2} instance 1205 * @param {SweetAlertOptions} params 1206 */ 1207 1208 const renderInput = (instance, params) => { 1209 const popup = getPopup(); 1210 const innerParams = privateProps.innerParams.get(instance); 1211 const rerender = !innerParams || params.input !== innerParams.input; 1212 inputClasses.forEach(inputClass => { 1213 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]); // set attributes 1214 1215 setAttributes(inputClass, params.inputAttributes); // set class 1216 1217 inputContainer.className = swalClasses[inputClass]; 1218 1219 if (rerender) { 1220 hide(inputContainer); 1221 } 1222 }); 1223 1224 if (params.input) { 1225 if (rerender) { 1226 showInput(params); 1227 } // set custom class 1228 1229 1230 setCustomClass(params); 1231 } 1232 }; 1233 /** 1234 * @param {SweetAlertOptions} params 1235 */ 1236 1237 const showInput = params => { 1238 if (!renderInputType[params.input]) { 1239 return error("Unexpected type of input! Expected \"text\", \"email\", \"password\", \"number\", \"tel\", \"select\", \"radio\", \"checkbox\", \"textarea\", \"file\" or \"url\", got \"".concat(params.input, "\"")); 1240 } 1241 1242 const inputContainer = getInputContainer(params.input); 1243 const input = renderInputType[params.input](inputContainer, params); 1244 show(inputContainer); // input autofocus 1245 1246 setTimeout(() => { 1247 focusInput(input); 1248 }); 1249 }; 1250 /** 1251 * @param {HTMLInputElement} input 1252 */ 1253 1254 1255 const removeAttributes = input => { 1256 for (let i = 0; i < input.attributes.length; i++) { 1257 const attrName = input.attributes[i].name; 1258 1259 if (!['type', 'value', 'style'].includes(attrName)) { 1260 input.removeAttribute(attrName); 1261 } 1262 } 1263 }; 1264 /** 1265 * @param {InputClass} inputClass 1266 * @param {SweetAlertOptions['inputAttributes']} inputAttributes 1267 */ 1268 1269 1270 const setAttributes = (inputClass, inputAttributes) => { 1271 const input = getInput(getPopup(), inputClass); 1272 1273 if (!input) { 1274 return; 1275 } 1276 1277 removeAttributes(input); 1278 1279 for (const attr in inputAttributes) { 1280 input.setAttribute(attr, inputAttributes[attr]); 1281 } 1282 }; 1283 /** 1284 * @param {SweetAlertOptions} params 1285 */ 1286 1287 1288 const setCustomClass = params => { 1289 const inputContainer = getInputContainer(params.input); 1290 1291 if (typeof params.customClass === 'object') { 1292 addClass(inputContainer, params.customClass.input); 1293 } 1294 }; 1295 /** 1296 * @param {HTMLInputElement | HTMLTextAreaElement} input 1297 * @param {SweetAlertOptions} params 1298 */ 1299 1300 1301 const setInputPlaceholder = (input, params) => { 1302 if (!input.placeholder || params.inputPlaceholder) { 1303 input.placeholder = params.inputPlaceholder; 1304 } 1305 }; 1306 /** 1307 * @param {Input} input 1308 * @param {Input} prependTo 1309 * @param {SweetAlertOptions} params 1310 */ 1311 1312 1313 const setInputLabel = (input, prependTo, params) => { 1314 if (params.inputLabel) { 1315 input.id = swalClasses.input; 1316 const label = document.createElement('label'); 1317 const labelClass = swalClasses['input-label']; 1318 label.setAttribute('for', input.id); 1319 label.className = labelClass; 1320 1321 if (typeof params.customClass === 'object') { 1322 addClass(label, params.customClass.inputLabel); 1323 } 1324 1325 label.innerText = params.inputLabel; 1326 prependTo.insertAdjacentElement('beforebegin', label); 1327 } 1328 }; 1329 /** 1330 * @param {SweetAlertOptions['input']} inputType 1331 * @returns {HTMLElement} 1332 */ 1333 1334 1335 const getInputContainer = inputType => { 1336 return getDirectChildByClass(getPopup(), swalClasses[inputType] || swalClasses.input); 1337 }; 1338 /** 1339 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input 1340 * @param {SweetAlertOptions['inputValue']} inputValue 1341 */ 1342 1343 1344 const checkAndSetInputValue = (input, inputValue) => { 1345 if (['string', 'number'].includes(typeof inputValue)) { 1346 input.value = "".concat(inputValue); 1347 } else if (!isPromise(inputValue)) { 1348 warn("Unexpected type of inputValue! Expected \"string\", \"number\" or \"Promise\", got \"".concat(typeof inputValue, "\"")); 1349 } 1350 }; 1351 /** @type Record<string, (input: Input | HTMLElement, params: SweetAlertOptions) =>
vendor: 13,900 bytes, lines 1351-1841
1351 Input> */ 1352 1353 1354 const renderInputType = {}; 1355 /** 1356 * @param {HTMLInputElement} input 1357 * @param {SweetAlertOptions} params 1358 * @returns {HTMLInputElement} 1359 */ 1360 1361 renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = (input, params) => { 1362 checkAndSetInputValue(input, params.inputValue); 1363 setInputLabel(input, input, params); 1364 setInputPlaceholder(input, params); 1365 input.type = params.input; 1366 return input; 1367 }; 1368 /** 1369 * @param {HTMLInputElement} input 1370 * @param {SweetAlertOptions} params 1371 * @returns {HTMLInputElement} 1372 */ 1373 1374 1375 renderInputType.file = (input, params) => { 1376 setInputLabel(input, input, params); 1377 setInputPlaceholder(input, params); 1378 return input; 1379 }; 1380 /** 1381 * @param {HTMLInputElement} range 1382 * @param {SweetAlertOptions} params 1383 * @returns {HTMLInputElement} 1384 */ 1385 1386 1387 renderInputType.range = (range, params) => { 1388 const rangeInput = range.querySelector('input'); 1389 const rangeOutput = range.querySelector('output'); 1390 checkAndSetInputValue(rangeInput, params.inputValue); 1391 rangeInput.type = params.input; 1392 checkAndSetInputValue(rangeOutput, params.inputValue); 1393 setInputLabel(rangeInput, range, params); 1394 return range; 1395 }; 1396 /** 1397 * @param {HTMLSelectElement} select 1398 * @param {SweetAlertOptions} params 1399 * @returns {HTMLSelectElement} 1400 */ 1401 1402 1403 renderInputType.select = (select, params) => { 1404 select.textContent = ''; 1405 1406 if (params.inputPlaceholder) { 1407 const placeholder = document.createElement('option'); 1408 setInnerHtml(placeholder, params.inputPlaceholder); 1409 placeholder.value = ''; 1410 placeholder.disabled = true; 1411 placeholder.selected = true; 1412 select.appendChild(placeholder); 1413 } 1414 1415 setInputLabel(select, select, params); 1416 return select; 1417 }; 1418 /** 1419 * @param {HTMLInputElement} radio 1420 * @returns {HTMLInputElement} 1421 */ 1422 1423 1424 renderInputType.radio = radio => { 1425 radio.textContent = ''; 1426 return radio; 1427 }; 1428 /** 1429 * @param {HTMLLabelElement} checkboxContainer 1430 * @param {SweetAlertOptions} params 1431 * @returns {HTMLInputElement} 1432 */ 1433 1434 1435 renderInputType.checkbox = (checkboxContainer, params) => { 1436 const checkbox = getInput(getPopup(), 'checkbox'); 1437 checkbox.value = '1'; 1438 checkbox.id = swalClasses.checkbox; 1439 checkbox.checked = Boolean(params.inputValue); 1440 const label = checkboxContainer.querySelector('span'); 1441 setInnerHtml(label, params.inputPlaceholder); 1442 return checkbox; 1443 }; 1444 /** 1445 * @param {HTMLTextAreaElement} textarea 1446 * @param {SweetAlertOptions} params 1447 * @returns {HTMLTextAreaElement} 1448 */ 1449 1450 1451 renderInputType.textarea = (textarea, params) => { 1452 checkAndSetInputValue(textarea, params.inputValue); 1453 setInputPlaceholder(textarea, params); 1454 setInputLabel(textarea, textarea, params); 1455 /** 1456 * @param {HTMLElement} el 1457 * @returns {number} 1458 */ 1459 1460 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight); // https://github.com/sweetalert2/sweetalert2/issues/2291 1461 1462 1463 setTimeout(() => { 1464 // https://github.com/sweetalert2/sweetalert2/issues/1699 1465 if ('MutationObserver' in window) { 1466 const initialPopupWidth = parseInt(window.getComputedStyle(getPopup()).width); 1467 1468 const textareaResizeHandler = () => { 1469 const textareaWidth = textarea.offsetWidth + getMargin(textarea); 1470 1471 if (textareaWidth > initialPopupWidth) { 1472 getPopup().style.width = "".concat(textareaWidth, "px"); 1473 } else { 1474 getPopup().style.width = null; 1475 } 1476 }; 1477 1478 new MutationObserver(textareaResizeHandler).observe(textarea, { 1479 attributes: true, 1480 attributeFilter: ['style'] 1481 }); 1482 } 1483 }); 1484 return textarea; 1485 }; 1486 1487 /** 1488 * @param {SweetAlert2} instance 1489 * @param {SweetAlertOptions} params 1490 */ 1491 1492 const renderContent = (instance, params) => { 1493 const htmlContainer = getHtmlContainer(); 1494 applyCustomClass(htmlContainer, params, 'htmlContainer'); // Content as HTML 1495 1496 if (params.html) { 1497 parseHtmlToContainer(params.html, htmlContainer); 1498 show(htmlContainer, 'block'); 1499 } // Content as plain text 1500 else if (params.text) { 1501 htmlContainer.textContent = params.text; 1502 show(htmlContainer, 'block'); 1503 } // No content 1504 else { 1505 hide(htmlContainer); 1506 } 1507 1508 renderInput(instance, params); 1509 }; 1510 1511 /** 1512 * @param {SweetAlert2} instance 1513 * @param {SweetAlertOptions} params 1514 */ 1515 1516 const renderFooter = (instance, params) => { 1517 const footer = getFooter(); 1518 toggle(footer, params.footer); 1519 1520 if (params.footer) { 1521 parseHtmlToContainer(params.footer, footer); 1522 } // Custom class 1523 1524 1525 applyCustomClass(footer, params, 'footer'); 1526 }; 1527 1528 /** 1529 * @param {SweetAlert2} instance 1530 * @param {SweetAlertOptions} params 1531 */ 1532 1533 const renderCloseButton = (instance, params) => { 1534 const closeButton = getCloseButton(); 1535 setInnerHtml(closeButton, params.closeButtonHtml); // Custom class 1536 1537 applyCustomClass(closeButton, params, 'closeButton'); 1538 toggle(closeButton, params.showCloseButton); 1539 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel); 1540 }; 1541 1542 /** 1543 * @param {SweetAlert2} instance 1544 * @param {SweetAlertOptions} params 1545 */ 1546 1547 const renderIcon = (instance, params) => { 1548 const innerParams = privateProps.innerParams.get(instance); 1549 const icon = getIcon(); // if the given icon already rendered, apply the styling without re-rendering the icon 1550 1551 if (innerParams && params.icon === innerParams.icon) { 1552 // Custom or default content 1553 setContent(icon, params); 1554 applyStyles(icon, params); 1555 return; 1556 } 1557 1558 if (!params.icon && !params.iconHtml) { 1559 hide(icon); 1560 return; 1561 } 1562 1563 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) { 1564 error("Unknown icon! Expected \"success\", \"error\", \"warning\", \"info\" or \"question\", got \"".concat(params.icon, "\"")); 1565 hide(icon); 1566 return; 1567 } 1568 1569 show(icon); // Custom or default content 1570 1571 setContent(icon, params); 1572 applyStyles(icon, params); // Animate icon 1573 1574 addClass(icon, params.showClass.icon); 1575 }; 1576 /** 1577 * @param {HTMLElement} icon 1578 * @param {SweetAlertOptions} params 1579 */ 1580 1581 const applyStyles = (icon, params) => { 1582 for (const iconType in iconTypes) { 1583 if (params.icon !== iconType) { 1584 removeClass(icon, iconTypes[iconType]); 1585 } 1586 } 1587 1588 addClass(icon, iconTypes[params.icon]); // Icon color 1589 1590 setColor(icon, params); // Success icon background color 1591 1592 adjustSuccessIconBackgroundColor(); // Custom class 1593 1594 applyCustomClass(icon, params, 'icon'); 1595 }; // Adjust success icon background color to match the popup background color 1596 1597 1598 const adjustSuccessIconBackgroundColor = () => { 1599 const popup = getPopup(); 1600 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color'); 1601 /** @type {NodeListOf<HTMLElement>} */ 1602 1603 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix'); 1604 1605 for (let i = 0; i < successIconParts.length; i++) { 1606 successIconParts[i].style.backgroundColor = popupBackgroundColor; 1607 } 1608 }; 1609 1610 const successIconHtml = "\n <div class=\"swal2-success-circular-line-left\"></div>\n <span class=\"swal2-success-line-tip\"></span> <span class=\"swal2-success-line-long\"></span>\n <div class=\"swal2-success-ring\"></div> <div class=\"swal2-success-fix\"></div>\n <div class=\"swal2-success-circular-line-right\"></div>\n"; 1611 const errorIconHtml = "\n <span class=\"swal2-x-mark\">\n <span class=\"swal2-x-mark-line-left\"></span>\n <span class=\"swal2-x-mark-line-right\"></span>\n </span>\n"; 1612 /** 1613 * @param {HTMLElement} icon 1614 * @param {SweetAlertOptions} params 1615 */ 1616 1617 const setContent = (icon, params) => { 1618 let oldContent = icon.innerHTML; 1619 let newContent; 1620 1621 if (params.iconHtml) { 1622 newContent = iconContent(params.iconHtml); 1623 } else if (params.icon === 'success') { 1624 newContent = successIconHtml; 1625 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor() 1626 } else if (params.icon === 'error') { 1627 newContent = errorIconHtml; 1628 } else { 1629 const defaultIconHtml = { 1630 question: '?', 1631 warning: '!', 1632 info: 'i' 1633 }; 1634 newContent = iconContent(defaultIconHtml[params.icon]); 1635 } 1636 1637 if (oldContent.trim() !== newContent.trim()) { 1638 setInnerHtml(icon, newContent); 1639 } 1640 }; 1641 /** 1642 * @param {HTMLElement} icon 1643 * @param {SweetAlertOptions} params 1644 */ 1645 1646 1647 const setColor = (icon, params) => { 1648 if (!params.iconColor) { 1649 return; 1650 } 1651 1652 icon.style.color = params.iconColor; 1653 icon.style.borderColor = params.iconColor; 1654 1655 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) { 1656 setStyle(icon, sel, 'backgroundColor', params.iconColor); 1657 } 1658 1659 setStyle(icon, '.swal2-success-ring', 'borderColor', params.iconColor); 1660 }; 1661 /** 1662 * @param {string} content 1663 * @returns {string} 1664 */ 1665 1666 1667 const iconContent = content => "<div class=\"".concat(swalClasses['icon-content'], "\">").concat(content, "</div>"); 1668 1669 /** 1670 * @param {SweetAlert2} instance 1671 * @param {SweetAlertOptions} params 1672 */ 1673 1674 const renderImage = (instance, params) => { 1675 const image = getImage(); 1676 1677 if (!params.imageUrl) { 1678 return hide(image); 1679 } 1680 1681 show(image, ''); // Src, alt 1682 1683 image.setAttribute('src', params.imageUrl); 1684 image.setAttribute('alt', params.imageAlt); // Width, height 1685 1686 applyNumericalStyle(image, 'width', params.imageWidth); 1687 applyNumericalStyle(image, 'height', params.imageHeight); // Class 1688 1689 image.className = swalClasses.image; 1690 applyCustomClass(image, params, 'image'); 1691 }; 1692 1693 /** 1694 * @param {SweetAlert2} instance 1695 * @param {SweetAlertOptions} params 1696 */ 1697 1698 const renderProgressSteps = (instance, params) => { 1699 const progressStepsContainer = getProgressSteps(); 1700 1701 if (!params.progressSteps || params.progressSteps.length === 0) { 1702 return hide(progressStepsContainer); 1703 } 1704 1705 show(progressStepsContainer); 1706 progressStepsContainer.textContent = ''; 1707 1708 if (params.currentProgressStep >= params.progressSteps.length) { 1709 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)'); 1710 } 1711 1712 params.progressSteps.forEach((step, index) => { 1713 const stepEl = createStepElement(step); 1714 progressStepsContainer.appendChild(stepEl); 1715 1716 if (index === params.currentProgressStep) { 1717 addClass(stepEl, swalClasses['active-progress-step']); 1718 } 1719 1720 if (index !== params.progressSteps.length - 1) { 1721 const lineEl = createLineElement(params); 1722 progressStepsContainer.appendChild(lineEl); 1723 } 1724 }); 1725 }; 1726 /** 1727 * @param {string} step 1728 * @returns {HTMLLIElement} 1729 */ 1730 1731 const createStepElement = step => { 1732 const stepEl = document.createElement('li'); 1733 addClass(stepEl, swalClasses['progress-step']); 1734 setInnerHtml(stepEl, step); 1735 return stepEl; 1736 }; 1737 /** 1738 * @param {SweetAlertOptions} params 1739 * @returns {HTMLLIElement} 1740 */ 1741 1742 1743 const createLineElement = params => { 1744 const lineEl = document.createElement('li'); 1745 addClass(lineEl, swalClasses['progress-step-line']); 1746 1747 if (params.progressStepsDistance) { 1748 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance); 1749 } 1750 1751 return lineEl; 1752 }; 1753 1754 /** 1755 * @param {SweetAlert2} instance 1756 * @param {SweetAlertOptions} params 1757 */ 1758 1759 const renderTitle = (instance, params) => { 1760 const title = getTitle(); 1761 toggle(title, params.title || params.titleText, 'block'); 1762 1763 if (params.title) { 1764 parseHtmlToContainer(params.title, title); 1765 } 1766 1767 if (params.titleText) { 1768 title.innerText = params.titleText; 1769 } // Custom class 1770 1771 1772 applyCustomClass(title, params, 'title'); 1773 }; 1774 1775 /** 1776 * @param {SweetAlert2} instance 1777 * @param {SweetAlertOptions} params 1778 */ 1779 1780 const renderPopup = (instance, params) => { 1781 const container = getContainer(); 1782 const popup = getPopup(); // Width 1783 // https://github.com/sweetalert2/sweetalert2/issues/2170 1784 1785 if (params.toast) { 1786 applyNumericalStyle(container, 'width', params.width); 1787 popup.style.width = '100%'; 1788 popup.insertBefore(getLoader(), getIcon()); 1789 } else { 1790 applyNumericalStyle(popup, 'width', params.width); 1791 } // Padding 1792 1793 1794 applyNumericalStyle(popup, 'padding', params.padding); // Color 1795 1796 if (params.color) { 1797 popup.style.color = params.color; 1798 } // Background 1799 1800 1801 if (params.background) { 1802 popup.style.background = params.background; 1803 } 1804 1805 hide(getValidationMessage()); // Classes 1806 1807 addClasses(popup, params); 1808 }; 1809 /** 1810 * @param {HTMLElement} popup 1811 * @param {SweetAlertOptions} params 1812 */ 1813 1814 const addClasses = (popup, params) => { 1815 // Default Class + showClass when updating Swal.update({}) 1816 popup.className = "".concat(swalClasses.popup, " ").concat(isVisible(popup) ? params.showClass.popup : ''); 1817 1818 if (params.toast) { 1819 addClass([document.documentElement, document.body], swalClasses['toast-shown']); 1820 addClass(popup, swalClasses.toast); 1821 } else { 1822 addClass(popup, swalClasses.modal); 1823 } // Custom class 1824 1825 1826 applyCustomClass(popup, params, 'popup'); 1827 1828 if (typeof params.customClass === 'string') { 1829 addClass(popup, params.customClass); 1830 } // Icon class (#1842) 1831 1832 1833 if (params.icon) { 1834 addClass(popup, swalClasses["icon-".concat(params.icon)]); 1835 } 1836 }; 1837 1838 /** 1839 * @param {SweetAlert2} instance 1840 * @param {SweetAlertOptions} params 1841 */
vendor: 7,976 bytes, lines 1841-2112
1841 1842 1843 const render = (instance, params) => { 1844 renderPopup(instance, params); 1845 renderContainer(instance, params); 1846 renderProgressSteps(instance, params); 1847 renderIcon(instance, params); 1848 renderImage(instance, params); 1849 renderTitle(instance, params); 1850 renderCloseButton(instance, params); 1851 renderContent(instance, params); 1852 renderActions(instance, params); 1853 renderFooter(instance, params); 1854 1855 if (typeof params.didRender === 'function') { 1856 params.didRender(getPopup()); 1857 } 1858 }; 1859 1860 const DismissReason = Object.freeze({ 1861 cancel: 'cancel', 1862 backdrop: 'backdrop', 1863 close: 'close', 1864 esc: 'esc', 1865 timer: 'timer' 1866 }); 1867 1868 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that 1869 // elements not within the active modal dialog will not be surfaced if a user opens a screen 1870 // readerâs list of elements (headings, form controls, landmarks, etc.) in the document. 1871 1872 const setAriaHidden = () => { 1873 const bodyChildren = toArray(document.body.children); 1874 bodyChildren.forEach(el => { 1875 if (el === getContainer() || el.contains(getContainer())) { 1876 return; 1877 } 1878 1879 if (el.hasAttribute('aria-hidden')) { 1880 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden')); 1881 } 1882 1883 el.setAttribute('aria-hidden', 'true'); 1884 }); 1885 }; 1886 const unsetAriaHidden = () => { 1887 const bodyChildren = toArray(document.body.children); 1888 bodyChildren.forEach(el => { 1889 if (el.hasAttribute('data-previous-aria-hidden')) { 1890 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden')); 1891 el.removeAttribute('data-previous-aria-hidden'); 1892 } else { 1893 el.removeAttribute('aria-hidden'); 1894 } 1895 }); 1896 }; 1897 1898 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer']; 1899 const getTemplateParams = params => { 1900 const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template; 1901 1902 if (!template) { 1903 return {}; 1904 } 1905 /** @type {DocumentFragment} */ 1906 1907 1908 const templateContent = template.content; 1909 showWarningsForElements(templateContent); 1910 const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams)); 1911 return result; 1912 }; 1913 /** 1914 * @param {DocumentFragment} templateContent 1915 */ 1916 1917 const getSwalParams = templateContent => { 1918 const result = {}; 1919 toArray(templateContent.querySelectorAll('swal-param')).forEach(param => { 1920 showWarningsForAttributes(param, ['name', 'value']); 1921 const paramName = param.getAttribute('name'); 1922 const value = param.getAttribute('value'); 1923 1924 if (typeof defaultParams[paramName] === 'boolean' && value === 'false') { 1925 result[paramName] = false; 1926 } 1927 1928 if (typeof defaultParams[paramName] === 'object') { 1929 result[paramName] = JSON.parse(value); 1930 } 1931 }); 1932 return result; 1933 }; 1934 /** 1935 * @param {DocumentFragment} templateContent 1936 */ 1937 1938 1939 const getSwalButtons = templateContent => { 1940 const result = {}; 1941 toArray(templateContent.querySelectorAll('swal-button')).forEach(button => { 1942 showWarningsForAttributes(button, ['type', 'color', 'aria-label']); 1943 const type = button.getAttribute('type'); 1944 result["".concat(type, "ButtonText")] = button.innerHTML; 1945 result["show".concat(capitalizeFirstLetter(type), "Button")] = true; 1946 1947 if (button.hasAttribute('color')) { 1948 result["".concat(type, "ButtonColor")] = button.getAttribute('color'); 1949 } 1950 1951 if (button.hasAttribute('aria-label')) { 1952 result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label'); 1953 } 1954 }); 1955 return result; 1956 }; 1957 /** 1958 * @param {DocumentFragment} templateContent 1959 */ 1960 1961 1962 const getSwalImage = templateContent => { 1963 const result = {}; 1964 /** @type {HTMLElement} */ 1965 1966 const image = templateContent.querySelector('swal-image'); 1967 1968 if (image) { 1969 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']); 1970 1971 if (image.hasAttribute('src')) { 1972 result.imageUrl = image.getAttribute('src'); 1973 } 1974 1975 if (image.hasAttribute('width')) { 1976 result.imageWidth = image.getAttribute('width'); 1977 } 1978 1979 if (image.hasAttribute('height')) { 1980 result.imageHeight = image.getAttribute('height'); 1981 } 1982 1983 if (image.hasAttribute('alt')) { 1984 result.imageAlt = image.getAttribute('alt'); 1985 } 1986 } 1987 1988 return result; 1989 }; 1990 /** 1991 * @param {DocumentFragment} templateContent 1992 */ 1993 1994 1995 const getSwalIcon = templateContent => { 1996 const result = {}; 1997 /** @type {HTMLElement} */ 1998 1999 const icon = templateContent.querySelector('swal-icon'); 2000 2001 if (icon) { 2002 showWarningsForAttributes(icon, ['type', 'color']); 2003 2004 if (icon.hasAttribute('type')) { 2005 result.icon = icon.getAttribute('type'); 2006 } 2007 2008 if (icon.hasAttribute('color')) { 2009 result.iconColor = icon.getAttribute('color'); 2010 } 2011 2012 result.iconHtml = icon.innerHTML; 2013 } 2014 2015 return result; 2016 }; 2017 /** 2018 * @param {DocumentFragment} templateContent 2019 */ 2020 2021 2022 const getSwalInput = templateContent => { 2023 const result = {}; 2024 /** @type {HTMLElement} */ 2025 2026 const input = templateContent.querySelector('swal-input'); 2027 2028 if (input) { 2029 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']); 2030 result.input = input.getAttribute('type') || 'text'; 2031 2032 if (input.hasAttribute('label')) { 2033 result.inputLabel = input.getAttribute('label'); 2034 } 2035 2036 if (input.hasAttribute('placeholder')) { 2037 result.inputPlaceholder = input.getAttribute('placeholder'); 2038 } 2039 2040 if (input.hasAttribute('value')) { 2041 result.inputValue = input.getAttribute('value'); 2042 } 2043 } 2044 2045 const inputOptions = templateContent.querySelectorAll('swal-input-option'); 2046 2047 if (inputOptions.length) { 2048 result.inputOptions = {}; 2049 toArray(inputOptions).forEach(option => { 2050 showWarningsForAttributes(option, ['value']); 2051 const optionValue = option.getAttribute('value'); 2052 const optionName = option.innerHTML; 2053 result.inputOptions[optionValue] = optionName; 2054 }); 2055 } 2056 2057 return result; 2058 }; 2059 /** 2060 * @param {DocumentFragment} templateContent 2061 * @param {string[]} paramNames 2062 */ 2063 2064 2065 const getSwalStringParams = (templateContent, paramNames) => { 2066 const result = {}; 2067 2068 for (const i in paramNames) { 2069 const paramName = paramNames[i]; 2070 /** @type {HTMLElement} */ 2071 2072 const tag = templateContent.querySelector(paramName); 2073 2074 if (tag) { 2075 showWarningsForAttributes(tag, []); 2076 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim(); 2077 } 2078 } 2079 2080 return result; 2081 }; 2082 /** 2083 * @param {DocumentFragment} templateContent 2084 */ 2085 2086 2087 const showWarningsForElements = templateContent => { 2088 const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']); 2089 toArray(templateContent.children).forEach(el => { 2090 const tagName = el.tagName.toLowerCase(); 2091 2092 if (allowedElements.indexOf(tagName) === -1) { 2093 warn("Unrecognized element <".concat(tagName, ">")); 2094 } 2095 }); 2096 }; 2097 /** 2098 * @param {HTMLElement} el 2099 * @param {string[]} allowedAttributes 2100 */ 2101 2102 2103 const showWarningsForAttributes = (el, allowedAttributes) => { 2104 toArray(el.attributes).forEach(attribute => { 2105 if (allowedAttributes.indexOf(attribute.name) === -1) { 2106 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.')]); 2107 } 2108 }); 2109 }; 2110 2111 var defaultInputValidators = { 2112
vendor: 22,365 bytes, lines 2112-2862
2112/** 2113 * @param {string} string 2114 * @param {string} validationMessage 2115 * @returns {Promise<void | string>} 2116 */ 2117 email: (string, validationMessage) => { 2118 return /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address'); 2119 }, 2120 2121 /** 2122 * @param {string} string 2123 * @param {string} validationMessage 2124 * @returns {Promise<void | string>} 2125 */ 2126 url: (string, validationMessage) => { 2127 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013 2128 return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid URL'); 2129 } 2130 }; 2131 2132 /** 2133 * @param {SweetAlertOptions} params 2134 */ 2135 2136 function setDefaultInputValidators(params) { 2137 // Use default `inputValidator` for supported input types if not provided 2138 if (!params.inputValidator) { 2139 Object.keys(defaultInputValidators).forEach(key => { 2140 if (params.input === key) { 2141 params.inputValidator = defaultInputValidators[key]; 2142 } 2143 }); 2144 } 2145 } 2146 /** 2147 * @param {SweetAlertOptions} params 2148 */ 2149 2150 2151 function validateCustomTargetElement(params) { 2152 // Determine if the custom target element is valid 2153 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) { 2154 warn('Target parameter is not valid, defaulting to "body"'); 2155 params.target = 'body'; 2156 } 2157 } 2158 /** 2159 * Set type, text and actions on popup 2160 * 2161 * @param {SweetAlertOptions} params 2162 */ 2163 2164 2165 function setParameters(params) { 2166 setDefaultInputValidators(params); // showLoaderOnConfirm && preConfirm 2167 2168 if (params.showLoaderOnConfirm && !params.preConfirm) { 2169 warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request'); 2170 } 2171 2172 validateCustomTargetElement(params); // Replace newlines with <br> in title 2173 2174 if (typeof params.title === 'string') { 2175 params.title = params.title.split('\n').join('<br />'); 2176 } 2177 2178 init(params); 2179 } 2180 2181 class Timer { 2182 constructor(callback, delay) { 2183 this.callback = callback; 2184 this.remaining = delay; 2185 this.running = false; 2186 this.start(); 2187 } 2188 2189 start() { 2190 if (!this.running) { 2191 this.running = true; 2192 this.started = new Date(); 2193 this.id = setTimeout(this.callback, this.remaining); 2194 } 2195 2196 return this.remaining; 2197 } 2198 2199 stop() { 2200 if (this.running) { 2201 this.running = false; 2202 clearTimeout(this.id); 2203 this.remaining -= new Date().getTime() - this.started.getTime(); 2204 } 2205 2206 return this.remaining; 2207 } 2208 2209 increase(n) { 2210 const running = this.running; 2211 2212 if (running) { 2213 this.stop(); 2214 } 2215 2216 this.remaining += n; 2217 2218 if (running) { 2219 this.start(); 2220 } 2221 2222 return this.remaining; 2223 } 2224 2225 getTimerLeft() { 2226 if (this.running) { 2227 this.stop(); 2228 this.start(); 2229 } 2230 2231 return this.remaining; 2232 } 2233 2234 isRunning() { 2235 return this.running; 2236 } 2237 2238 } 2239 2240 const fixScrollbar = () => { 2241 // for queues, do not do this more than once 2242 if (states.previousBodyPadding !== null) { 2243 return; 2244 } // if the body has overflow 2245 2246 2247 if (document.body.scrollHeight > window.innerHeight) { 2248 // add padding so the content doesn't shift after removal of scrollbar 2249 states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right')); 2250 document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px"); 2251 } 2252 }; 2253 const undoScrollbar = () => { 2254 if (states.previousBodyPadding !== null) { 2255 document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px"); 2256 states.previousBodyPadding = null; 2257 } 2258 }; 2259 2260 /* istanbul ignore file */ 2261 2262 const iOSfix = () => { 2263 const iOS = // @ts-ignore 2264 /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream || navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; 2265 2266 if (iOS && !hasClass(document.body, swalClasses.iosfix)) { 2267 const offset = document.body.scrollTop; 2268 document.body.style.top = "".concat(offset * -1, "px"); 2269 addClass(document.body, swalClasses.iosfix); 2270 lockBodyScroll(); 2271 addBottomPaddingForTallPopups(); 2272 } 2273 }; 2274 /** 2275 * https://github.com/sweetalert2/sweetalert2/issues/1948 2276 */ 2277 2278 const addBottomPaddingForTallPopups = () => { 2279 const ua = navigator.userAgent; 2280 const iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i); 2281 const webkit = !!ua.match(/WebKit/i); 2282 const iOSSafari = iOS && webkit && !ua.match(/CriOS/i); 2283 2284 if (iOSSafari) { 2285 const bottomPanelHeight = 44; 2286 2287 if (getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) { 2288 getContainer().style.paddingBottom = "".concat(bottomPanelHeight, "px"); 2289 } 2290 } 2291 }; 2292 /** 2293 * https://github.com/sweetalert2/sweetalert2/issues/1246 2294 */ 2295 2296 2297 const lockBodyScroll = () => { 2298 const container = getContainer(); 2299 let preventTouchMove; 2300 2301 container.ontouchstart = e => { 2302 preventTouchMove = shouldPreventTouchMove(e); 2303 }; 2304 2305 container.ontouchmove = e => { 2306 if (preventTouchMove) { 2307 e.preventDefault(); 2308 e.stopPropagation(); 2309 } 2310 }; 2311 }; 2312 2313 const shouldPreventTouchMove = event => { 2314 const target = event.target; 2315 const container = getContainer(); 2316 2317 if (isStylus(event) || isZoom(event)) { 2318 return false; 2319 } 2320 2321 if (target === container) { 2322 return true; 2323 } 2324 2325 if (!isScrollable(container) && target.tagName !== 'INPUT' && // #1603 2326 target.tagName !== 'TEXTAREA' && // #2266 2327 !(isScrollable(getHtmlContainer()) && // #1944 2328 getHtmlContainer().contains(target))) { 2329 return true; 2330 } 2331 2332 return false; 2333 }; 2334 /** 2335 * https://github.com/sweetalert2/sweetalert2/issues/1786 2336 * 2337 * @param {*} event 2338 * @returns {boolean} 2339 */ 2340 2341 2342 const isStylus = event => { 2343 return event.touches && event.touches.length && event.touches[0].touchType === 'stylus'; 2344 }; 2345 /** 2346 * https://github.com/sweetalert2/sweetalert2/issues/1891 2347 * 2348 * @param {TouchEvent} event 2349 * @returns {boolean} 2350 */ 2351 2352 2353 const isZoom = event => { 2354 return event.touches && event.touches.length > 1; 2355 }; 2356 2357 const undoIOSfix = () => { 2358 if (hasClass(document.body, swalClasses.iosfix)) { 2359 const offset = parseInt(document.body.style.top, 10); 2360 removeClass(document.body, swalClasses.iosfix); 2361 document.body.style.top = ''; 2362 document.body.scrollTop = offset * -1; 2363 } 2364 }; 2365 2366 const SHOW_CLASS_TIMEOUT = 10; 2367 /** 2368 * Open popup, add necessary classes and styles, fix scrollbar 2369 * 2370 * @param params 2371 */ 2372 2373 const openPopup = params => { 2374 const container = getContainer(); 2375 const popup = getPopup(); 2376 2377 if (typeof params.willOpen === 'function') { 2378 params.willOpen(popup); 2379 } 2380 2381 const bodyStyles = window.getComputedStyle(document.body); 2382 const initialBodyOverflow = bodyStyles.overflowY; 2383 addClasses$1(container, popup, params); // scrolling is 'hidden' until animation is done, after that 'auto' 2384 2385 setTimeout(() => { 2386 setScrollingVisibility(container, popup); 2387 }, SHOW_CLASS_TIMEOUT); 2388 2389 if (isModal()) { 2390 fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow); 2391 setAriaHidden(); 2392 } 2393 2394 if (!isToast() && !globalState.previousActiveElement) { 2395 globalState.previousActiveElement = document.activeElement; 2396 } 2397 2398 if (typeof params.didOpen === 'function') { 2399 setTimeout(() => params.didOpen(popup)); 2400 } 2401 2402 removeClass(container, swalClasses['no-transition']); 2403 }; 2404 2405 const swalOpenAnimationFinished = event => { 2406 const popup = getPopup(); 2407 2408 if (event.target !== popup) { 2409 return; 2410 } 2411 2412 const container = getContainer(); 2413 popup.removeEventListener(animationEndEvent, swalOpenAnimationFinished); 2414 container.style.overflowY = 'auto'; 2415 }; 2416 2417 const setScrollingVisibility = (container, popup) => { 2418 if (animationEndEvent && hasCssAnimation(popup)) { 2419 container.style.overflowY = 'hidden'; 2420 popup.addEventListener(animationEndEvent, swalOpenAnimationFinished); 2421 } else { 2422 container.style.overflowY = 'auto'; 2423 } 2424 }; 2425 2426 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => { 2427 iOSfix(); 2428 2429 if (scrollbarPadding && initialBodyOverflow !== 'hidden') { 2430 fixScrollbar(); 2431 } // sweetalert2/issues/1247 2432 2433 2434 setTimeout(() => { 2435 container.scrollTop = 0; 2436 }); 2437 }; 2438 2439 const addClasses$1 = (container, popup, params) => { 2440 addClass(container, params.showClass.backdrop); // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059 2441 2442 popup.style.setProperty('opacity', '0', 'important'); 2443 show(popup, 'grid'); 2444 setTimeout(() => { 2445 // Animate popup right after showing it 2446 addClass(popup, params.showClass.popup); // and remove the opacity workaround 2447 2448 popup.style.removeProperty('opacity'); 2449 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062 2450 2451 addClass([document.documentElement, document.body], swalClasses.shown); 2452 2453 if (params.heightAuto && params.backdrop && !params.toast) { 2454 addClass([document.documentElement, document.body], swalClasses['height-auto']); 2455 } 2456 }; 2457 2458 /** 2459 * Shows loader (spinner), this is useful with AJAX requests. 2460 * By default the loader be shown instead of the "Confirm" button. 2461 */ 2462 2463 const showLoading = buttonToReplace => { 2464 let popup = getPopup(); 2465 2466 if (!popup) { 2467 new Swal(); // eslint-disable-line no-new 2468 } 2469 2470 popup = getPopup(); 2471 const loader = getLoader(); 2472 2473 if (isToast()) { 2474 hide(getIcon()); 2475 } else { 2476 replaceButton(popup, buttonToReplace); 2477 } 2478 2479 show(loader); 2480 popup.setAttribute('data-loading', 'true'); 2481 popup.setAttribute('aria-busy', 'true'); 2482 popup.focus(); 2483 }; 2484 2485 const replaceButton = (popup, buttonToReplace) => { 2486 const actions = getActions(); 2487 const loader = getLoader(); 2488 2489 if (!buttonToReplace && isVisible(getConfirmButton())) { 2490 buttonToReplace = getConfirmButton(); 2491 } 2492 2493 show(actions); 2494 2495 if (buttonToReplace) { 2496 hide(buttonToReplace); 2497 loader.setAttribute('data-button-to-replace', buttonToReplace.className); 2498 } 2499 2500 loader.parentNode.insertBefore(loader, buttonToReplace); 2501 addClass([popup, actions], swalClasses.loading); 2502 }; 2503 2504 const handleInputOptionsAndValue = (instance, params) => { 2505 if (params.input === 'select' || params.input === 'radio') { 2506 handleInputOptions(instance, params); 2507 } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) { 2508 showLoading(getConfirmButton()); 2509 handleInputValue(instance, params); 2510 } 2511 }; 2512 const getInputValue = (instance, innerParams) => { 2513 const input = instance.getInput(); 2514 2515 if (!input) { 2516 return null; 2517 } 2518 2519 switch (innerParams.input) { 2520 case 'checkbox': 2521 return getCheckboxValue(input); 2522 2523 case 'radio': 2524 return getRadioValue(input); 2525 2526 case 'file': 2527 return getFileValue(input); 2528 2529 default: 2530 return innerParams.inputAutoTrim ? input.value.trim() : input.value; 2531 } 2532 }; 2533 2534 const getCheckboxValue = input => input.checked ? 1 : 0; 2535 2536 const getRadioValue = input => input.checked ? input.value : null; 2537 2538 const getFileValue = input => input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null; 2539 2540 const handleInputOptions = (instance, params) => { 2541 const popup = getPopup(); 2542 2543 const processInputOptions = inputOptions => populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params); 2544 2545 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) { 2546 showLoading(getConfirmButton()); 2547 asPromise(params.inputOptions).then(inputOptions => { 2548 instance.hideLoading(); 2549 processInputOptions(inputOptions); 2550 }); 2551 } else if (typeof params.inputOptions === 'object') { 2552 processInputOptions(params.inputOptions); 2553 } else { 2554 error("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(typeof params.inputOptions)); 2555 } 2556 }; 2557 2558 const handleInputValue = (instance, params) => { 2559 const input = instance.getInput(); 2560 hide(input); 2561 asPromise(params.inputValue).then(inputValue => { 2562 input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : "".concat(inputValue); 2563 show(input); 2564 input.focus(); 2565 instance.hideLoading(); 2566 }).catch(err => { 2567 error("Error in inputValue promise: ".concat(err)); 2568 input.value = ''; 2569 show(input); 2570 input.focus(); 2571 instance.hideLoading(); 2572 }); 2573 }; 2574 2575 const populateInputOptions = { 2576 select: (popup, inputOptions, params) => { 2577 const select = getDirectChildByClass(popup, swalClasses.select); 2578 2579 const renderOption = (parent, optionLabel, optionValue) => { 2580 const option = document.createElement('option'); 2581 option.value = optionValue; 2582 setInnerHtml(option, optionLabel); 2583 option.selected = isSelected(optionValue, params.inputValue); 2584 parent.appendChild(option); 2585 }; 2586 2587 inputOptions.forEach(inputOption => { 2588 const optionValue = inputOption[0]; 2589 const optionLabel = inputOption[1]; // <optgroup> spec: 2590 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6 2591 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..." 2592 // check whether this is a <optgroup> 2593 2594 if (Array.isArray(optionLabel)) { 2595 // if it is an array, then it is an <optgroup> 2596 const optgroup = document.createElement('optgroup'); 2597 optgroup.label = optionValue; 2598 optgroup.disabled = false; // not configurable for now 2599 2600 select.appendChild(optgroup); 2601 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0])); 2602 } else { 2603 // case of <option> 2604 renderOption(select, optionLabel, optionValue); 2605 } 2606 }); 2607 select.focus(); 2608 }, 2609 radio: (popup, inputOptions, params) => { 2610 const radio = getDirectChildByClass(popup, swalClasses.radio); 2611 inputOptions.forEach(inputOption => { 2612 const radioValue = inputOption[0]; 2613 const radioLabel = inputOption[1]; 2614 const radioInput = document.createElement('input'); 2615 const radioLabelElement = document.createElement('label'); 2616 radioInput.type = 'radio'; 2617 radioInput.name = swalClasses.radio; 2618 radioInput.value = radioValue; 2619 2620 if (isSelected(radioValue, params.inputValue)) { 2621 radioInput.checked = true; 2622 } 2623 2624 const label = document.createElement('span'); 2625 setInnerHtml(label, radioLabel); 2626 label.className = swalClasses.label; 2627 radioLabelElement.appendChild(radioInput); 2628 radioLabelElement.appendChild(label); 2629 radio.appendChild(radioLabelElement); 2630 }); 2631 const radios = radio.querySelectorAll('input'); 2632 2633 if (radios.length) { 2634 radios[0].focus(); 2635 } 2636 } 2637 }; 2638 /** 2639 * Converts `inputOptions` into an array of `[value, label]`s 2640 * @param inputOptions 2641 */ 2642 2643 const formatInputOptions = inputOptions => { 2644 const result = []; 2645 2646 if (typeof Map !== 'undefined' && inputOptions instanceof Map) { 2647 inputOptions.forEach((value, key) => { 2648 let valueFormatted = value; 2649 2650 if (typeof valueFormatted === 'object') { 2651 // case of <optgroup> 2652 valueFormatted = formatInputOptions(valueFormatted); 2653 } 2654 2655 result.push([key, valueFormatted]); 2656 }); 2657 } else { 2658 Object.keys(inputOptions).forEach(key => { 2659 let valueFormatted = inputOptions[key]; 2660 2661 if (typeof valueFormatted === 'object') { 2662 // case of <optgroup> 2663 valueFormatted = formatInputOptions(valueFormatted); 2664 } 2665 2666 result.push([key, valueFormatted]); 2667 }); 2668 } 2669 2670 return result; 2671 }; 2672 2673 const isSelected = (optionValue, inputValue) => { 2674 return inputValue && inputValue.toString() === optionValue.toString(); 2675 }; 2676 2677 /** 2678 * Hides loader and shows back the button which was hidden by .showLoading() 2679 */ 2680 2681 function hideLoading() { 2682 // do nothing if popup is closed 2683 const innerParams = privateProps.innerParams.get(this); 2684 2685 if (!innerParams) { 2686 return; 2687 } 2688 2689 const domCache = privateProps.domCache.get(this); 2690 hide(domCache.loader); 2691 2692 if (isToast()) { 2693 if (innerParams.icon) { 2694 show(getIcon()); 2695 } 2696 } else { 2697 showRelatedButton(domCache); 2698 } 2699 2700 removeClass([domCache.popup, domCache.actions], swalClasses.loading); 2701 domCache.popup.removeAttribute('aria-busy'); 2702 domCache.popup.removeAttribute('data-loading'); 2703 domCache.confirmButton.disabled = false; 2704 domCache.denyButton.disabled = false; 2705 domCache.cancelButton.disabled = false; 2706 } 2707 2708 const showRelatedButton = domCache => { 2709 const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace')); 2710 2711 if (buttonToReplace.length) { 2712 show(buttonToReplace[0], 'inline-block'); 2713 } else if (allButtonsAreHidden()) { 2714 hide(domCache.actions); 2715 } 2716 }; 2717 2718 /** 2719 * Gets the input DOM node, this method works with input parameter. 2720 * @returns {HTMLElement | null} 2721 */ 2722 2723 function getInput$1(instance) { 2724 const innerParams = privateProps.innerParams.get(instance || this); 2725 const domCache = privateProps.domCache.get(instance || this); 2726 2727 if (!domCache) { 2728 return null; 2729 } 2730 2731 return getInput(domCache.popup, innerParams.input); 2732 } 2733 2734 /** 2735 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has. 2736 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 2737 * This is the approach that Babel will probably take to implement private methods/fields 2738 * https://github.com/tc39/proposal-private-methods 2739 * https://github.com/babel/babel/pull/7555 2740 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 2741 * then we can use that language feature. 2742 */ 2743 var privateMethods = { 2744 swalPromiseResolve: new WeakMap(), 2745 swalPromiseReject: new WeakMap() 2746 }; 2747 2748 /* 2749 * Global function to determine if SweetAlert2 popup is shown 2750 */ 2751 2752 const isVisible$1 = () => { 2753 return isVisible(getPopup()); 2754 }; 2755 /* 2756 * Global function to click 'Confirm' button 2757 */ 2758 2759 const clickConfirm = () => getConfirmButton() && getConfirmButton().click(); 2760 /* 2761 * Global function to click 'Deny' button 2762 */ 2763 2764 const clickDeny = () => getDenyButton() && getDenyButton().click(); 2765 /* 2766 * Global function to click 'Cancel' button 2767 */ 2768 2769 const clickCancel = () => getCancelButton() && getCancelButton().click(); 2770 2771 /** 2772 * @param {GlobalState} globalState 2773 */ 2774 2775 const removeKeydownHandler = globalState => { 2776 if (globalState.keydownTarget && globalState.keydownHandlerAdded) { 2777 globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, { 2778 capture: globalState.keydownListenerCapture 2779 }); 2780 globalState.keydownHandlerAdded = false; 2781 } 2782 }; 2783 /** 2784 * @param {SweetAlert2} instance 2785 * @param {GlobalState} globalState 2786 * @param {SweetAlertOptions} innerParams 2787 * @param {*} dismissWith 2788 */ 2789 2790 const addKeydownHandler = (instance, globalState, innerParams, dismissWith) => { 2791 removeKeydownHandler(globalState); 2792 2793 if (!innerParams.toast) { 2794 globalState.keydownHandler = e => keydownHandler(instance, e, dismissWith); 2795 2796 globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup(); 2797 globalState.keydownListenerCapture = innerParams.keydownListenerCapture; 2798 globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, { 2799 capture: globalState.keydownListenerCapture 2800 }); 2801 globalState.keydownHandlerAdded = true; 2802 } 2803 }; 2804 /** 2805 * @param {SweetAlertOptions} innerParams 2806 * @param {number} index 2807 * @param {number} increment 2808 */ 2809 2810 const setFocus = (innerParams, index, increment) => { 2811 const focusableElements = getFocusableElements(); // search for visible elements and select the next possible match 2812 2813 if (focusableElements.length) { 2814 index = index + increment; // rollover to first item 2815 2816 if (index === focusableElements.length) { 2817 index = 0; // go to last item 2818 } else if (index === -1) { 2819 index = focusableElements.length - 1; 2820 } 2821 2822 return focusableElements[index].focus(); 2823 } // no visible focusable elements, focus the popup 2824 2825 2826 getPopup().focus(); 2827 }; 2828 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown']; 2829 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp']; 2830 /** 2831 * @param {SweetAlert2} instance 2832 * @param {KeyboardEvent} e 2833 * @param {function} dismissWith 2834 */ 2835 2836 const keydownHandler = (instance, e, dismissWith) => { 2837 const innerParams = privateProps.innerParams.get(instance); 2838 2839 if (!innerParams) { 2840 return; // This instance has already been destroyed 2841 } // Ignore keydown during IME composition 2842 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition 2843 // https://github.com/sweetalert2/sweetalert2/issues/720 2844 // https://github.com/sweetalert2/sweetalert2/issues/2406 2845 2846 2847 if (e.isComposing || e.keyCode === 229) { 2848 return; 2849 } 2850 2851 if (innerParams.stopKeydownPropagation) { 2852 e.stopPropagation(); 2853 } // ENTER 2854 2855 2856 if (e.key === 'Enter') { 2857 handleEnter(instance, e, innerParams); 2858 } // TAB 2859 else if (e.key === 'Tab') { 2860 handleTab(e, innerParams); 2861 } // ARROWS - switch focus between buttons 2862 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(e.ke
vendor: 2,537 bytes, lines 2862-2962
2862y)) { 2863 handleArrows(e.key); 2864 } // ESC 2865 else if (e.key === 'Escape') { 2866 handleEsc(e, innerParams, dismissWith); 2867 } 2868 }; 2869 /** 2870 * @param {SweetAlert2} instance 2871 * @param {KeyboardEvent} e 2872 * @param {SweetAlertOptions} innerParams 2873 */ 2874 2875 2876 const handleEnter = (instance, e, innerParams) => { 2877 // https://github.com/sweetalert2/sweetalert2/issues/2386 2878 if (!callIfFunction(innerParams.allowEnterKey)) { 2879 return; 2880 } 2881 2882 if (e.target && instance.getInput() && e.target instanceof HTMLElement && e.target.outerHTML === instance.getInput().outerHTML) { 2883 if (['textarea', 'file'].includes(innerParams.input)) { 2884 return; // do not submit 2885 } 2886 2887 clickConfirm(); 2888 e.preventDefault(); 2889 } 2890 }; 2891 /** 2892 * @param {KeyboardEvent} e 2893 * @param {SweetAlertOptions} innerParams 2894 */ 2895 2896 2897 const handleTab = (e, innerParams) => { 2898 const targetElement = e.target; 2899 const focusableElements = getFocusableElements(); 2900 let btnIndex = -1; 2901 2902 for (let i = 0; i < focusableElements.length; i++) { 2903 if (targetElement === focusableElements[i]) { 2904 btnIndex = i; 2905 break; 2906 } 2907 } // Cycle to the next button 2908 2909 2910 if (!e.shiftKey) { 2911 setFocus(innerParams, btnIndex, 1); 2912 } // Cycle to the prev button 2913 else { 2914 setFocus(innerParams, btnIndex, -1); 2915 } 2916 2917 e.stopPropagation(); 2918 e.preventDefault(); 2919 }; 2920 /** 2921 * @param {string} key 2922 */ 2923 2924 2925 const handleArrows = key => { 2926 const confirmButton = getConfirmButton(); 2927 const denyButton = getDenyButton(); 2928 const cancelButton = getCancelButton(); 2929 2930 if (document.activeElement instanceof HTMLElement && ![confirmButton, denyButton, cancelButton].includes(document.activeElement)) { 2931 return; 2932 } 2933 2934 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling'; 2935 let buttonToFocus = document.activeElement; 2936 2937 for (let i = 0; i < getActions().children.length; i++) { 2938 buttonToFocus = buttonToFocus[sibling]; 2939 2940 if (!buttonToFocus) { 2941 return; 2942 } 2943 2944 if (buttonToFocus instanceof HTMLButtonElement && isVisible(buttonToFocus)) { 2945 break; 2946 } 2947 } 2948 2949 if (buttonToFocus instanceof HTMLButtonElement) { 2950 buttonToFocus.focus(); 2951 } 2952 }; 2953 /** 2954 * @param {KeyboardEvent} e 2955 * @param {SweetAlertOptions} innerParams 2956 * @param {function} dismissWith 2957 */ 2958 2959 2960 const handleEsc = (e, innerParams, dismissWith) => { 2961 if (callIfFunction(innerParams.allowEscapeKey)) { 2962 e.preventDefault();
vendor: 30,781 bytes, lines 2963-3970
2963 dismissWith(DismissReason.esc); 2964 } 2965 }; 2966 2967 /* 2968 * Instance method to close sweetAlert 2969 */ 2970 2971 function removePopupAndResetState(instance, container, returnFocus, didClose) { 2972 if (isToast()) { 2973 triggerDidCloseAndDispose(instance, didClose); 2974 } else { 2975 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose)); 2976 removeKeydownHandler(globalState); 2977 } 2978 2979 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088 2980 // for some reason removing the container in Safari will scroll the document to bottom 2981 2982 if (isSafari) { 2983 container.setAttribute('style', 'display:none !important'); 2984 container.removeAttribute('class'); 2985 container.innerHTML = ''; 2986 } else { 2987 container.remove(); 2988 } 2989 2990 if (isModal()) { 2991 undoScrollbar(); 2992 undoIOSfix(); 2993 unsetAriaHidden(); 2994 } 2995 2996 removeBodyClasses(); 2997 } 2998 2999 function removeBodyClasses() { 3000 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]); 3001 } 3002 3003 function close(resolveValue) { 3004 resolveValue = prepareResolveValue(resolveValue); 3005 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this); 3006 const didClose = triggerClosePopup(this); 3007 3008 if (this.isAwaitingPromise()) { 3009 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335 3010 if (!resolveValue.isDismissed) { 3011 handleAwaitingPromise(this); 3012 swalPromiseResolve(resolveValue); 3013 } 3014 } else if (didClose) { 3015 // Resolve Swal promise 3016 swalPromiseResolve(resolveValue); 3017 } 3018 } 3019 function isAwaitingPromise() { 3020 return !!privateProps.awaitingPromise.get(this); 3021 } 3022 3023 const triggerClosePopup = instance => { 3024 const popup = getPopup(); 3025 3026 if (!popup) { 3027 return false; 3028 } 3029 3030 const innerParams = privateProps.innerParams.get(instance); 3031 3032 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) { 3033 return false; 3034 } 3035 3036 removeClass(popup, innerParams.showClass.popup); 3037 addClass(popup, innerParams.hideClass.popup); 3038 const backdrop = getContainer(); 3039 removeClass(backdrop, innerParams.showClass.backdrop); 3040 addClass(backdrop, innerParams.hideClass.backdrop); 3041 handlePopupAnimation(instance, popup, innerParams); 3042 return true; 3043 }; 3044 3045 function rejectPromise(error) { 3046 const rejectPromise = privateMethods.swalPromiseReject.get(this); 3047 handleAwaitingPromise(this); 3048 3049 if (rejectPromise) { 3050 // Reject Swal promise 3051 rejectPromise(error); 3052 } 3053 } 3054 const handleAwaitingPromise = instance => { 3055 if (instance.isAwaitingPromise()) { 3056 privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335 3057 3058 if (!privateProps.innerParams.get(instance)) { 3059 instance._destroy(); 3060 } 3061 } 3062 }; 3063 3064 const prepareResolveValue = resolveValue => { 3065 // When user calls Swal.close() 3066 if (typeof resolveValue === 'undefined') { 3067 return { 3068 isConfirmed: false, 3069 isDenied: false, 3070 isDismissed: true 3071 }; 3072 } 3073 3074 return Object.assign({ 3075 isConfirmed: false, 3076 isDenied: false, 3077 isDismissed: false 3078 }, resolveValue); 3079 }; 3080 3081 const handlePopupAnimation = (instance, popup, innerParams) => { 3082 const container = getContainer(); // If animation is supported, animate 3083 3084 const animationIsSupported = animationEndEvent && hasCssAnimation(popup); 3085 3086 if (typeof innerParams.willClose === 'function') { 3087 innerParams.willClose(popup); 3088 } 3089 3090 if (animationIsSupported) { 3091 animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose); 3092 } else { 3093 // Otherwise, remove immediately 3094 removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose); 3095 } 3096 }; 3097 3098 const animatePopup = (instance, popup, container, returnFocus, didClose) => { 3099 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose); 3100 popup.addEventListener(animationEndEvent, function (e) { 3101 if (e.target === popup) { 3102 globalState.swalCloseEventFinishedCallback(); 3103 delete globalState.swalCloseEventFinishedCallback; 3104 } 3105 }); 3106 }; 3107 3108 const triggerDidCloseAndDispose = (instance, didClose) => { 3109 setTimeout(() => { 3110 if (typeof didClose === 'function') { 3111 didClose.bind(instance.params)(); 3112 } 3113 3114 instance._destroy(); 3115 }); 3116 }; 3117 3118 function setButtonsDisabled(instance, buttons, disabled) { 3119 const domCache = privateProps.domCache.get(instance); 3120 buttons.forEach(button => { 3121 domCache[button].disabled = disabled; 3122 }); 3123 } 3124 3125 function setInputDisabled(input, disabled) { 3126 if (!input) { 3127 return false; 3128 } 3129 3130 if (input.type === 'radio') { 3131 const radiosContainer = input.parentNode.parentNode; 3132 const radios = radiosContainer.querySelectorAll('input'); 3133 3134 for (let i = 0; i < radios.length; i++) { 3135 radios[i].disabled = disabled; 3136 } 3137 } else { 3138 input.disabled = disabled; 3139 } 3140 } 3141 3142 function enableButtons() { 3143 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false); 3144 } 3145 function disableButtons() { 3146 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true); 3147 } 3148 function enableInput() { 3149 return setInputDisabled(this.getInput(), false); 3150 } 3151 function disableInput() { 3152 return setInputDisabled(this.getInput(), true); 3153 } 3154 3155 function showValidationMessage(error) { 3156 const domCache = privateProps.domCache.get(this); 3157 const params = privateProps.innerParams.get(this); 3158 setInnerHtml(domCache.validationMessage, error); 3159 domCache.validationMessage.className = swalClasses['validation-message']; 3160 3161 if (params.customClass && params.customClass.validationMessage) { 3162 addClass(domCache.validationMessage, params.customClass.validationMessage); 3163 } 3164 3165 show(domCache.validationMessage); 3166 const input = this.getInput(); 3167 3168 if (input) { 3169 input.setAttribute('aria-invalid', true); 3170 input.setAttribute('aria-describedby', swalClasses['validation-message']); 3171 focusInput(input); 3172 addClass(input, swalClasses.inputerror); 3173 } 3174 } // Hide block with validation message 3175 3176 function resetValidationMessage$1() { 3177 const domCache = privateProps.domCache.get(this); 3178 3179 if (domCache.validationMessage) { 3180 hide(domCache.validationMessage); 3181 } 3182 3183 const input = this.getInput(); 3184 3185 if (input) { 3186 input.removeAttribute('aria-invalid'); 3187 input.removeAttribute('aria-describedby'); 3188 removeClass(input, swalClasses.inputerror); 3189 } 3190 } 3191 3192 function getProgressSteps$1() { 3193 const domCache = privateProps.domCache.get(this); 3194 return domCache.progressSteps; 3195 } 3196 3197 /** 3198 * Updates popup parameters. 3199 */ 3200 3201 function update(params) { 3202 const popup = getPopup(); 3203 const innerParams = privateProps.innerParams.get(this); 3204 3205 if (!popup || hasClass(popup, innerParams.hideClass.popup)) { 3206 return warn("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup."); 3207 } 3208 3209 const validUpdatableParams = filterValidParams(params); 3210 const updatedParams = Object.assign({}, innerParams, validUpdatableParams); 3211 render(this, updatedParams); 3212 privateProps.innerParams.set(this, updatedParams); 3213 Object.defineProperties(this, { 3214 params: { 3215 value: Object.assign({}, this.params, params), 3216 writable: false, 3217 enumerable: true 3218 } 3219 }); 3220 } 3221 3222 const filterValidParams = params => { 3223 const validUpdatableParams = {}; 3224 Object.keys(params).forEach(param => { 3225 if (isUpdatableParameter(param)) { 3226 validUpdatableParams[param] = params[param]; 3227 } else { 3228 warn("Invalid parameter to update: ".concat(param)); 3229 } 3230 }); 3231 return validUpdatableParams; 3232 }; 3233 3234 function _destroy() { 3235 const domCache = privateProps.domCache.get(this); 3236 const innerParams = privateProps.innerParams.get(this); 3237 3238 if (!innerParams) { 3239 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335 3240 3241 return; // This instance has already been destroyed 3242 } // Check if there is another Swal closing 3243 3244 3245 if (domCache.popup && globalState.swalCloseEventFinishedCallback) { 3246 globalState.swalCloseEventFinishedCallback(); 3247 delete globalState.swalCloseEventFinishedCallback; 3248 } 3249 3250 if (typeof innerParams.didDestroy === 'function') { 3251 innerParams.didDestroy(); 3252 } 3253 3254 disposeSwal(this); 3255 } 3256 /** 3257 * @param {SweetAlert2} instance 3258 */ 3259 3260 const disposeSwal = instance => { 3261 disposeWeakMaps(instance); // Unset this.params so GC will dispose it (#1569) 3262 // @ts-ignore 3263 3264 delete instance.params; // Unset globalState props so GC will dispose globalState (#1569) 3265 3266 delete globalState.keydownHandler; 3267 delete globalState.keydownTarget; // Unset currentInstance 3268 3269 delete globalState.currentInstance; 3270 }; 3271 /** 3272 * @param {SweetAlert2} instance 3273 */ 3274 3275 3276 const disposeWeakMaps = instance => { 3277 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335 3278 // @ts-ignore 3279 if (instance.isAwaitingPromise()) { 3280 unsetWeakMaps(privateProps, instance); 3281 privateProps.awaitingPromise.set(instance, true); 3282 } else { 3283 unsetWeakMaps(privateMethods, instance); 3284 unsetWeakMaps(privateProps, instance); 3285 } 3286 }; 3287 /** 3288 * @param {object} obj 3289 * @param {SweetAlert2} instance 3290 */ 3291 3292 3293 const unsetWeakMaps = (obj, instance) => { 3294 for (const i in obj) { 3295 obj[i].delete(instance); 3296 } 3297 }; 3298 3299 3300 3301 var instanceMethods = /*#__PURE__*/Object.freeze({ 3302 hideLoading: hideLoading, 3303 disableLoading: hideLoading, 3304 getInput: getInput$1, 3305 close: close, 3306 isAwaitingPromise: isAwaitingPromise, 3307 rejectPromise: rejectPromise, 3308 handleAwaitingPromise: handleAwaitingPromise, 3309 closePopup: close, 3310 closeModal: close, 3311 closeToast: close, 3312 enableButtons: enableButtons, 3313 disableButtons: disableButtons, 3314 enableInput: enableInput, 3315 disableInput: disableInput, 3316 showValidationMessage: showValidationMessage, 3317 resetValidationMessage: resetValidationMessage$1, 3318 getProgressSteps: getProgressSteps$1, 3319 update: update, 3320 _destroy: _destroy 3321 }); 3322 3323 const handleConfirmButtonClick = instance => { 3324 const innerParams = privateProps.innerParams.get(instance); 3325 instance.disableButtons(); 3326 3327 if (innerParams.input) { 3328 handleConfirmOrDenyWithInput(instance, 'confirm'); 3329 } else { 3330 confirm(instance, true); 3331 } 3332 }; 3333 const handleDenyButtonClick = instance => { 3334 const innerParams = privateProps.innerParams.get(instance); 3335 instance.disableButtons(); 3336 3337 if (innerParams.returnInputValueOnDeny) { 3338 handleConfirmOrDenyWithInput(instance, 'deny'); 3339 } else { 3340 deny(instance, false); 3341 } 3342 }; 3343 const handleCancelButtonClick = (instance, dismissWith) => { 3344 instance.disableButtons(); 3345 dismissWith(DismissReason.cancel); 3346 }; 3347 3348 const handleConfirmOrDenyWithInput = (instance, type 3349 /* 'confirm' | 'deny' */ 3350 ) => { 3351 const innerParams = privateProps.innerParams.get(instance); 3352 3353 if (!innerParams.input) { 3354 return error("The \"input\" parameter is needed to be set when using returnInputValueOn".concat(capitalizeFirstLetter(type))); 3355 } 3356 3357 const inputValue = getInputValue(instance, innerParams); 3358 3359 if (innerParams.inputValidator) { 3360 handleInputValidator(instance, inputValue, type); 3361 } else if (!instance.getInput().checkValidity()) { 3362 instance.enableButtons(); 3363 instance.showValidationMessage(innerParams.validationMessage); 3364 } else if (type === 'deny') { 3365 deny(instance, inputValue); 3366 } else { 3367 confirm(instance, inputValue); 3368 } 3369 }; 3370 3371 const handleInputValidator = (instance, inputValue, type 3372 /* 'confirm' | 'deny' */ 3373 ) => { 3374 const innerParams = privateProps.innerParams.get(instance); 3375 instance.disableInput(); 3376 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage))); 3377 validationPromise.then(validationMessage => { 3378 instance.enableButtons(); 3379 instance.enableInput(); 3380 3381 if (validationMessage) { 3382 instance.showValidationMessage(validationMessage); 3383 } else if (type === 'deny') { 3384 deny(instance, inputValue); 3385 } else { 3386 confirm(instance, inputValue); 3387 } 3388 }); 3389 }; 3390 3391 const deny = (instance, value) => { 3392 const innerParams = privateProps.innerParams.get(instance || undefined); 3393 3394 if (innerParams.showLoaderOnDeny) { 3395 showLoading(getDenyButton()); 3396 } 3397 3398 if (innerParams.preDeny) { 3399 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 3400 3401 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage))); 3402 preDenyPromise.then(preDenyValue => { 3403 if (preDenyValue === false) { 3404 instance.hideLoading(); 3405 handleAwaitingPromise(instance); 3406 } else { 3407 instance.closePopup({ 3408 isDenied: true, 3409 value: typeof preDenyValue === 'undefined' ? value : preDenyValue 3410 }); 3411 } 3412 }).catch(error$$1 => rejectWith(instance || undefined, error$$1)); 3413 } else { 3414 instance.closePopup({ 3415 isDenied: true, 3416 value 3417 }); 3418 } 3419 }; 3420 3421 const succeedWith = (instance, value) => { 3422 instance.closePopup({ 3423 isConfirmed: true, 3424 value 3425 }); 3426 }; 3427 3428 const rejectWith = (instance, error$$1) => { 3429 instance.rejectPromise(error$$1); 3430 }; 3431 3432 const confirm = (instance, value) => { 3433 const innerParams = privateProps.innerParams.get(instance || undefined); 3434 3435 if (innerParams.showLoaderOnConfirm) { 3436 showLoading(); 3437 } 3438 3439 if (innerParams.preConfirm) { 3440 instance.resetValidationMessage(); 3441 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 3442 3443 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage))); 3444 preConfirmPromise.then(preConfirmValue => { 3445 if (isVisible(getValidationMessage()) || preConfirmValue === false) { 3446 instance.hideLoading(); 3447 handleAwaitingPromise(instance); 3448 } else { 3449 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue); 3450 } 3451 }).catch(error$$1 => rejectWith(instance || undefined, error$$1)); 3452 } else { 3453 succeedWith(instance, value); 3454 } 3455 }; 3456 3457 const handlePopupClick = (instance, domCache, dismissWith) => { 3458 const innerParams = privateProps.innerParams.get(instance); 3459 3460 if (innerParams.toast) { 3461 handleToastClick(instance, domCache, dismissWith); 3462 } else { 3463 // Ignore click events that had mousedown on the popup but mouseup on the container 3464 // This can happen when the user drags a slider 3465 handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup 3466 3467 handleContainerMousedown(domCache); 3468 handleModalClick(instance, domCache, dismissWith); 3469 } 3470 }; 3471 3472 const handleToastClick = (instance, domCache, dismissWith) => { 3473 // Closing toast by internal click 3474 domCache.popup.onclick = () => { 3475 const innerParams = privateProps.innerParams.get(instance); 3476 3477 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) { 3478 return; 3479 } 3480 3481 dismissWith(DismissReason.close); 3482 }; 3483 }; 3484 /** 3485 * @param {*} innerParams 3486 * @returns {boolean} 3487 */ 3488 3489 3490 const isAnyButtonShown = innerParams => { 3491 return innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton; 3492 }; 3493 3494 let ignoreOutsideClick = false; 3495 3496 const handleModalMousedown = domCache => { 3497 domCache.popup.onmousedown = () => { 3498 domCache.container.onmouseup = function (e) { 3499 domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't 3500 // have any other direct children aside of the popup 3501 3502 if (e.target === domCache.container) { 3503 ignoreOutsideClick = true; 3504 } 3505 }; 3506 }; 3507 }; 3508 3509 const handleContainerMousedown = domCache => { 3510 domCache.container.onmousedown = () => { 3511 domCache.popup.onmouseup = function (e) { 3512 domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup 3513 3514 if (e.target === domCache.popup || domCache.popup.contains(e.target)) { 3515 ignoreOutsideClick = true; 3516 } 3517 }; 3518 }; 3519 }; 3520 3521 const handleModalClick = (instance, domCache, dismissWith) => { 3522 domCache.container.onclick = e => { 3523 const innerParams = privateProps.innerParams.get(instance); 3524 3525 if (ignoreOutsideClick) { 3526 ignoreOutsideClick = false; 3527 return; 3528 } 3529 3530 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) { 3531 dismissWith(DismissReason.backdrop); 3532 } 3533 }; 3534 }; 3535 3536 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery; 3537 3538 const isElement = elem => elem instanceof Element || isJqueryElement(elem); 3539 3540 const argsToParams = args => { 3541 const params = {}; 3542 3543 if (typeof args[0] === 'object' && !isElement(args[0])) { 3544 Object.assign(params, args[0]); 3545 } else { 3546 ['title', 'html', 'icon'].forEach((name, index) => { 3547 const arg = args[index]; 3548 3549 if (typeof arg === 'string' || isElement(arg)) { 3550 params[name] = arg; 3551 } else if (arg !== undefined) { 3552 error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg)); 3553 } 3554 }); 3555 } 3556 3557 return params; 3558 }; 3559 3560 function fire() { 3561 const Swal = this; // eslint-disable-line @typescript-eslint/no-this-alias 3562 3563 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3564 args[_key] = arguments[_key]; 3565 } 3566 3567 return new Swal(...args); 3568 } 3569 3570 /** 3571 * Returns an extended version of `Swal` containing `params` as defaults. 3572 * Useful for reusing Swal configuration. 3573 * 3574 * For example: 3575 * 3576 * Before: 3577 * const textPromptOptions = { input: 'text', showCancelButton: true } 3578 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' }) 3579 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' }) 3580 * 3581 * After: 3582 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true }) 3583 * const {value: firstName} = await TextPrompt('What is your first name?') 3584 * const {value: lastName} = await TextPrompt('What is your last name?') 3585 * 3586 * @param mixinParams 3587 */ 3588 function mixin(mixinParams) { 3589 class MixinSwal extends this { 3590 _main(params, priorityMixinParams) { 3591 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams)); 3592 } 3593 3594 } 3595 3596 return MixinSwal; 3597 } 3598 3599 /** 3600 * If `timer` parameter is set, returns number of milliseconds of timer remained. 3601 * Otherwise, returns undefined. 3602 */ 3603 3604 const getTimerLeft = () => { 3605 return globalState.timeout && globalState.timeout.getTimerLeft(); 3606 }; 3607 /** 3608 * Stop timer. Returns number of milliseconds of timer remained. 3609 * If `timer` parameter isn't set, returns undefined. 3610 */ 3611 3612 const stopTimer = () => { 3613 if (globalState.timeout) { 3614 stopTimerProgressBar(); 3615 return globalState.timeout.stop(); 3616 } 3617 }; 3618 /** 3619 * Resume timer. Returns number of milliseconds of timer remained. 3620 * If `timer` parameter isn't set, returns undefined. 3621 */ 3622 3623 const resumeTimer = () => { 3624 if (globalState.timeout) { 3625 const remaining = globalState.timeout.start(); 3626 animateTimerProgressBar(remaining); 3627 return remaining; 3628 } 3629 }; 3630 /** 3631 * Resume timer. Returns number of milliseconds of timer remained. 3632 * If `timer` parameter isn't set, returns undefined. 3633 */ 3634 3635 const toggleTimer = () => { 3636 const timer = globalState.timeout; 3637 return timer && (timer.running ? stopTimer() : resumeTimer()); 3638 }; 3639 /** 3640 * Increase timer. Returns number of milliseconds of an updated timer. 3641 * If `timer` parameter isn't set, returns undefined. 3642 */ 3643 3644 const increaseTimer = n => { 3645 if (globalState.timeout) { 3646 const remaining = globalState.timeout.increase(n); 3647 animateTimerProgressBar(remaining, true); 3648 return remaining; 3649 } 3650 }; 3651 /** 3652 * Check if timer is running. Returns true if timer is running 3653 * or false if timer is paused or stopped. 3654 * If `timer` parameter isn't set, returns undefined 3655 */ 3656 3657 const isTimerRunning = () => { 3658 return globalState.timeout && globalState.timeout.isRunning(); 3659 }; 3660 3661 let bodyClickListenerAdded = false; 3662 const clickHandlers = {}; 3663 function bindClickHandler() { 3664 let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template'; 3665 clickHandlers[attr] = this; 3666 3667 if (!bodyClickListenerAdded) { 3668 document.body.addEventListener('click', bodyClickListener); 3669 bodyClickListenerAdded = true; 3670 } 3671 } 3672 3673 const bodyClickListener = event => { 3674 for (let el = event.target; el && el !== document; el = el.parentNode) { 3675 for (const attr in clickHandlers) { 3676 const template = el.getAttribute(attr); 3677 3678 if (template) { 3679 clickHandlers[attr].fire({ 3680 template 3681 }); 3682 return; 3683 } 3684 } 3685 } 3686 }; 3687 3688 3689 3690 var staticMethods = /*#__PURE__*/Object.freeze({ 3691 isValidParameter: isValidParameter, 3692 isUpdatableParameter: isUpdatableParameter, 3693 isDeprecatedParameter: isDeprecatedParameter, 3694 argsToParams: argsToParams, 3695 isVisible: isVisible$1, 3696 clickConfirm: clickConfirm, 3697 clickDeny: clickDeny, 3698 clickCancel: clickCancel, 3699 getContainer: getContainer, 3700 getPopup: getPopup, 3701 getTitle: getTitle, 3702 getHtmlContainer: getHtmlContainer, 3703 getImage: getImage, 3704 getIcon: getIcon, 3705 getInputLabel: getInputLabel, 3706 getCloseButton: getCloseButton, 3707 getActions: getActions, 3708 getConfirmButton: getConfirmButton, 3709 getDenyButton: getDenyButton, 3710 getCancelButton: getCancelButton, 3711 getLoader: getLoader, 3712 getFooter: getFooter, 3713 getTimerProgressBar: getTimerProgressBar, 3714 getFocusableElements: getFocusableElements, 3715 getValidationMessage: getValidationMessage, 3716 isLoading: isLoading, 3717 fire: fire, 3718 mixin: mixin, 3719 showLoading: showLoading, 3720 enableLoading: showLoading, 3721 getTimerLeft: getTimerLeft, 3722 stopTimer: stopTimer, 3723 resumeTimer: resumeTimer, 3724 toggleTimer: toggleTimer, 3725 increaseTimer: increaseTimer, 3726 isTimerRunning: isTimerRunning, 3727 bindClickHandler: bindClickHandler 3728 }); 3729 3730 let currentInstance; 3731 3732 class SweetAlert { 3733 constructor() { 3734 // Prevent run in Node env 3735 if (typeof window === 'undefined') { 3736 return; 3737 } 3738 3739 currentInstance = this; // @ts-ignore 3740 3741 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3742 args[_key] = arguments[_key]; 3743 } 3744 3745 const outerParams = Object.freeze(this.constructor.argsToParams(args)); 3746 Object.defineProperties(this, { 3747 params: { 3748 value: outerParams, 3749 writable: false, 3750 enumerable: true, 3751 configurable: true 3752 } 3753 }); // @ts-ignore 3754 3755 const promise = currentInstance._main(currentInstance.params); 3756 3757 privateProps.promise.set(this, promise); 3758 } 3759 3760 _main(userParams) { 3761 let mixinParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3762 showWarningsForParams(Object.assign({}, mixinParams, userParams)); 3763 3764 if (globalState.currentInstance) { 3765 // @ts-ignore 3766 globalState.currentInstance._destroy(); 3767 3768 if (isModal()) { 3769 unsetAriaHidden(); 3770 } 3771 } 3772 3773 globalState.currentInstance = currentInstance; 3774 const innerParams = prepareParams(userParams, mixinParams); 3775 setParameters(innerParams); 3776 Object.freeze(innerParams); // clear the previous timer 3777 3778 if (globalState.timeout) { 3779 globalState.timeout.stop(); 3780 delete globalState.timeout; 3781 } // clear the restore focus timeout 3782 3783 3784 clearTimeout(globalState.restoreFocusTimeout); 3785 const domCache = populateDomCache(currentInstance); 3786 render(currentInstance, innerParams); 3787 privateProps.innerParams.set(currentInstance, innerParams); 3788 return swalPromise(currentInstance, domCache, innerParams); 3789 } // `catch` cannot be the name of a module export, so we define our thenable methods here instead 3790 3791 3792 then(onFulfilled) { 3793 const promise = privateProps.promise.get(this); 3794 return promise.then(onFulfilled); 3795 } 3796 3797 finally(onFinally) { 3798 const promise = privateProps.promise.get(this); 3799 return promise.finally(onFinally); 3800 } 3801 3802 } 3803 3804 const swalPromise = (instance, domCache, innerParams) => { 3805 return new Promise((resolve, reject) => { 3806 // functions to handle all closings/dismissals 3807 const dismissWith = dismiss => { 3808 instance.closePopup({ 3809 isDismissed: true, 3810 dismiss 3811 }); 3812 }; 3813 3814 privateMethods.swalPromiseResolve.set(instance, resolve); 3815 privateMethods.swalPromiseReject.set(instance, reject); 3816 3817 domCache.confirmButton.onclick = () => handleConfirmButtonClick(instance); 3818 3819 domCache.denyButton.onclick = () => handleDenyButtonClick(instance); 3820 3821 domCache.cancelButton.onclick = () => handleCancelButtonClick(instance, dismissWith); 3822 3823 domCache.closeButton.onclick = () => dismissWith(DismissReason.close); 3824 3825 handlePopupClick(instance, domCache, dismissWith); 3826 addKeydownHandler(instance, globalState, innerParams, dismissWith); 3827 handleInputOptionsAndValue(instance, innerParams); 3828 openPopup(innerParams); 3829 setupTimer(globalState, innerParams, dismissWith); 3830 initFocus(domCache, innerParams); // Scroll container to top on open (#1247, #1946) 3831 3832 setTimeout(() => { 3833 domCache.container.scrollTop = 0; 3834 }); 3835 }); 3836 }; 3837 3838 const prepareParams = (userParams, mixinParams) => { 3839 const templateParams = getTemplateParams(userParams); 3840 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131 3841 3842 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass); 3843 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass); 3844 return params; 3845 }; 3846 /** 3847 * @param {SweetAlert2} instance 3848 * @returns {DomCache} 3849 */ 3850 3851 3852 const populateDomCache = instance => { 3853 const domCache = { 3854 popup: getPopup(), 3855 container: getContainer(), 3856 actions: getActions(), 3857 confirmButton: getConfirmButton(), 3858 denyButton: getDenyButton(), 3859 cancelButton: getCancelButton(), 3860 loader: getLoader(), 3861 closeButton: getCloseButton(), 3862 validationMessage: getValidationMessage(), 3863 progressSteps: getProgressSteps() 3864 }; 3865 privateProps.domCache.set(instance, domCache); 3866 return domCache; 3867 }; 3868 /** 3869 * @param {GlobalState} globalState 3870 * @param {SweetAlertOptions} innerParams 3871 * @param {function} dismissWith 3872 */ 3873 3874 3875 const setupTimer = (globalState$$1, innerParams, dismissWith) => { 3876 const timerProgressBar = getTimerProgressBar(); 3877 hide(timerProgressBar); 3878 3879 if (innerParams.timer) { 3880 globalState$$1.timeout = new Timer(() => { 3881 dismissWith('timer'); 3882 delete globalState$$1.timeout; 3883 }, innerParams.timer); 3884 3885 if (innerParams.timerProgressBar) { 3886 show(timerProgressBar); 3887 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar'); 3888 setTimeout(() => { 3889 if (globalState$$1.timeout && globalState$$1.timeout.running) { 3890 // timer can be already stopped or unset at this point 3891 animateTimerProgressBar(innerParams.timer); 3892 } 3893 }); 3894 } 3895 } 3896 }; 3897 /** 3898 * @param {DomCache} domCache 3899 * @param {SweetAlertOptions} innerParams 3900 */ 3901 3902 3903 const initFocus = (domCache, innerParams) => { 3904 if (innerParams.toast) { 3905 return; 3906 } 3907 3908 if (!callIfFunction(innerParams.allowEnterKey)) { 3909 return blurActiveElement(); 3910 } 3911 3912 if (!focusButton(domCache, innerParams)) { 3913 setFocus(innerParams, -1, 1); 3914 } 3915 }; 3916 /** 3917 * @param {DomCache} domCache 3918 * @param {SweetAlertOptions} innerParams 3919 * @returns {boolean} 3920 */ 3921 3922 3923 const focusButton = (domCache, innerParams) => { 3924 if (innerParams.focusDeny && isVisible(domCache.denyButton)) { 3925 domCache.denyButton.focus(); 3926 return true; 3927 } 3928 3929 if (innerParams.focusCancel && isVisible(domCache.cancelButton)) { 3930 domCache.cancelButton.focus(); 3931 return true; 3932 } 3933 3934 if (innerParams.focusConfirm && isVisible(domCache.confirmButton)) { 3935 domCache.confirmButton.focus(); 3936 return true; 3937 } 3938 3939 return false; 3940 }; 3941 3942 const blurActiveElement = () => { 3943 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') { 3944 document.activeElement.blur(); 3945 } 3946 }; // Assign instance methods from src/instanceMethods/*.js to prototype 3947 3948 3949 Object.assign(SweetAlert.prototype, instanceMethods); // Assign static methods from src/staticMethods/*.js to constructor 3950 3951 Object.assign(SweetAlert, staticMethods); // Proxy to instance methods to constructor, for now, for backwards compatibility 3952 3953 Object.keys(instanceMethods).forEach(key => { 3954 SweetAlert[key] = function () { 3955 if (currentInstance) { 3956 return currentInstance[key](...arguments); 3957 } 3958 }; 3959 }); 3960 SweetAlert.DismissReason = DismissReason; 3961 SweetAlert.version = '11.4.19'; 3962 3963 const Swal = SweetAlert; // @ts-ignore 3964 3965 Swal.default = Swal; 3966 3967 return Swal; 3968 3969})); 3970if (typeof this !== 'undefined' && this.Sweetalert2){ this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.