vendor: 115,556 bytes, lines 1-3206
1/*! 2* sweetalert2 v11.2.1 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 DismissReason = Object.freeze({ 12 cancel: 'cancel', 13 backdrop: 'backdrop', 14 close: 'close', 15 esc: 'esc', 16 timer: 'timer' 17 }); 18 19 const consolePrefix = 'SweetAlert2:'; 20 /** 21 * Filter the unique values into a new array 22 * @param arr 23 */ 24 25 const uniqueArray = arr => { 26 const result = []; 27 28 for (let i = 0; i < arr.length; i++) { 29 if (result.indexOf(arr[i]) === -1) { 30 result.push(arr[i]); 31 } 32 } 33 34 return result; 35 }; 36 /** 37 * Capitalize the first letter of a string 38 * @param str 39 */ 40 41 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1); 42 /** 43 * Convert NodeList to Array 44 * @param nodeList 45 */ 46 47 const toArray = nodeList => Array.prototype.slice.call(nodeList); 48 /** 49 * Standardise console warnings 50 * @param message 51 */ 52 53 const warn = message => { 54 console.warn("".concat(consolePrefix, " ").concat(typeof message === 'object' ? message.join(' ') : message)); 55 }; 56 /** 57 * Standardise console errors 58 * @param message 59 */ 60 61 const error = message => { 62 console.error("".concat(consolePrefix, " ").concat(message)); 63 }; 64 /** 65 * Private global state for `warnOnce` 66 * @type {Array} 67 * @private 68 */ 69 70 const previousWarnOnceMessages = []; 71 /** 72 * Show a console warning, but only if it hasn't already been shown 73 * @param message 74 */ 75 76 const warnOnce = message => { 77 if (!previousWarnOnceMessages.includes(message)) { 78 previousWarnOnceMessages.push(message); 79 warn(message); 80 } 81 }; 82 /** 83 * Show a one-time console warning about deprecated params/methods 84 */ 85 86 const warnAboutDeprecation = (deprecatedParam, useInstead) => { 87 warnOnce("\"".concat(deprecatedParam, "\" is deprecated and will be removed in the next major release. Please use \"").concat(useInstead, "\" instead.")); 88 }; 89 /** 90 * If `arg` is a function, call it (with no arguments or context) and return the result. 91 * Otherwise, just pass the value through 92 * @param arg 93 */ 94 95 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg; 96 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function'; 97 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg); 98 const isPromise = arg => arg && Promise.resolve(arg) === arg; 99 100 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery; 101 102 const isElement = elem => elem instanceof Element || isJqueryElement(elem); 103 104 const argsToParams = args => { 105 const params = {}; 106 107 if (typeof args[0] === 'object' && !isElement(args[0])) { 108 Object.assign(params, args[0]); 109 } else { 110 ['title', 'html', 'icon'].forEach((name, index) => { 111 const arg = args[index]; 112 113 if (typeof arg === 'string' || isElement(arg)) { 114 params[name] = arg; 115 } else if (arg !== undefined) { 116 error("Unexpected type of ".concat(name, "! Expected \"string\" or \"Element\", got ").concat(typeof arg)); 117 } 118 }); 119 } 120 121 return params; 122 }; 123 124 const swalPrefix = 'swal2-'; 125 const prefix = items => { 126 const result = {}; 127 128 for (const i in items) { 129 result[items[i]] = swalPrefix + items[i]; 130 } 131 132 return result; 133 }; 134 const swalClasses = prefix(['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'default-outline', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error']); 135 const iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']); 136 137 const getContainer = () => document.body.querySelector(".".concat(swalClasses.container)); 138 const elementBySelector = selectorString => { 139 const container = getContainer(); 140 return container ? container.querySelector(selectorString) : null; 141 }; 142 143 const elementByClass = className => { 144 return elementBySelector(".".concat(className)); 145 }; 146 147 const getPopup = () => elementByClass(swalClasses.popup); 148 const getIcon = () => elementByClass(swalClasses.icon); 149 const getTitle = () => elementByClass(swalClasses.title); 150 const getHtmlContainer = () => elementByClass(swalClasses['html-container']); 151 const getImage = () => elementByClass(swalClasses.image); 152 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']); 153 const getValidationMessage = () => elementByClass(swalClasses['validation-message']); 154 const getConfirmButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.confirm)); 155 const getDenyButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.deny)); 156 const getInputLabel = () => elementByClass(swalClasses['input-label']); 157 const getLoader = () => elementBySelector(".".concat(swalClasses.loader)); 158 const getCancelButton = () => elementBySelector(".".concat(swalClasses.actions, " .").concat(swalClasses.cancel)); 159 const getActions = () => elementByClass(swalClasses.actions); 160 const getFooter = () => elementByClass(swalClasses.footer); 161 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']); 162 const getCloseButton = () => elementByClass(swalClasses.close); // https://github.com/jkup/focusable/blob/master/index.js 163 164 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"; 165 const getFocusableElements = () => { 166 const focusableElementsWithTabindex = toArray(getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')) // sort according to tabindex 167 .sort((a, b) => { 168 a = parseInt(a.getAttribute('tabindex')); 169 b = parseInt(b.getAttribute('tabindex')); 170 171 if (a > b) { 172 return 1; 173 } else if (a < b) { 174 return -1; 175 } 176 177 return 0; 178 }); 179 const otherFocusableElements = toArray(getPopup().querySelectorAll(focusable)).filter(el => el.getAttribute('tabindex') !== '-1'); 180 return uniqueArray(focusableElementsWithTabindex.concat(otherFocusableElements)).filter(el => isVisible(el)); 181 }; 182 const isModal = () => { 183 return !isToast() && !document.body.classList.contains(swalClasses['no-backdrop']); 184 }; 185 const isToast = () => { 186 return document.body.classList.contains(swalClasses['toast-shown']); 187 }; 188 const isLoading = () => { 189 return getPopup().hasAttribute('data-loading'); 190 }; 191 192 const states = { 193 previousBodyPadding: null 194 }; 195 const setInnerHtml = (elem, html) => { 196 // #1926 197 elem.textContent = ''; 198 199 if (html) { 200 const parser = new DOMParser(); 201 const parsed = parser.parseFromString(html, "text/html"); 202 toArray(parsed.querySelector('head').childNodes).forEach(child => { 203 elem.appendChild(child); 204 }); 205 toArray(parsed.querySelector('body').childNodes).forEach(child => { 206 elem.appendChild(child); 207 }); 208 } 209 }; 210 const hasClass = (elem, className) => { 211 if (!className) { 212 return false; 213 } 214 215 const classList = className.split(/\s+/); 216 217 for (let i = 0; i < classList.length; i++) { 218 if (!elem.classList.contains(classList[i])) { 219 return false; 220 } 221 } 222 223 return true; 224 }; 225 226 const removeCustomClasses = (elem, params) => { 227 toArray(elem.classList).forEach(className => { 228 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass).includes(className)) { 229 elem.classList.remove(className); 230 } 231 }); 232 }; 233 234 const applyCustomClass = (elem, params, className) => { 235 removeCustomClasses(elem, params); 236 237 if (params.customClass && params.customClass[className]) { 238 if (typeof params.customClass[className] !== 'string' && !params.customClass[className].forEach) { 239 return warn("Invalid type of customClass.".concat(className, "! Expected string or iterable object, got \"").concat(typeof params.customClass[className], "\"")); 240 } 241 242 addClass(elem, params.customClass[className]); 243 } 244 }; 245 const getInput = (popup, inputType) => { 246 if (!inputType) { 247 return null; 248 } 249 250 switch (inputType) { 251 case 'select': 252 case 'textarea': 253 case 'file': 254 return getChildByClass(popup, swalClasses[inputType]); 255 256 case 'checkbox': 257 return popup.querySelector(".".concat(swalClasses.checkbox, " input")); 258 259 case 'radio': 260 return popup.querySelector(".".concat(swalClasses.radio, " input:checked")) || popup.querySelector(".".concat(swalClasses.radio, " input:first-child")); 261 262 case 'range': 263 return popup.querySelector(".".concat(swalClasses.range, " input")); 264 265 default: 266 return getChildByClass(popup, swalClasses.input); 267 } 268 }; 269 const focusInput = input => { 270 input.focus(); // place cursor at end of text in text input 271 272 if (input.type !== 'file') { 273 // http://stackoverflow.com/a/2345915 274 const val = input.value; 275 input.value = ''; 276 input.value = val; 277 } 278 }; 279 const toggleClass = (target, classList, condition) => { 280 if (!target || !classList) { 281 return; 282 } 283 284 if (typeof classList === 'string') { 285 classList = classList.split(/\s+/).filter(Boolean); 286 } 287 288 classList.forEach(className => { 289 if (target.forEach) { 290 target.forEach(elem => { 291 condition ? elem.classList.add(className) : elem.classList.remove(className); 292 }); 293 } else { 294 condition ? target.classList.add(className) : target.classList.remove(className); 295 } 296 }); 297 }; 298 const addClass = (target, classList) => { 299 toggleClass(target, classList, true); 300 }; 301 const removeClass = (target, classList) => { 302 toggleClass(target, classList, false); 303 }; 304 const getChildByClass = (elem, className) => { 305 for (let i = 0; i < elem.childNodes.length; i++) { 306 if (hasClass(elem.childNodes[i], className)) { 307 return elem.childNodes[i]; 308 } 309 } 310 }; 311 const applyNumericalStyle = (elem, property, value) => { 312 if (value === "".concat(parseInt(value))) { 313 value = parseInt(value); 314 } 315 316 if (value || parseInt(value) === 0) { 317 elem.style[property] = typeof value === 'number' ? "".concat(value, "px") : value; 318 } else { 319 elem.style.removeProperty(property); 320 } 321 }; 322 const show = function (elem) { 323 let display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'flex'; 324 elem.style.display = display; 325 }; 326 const hide = elem => { 327 elem.style.display = 'none'; 328 }; 329 const setStyle = (parent, selector, property, value) => { 330 const el = parent.querySelector(selector); 331 332 if (el) { 333 el.style[property] = value; 334 } 335 }; 336 const toggle = (elem, condition, display) => { 337 condition ? show(elem, display) : hide(elem); 338 }; // borrowed from jquery $(elem).is(':visible') implementation 339 340 const isVisible = elem => !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length)); 341 const allButtonsAreHidden = () => !isVisible(getConfirmButton()) && !isVisible(getDenyButton()) && !isVisible(getCancelButton()); 342 const isScrollable = elem => !!(elem.scrollHeight > elem.clientHeight); // borrowed from https://stackoverflow.com/a/46352119 343 344 const hasCssAnimation = elem => { 345 const style = window.getComputedStyle(elem); 346 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0'); 347 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0'); 348 return animDuration > 0 || transDuration > 0; 349 }; 350 const animateTimerProgressBar = function (timer) { 351 let reset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 352 const timerProgressBar = getTimerProgressBar(); 353 354 if (isVisible(timerProgressBar)) { 355 if (reset) { 356 timerProgressBar.style.transition = 'none'; 357 timerProgressBar.style.width = '100%'; 358 } 359 360 setTimeout(() => { 361 timerProgressBar.style.transition = "width ".concat(timer / 1000, "s linear"); 362 timerProgressBar.style.width = '0%'; 363 }, 10); 364 } 365 }; 366 const stopTimerProgressBar = () => { 367 const timerProgressBar = getTimerProgressBar(); 368 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width); 369 timerProgressBar.style.removeProperty('transition'); 370 timerProgressBar.style.width = '100%'; 371 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width); 372 const timerProgressBarPercent = parseInt(timerProgressBarWidth / timerProgressBarFullWidth * 100); 373 timerProgressBar.style.removeProperty('transition'); 374 timerProgressBar.style.width = "".concat(timerProgressBarPercent, "%"); 375 }; 376 377 // Detect Node env 378 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined'; 379 380 const sweetHTML = "\n <div aria-labelledby=\"".concat(swalClasses.title, "\" aria-describedby=\"").concat(swalClasses['html-container'], "\" class=\"").concat(swalClasses.popup, "\" tabindex=\"-1\">\n <button type=\"button\" class=\"").concat(swalClasses.close, "\"></button>\n <ul class=\"").concat(swalClasses['progress-steps'], "\"></ul>\n <div class=\"").concat(swalClasses.icon, "\"></div>\n <img class=\"").concat(swalClasses.image, "\" />\n <h2 class=\"").concat(swalClasses.title, "\" id=\"").concat(swalClasses.title, "\"></h2>\n <div class=\"").concat(swalClasses['html-container'], "\" id=\"").concat(swalClasses['html-container'], "\"></div>\n <input class=\"").concat(swalClasses.input, "\" />\n <input type=\"file\" class=\"").concat(swalClasses.file, "\" />\n <div class=\"").concat(swalClasses.range, "\">\n <input type=\"range\" />\n <output></output>\n </div>\n <select class=\"").concat(swalClasses.select, "\"></select>\n <div class=\"").concat(swalClasses.radio, "\"></div>\n <label for=\"").concat(swalClasses.checkbox, "\" class=\"").concat(swalClasses.checkbox, "\">\n <input type=\"checkbox\" />\n <span class=\"").concat(swalClasses.label, "\"></span>\n </label>\n <textarea class=\"").concat(swalClasses.textarea, "\"></textarea>\n <div class=\"").concat(swalClasses['validation-message'], "\" id=\"").concat(swalClasses['validation-message'], "\"></div>\n <div class=\"").concat(swalClasses.actions, "\">\n <div class=\"").concat(swalClasses.loader, "\"></div>\n <button type=\"button\" class=\"").concat(swalClasses.confirm, "\"></button>\n <button type=\"button\" class=\"").concat(swalClasses.deny, "\"></button>\n <button type=\"button\" class=\"").concat(swalClasses.cancel, "\"></button>\n </div>\n <div class=\"").concat(swalClasses.footer, "\"></div>\n <div class=\"").concat(swalClasses['timer-progress-bar-container'], "\">\n <div class=\"").concat(swalClasses['timer-progress-bar'], "\"></div>\n </div>\n </div>\n").replace(/(^|\n)\s*/g, ''); 381 382 const resetOldContainer = () => { 383 const oldContainer = getContainer(); 384 385 if (!oldContainer) { 386 return false; 387 } 388 389 oldContainer.remove(); 390 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['has-column']]); 391 return true; 392 }; 393 394 const resetValidationMessage = () => { 395 if (Swal.isVisible()) { 396 Swal.resetValidationMessage(); 397 } 398 }; 399 400 const addInputChangeListeners = () => { 401 const popup = getPopup(); 402 const input = getChildByClass(popup, swalClasses.input); 403 const file = getChildByClass(popup, swalClasses.file); 404 const range = popup.querySelector(".".concat(swalClasses.range, " input")); 405 const rangeOutput = popup.querySelector(".".concat(swalClasses.range, " output")); 406 const select = getChildByClass(popup, swalClasses.select); 407 const checkbox = popup.querySelector(".".concat(swalClasses.checkbox, " input")); 408 const textarea = getChildByClass(popup, swalClasses.textarea); 409 input.oninput = resetValidationMessage; 410 file.onchange = resetValidationMessage; 411 select.onchange = resetValidationMessage; 412 checkbox.onchange = resetValidationMessage; 413 textarea.oninput = resetValidationMessage; 414 415 range.oninput = () => { 416 resetValidationMessage(); 417 rangeOutput.value = range.value; 418 }; 419 420 range.onchange = () => { 421 resetValidationMessage(); 422 range.nextSibling.value = range.value; 423 }; 424 }; 425 426 const getTarget = target => typeof target === 'string' ? document.querySelector(target) : target; 427 428 const setupAccessibility = params => { 429 const popup = getPopup(); 430 popup.setAttribute('role', params.toast ? 'alert' : 'dialog'); 431 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive'); 432 433 if (!params.toast) { 434 popup.setAttribute('aria-modal', 'true'); 435 } 436 }; 437 438 const setupRTL = targetElement => { 439 if (window.getComputedStyle(targetElement).direction === 'rtl') { 440 addClass(getContainer(), swalClasses.rtl); 441 } 442 }; 443 /* 444 * Add modal + backdrop to DOM 445 */ 446 447 448 const init = params => { 449 // Clean up the old popup container if it exists 450 const oldContainerExisted = resetOldContainer(); 451 /* istanbul ignore if */ 452 453 if (isNodeEnv()) { 454 error('SweetAlert2 requires document to initialize'); 455 return; 456 } 457 458 const container = document.createElement('div'); 459 container.className = swalClasses.container; 460 461 if (oldContainerExisted) { 462 addClass(container, swalClasses['no-transition']); 463 } 464 465 setInnerHtml(container, sweetHTML); 466 const targetElement = getTarget(params.target); 467 targetElement.appendChild(container); 468 setupAccessibility(params); 469 setupRTL(targetElement); 470 addInputChangeListeners(); 471 }; 472 473 const parseHtmlToContainer = (param, target) => { 474 // DOM element 475 if (param instanceof HTMLElement) { 476 target.appendChild(param); // Object 477 } else if (typeof param === 'object') { 478 handleObject(param, target); // Plain string 479 } else if (param) { 480 setInnerHtml(target, param); 481 } 482 }; 483 484 const handleObject = (param, target) => { 485 // JQuery element(s) 486 if (param.jquery) { 487 handleJqueryElem(target, param); // For other objects use their string representation 488 } else { 489 setInnerHtml(target, param.toString()); 490 } 491 }; 492 493 const handleJqueryElem = (target, elem) => { 494 target.textContent = ''; 495 496 if (0 in elem) { 497 for (let i = 0; (i in elem); i++) { 498 target.appendChild(elem[i].cloneNode(true)); 499 } 500 } else { 501 target.appendChild(elem.cloneNode(true)); 502 } 503 }; 504 505 const animationEndEvent = (() => { 506 // Prevent run in Node env 507 508 /* istanbul ignore if */ 509 if (isNodeEnv()) { 510 return false; 511 } 512 513 const testEl = document.createElement('div'); 514 const transEndEventNames = { 515 WebkitAnimation: 'webkitAnimationEnd', 516 OAnimation: 'oAnimationEnd oanimationend', 517 animation: 'animationend' 518 }; 519 520 for (const i in transEndEventNames) { 521 if (Object.prototype.hasOwnProperty.call(transEndEventNames, i) && typeof testEl.style[i] !== 'undefined') { 522 return transEndEventNames[i]; 523 } 524 } 525 526 return false; 527 })(); 528 529 // https://github.com/twbs/bootstrap/blob/master/js/src/modal.js 530 531 const measureScrollbar = () => { 532 const scrollDiv = document.createElement('div'); 533 scrollDiv.className = swalClasses['scrollbar-measure']; 534 document.body.appendChild(scrollDiv); 535 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; 536 document.body.removeChild(scrollDiv); 537 return scrollbarWidth; 538 }; 539 540 const renderActions = (instance, params) => { 541 const actions = getActions(); 542 const loader = getLoader(); // Actions (buttons) wrapper 543 544 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) { 545 hide(actions); 546 } else { 547 show(actions); 548 } // Custom class 549 550 551 applyCustomClass(actions, params, 'actions'); // Render all the buttons 552 553 renderButtons(actions, loader, params); // Loader 554 555 setInnerHtml(loader, params.loaderHtml); 556 applyCustomClass(loader, params, 'loader'); 557 }; 558 559 function renderButtons(actions, loader, params) { 560 const confirmButton = getConfirmButton(); 561 const denyButton = getDenyButton(); 562 const cancelButton = getCancelButton(); // Render buttons 563 564 renderButton(confirmButton, 'confirm', params); 565 renderButton(denyButton, 'deny', params); 566 renderButton(cancelButton, 'cancel', params); 567 handleButtonsStyling(confirmButton, denyButton, cancelButton, params); 568 569 if (params.reverseButtons) { 570 if (params.toast) { 571 actions.insertBefore(cancelButton, confirmButton); 572 actions.insertBefore(denyButton, confirmButton); 573 } else { 574 actions.insertBefore(cancelButton, loader); 575 actions.insertBefore(denyButton, loader); 576 actions.insertBefore(confirmButton, loader); 577 } 578 } 579 } 580 581 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) { 582 if (!params.buttonsStyling) { 583 return removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled); 584 } 585 586 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled); // Buttons background colors 587 588 if (params.confirmButtonColor) { 589 confirmButton.style.backgroundColor = params.confirmButtonColor; 590 addClass(confirmButton, swalClasses['default-outline']); 591 } 592 593 if (params.denyButtonColor) { 594 denyButton.style.backgroundColor = params.denyButtonColor; 595 addClass(denyButton, swalClasses['default-outline']); 596 } 597 598 if (params.cancelButtonColor) { 599 cancelButton.style.backgroundColor = params.cancelButtonColor; 600 addClass(cancelButton, swalClasses['default-outline']); 601 } 602 } 603 604 function renderButton(button, buttonType, params) { 605 toggle(button, params["show".concat(capitalizeFirstLetter(buttonType), "Button")], 'inline-block'); 606 setInnerHtml(button, params["".concat(buttonType, "ButtonText")]); // Set caption text 607 608 button.setAttribute('aria-label', params["".concat(buttonType, "ButtonAriaLabel")]); // ARIA label 609 // Add buttons custom classes 610 611 button.className = swalClasses[buttonType]; 612 applyCustomClass(button, params, "".concat(buttonType, "Button")); 613 addClass(button, params["".concat(buttonType, "ButtonClass")]); 614 } 615 616 function handleBackdropParam(container, backdrop) { 617 if (typeof backdrop === 'string') { 618 container.style.background = backdrop; 619 } else if (!backdrop) { 620 addClass([document.documentElement, document.body], swalClasses['no-backdrop']); 621 } 622 } 623 624 function handlePositionParam(container, position) { 625 if (position in swalClasses) { 626 addClass(container, swalClasses[position]); 627 } else { 628 warn('The "position" parameter is not valid, defaulting to "center"'); 629 addClass(container, swalClasses.center); 630 } 631 } 632 633 function handleGrowParam(container, grow) { 634 if (grow && typeof grow === 'string') { 635 const growClass = "grow-".concat(grow); 636 637 if (growClass in swalClasses) { 638 addClass(container, swalClasses[growClass]); 639 } 640 } 641 } 642 643 const renderContainer = (instance, params) => { 644 const container = getContainer(); 645 646 if (!container) { 647 return; 648 } 649 650 handleBackdropParam(container, params.backdrop); 651 handlePositionParam(container, params.position); 652 handleGrowParam(container, params.grow); // Custom class 653 654 applyCustomClass(container, params, 'container'); 655 }; 656 657 /** 658 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has. 659 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 660 * This is the approach that Babel will probably take to implement private methods/fields 661 * https://github.com/tc39/proposal-private-methods 662 * https://github.com/babel/babel/pull/7555 663 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 664 * then we can use that language feature. 665 */ 666 var privateProps = { 667 awaitingPromise: new WeakMap(), 668 promise: new WeakMap(), 669 innerParams: new WeakMap(), 670 domCache: new WeakMap() 671 }; 672 673 const inputTypes = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea']; 674 const renderInput = (instance, params) => { 675 const popup = getPopup(); 676 const innerParams = privateProps.innerParams.get(instance); 677 const rerender = !innerParams || params.input !== innerParams.input; 678 inputTypes.forEach(inputType => { 679 const inputClass = swalClasses[inputType]; 680 const inputContainer = getChildByClass(popup, inputClass); // set attributes 681 682 setAttributes(inputType, params.inputAttributes); // set class 683 684 inputContainer.className = inputClass; 685 686 if (rerender) { 687 hide(inputContainer); 688 } 689 }); 690 691 if (params.input) { 692 if (rerender) { 693 showInput(params); 694 } // set custom class 695 696 697 setCustomClass(params); 698 } 699 }; 700 701 const showInput = params => { 702 if (!renderInputType[params.input]) { 703 return error("Unexpected type of input! Expected \"text\", \"email\", \"password\", \"number\", \"tel\", \"select\", \"radio\", \"checkbox\", \"textarea\", \"file\" or \"url\", got \"".concat(params.input, "\"")); 704 } 705 706 const inputContainer = getInputContainer(params.input); 707 const input = renderInputType[params.input](inputContainer, params); 708 show(input); // input autofocus 709 710 setTimeout(() => { 711 focusInput(input); 712 }); 713 }; 714 715 const removeAttributes = input => { 716 for (let i = 0; i < input.attributes.length; i++) { 717 const attrName = input.attributes[i].name; 718 719 if (!['type', 'value', 'style'].includes(attrName)) { 720 input.removeAttribute(attrName); 721 } 722 } 723 }; 724 725 const setAttributes = (inputType, inputAttributes) => { 726 const input = getInput(getPopup(), inputType); 727 728 if (!input) { 729 return; 730 } 731 732 removeAttributes(input); 733 734 for (const attr in inputAttributes) { 735 input.setAttribute(attr, inputAttributes[attr]); 736 } 737 }; 738 739 const setCustomClass = params => { 740 const inputContainer = getInputContainer(params.input); 741 742 if (params.customClass) { 743 addClass(inputContainer, params.customClass.input); 744 } 745 }; 746 747 const setInputPlaceholder = (input, params) => { 748 if (!input.placeholder || params.inputPlaceholder) { 749 input.placeholder = params.inputPlaceholder; 750 } 751 }; 752 753 const setInputLabel = (input, prependTo, params) => { 754 if (params.inputLabel) { 755 input.id = swalClasses.input; 756 const label = document.createElement('label'); 757 const labelClass = swalClasses['input-label']; 758 label.setAttribute('for', input.id); 759 label.className = labelClass; 760 addClass(label, params.customClass.inputLabel); 761 label.innerText = params.inputLabel; 762 prependTo.insertAdjacentElement('beforebegin', label); 763 } 764 }; 765 766 const getInputContainer = inputType => { 767 const inputClass = swalClasses[inputType] ? swalClasses[inputType] : swalClasses.input; 768 return getChildByClass(getPopup(), inputClass); 769 }; 770 771 const renderInputType = {}; 772 773 renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = (input, params) => { 774 if (typeof params.inputValue === 'string' || typeof params.inputValue === 'number') { 775 input.value = params.inputValue; 776 } else if (!isPromise(params.inputValue)) { 777 warn("Unexpected type of inputValue! Expected \"string\", \"number\" or \"Promise\", got \"".concat(typeof params.inputValue, "\"")); 778 } 779 780 setInputLabel(input, input, params); 781 setInputPlaceholder(input, params); 782 input.type = params.input; 783 return input; 784 }; 785 786 renderInputType.file = (input, params) => { 787 setInputLabel(input, input, params); 788 setInputPlaceholder(input, params); 789 return input; 790 }; 791 792 renderInputType.range = (range, params) => { 793 const rangeInput = range.querySelector('input'); 794 const rangeOutput = range.querySelector('output'); 795 rangeInput.value = params.inputValue; 796 rangeInput.type = params.input; 797 rangeOutput.value = params.inputValue; 798 setInputLabel(rangeInput, range, params); 799 return range; 800 }; 801 802 renderInputType.select = (select, params) => { 803 select.textContent = ''; 804 805 if (params.inputPlaceholder) { 806 const placeholder = document.createElement('option'); 807 setInnerHtml(placeholder, params.inputPlaceholder); 808 placeholder.value = ''; 809 placeholder.disabled = true; 810 placeholder.selected = true; 811 select.appendChild(placeholder); 812 } 813 814 setInputLabel(select, select, params); 815 return select; 816 }; 817 818 renderInputType.radio = radio => { 819 radio.textContent = ''; 820 return radio; 821 }; 822 823 renderInputType.checkbox = (checkboxContainer, params) => { 824 const checkbox = getInput(getPopup(), 'checkbox'); 825 checkbox.value = 1; 826 checkbox.id = swalClasses.checkbox; 827 checkbox.checked = Boolean(params.inputValue); 828 const label = checkboxContainer.querySelector('span'); 829 setInnerHtml(label, params.inputPlaceholder); 830 return checkboxContainer; 831 }; 832 833 renderInputType.textarea = (textarea, params) => { 834 textarea.value = params.inputValue; 835 setInputPlaceholder(textarea, params); 836 setInputLabel(textarea, textarea, params); 837 838 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight); 839 840 setTimeout(() => { 841 // #2291 842 if ('MutationObserver' in window) { 843 // #1699 844 const initialPopupWidth = parseInt(window.getComputedStyle(getPopup()).width); 845 846 const textareaResizeHandler = () => { 847 const textareaWidth = textarea.offsetWidth + getMargin(textarea); 848 849 if (textareaWidth > initialPopupWidth) { 850 getPopup().style.width = "".concat(textareaWidth, "px"); 851 } else { 852 getPopup().style.width = null; 853 } 854 }; 855 856 new MutationObserver(textareaResizeHandler).observe(textarea, { 857 attributes: true, 858 attributeFilter: ['style'] 859 }); 860 } 861 }); 862 return textarea; 863 }; 864 865 const renderContent = (instance, params) => { 866 const htmlContainer = getHtmlContainer(); 867 applyCustomClass(htmlContainer, params, 'htmlContainer'); // Content as HTML 868 869 if (params.html) { 870 parseHtmlToContainer(params.html, htmlContainer); 871 show(htmlContainer, 'block'); // Content as plain text 872 } else if (params.text) { 873 htmlContainer.textContent = params.text; 874 show(htmlContainer, 'block'); // No content 875 } else { 876 hide(htmlContainer); 877 } 878 879 renderInput(instance, params); 880 }; 881 882 const renderFooter = (instance, params) => { 883 const footer = getFooter(); 884 toggle(footer, params.footer); 885 886 if (params.footer) { 887 parseHtmlToContainer(params.footer, footer); 888 } // Custom class 889 890 891 applyCustomClass(footer, params, 'footer'); 892 }; 893 894 const renderCloseButton = (instance, params) => { 895 const closeButton = getCloseButton(); 896 setInnerHtml(closeButton, params.closeButtonHtml); // Custom class 897 898 applyCustomClass(closeButton, params, 'closeButton'); 899 toggle(closeButton, params.showCloseButton); 900 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel); 901 }; 902 903 const renderIcon = (instance, params) => { 904 const innerParams = privateProps.innerParams.get(instance); 905 const icon = getIcon(); // if the given icon already rendered, apply the styling without re-rendering the icon 906 907 if (innerParams && params.icon === innerParams.icon) { 908 // Custom or default content 909 setContent(icon, params); 910 applyStyles(icon, params); 911 return; 912 } 913 914 if (!params.icon && !params.iconHtml) { 915 return hide(icon); 916 } 917 918 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) { 919 error("Unknown icon! Expected \"success\", \"error\", \"warning\", \"info\" or \"question\", got \"".concat(params.icon, "\"")); 920 return hide(icon); 921 } 922 923 show(icon); // Custom or default content 924 925 setContent(icon, params); 926 applyStyles(icon, params); // Animate icon 927 928 addClass(icon, params.showClass.icon); 929 }; 930 931 const applyStyles = (icon, params) => { 932 for (const iconType in iconTypes) { 933 if (params.icon !== iconType) { 934 removeClass(icon, iconTypes[iconType]); 935 } 936 } 937 938 addClass(icon, iconTypes[params.icon]); // Icon color 939 940 setColor(icon, params); // Success icon background color 941 942 adjustSuccessIconBackgoundColor(); // Custom class 943 944 applyCustomClass(icon, params, 'icon'); 945 }; // Adjust success icon background color to match the popup background color 946 947 948 const adjustSuccessIconBackgoundColor = () => { 949 const popup = getPopup(); 950 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color'); 951 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix'); 952 953 for (let i = 0; i < successIconParts.length; i++) { 954 successIconParts[i].style.backgroundColor = popupBackgroundColor; 955 } 956 }; 957 958 const setContent = (icon, params) => { 959 icon.textContent = ''; 960 961 if (params.iconHtml) { 962 setInnerHtml(icon, iconContent(params.iconHtml)); 963 } else if (params.icon === 'success') { 964 setInnerHtml(icon, "\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 "); 965 } else if (params.icon === 'error') { 966 setInnerHtml(icon, "\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 "); 967 } else { 968 const defaultIconHtml = { 969 question: '?', 970 warning: '!', 971 info: 'i' 972 }; 973 setInnerHtml(icon, iconContent(defaultIconHtml[params.icon])); 974 } 975 }; 976 977 const setColor = (icon, params) => { 978 if (!params.iconColor) { 979 return; 980 } 981 982 icon.style.color = params.iconColor; 983 icon.style.borderColor = params.iconColor; 984 985 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) { 986 setStyle(icon, sel, 'backgroundColor', params.iconColor); 987 } 988 989 setStyle(icon, '.swal2-success-ring', 'borderColor', params.iconColor); 990 }; 991 992 const iconContent = content => "<div class=\"".concat(swalClasses['icon-content'], "\">").concat(content, "</div>"); 993 994 const renderImage = (instance, params) => { 995 const image = getImage(); 996 997 if (!params.imageUrl) { 998 return hide(image); 999 } 1000 1001 show(image, ''); // Src, alt 1002 1003 image.setAttribute('src', params.imageUrl); 1004 image.setAttribute('alt', params.imageAlt); // Width, height 1005 1006 applyNumericalStyle(image, 'width', params.imageWidth); 1007 applyNumericalStyle(image, 'height', params.imageHeight); // Class 1008 1009 image.className = swalClasses.image; 1010 applyCustomClass(image, params, 'image'); 1011 }; 1012 1013 const createStepElement = step => { 1014 const stepEl = document.createElement('li'); 1015 addClass(stepEl, swalClasses['progress-step']); 1016 setInnerHtml(stepEl, step); 1017 return stepEl; 1018 }; 1019 1020 const createLineElement = params => { 1021 const lineEl = document.createElement('li'); 1022 addClass(lineEl, swalClasses['progress-step-line']); 1023 1024 if (params.progressStepsDistance) { 1025 lineEl.style.width = params.progressStepsDistance; 1026 } 1027 1028 return lineEl; 1029 }; 1030 1031 const renderProgressSteps = (instance, params) => { 1032 const progressStepsContainer = getProgressSteps(); 1033 1034 if (!params.progressSteps || params.progressSteps.length === 0) { 1035 return hide(progressStepsContainer); 1036 } 1037 1038 show(progressStepsContainer); 1039 progressStepsContainer.textContent = ''; 1040 1041 if (params.currentProgressStep >= params.progressSteps.length) { 1042 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)'); 1043 } 1044 1045 params.progressSteps.forEach((step, index) => { 1046 const stepEl = createStepElement(step); 1047 progressStepsContainer.appendChild(stepEl); 1048 1049 if (index === params.currentProgressStep) { 1050 addClass(stepEl, swalClasses['active-progress-step']); 1051 } 1052 1053 if (index !== params.progressSteps.length - 1) { 1054 const lineEl = createLineElement(params); 1055 progressStepsContainer.appendChild(lineEl); 1056 } 1057 }); 1058 }; 1059 1060 const renderTitle = (instance, params) => { 1061 const title = getTitle(); 1062 toggle(title, params.title || params.titleText, 'block'); 1063 1064 if (params.title) { 1065 parseHtmlToContainer(params.title, title); 1066 } 1067 1068 if (params.titleText) { 1069 title.innerText = params.titleText; 1070 } // Custom class 1071 1072 1073 applyCustomClass(title, params, 'title'); 1074 }; 1075 1076 const renderPopup = (instance, params) => { 1077 const container = getContainer(); 1078 const popup = getPopup(); // Width 1079 1080 if (params.toast) { 1081 // #2170 1082 applyNumericalStyle(container, 'width', params.width); 1083 popup.style.width = '100%'; 1084 popup.insertBefore(getLoader(), getIcon()); 1085 } else { 1086 applyNumericalStyle(popup, 'width', params.width); 1087 } // Padding 1088 1089 1090 applyNumericalStyle(popup, 'padding', params.padding); // Background 1091 1092 if (params.background) { 1093 popup.style.background = params.background; 1094 } 1095 1096 hide(getValidationMessage()); // Classes 1097 1098 addClasses(popup, params); 1099 }; 1100 1101 const addClasses = (popup, params) => { 1102 // Default Class + showClass when updating Swal.update({}) 1103 popup.className = "".concat(swalClasses.popup, " ").concat(isVisible(popup) ? params.showClass.popup : ''); 1104 1105 if (params.toast) { 1106 addClass([document.documentElement, document.body], swalClasses['toast-shown']); 1107 addClass(popup, swalClasses.toast); 1108 } else { 1109 addClass(popup, swalClasses.modal); 1110 } // Custom class 1111 1112 1113 applyCustomClass(popup, params, 'popup'); 1114 1115 if (typeof params.customClass === 'string') { 1116 addClass(popup, params.customClass); 1117 } // Icon class (#1842) 1118 1119 1120 if (params.icon) { 1121 addClass(popup, swalClasses["icon-".concat(params.icon)]); 1122 } 1123 }; 1124 1125 const render = (instance, params) => { 1126 renderPopup(instance, params); 1127 renderContainer(instance, params); 1128 renderProgressSteps(instance, params); 1129 renderIcon(instance, params); 1130 renderImage(instance, params); 1131 renderTitle(instance, params); 1132 renderCloseButton(instance, params); 1133 renderContent(instance, params); 1134 renderActions(instance, params); 1135 renderFooter(instance, params); 1136 1137 if (typeof params.didRender === 'function') { 1138 params.didRender(getPopup()); 1139 } 1140 }; 1141 1142 /* 1143 * Global function to determine if SweetAlert2 popup is shown 1144 */ 1145 1146 const isVisible$1 = () => { 1147 return isVisible(getPopup()); 1148 }; 1149 /* 1150 * Global function to click 'Confirm' button 1151 */ 1152 1153 const clickConfirm = () => getConfirmButton() && getConfirmButton().click(); 1154 /* 1155 * Global function to click 'Deny' button 1156 */ 1157 1158 const clickDeny = () => getDenyButton() && getDenyButton().click(); 1159 /* 1160 * Global function to click 'Cancel' button 1161 */ 1162 1163 const clickCancel = () => getCancelButton() && getCancelButton().click(); 1164 1165 function fire() { 1166 const Swal = this; 1167 1168 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 1169 args[_key] = arguments[_key]; 1170 } 1171 1172 return new Swal(...args); 1173 } 1174 1175 /** 1176 * Returns an extended version of `Swal` containing `params` as defaults. 1177 * Useful for reusing Swal configuration. 1178 * 1179 * For example: 1180 * 1181 * Before: 1182 * const textPromptOptions = { input: 'text', showCancelButton: true } 1183 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' }) 1184 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' }) 1185 * 1186 * After: 1187 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true }) 1188 * const {value: firstName} = await TextPrompt('What is your first name?') 1189 * const {value: lastName} = await TextPrompt('What is your last name?') 1190 * 1191 * @param mixinParams 1192 */ 1193 function mixin(mixinParams) { 1194 class MixinSwal extends this { 1195 _main(params, priorityMixinParams) { 1196 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams)); 1197 } 1198 1199 } 1200 1201 return MixinSwal; 1202 } 1203 1204 /** 1205 * Shows loader (spinner), this is useful with AJAX requests. 1206 * By default the loader be shown instead of the "Confirm" button. 1207 */ 1208 1209 const showLoading = buttonToReplace => { 1210 let popup = getPopup(); 1211 1212 if (!popup) { 1213 Swal.fire(); 1214 } 1215 1216 popup = getPopup(); 1217 const loader = getLoader(); 1218 1219 if (isToast()) { 1220 hide(getIcon()); 1221 } else { 1222 replaceButton(popup, buttonToReplace); 1223 } 1224 1225 show(loader); 1226 popup.setAttribute('data-loading', true); 1227 popup.setAttribute('aria-busy', true); 1228 popup.focus(); 1229 }; 1230 1231 const replaceButton = (popup, buttonToReplace) => { 1232 const actions = getActions(); 1233 const loader = getLoader(); 1234 1235 if (!buttonToReplace && isVisible(getConfirmButton())) { 1236 buttonToReplace = getConfirmButton(); 1237 } 1238 1239 show(actions); 1240 1241 if (buttonToReplace) { 1242 hide(buttonToReplace); 1243 loader.setAttribute('data-button-to-replace', buttonToReplace.className); 1244 } 1245 1246 loader.parentNode.insertBefore(loader, buttonToReplace); 1247 addClass([popup, actions], swalClasses.loading); 1248 }; 1249 1250 const RESTORE_FOCUS_TIMEOUT = 100; 1251 1252 const globalState = {}; 1253 1254 const focusPreviousActiveElement = () => { 1255 if (globalState.previousActiveElement && globalState.previousActiveElement.focus) { 1256 globalState.previousActiveElement.focus(); 1257 globalState.previousActiveElement = null; 1258 } else if (document.body) { 1259 document.body.focus(); 1260 } 1261 }; // Restore previous active (focused) element 1262 1263 1264 const restoreActiveElement = returnFocus => { 1265 return new Promise(resolve => { 1266 if (!returnFocus) { 1267 return resolve(); 1268 } 1269 1270 const x = window.scrollX; 1271 const y = window.scrollY; 1272 globalState.restoreFocusTimeout = setTimeout(() => { 1273 focusPreviousActiveElement(); 1274 resolve(); 1275 }, RESTORE_FOCUS_TIMEOUT); // issues/900 1276 1277 window.scrollTo(x, y); 1278 }); 1279 }; 1280 1281 /** 1282 * If `timer` parameter is set, returns number of milliseconds of timer remained. 1283 * Otherwise, returns undefined. 1284 */ 1285 1286 const getTimerLeft = () => { 1287 return globalState.timeout && globalState.timeout.getTimerLeft(); 1288 }; 1289 /** 1290 * Stop timer. Returns number of milliseconds of timer remained. 1291 * If `timer` parameter isn't set, returns undefined. 1292 */ 1293 1294 const stopTimer = () => { 1295 if (globalState.timeout) { 1296 stopTimerProgressBar(); 1297 return globalState.timeout.stop(); 1298 } 1299 }; 1300 /** 1301 * Resume timer. Returns number of milliseconds of timer remained. 1302 * If `timer` parameter isn't set, returns undefined. 1303 */ 1304 1305 const resumeTimer = () => { 1306 if (globalState.timeout) { 1307 const remaining = globalState.timeout.start(); 1308 animateTimerProgressBar(remaining); 1309 return remaining; 1310 } 1311 }; 1312 /** 1313 * Resume timer. Returns number of milliseconds of timer remained. 1314 * If `timer` parameter isn't set, returns undefined. 1315 */ 1316 1317 const toggleTimer = () => { 1318 const timer = globalState.timeout; 1319 return timer && (timer.running ? stopTimer() : resumeTimer()); 1320 }; 1321 /** 1322 * Increase timer. Returns number of milliseconds of an updated timer. 1323 * If `timer` parameter isn't set, returns undefined. 1324 */ 1325 1326 const increaseTimer = n => { 1327 if (globalState.timeout) { 1328 const remaining = globalState.timeout.increase(n); 1329 animateTimerProgressBar(remaining, true); 1330 return remaining; 1331 } 1332 }; 1333 /** 1334 * Check if timer is running. Returns true if timer is running 1335 * or false if timer is paused or stopped. 1336 * If `timer` parameter isn't set, returns undefined 1337 */ 1338 1339 const isTimerRunning = () => { 1340 return globalState.timeout && globalState.timeout.isRunning(); 1341 }; 1342 1343 let bodyClickListenerAdded = false; 1344 const clickHandlers = {}; 1345 function bindClickHandler() { 1346 let attr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data-swal-template'; 1347 clickHandlers[attr] = this; 1348 1349 if (!bodyClickListenerAdded) { 1350 document.body.addEventListener('click', bodyClickListener); 1351 bodyClickListenerAdded = true; 1352 } 1353 } 1354 1355 const bodyClickListener = event => { 1356 for (let el = event.target; el && el !== document; el = el.parentNode) { 1357 for (const attr in clickHandlers) { 1358 const template = el.getAttribute(attr); 1359 1360 if (template) { 1361 clickHandlers[attr].fire({ 1362 template 1363 }); 1364 return; 1365 } 1366 } 1367 } 1368 }; 1369 1370 const defaultParams = { 1371 title: '', 1372 titleText: '', 1373 text: '', 1374 html: '', 1375 footer: '', 1376 icon: undefined, 1377 iconColor: undefined, 1378 iconHtml: undefined, 1379 template: undefined, 1380 toast: false, 1381 showClass: { 1382 popup: 'swal2-show', 1383 backdrop: 'swal2-backdrop-show', 1384 icon: 'swal2-icon-show' 1385 }, 1386 hideClass: { 1387 popup: 'swal2-hide', 1388 backdrop: 'swal2-backdrop-hide', 1389 icon: 'swal2-icon-hide' 1390 }, 1391 customClass: {}, 1392 target: 'body', 1393 backdrop: true, 1394 heightAuto: true, 1395 allowOutsideClick: true, 1396 allowEscapeKey: true, 1397 allowEnterKey: true, 1398 stopKeydownPropagation: true, 1399 keydownListenerCapture: false, 1400 showConfirmButton: true, 1401 showDenyButton: false, 1402 showCancelButton: false, 1403 preConfirm: undefined, 1404 preDeny: undefined, 1405 confirmButtonText: 'OK', 1406 confirmButtonAriaLabel: '', 1407 confirmButtonColor: undefined, 1408 denyButtonText: 'No', 1409 denyButtonAriaLabel: '', 1410 denyButtonColor: undefined, 1411 cancelButtonText: 'Cancel', 1412 cancelButtonAriaLabel: '', 1413 cancelButtonColor: undefined, 1414 buttonsStyling: true, 1415 reverseButtons: false, 1416 focusConfirm: true, 1417 focusDeny: false, 1418 focusCancel: false, 1419 returnFocus: true, 1420 showCloseButton: false, 1421 closeButtonHtml: '×', 1422 closeButtonAriaLabel: 'Close this dialog', 1423 loaderHtml: '', 1424 showLoaderOnConfirm: false, 1425 showLoaderOnDeny: false, 1426 imageUrl: undefined, 1427 imageWidth: undefined, 1428 imageHeight: undefined, 1429 imageAlt: '', 1430 timer: undefined, 1431 timerProgressBar: false, 1432 width: undefined, 1433 padding: undefined, 1434 background: undefined, 1435 input: undefined, 1436 inputPlaceholder: '', 1437 inputLabel: '', 1438 inputValue: '', 1439 inputOptions: {}, 1440 inputAutoTrim: true, 1441 inputAttributes: {}, 1442 inputValidator: undefined, 1443 returnInputValueOnDeny: false, 1444 validationMessage: undefined, 1445 grow: false, 1446 position: 'center', 1447 progressSteps: [], 1448 currentProgressStep: undefined, 1449 progressStepsDistance: undefined, 1450 willOpen: undefined, 1451 didOpen: undefined, 1452 didRender: undefined, 1453 willClose: undefined, 1454 didClose: undefined, 1455 didDestroy: undefined, 1456 scrollbarPadding: true 1457 }; 1458 const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', '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']; 1459 const deprecatedParams = {}; 1460 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture']; 1461 /** 1462 * Is valid parameter 1463 * @param {String} paramName 1464 */ 1465 1466 const isValidParameter = paramName => { 1467 return Object.prototype.hasOwnProperty.call(defaultParams, paramName); 1468 }; 1469 /** 1470 * Is valid parameter for Swal.update() method 1471 * @param {String} paramName 1472 */ 1473 1474 const isUpdatableParameter = paramName => { 1475 return updatableParams.indexOf(paramName) !== -1; 1476 }; 1477 /** 1478 * Is deprecated parameter 1479 * @param {String} paramName 1480 */ 1481 1482 const isDeprecatedParameter = paramName => { 1483 return deprecatedParams[paramName]; 1484 }; 1485 1486 const checkIfParamIsValid = param => { 1487 if (!isValidParameter(param)) { 1488 warn("Unknown parameter \"".concat(param, "\"")); 1489 } 1490 }; 1491 1492 const checkIfToastParamIsValid = param => { 1493 if (toastIncompatibleParams.includes(param)) { 1494 warn("The parameter \"".concat(param, "\" is incompatible with toasts")); 1495 } 1496 }; 1497 1498 const checkIfParamIsDeprecated = param => { 1499 if (isDeprecatedParameter(param)) { 1500 warnAboutDeprecation(param, isDeprecatedParameter(param)); 1501 } 1502 }; 1503 /** 1504 * Show relevant warnings for given params 1505 * 1506 * @param params 1507 */ 1508 1509 1510 const showWarningsForParams = params => { 1511 if (!params.backdrop && params.allowOutsideClick) { 1512 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'); 1513 } 1514 1515 for (const param in params) { 1516 checkIfParamIsValid(param); 1517 1518 if (params.toast) { 1519 checkIfToastParamIsValid(param); 1520 } 1521 1522 checkIfParamIsDeprecated(param); 1523 } 1524 }; 1525 1526 1527 1528 var staticMethods = /*#__PURE__*/Object.freeze({ 1529 isValidParameter: isValidParameter, 1530 isUpdatableParameter: isUpdatableParameter, 1531 isDeprecatedParameter: isDeprecatedParameter, 1532 argsToParams: argsToParams, 1533 isVisible: isVisible$1, 1534 clickConfirm: clickConfirm, 1535 clickDeny: clickDeny, 1536 clickCancel: clickCancel, 1537 getContainer: getContainer, 1538 getPopup: getPopup, 1539 getTitle: getTitle, 1540 getHtmlContainer: getHtmlContainer, 1541 getImage: getImage, 1542 getIcon: getIcon, 1543 getInputLabel: getInputLabel, 1544 getCloseButton: getCloseButton, 1545 getActions: getActions, 1546 getConfirmButton: getConfirmButton, 1547 getDenyButton: getDenyButton, 1548 getCancelButton: getCancelButton, 1549 getLoader: getLoader, 1550 getFooter: getFooter, 1551 getTimerProgressBar: getTimerProgressBar, 1552 getFocusableElements: getFocusableElements, 1553 getValidationMessage: getValidationMessage, 1554 isLoading: isLoading, 1555 fire: fire, 1556 mixin: mixin, 1557 showLoading: showLoading, 1558 enableLoading: showLoading, 1559 getTimerLeft: getTimerLeft, 1560 stopTimer: stopTimer, 1561 resumeTimer: resumeTimer, 1562 toggleTimer: toggleTimer, 1563 increaseTimer: increaseTimer, 1564 isTimerRunning: isTimerRunning, 1565 bindClickHandler: bindClickHandler 1566 }); 1567 1568 /** 1569 * Hides loader and shows back the button which was hidden by .showLoading() 1570 */ 1571 1572 function hideLoading() { 1573 // do nothing if popup is closed 1574 const innerParams = privateProps.innerParams.get(this); 1575 1576 if (!innerParams) { 1577 return; 1578 } 1579 1580 const domCache = privateProps.domCache.get(this); 1581 hide(domCache.loader); 1582 1583 if (isToast()) { 1584 if (innerParams.icon) { 1585 show(getIcon()); 1586 } 1587 } else { 1588 showRelatedButton(domCache); 1589 } 1590 1591 removeClass([domCache.popup, domCache.actions], swalClasses.loading); 1592 domCache.popup.removeAttribute('aria-busy'); 1593 domCache.popup.removeAttribute('data-loading'); 1594 domCache.confirmButton.disabled = false; 1595 domCache.denyButton.disabled = false; 1596 domCache.cancelButton.disabled = false; 1597 } 1598 1599 const showRelatedButton = domCache => { 1600 const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace')); 1601 1602 if (buttonToReplace.length) { 1603 show(buttonToReplace[0], 'inline-block'); 1604 } else if (allButtonsAreHidden()) { 1605 hide(domCache.actions); 1606 } 1607 }; 1608 1609 function getInput$1(instance) { 1610 const innerParams = privateProps.innerParams.get(instance || this); 1611 const domCache = privateProps.domCache.get(instance || this); 1612 1613 if (!domCache) { 1614 return null; 1615 } 1616 1617 return getInput(domCache.popup, innerParams.input); 1618 } 1619 1620 const fixScrollbar = () => { 1621 // for queues, do not do this more than once 1622 if (states.previousBodyPadding !== null) { 1623 return; 1624 } // if the body has overflow 1625 1626 1627 if (document.body.scrollHeight > window.innerHeight) { 1628 // add padding so the content doesn't shift after removal of scrollbar 1629 states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right')); 1630 document.body.style.paddingRight = "".concat(states.previousBodyPadding + measureScrollbar(), "px"); 1631 } 1632 }; 1633 const undoScrollbar = () => { 1634 if (states.previousBodyPadding !== null) { 1635 document.body.style.paddingRight = "".concat(states.previousBodyPadding, "px"); 1636 states.previousBodyPadding = null; 1637 } 1638 }; 1639 1640 /* istanbul ignore file */ 1641 1642 const iOSfix = () => { 1643 const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream || navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; 1644 1645 if (iOS && !hasClass(document.body, swalClasses.iosfix)) { 1646 const offset = document.body.scrollTop; 1647 document.body.style.top = "".concat(offset * -1, "px"); 1648 addClass(document.body, swalClasses.iosfix); 1649 lockBodyScroll(); 1650 addBottomPaddingForTallPopups(); // #1948 1651 } 1652 }; 1653 1654 const addBottomPaddingForTallPopups = () => { 1655 const safari = !navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i); 1656 1657 if (safari) { 1658 const bottomPanelHeight = 44; 1659 1660 if (getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) { 1661 getContainer().style.paddingBottom = "".concat(bottomPanelHeight, "px"); 1662 } 1663 } 1664 }; 1665 1666 const lockBodyScroll = () => { 1667 // #1246 1668 const container = getContainer(); 1669 let preventTouchMove; 1670 1671 container.ontouchstart = e => { 1672 preventTouchMove = shouldPreventTouchMove(e); 1673 }; 1674 1675 container.ontouchmove = e => { 1676 if (preventTouchMove) { 1677 e.preventDefault(); 1678 e.stopPropagation(); 1679 } 1680 }; 1681 }; 1682 1683 const shouldPreventTouchMove = event => { 1684 const target = event.target; 1685 const container = getContainer(); 1686 1687 if (isStylys(event) || isZoom(event)) { 1688 return false; 1689 } 1690 1691 if (target === container) { 1692 return true; 1693 } 1694 1695 if (!isScrollable(container) && target.tagName !== 'INPUT' && // #1603 1696 target.tagName !== 'TEXTAREA' && // #2266 1697 !(isScrollable(getHtmlContainer()) && // #1944 1698 getHtmlContainer().contains(target))) { 1699 return true; 1700 } 1701 1702 return false; 1703 }; 1704 1705 const isStylys = event => { 1706 // #1786 1707 return event.touches && event.touches.length && event.touches[0].touchType === 'stylus'; 1708 }; 1709 1710 const isZoom = event => { 1711 // #1891 1712 return event.touches && event.touches.length > 1; 1713 }; 1714 1715 const undoIOSfix = () => { 1716 if (hasClass(document.body, swalClasses.iosfix)) { 1717 const offset = parseInt(document.body.style.top, 10); 1718 removeClass(document.body, swalClasses.iosfix); 1719 document.body.style.top = ''; 1720 document.body.scrollTop = offset * -1; 1721 } 1722 }; 1723 1724 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that 1725 // elements not within the active modal dialog will not be surfaced if a user opens a screen 1726 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document. 1727 1728 const setAriaHidden = () => { 1729 const bodyChildren = toArray(document.body.children); 1730 bodyChildren.forEach(el => { 1731 if (el === getContainer() || el.contains(getContainer())) { 1732 return; 1733 } 1734 1735 if (el.hasAttribute('aria-hidden')) { 1736 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden')); 1737 } 1738 1739 el.setAttribute('aria-hidden', 'true'); 1740 }); 1741 }; 1742 const unsetAriaHidden = () => { 1743 const bodyChildren = toArray(document.body.children); 1744 bodyChildren.forEach(el => { 1745 if (el.hasAttribute('data-previous-aria-hidden')) { 1746 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden')); 1747 el.removeAttribute('data-previous-aria-hidden'); 1748 } else { 1749 el.removeAttribute('aria-hidden'); 1750 } 1751 }); 1752 }; 1753 1754 /** 1755 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has. 1756 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 1757 * This is the approach that Babel will probably take to implement private methods/fields 1758 * https://github.com/tc39/proposal-private-methods 1759 * https://github.com/babel/babel/pull/7555 1760 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 1761 * then we can use that language feature. 1762 */ 1763 var privateMethods = { 1764 swalPromiseResolve: new WeakMap(), 1765 swalPromiseReject: new WeakMap() 1766 }; 1767 1768 /* 1769 * Instance method to close sweetAlert 1770 */ 1771 1772 function removePopupAndResetState(instance, container, returnFocus, didClose) { 1773 if (isToast()) { 1774 triggerDidCloseAndDispose(instance, didClose); 1775 } else { 1776 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose)); 1777 globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, { 1778 capture: globalState.keydownListenerCapture 1779 }); 1780 globalState.keydownHandlerAdded = false; 1781 } 1782 1783 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // workaround for #2088 1784 // for some reason removing the container in Safari will scroll the document to bottom 1785 1786 if (isSafari) { 1787 container.setAttribute('style', 'display:none !important'); 1788 container.removeAttribute('class'); 1789 container.innerHTML = ''; 1790 } else { 1791 container.remove(); 1792 } 1793 1794 if (isModal()) { 1795 undoScrollbar(); 1796 undoIOSfix(); 1797 unsetAriaHidden(); 1798 } 1799 1800 removeBodyClasses(); 1801 } 1802 1803 function removeBodyClasses() { 1804 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]); 1805 } 1806 1807 function close(resolveValue) { 1808 resolveValue = prepareResolveValue(resolveValue); 1809 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this); 1810 const didClose = triggerClosePopup(this); 1811 1812 if (this.isAwaitingPromise()) { 1813 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335 1814 if (!resolveValue.isDismissed) { 1815 handleAwaitingPromise(this); 1816 swalPromiseResolve(resolveValue); 1817 } 1818 } else if (didClose) { 1819 // Resolve Swal promise 1820 swalPromiseResolve(resolveValue); 1821 } 1822 } 1823 function isAwaitingPromise() { 1824 return !!privateProps.awaitingPromise.get(this); 1825 } 1826 1827 const triggerClosePopup = instance => { 1828 const popup = getPopup(); 1829 1830 if (!popup) { 1831 return false; 1832 } 1833 1834 const innerParams = privateProps.innerParams.get(instance); 1835 1836 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) { 1837 return false; 1838 } 1839 1840 removeClass(popup, innerParams.showClass.popup); 1841 addClass(popup, innerParams.hideClass.popup); 1842 const backdrop = getContainer(); 1843 removeClass(backdrop, innerParams.showClass.backdrop); 1844 addClass(backdrop, innerParams.hideClass.backdrop); 1845 handlePopupAnimation(instance, popup, innerParams); 1846 return true; 1847 }; 1848 1849 function rejectPromise(error) { 1850 const rejectPromise = privateMethods.swalPromiseReject.get(this); 1851 handleAwaitingPromise(this); 1852 1853 if (rejectPromise) { 1854 // Reject Swal promise 1855 rejectPromise(error); 1856 } 1857 } 1858 1859 const handleAwaitingPromise = instance => { 1860 if (instance.isAwaitingPromise()) { 1861 privateProps.awaitingPromise.delete(instance); // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335 1862 1863 if (!privateProps.innerParams.get(instance)) { 1864 instance._destroy(); 1865 } 1866 } 1867 }; 1868 1869 const prepareResolveValue = resolveValue => { 1870 // When user calls Swal.close() 1871 if (typeof resolveValue === 'undefined') { 1872 return { 1873 isConfirmed: false, 1874 isDenied: false, 1875 isDismissed: true 1876 }; 1877 } 1878 1879 return Object.assign({ 1880 isConfirmed: false, 1881 isDenied: false, 1882 isDismissed: false 1883 }, resolveValue); 1884 }; 1885 1886 const handlePopupAnimation = (instance, popup, innerParams) => { 1887 const container = getContainer(); // If animation is supported, animate 1888 1889 const animationIsSupported = animationEndEvent && hasCssAnimation(popup); 1890 1891 if (typeof innerParams.willClose === 'function') { 1892 innerParams.willClose(popup); 1893 } 1894 1895 if (animationIsSupported) { 1896 animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose); 1897 } else { 1898 // Otherwise, remove immediately 1899 removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose); 1900 } 1901 }; 1902 1903 const animatePopup = (instance, popup, container, returnFocus, didClose) => { 1904 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose); 1905 popup.addEventListener(animationEndEvent, function (e) { 1906 if (e.target === popup) { 1907 globalState.swalCloseEventFinishedCallback(); 1908 delete globalState.swalCloseEventFinishedCallback; 1909 } 1910 }); 1911 }; 1912 1913 const triggerDidCloseAndDispose = (instance, didClose) => { 1914 setTimeout(() => { 1915 if (typeof didClose === 'function') { 1916 didClose.bind(instance.params)(); 1917 } 1918 1919 instance._destroy(); 1920 }); 1921 }; 1922 1923 function setButtonsDisabled(instance, buttons, disabled) { 1924 const domCache = privateProps.domCache.get(instance); 1925 buttons.forEach(button => { 1926 domCache[button].disabled = disabled; 1927 }); 1928 } 1929 1930 function setInputDisabled(input, disabled) { 1931 if (!input) { 1932 return false; 1933 } 1934 1935 if (input.type === 'radio') { 1936 const radiosContainer = input.parentNode.parentNode; 1937 const radios = radiosContainer.querySelectorAll('input'); 1938 1939 for (let i = 0; i < radios.length; i++) { 1940 radios[i].disabled = disabled; 1941 } 1942 } else { 1943 input.disabled = disabled; 1944 } 1945 } 1946 1947 function enableButtons() { 1948 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false); 1949 } 1950 function disableButtons() { 1951 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true); 1952 } 1953 function enableInput() { 1954 return setInputDisabled(this.getInput(), false); 1955 } 1956 function disableInput() { 1957 return setInputDisabled(this.getInput(), true); 1958 } 1959 1960 function showValidationMessage(error) { 1961 const domCache = privateProps.domCache.get(this); 1962 const params = privateProps.innerParams.get(this); 1963 setInnerHtml(domCache.validationMessage, error); 1964 domCache.validationMessage.className = swalClasses['validation-message']; 1965 1966 if (params.customClass && params.customClass.validationMessage) { 1967 addClass(domCache.validationMessage, params.customClass.validationMessage); 1968 } 1969 1970 show(domCache.validationMessage); 1971 const input = this.getInput(); 1972 1973 if (input) { 1974 input.setAttribute('aria-invalid', true); 1975 input.setAttribute('aria-describedby', swalClasses['validation-message']); 1976 focusInput(input); 1977 addClass(input, swalClasses.inputerror); 1978 } 1979 } // Hide block with validation message 1980 1981 function resetValidationMessage$1() { 1982 const domCache = privateProps.domCache.get(this); 1983 1984 if (domCache.validationMessage) { 1985 hide(domCache.validationMessage); 1986 } 1987 1988 const input = this.getInput(); 1989 1990 if (input) { 1991 input.removeAttribute('aria-invalid'); 1992 input.removeAttribute('aria-describedby'); 1993 removeClass(input, swalClasses.inputerror); 1994 } 1995 } 1996 1997 function getProgressSteps$1() { 1998 const domCache = privateProps.domCache.get(this); 1999 return domCache.progressSteps; 2000 } 2001 2002 class Timer { 2003 constructor(callback, delay) { 2004 this.callback = callback; 2005 this.remaining = delay; 2006 this.running = false; 2007 this.start(); 2008 } 2009 2010 start() { 2011 if (!this.running) { 2012 this.running = true; 2013 this.started = new Date(); 2014 this.id = setTimeout(this.callback, this.remaining); 2015 } 2016 2017 return this.remaining; 2018 } 2019 2020 stop() { 2021 if (this.running) { 2022 this.running = false; 2023 clearTimeout(this.id); 2024 this.remaining -= new Date() - this.started; 2025 } 2026 2027 return this.remaining; 2028 } 2029 2030 increase(n) { 2031 const running = this.running; 2032 2033 if (running) { 2034 this.stop(); 2035 } 2036 2037 this.remaining += n; 2038 2039 if (running) { 2040 this.start(); 2041 } 2042 2043 return this.remaining; 2044 } 2045 2046 getTimerLeft() { 2047 if (this.running) { 2048 this.stop(); 2049 this.start(); 2050 } 2051 2052 return this.remaining; 2053 } 2054 2055 isRunning() { 2056 return this.running; 2057 } 2058 2059 } 2060 2061 var defaultInputValidators = { 2062 email: (string, validationMessage) => { 2063 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'); 2064 }, 2065 url: (string, validationMessage) => { 2066 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013 2067 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'); 2068 } 2069 }; 2070 2071 function setDefaultInputValidators(params) { 2072 // Use default `inputValidator` for supported input types if not provided 2073 if (!params.inputValidator) { 2074 Object.keys(defaultInputValidators).forEach(key => { 2075 if (params.input === key) { 2076 params.inputValidator = defaultInputValidators[key]; 2077 } 2078 }); 2079 } 2080 } 2081 2082 function validateCustomTargetElement(params) { 2083 // Determine if the custom target element is valid 2084 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) { 2085 warn('Target parameter is not valid, defaulting to "body"'); 2086 params.target = 'body'; 2087 } 2088 } 2089 /** 2090 * Set type, text and actions on popup 2091 * 2092 * @param params 2093 * @returns {boolean} 2094 */ 2095 2096 2097 function setParameters(params) { 2098 setDefaultInputValidators(params); // showLoaderOnConfirm && preConfirm 2099 2100 if (params.showLoaderOnConfirm && !params.preConfirm) { 2101 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'); 2102 } 2103 2104 validateCustomTargetElement(params); // Replace newlines with <br> in title 2105 2106 if (typeof params.title === 'string') { 2107 params.title = params.title.split('\n').join('<br />'); 2108 } 2109 2110 init(params); 2111 } 2112 2113 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer']; 2114 const getTemplateParams = params => { 2115 const template = typeof params.template === 'string' ? document.querySelector(params.template) : params.template; 2116 2117 if (!template) { 2118 return {}; 2119 } 2120 2121 const templateContent = template.content; 2122 showWarningsForElements(templateContent); 2123 const result = Object.assign(getSwalParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams)); 2124 return result; 2125 }; 2126 2127 const getSwalParams = templateContent => { 2128 const result = {}; 2129 toArray(templateContent.querySelectorAll('swal-param')).forEach(param => { 2130 showWarningsForAttributes(param, ['name', 'value']); 2131 const paramName = param.getAttribute('name'); 2132 let value = param.getAttribute('value'); 2133 2134 if (typeof defaultParams[paramName] === 'boolean' && value === 'false') { 2135 value = false; 2136 } 2137 2138 if (typeof defaultParams[paramName] === 'object') { 2139 value = JSON.parse(value); 2140 } 2141 2142 result[paramName] = value; 2143 }); 2144 return result; 2145 }; 2146 2147 const getSwalButtons = templateContent => { 2148 const result = {}; 2149 toArray(templateContent.querySelectorAll('swal-button')).forEach(button => { 2150 showWarningsForAttributes(button, ['type', 'color', 'aria-label']); 2151 const type = button.getAttribute('type'); 2152 result["".concat(type, "ButtonText")] = button.innerHTML; 2153 result["show".concat(capitalizeFirstLetter(type), "Button")] = true; 2154 2155 if (button.hasAttribute('color')) { 2156 result["".concat(type, "ButtonColor")] = button.getAttribute('color'); 2157 } 2158 2159 if (button.hasAttribute('aria-label')) { 2160 result["".concat(type, "ButtonAriaLabel")] = button.getAttribute('aria-label'); 2161 } 2162 }); 2163 return result; 2164 }; 2165 2166 const getSwalImage = templateContent => { 2167 const result = {}; 2168 const image = templateContent.querySelector('swal-image'); 2169 2170 if (image) { 2171 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']); 2172 2173 if (image.hasAttribute('src')) { 2174 result.imageUrl = image.getAttribute('src'); 2175 } 2176 2177 if (image.hasAttribute('width')) { 2178 result.imageWidth = image.getAttribute('width'); 2179 } 2180 2181 if (image.hasAttribute('height')) { 2182 result.imageHeight = image.getAttribute('height'); 2183 } 2184 2185 if (image.hasAttribute('alt')) { 2186 result.imageAlt = image.getAttribute('alt'); 2187 } 2188 } 2189 2190 return result; 2191 }; 2192 2193 const getSwalIcon = templateContent => { 2194 const result = {}; 2195 const icon = templateContent.querySelector('swal-icon'); 2196 2197 if (icon) { 2198 showWarningsForAttributes(icon, ['type', 'color']); 2199 2200 if (icon.hasAttribute('type')) { 2201 result.icon = icon.getAttribute('type'); 2202 } 2203 2204 if (icon.hasAttribute('color')) { 2205 result.iconColor = icon.getAttribute('color'); 2206 } 2207 2208 result.iconHtml = icon.innerHTML; 2209 } 2210 2211 return result; 2212 }; 2213 2214 const getSwalInput = templateContent => { 2215 const result = {}; 2216 const input = templateContent.querySelector('swal-input'); 2217 2218 if (input) { 2219 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']); 2220 result.input = input.getAttribute('type') || 'text'; 2221 2222 if (input.hasAttribute('label')) { 2223 result.inputLabel = input.getAttribute('label'); 2224 } 2225 2226 if (input.hasAttribute('placeholder')) { 2227 result.inputPlaceholder = input.getAttribute('placeholder'); 2228 } 2229 2230 if (input.hasAttribute('value')) { 2231 result.inputValue = input.getAttribute('value'); 2232 } 2233 } 2234 2235 const inputOptions = templateContent.querySelectorAll('swal-input-option'); 2236 2237 if (inputOptions.length) { 2238 result.inputOptions = {}; 2239 toArray(inputOptions).forEach(option => { 2240 showWarningsForAttributes(option, ['value']); 2241 const optionValue = option.getAttribute('value'); 2242 const optionName = option.innerHTML; 2243 result.inputOptions[optionValue] = optionName; 2244 }); 2245 } 2246 2247 return result; 2248 }; 2249 2250 const getSwalStringParams = (templateContent, paramNames) => { 2251 const result = {}; 2252 2253 for (const i in paramNames) { 2254 const paramName = paramNames[i]; 2255 const tag = templateContent.querySelector(paramName); 2256 2257 if (tag) { 2258 showWarningsForAttributes(tag, []); 2259 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim(); 2260 } 2261 } 2262 2263 return result; 2264 }; 2265 2266 const showWarningsForElements = template => { 2267 const allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']); 2268 toArray(template.children).forEach(el => { 2269 const tagName = el.tagName.toLowerCase(); 2270 2271 if (allowedElements.indexOf(tagName) === -1) { 2272 warn("Unrecognized element <".concat(tagName, ">")); 2273 } 2274 }); 2275 }; 2276 2277 const showWarningsForAttributes = (el, allowedAttributes) => { 2278 toArray(el.attributes).forEach(attribute => { 2279 if (allowedAttributes.indexOf(attribute.name) === -1) { 2280 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.')]); 2281 } 2282 }); 2283 }; 2284 2285 const SHOW_CLASS_TIMEOUT = 10; 2286 /** 2287 * Open popup, add necessary classes and styles, fix scrollbar 2288 * 2289 * @param params 2290 */ 2291 2292 const openPopup = params => { 2293 const container = getContainer(); 2294 const popup = getPopup(); 2295 2296 if (typeof params.willOpen === 'function') { 2297 params.willOpen(popup); 2298 } 2299 2300 const bodyStyles = window.getComputedStyle(document.body); 2301 const initialBodyOverflow = bodyStyles.overflowY; 2302 addClasses$1(container, popup, params); // scrolling is 'hidden' until animation is done, after that 'auto' 2303 2304 setTimeout(() => { 2305 setScrollingVisibility(container, popup); 2306 }, SHOW_CLASS_TIMEOUT); 2307 2308 if (isModal()) { 2309 fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow); 2310 setAriaHidden(); 2311 } 2312 2313 if (!isToast() && !globalState.previousActiveElement) { 2314 globalState.previousActiveElement = document.activeElement; 2315 } 2316 2317 if (typeof params.didOpen === 'function') { 2318 setTimeout(() => params.didOpen(popup)); 2319 } 2320 2321 removeClass(container, swalClasses['no-transition']); 2322 }; 2323 2324 const swalOpenAnimationFinished = event => { 2325 const popup = getPopup(); 2326 2327 if (event.target !== popup) { 2328 return; 2329 } 2330 2331 const container = getContainer(); 2332 popup.removeEventListener(animationEndEvent, swalOpenAnimationFinished); 2333 container.style.overflowY = 'auto'; 2334 }; 2335 2336 const setScrollingVisibility = (container, popup) => { 2337 if (animationEndEvent && hasCssAnimation(popup)) { 2338 container.style.overflowY = 'hidden'; 2339 popup.addEventListener(animationEndEvent, swalOpenAnimationFinished); 2340 } else { 2341 container.style.overflowY = 'auto'; 2342 } 2343 }; 2344 2345 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => { 2346 iOSfix(); 2347 2348 if (scrollbarPadding && initialBodyOverflow !== 'hidden') { 2349 fixScrollbar(); 2350 } // sweetalert2/issues/1247 2351 2352 2353 setTimeout(() => { 2354 container.scrollTop = 0; 2355 }); 2356 }; 2357 2358 const addClasses$1 = (container, popup, params) => { 2359 addClass(container, params.showClass.backdrop); // the workaround with setting/unsetting opacity is needed for #2019 and 2059 2360 2361 popup.style.setProperty('opacity', '0', 'important'); 2362 show(popup, 'grid'); 2363 setTimeout(() => { 2364 // Animate popup right after showing it 2365 addClass(popup, params.showClass.popup); // and remove the opacity workaround 2366 2367 popup.style.removeProperty('opacity'); 2368 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062 2369 2370 addClass([document.documentElement, document.body], swalClasses.shown); 2371 2372 if (params.heightAuto && params.backdrop && !params.toast) { 2373 addClass([document.documentElement, document.body], swalClasses['height-auto']); 2374 } 2375 }; 2376 2377 const handleInputOptionsAndValue = (instance, params) => { 2378 if (params.input === 'select' || params.input === 'radio') { 2379 handleInputOptions(instance, params); 2380 } else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) { 2381 showLoading(getConfirmButton()); 2382 handleInputValue(instance, params); 2383 } 2384 }; 2385 const getInputValue = (instance, innerParams) => { 2386 const input = instance.getInput(); 2387 2388 if (!input) { 2389 return null; 2390 } 2391 2392 switch (innerParams.input) { 2393 case 'checkbox': 2394 return getCheckboxValue(input); 2395 2396 case 'radio': 2397 return getRadioValue(input); 2398 2399 case 'file': 2400 return getFileValue(input); 2401 2402 default: 2403 return innerParams.inputAutoTrim ? input.value.trim() : input.value; 2404 } 2405 }; 2406 2407 const getCheckboxValue = input => input.checked ? 1 : 0; 2408 2409 const getRadioValue = input => input.checked ? input.value : null; 2410 2411 const getFileValue = input => input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null; 2412 2413 const handleInputOptions = (instance, params) => { 2414 const popup = getPopup(); 2415 2416 const processInputOptions = inputOptions => populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params); 2417 2418 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) { 2419 showLoading(getConfirmButton()); 2420 asPromise(params.inputOptions).then(inputOptions => { 2421 instance.hideLoading(); 2422 processInputOptions(inputOptions); 2423 }); 2424 } else if (typeof params.inputOptions === 'object') { 2425 processInputOptions(params.inputOptions); 2426 } else { 2427 error("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(typeof params.inputOptions)); 2428 } 2429 }; 2430 2431 const handleInputValue = (instance, params) => { 2432 const input = instance.getInput(); 2433 hide(input); 2434 asPromise(params.inputValue).then(inputValue => { 2435 input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : "".concat(inputValue); 2436 show(input); 2437 input.focus(); 2438 instance.hideLoading(); 2439 }).catch(err => { 2440 error("Error in inputValue promise: ".concat(err)); 2441 input.value = ''; 2442 show(input); 2443 input.focus(); 2444 instance.hideLoading(); 2445 }); 2446 }; 2447 2448 const populateInputOptions = { 2449 select: (popup, inputOptions, params) => { 2450 const select = getChildByClass(popup, swalClasses.select); 2451 2452 const renderOption = (parent, optionLabel, optionValue) => { 2453 const option = document.createElement('option'); 2454 option.value = optionValue; 2455 setInnerHtml(option, optionLabel); 2456 option.selected = isSelected(optionValue, params.inputValue); 2457 parent.appendChild(option); 2458 }; 2459 2460 inputOptions.forEach(inputOption => { 2461 const optionValue = inputOption[0]; 2462 const optionLabel = inputOption[1]; // <optgroup> spec: 2463 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6 2464 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..." 2465 // check whether this is a <optgroup> 2466 2467 if (Array.isArray(optionLabel)) { 2468 // if it is an array, then it is an <optgroup> 2469 const optgroup = document.createElement('optgroup'); 2470 optgroup.label = optionValue; 2471 optgroup.disabled = false; // not configurable for now 2472 2473 select.appendChild(optgroup); 2474 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0])); 2475 } else { 2476 // case of <option> 2477 renderOption(select, optionLabel, optionValue); 2478 } 2479 }); 2480 select.focus(); 2481 }, 2482 radio: (popup, inputOptions, params) => { 2483 const radio = getChildByClass(popup, swalClasses.radio); 2484 inputOptions.forEach(inputOption => { 2485 const radioValue = inputOption[0]; 2486 const radioLabel = inputOption[1]; 2487 const radioInput = document.createElement('input'); 2488 const radioLabelElement = document.createElement('label'); 2489 radioInput.type = 'radio'; 2490 radioInput.name = swalClasses.radio; 2491 radioInput.value = radioValue; 2492 2493 if (isSelected(radioValue, params.inputValue)) { 2494 radioInput.checked = true; 2495 } 2496 2497 const label = document.createElement('span'); 2498 setInnerHtml(label, radioLabel); 2499 label.className = swalClasses.label; 2500 radioLabelElement.appendChild(radioInput); 2501 radioLabelElement.appendChild(label); 2502 radio.appendChild(radioLabelElement); 2503 }); 2504 const radios = radio.querySelectorAll('input'); 2505 2506 if (radios.length) { 2507 radios[0].focus(); 2508 } 2509 } 2510 }; 2511 /** 2512 * Converts `inputOptions` into an array of `[value, label]`s 2513 * @param inputOptions 2514 */ 2515 2516 const formatInputOptions = inputOptions => { 2517 const result = []; 2518 2519 if (typeof Map !== 'undefined' && inputOptions instanceof Map) { 2520 inputOptions.forEach((value, key) => { 2521 let valueFormatted = value; 2522 2523 if (typeof valueFormatted === 'object') { 2524 // case of <optgroup> 2525 valueFormatted = formatInputOptions(valueFormatted); 2526 } 2527 2528 result.push([key, valueFormatted]); 2529 }); 2530 } else { 2531 Object.keys(inputOptions).forEach(key => { 2532 let valueFormatted = inputOptions[key]; 2533 2534 if (typeof valueFormatted === 'object') { 2535 // case of <optgroup> 2536 valueFormatted = formatInputOptions(valueFormatted); 2537 } 2538 2539 result.push([key, valueFormatted]); 2540 }); 2541 } 2542 2543 return result; 2544 }; 2545 2546 const isSelected = (optionValue, inputValue) => { 2547 return inputValue && inputValue.toString() === optionValue.toString(); 2548 }; 2549 2550 const handleConfirmButtonClick = instance => { 2551 const innerParams = privateProps.innerParams.get(instance); 2552 instance.disableButtons(); 2553 2554 if (innerParams.input) { 2555 handleConfirmOrDenyWithInput(instance, 'confirm'); 2556 } else { 2557 confirm(instance, true); 2558 } 2559 }; 2560 const handleDenyButtonClick = instance => { 2561 const innerParams = privateProps.innerParams.get(instance); 2562 instance.disableButtons(); 2563 2564 if (innerParams.returnInputValueOnDeny) { 2565 handleConfirmOrDenyWithInput(instance, 'deny'); 2566 } else { 2567 deny(instance, false); 2568 } 2569 }; 2570 const handleCancelButtonClick = (instance, dismissWith) => { 2571 instance.disableButtons(); 2572 dismissWith(DismissReason.cancel); 2573 }; 2574 2575 const handleConfirmOrDenyWithInput = (instance, type 2576 /* 'confirm' | 'deny' */ 2577 ) => { 2578 const innerParams = privateProps.innerParams.get(instance); 2579 const inputValue = getInputValue(instance, innerParams); 2580 2581 if (innerParams.inputValidator) { 2582 handleInputValidator(instance, inputValue, type); 2583 } else if (!instance.getInput().checkValidity()) { 2584 instance.enableButtons(); 2585 instance.showValidationMessage(innerParams.validationMessage); 2586 } else if (type === 'deny') { 2587 deny(instance, inputValue); 2588 } else { 2589 confirm(instance, inputValue); 2590 } 2591 }; 2592 2593 const handleInputValidator = (instance, inputValue, type 2594 /* 'confirm' | 'deny' */ 2595 ) => { 2596 const innerParams = privateProps.innerParams.get(instance); 2597 instance.disableInput(); 2598 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage))); 2599 validationPromise.then(validationMessage => { 2600 instance.enableButtons(); 2601 instance.enableInput(); 2602 2603 if (validationMessage) { 2604 instance.showValidationMessage(validationMessage); 2605 } else if (type === 'deny') { 2606 deny(instance, inputValue); 2607 } else { 2608 confirm(instance, inputValue); 2609 } 2610 }); 2611 }; 2612 2613 const deny = (instance, value) => { 2614 const innerParams = privateProps.innerParams.get(instance || undefined); 2615 2616 if (innerParams.showLoaderOnDeny) { 2617 showLoading(getDenyButton()); 2618 } 2619 2620 if (innerParams.preDeny) { 2621 privateProps.awaitingPromise.set(instance || undefined, true); // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesnt get destroyed until the result from this preDeny's promise is received 2622 2623 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage))); 2624 preDenyPromise.then(preDenyValue => { 2625 if (preDenyValue === false) { 2626 instance.hideLoading(); 2627 } else { 2628 instance.closePopup({ 2629 isDenied: true, 2630 value: typeof preDenyValue === 'undefined' ? value : preDenyValue 2631 }); 2632 } 2633 }).catch(error$$1 => rejectWith(instance || undefined, error$$1)); 2634 } else { 2635 instance.closePopup({ 2636 isDenied: true, 2637 value 2638 }); 2639 } 2640 }; 2641 2642 const succeedWith = (instance, value) => { 2643 instance.closePopup({ 2644 isConfirmed: true, 2645 value 2646 }); 2647 }; 2648 2649 const rejectWith = (instance, error$$1) => { 2650 instance.rejectPromise(error$$1); 2651 }; 2652 2653 const confirm = (instance, value) => { 2654 const innerParams = privateProps.innerParams.get(instance || undefined); 2655 2656 if (innerParams.showLoaderOnConfirm) { 2657 showLoading(); 2658 } 2659 2660 if (innerParams.preConfirm) { 2661 instance.resetValidationMessage(); 2662 privateProps.awaitingPromise.set(instance || undefined, true); // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesnt get destroyed until the result from this preConfirm's promise is received 2663 2664 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage))); 2665 preConfirmPromise.then(preConfirmValue => { 2666 if (isVisible(getValidationMessage()) || preConfirmValue === false) { 2667 instance.hideLoading(); 2668 } else { 2669 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue); 2670 } 2671 }).catch(error$$1 => rejectWith(instance || undefined, error$$1)); 2672 } else { 2673 succeedWith(instance, value); 2674 } 2675 }; 2676 2677 const addKeydownHandler = (instance, globalState, innerParams, dismissWith) => { 2678 if (globalState.keydownTarget && globalState.keydownHandlerAdded) { 2679 globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, { 2680 capture: globalState.keydownListenerCapture 2681 }); 2682 globalState.keydownHandlerAdded = false; 2683 } 2684 2685 if (!innerParams.toast) { 2686 globalState.keydownHandler = e => keydownHandler(instance, e, dismissWith); 2687 2688 globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup(); 2689 globalState.keydownListenerCapture = innerParams.keydownListenerCapture; 2690 globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, { 2691 capture: globalState.keydownListenerCapture 2692 }); 2693 globalState.keydownHandlerAdded = true; 2694 } 2695 }; // Focus handling 2696 2697 const setFocus = (innerParams, index, increment) => { 2698 const focusableElements = getFocusableElements(); // search for visible elements and select the next possible match 2699 2700 if (focusableElements.length) { 2701 index = index + increment; // rollover to first item 2702 2703 if (index === focusableElements.length) { 2704 index = 0; // go to last item 2705 } else if (index === -1) { 2706 index = focusableElements.length - 1; 2707 } 2708 2709 return focusableElements[index].focus(); 2710 } // no visible focusable elements, focus the popup 2711 2712 2713 getPopup().focus(); 2714 }; 2715 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown']; 2716 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp']; 2717 2718 const keydownHandler = (instance, e, dismissWith) => { 2719 const innerParams = privateProps.innerParams.get(instance); 2720 2721 if (!innerParams) { 2722 return; // This instance has already been destroyed 2723 } 2724 2725 if (innerParams.stopKeydownPropagation) { 2726 e.stopPropagation(); 2727 } // ENTER 2728 2729 2730 if (e.key === 'Enter') { 2731 handleEnter(instance, e, innerParams); // TAB 2732 } else if (e.key === 'Tab') { 2733 handleTab(e, innerParams); // ARROWS - switch focus between buttons 2734 } else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(e.key)) { 2735 handleArrows(e.key); // ESC 2736 } else if (e.key === 'Escape') { 2737 handleEsc(e, innerParams, dismissWith); 2738 } 2739 }; 2740 2741 const handleEnter = (instance, e, innerParams) => { 2742 // #720 #721 2743 if (e.isComposing) { 2744 return; 2745 } 2746 2747 if (e.target && instance.getInput() && e.target.outerHTML === instance.getInput().outerHTML) { 2748 if (['textarea', 'file'].includes(innerParams.input)) { 2749 return; // do not submit 2750 } 2751 2752 clickConfirm(); 2753 e.preventDefault(); 2754 } 2755 }; 2756 2757 const handleTab = (e, innerParams) => { 2758 const targetElement = e.target; 2759 const focusableElements = getFocusableElements(); 2760 let btnIndex = -1; 2761 2762 for (let i = 0; i < focusableElements.length; i++) { 2763 if (targetElement === focusableElements[i]) { 2764 btnIndex = i; 2765 break; 2766 } 2767 } 2768 2769 if (!e.shiftKey) { 2770 // Cycle to the next button 2771 setFocus(innerParams, btnIndex, 1); 2772 } else { 2773 // Cycle to the prev button 2774 setFocus(innerParams, btnIndex, -1); 2775 } 2776 2777 e.stopPropagation(); 2778 e.preventDefault(); 2779 }; 2780 2781 const handleArrows = key => { 2782 const confirmButton = getConfirmButton(); 2783 const denyButton = getDenyButton(); 2784 const cancelButton = getCancelButton(); 2785 2786 if (![confirmButton, denyButton, cancelButton].includes(document.activeElement)) { 2787 return; 2788 } 2789 2790 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling'; 2791 const buttonToFocus = document.activeElement[sibling]; 2792 2793 if (buttonToFocus) { 2794 buttonToFocus.focus(); 2795 } 2796 }; 2797 2798 const handleEsc = (e, innerParams, dismissWith) => { 2799 if (callIfFunction(innerParams.allowEscapeKey)) { 2800 e.preventDefault(); 2801 dismissWith(DismissReason.esc); 2802 } 2803 }; 2804 2805 const handlePopupClick = (instance, domCache, dismissWith) => { 2806 const innerParams = privateProps.innerParams.get(instance); 2807 2808 if (innerParams.toast) { 2809 handleToastClick(instance, domCache, dismissWith); 2810 } else { 2811 // Ignore click events that had mousedown on the popup but mouseup on the container 2812 // This can happen when the user drags a slider 2813 handleModalMousedown(domCache); // Ignore click events that had mousedown on the container but mouseup on the popup 2814 2815 handleContainerMousedown(domCache); 2816 handleModalClick(instance, domCache, dismissWith); 2817 } 2818 }; 2819 2820 const handleToastClick = (instance, domCache, dismissWith) => { 2821 // Closing toast by internal click 2822 domCache.popup.onclick = () => { 2823 const innerParams = privateProps.innerParams.get(instance); 2824 2825 if (innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton || innerParams.timer || innerParams.input) { 2826 return; 2827 } 2828 2829 dismissWith(DismissReason.close); 2830 }; 2831 }; 2832 2833 let ignoreOutsideClick = false; 2834 2835 const handleModalMousedown = domCache => { 2836 domCache.popup.onmousedown = () => { 2837 domCache.container.onmouseup = function (e) { 2838 domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't 2839 // have any other direct children aside of the popup 2840 2841 if (e.target === domCache.container) { 2842 ignoreOutsideClick = true; 2843 } 2844 }; 2845 }; 2846 }; 2847 2848 const handleContainerMousedown = domCache => { 2849 domCache.container.onmousedown = () => { 2850 domCache.popup.onmouseup = function (e) { 2851 domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup 2852 2853 if (e.target === domCache.popup || domCache.popup.contains(e.target)) { 2854 ignoreOutsideClick = true; 2855 } 2856 }; 2857 }; 2858 }; 2859 2860 const handleModalClick = (instance, domCache, dismissWith) => { 2861 domCache.container.onclick = e => { 2862 const innerParams = privateProps.innerParams.get(instance); 2863 2864 if (ignoreOutsideClick) { 2865 ignoreOutsideClick = false; 2866 return; 2867 } 2868 2869 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) { 2870 dismissWith(DismissReason.backdrop); 2871 } 2872 }; 2873 }; 2874 2875 function _main(userParams) { 2876 let mixinParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2877 showWarningsForParams(Object.assign({}, mixinParams, userParams)); 2878 2879 if (globalState.currentInstance) { 2880 globalState.currentInstance._destroy(); 2881 2882 if (isModal()) { 2883 unsetAriaHidden(); 2884 } 2885 } 2886 2887 globalState.currentInstance = this; 2888 const innerParams = prepareParams(userParams, mixinParams); 2889 setParameters(innerParams); 2890 Object.freeze(innerParams); // clear the previous timer 2891 2892 if (globalState.timeout) { 2893 globalState.timeout.stop(); 2894 delete globalState.timeout; 2895 } // clear the restore focus timeout 2896 2897 2898 clearTimeout(globalState.restoreFocusTimeout); 2899 const domCache = populateDomCache(this); 2900 render(this, innerParams); 2901 privateProps.innerParams.set(this, innerParams); 2902 return swalPromise(this, domCache, innerParams); 2903 } 2904 2905 const prepareParams = (userParams, mixinParams) => { 2906 const templateParams = getTemplateParams(userParams); 2907 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131 2908 2909 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass); 2910 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass); 2911 return params; 2912 }; 2913 2914 const swalPromise = (instance, domCache, innerParams) => { 2915 return new Promise((resolve, reject) => { 2916 // functions to handle all closings/dismissals 2917 const dismissWith = dismiss => { 2918 instance.closePopup({ 2919 isDismissed: true, 2920 dismiss 2921 }); 2922 }; 2923 2924 privateMethods.swalPromiseResolve.set(instance, resolve); 2925 privateMethods.swalPromiseReject.set(instance, reject); 2926 2927 domCache.confirmButton.onclick = () => handleConfirmButtonClick(instance); 2928 2929 domCache.denyButton.onclick = () => handleDenyButtonClick(instance); 2930 2931 domCache.cancelButton.onclick = () => handleCancelButtonClick(instance, dismissWith); 2932 2933 domCache.closeButton.onclick = () => dismissWith(DismissReason.close); 2934 2935 handlePopupClick(instance, domCache, dismissWith); 2936 addKeydownHandler(instance, globalState, innerParams, dismissWith); 2937 handleInputOptionsAndValue(instance, innerParams); 2938 openPopup(innerParams); 2939 setupTimer(globalState, innerParams, dismissWith); 2940 initFocus(domCache, innerParams); // Scroll container to top on open (#1247, #1946) 2941 2942 setTimeout(() => { 2943 domCache.container.scrollTop = 0; 2944 }); 2945 }); 2946 }; 2947 2948 const populateDomCache = instance => { 2949 const domCache = { 2950 popup: getPopup(), 2951 container: getContainer(), 2952 actions: getActions(), 2953 confirmButton: getConfirmButton(), 2954 denyButton: getDenyButton(), 2955 cancelButton: getCancelButton(), 2956 loader: getLoader(), 2957 closeButton: getCloseButton(), 2958 validationMessage: getValidationMessage(), 2959 progressSteps: getProgressSteps() 2960 }; 2961 privateProps.domCache.set(instance, domCache); 2962 return domCache; 2963 }; 2964 2965 const setupTimer = (globalState$$1, innerParams, dismissWith) => { 2966 const timerProgressBar = getTimerProgressBar(); 2967 hide(timerProgressBar); 2968 2969 if (innerParams.timer) { 2970 globalState$$1.timeout = new Timer(() => { 2971 dismissWith('timer'); 2972 delete globalState$$1.timeout; 2973 }, innerParams.timer); 2974 2975 if (innerParams.timerProgressBar) { 2976 show(timerProgressBar); 2977 setTimeout(() => { 2978 if (globalState$$1.timeout && globalState$$1.timeout.running) { 2979 // timer can be already stopped or unset at this point 2980 animateTimerProgressBar(innerParams.timer); 2981 } 2982 }); 2983 } 2984 } 2985 }; 2986 2987 const initFocus = (domCache, innerParams) => { 2988 if (innerParams.toast) { 2989 return; 2990 } 2991 2992 if (!callIfFunction(innerParams.allowEnterKey)) { 2993 return blurActiveElement(); 2994 } 2995 2996 if (!focusButton(domCache, innerParams)) { 2997 setFocus(innerParams, -1, 1); 2998 } 2999 }; 3000 3001 const focusButton = (domCache, innerParams) => { 3002 if (innerParams.focusDeny && isVisible(domCache.denyButton)) { 3003 domCache.denyButton.focus(); 3004 return true; 3005 } 3006 3007 if (innerParams.focusCancel && isVisible(domCache.cancelButton)) { 3008 domCache.cancelButton.focus(); 3009 return true; 3010 } 3011 3012 if (innerParams.focusConfirm && isVisible(domCache.confirmButton)) { 3013 domCache.confirmButton.focus(); 3014 return true; 3015 } 3016 3017 return false; 3018 }; 3019 3020 const blurActiveElement = () => { 3021 if (document.activeElement && typeof document.activeElement.blur === 'function') { 3022 document.activeElement.blur(); 3023 } 3024 }; 3025 3026 /** 3027 * Updates popup parameters. 3028 */ 3029 3030 function update(params) { 3031 const popup = getPopup(); 3032 const innerParams = privateProps.innerParams.get(this); 3033 3034 if (!popup || hasClass(popup, innerParams.hideClass.popup)) { 3035 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."); 3036 } 3037 3038 const validUpdatableParams = {}; // assign valid params from `params` to `defaults` 3039 3040 Object.keys(params).forEach(param => { 3041 if (Swal.isUpdatableParameter(param)) { 3042 validUpdatableParams[param] = params[param]; 3043 } else { 3044 warn("Invalid parameter to update: \"".concat(param, "\". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md")); 3045 } 3046 }); 3047 const updatedParams = Object.assign({}, innerParams, validUpdatableParams); 3048 render(this, updatedParams); 3049 privateProps.innerParams.set(this, updatedParams); 3050 Object.defineProperties(this, { 3051 params: { 3052 value: Object.assign({}, this.params, params), 3053 writable: false, 3054 enumerable: true 3055 } 3056 }); 3057 } 3058 3059 function _destroy() { 3060 const domCache = privateProps.domCache.get(this); 3061 const innerParams = privateProps.innerParams.get(this); 3062 3063 if (!innerParams) { 3064 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining weakmaps #2335 3065 3066 return; // This instance has already been destroyed 3067 } // Check if there is another Swal closing 3068 3069 3070 if (domCache.popup && globalState.swalCloseEventFinishedCallback) { 3071 globalState.swalCloseEventFinishedCallback(); 3072 delete globalState.swalCloseEventFinishedCallback; 3073 } // Check if there is a swal disposal defer timer 3074 3075 3076 if (globalState.deferDisposalTimer) { 3077 clearTimeout(globalState.deferDisposalTimer); 3078 delete globalState.deferDisposalTimer; 3079 } 3080 3081 if (typeof innerParams.didDestroy === 'function') { 3082 innerParams.didDestroy(); 3083 } 3084 3085 disposeSwal(this); 3086 } 3087 3088 const disposeSwal = instance => { 3089 disposeWeakMaps(instance); // Unset this.params so GC will dispose it (#1569) 3090 3091 delete instance.params; // Unset globalState props so GC will dispose globalState (#1569) 3092 3093 delete globalState.keydownHandler; 3094 delete globalState.keydownTarget; // Unset currentInstance 3095 3096 delete globalState.currentInstance; 3097 }; 3098 3099 const disposeWeakMaps = instance => { 3100 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335 3101 if (instance.isAwaitingPromise()) { 3102 unsetWeakMaps(privateProps, instance); 3103 privateProps.awaitingPromise.set(instance, true); 3104 } else { 3105 unsetWeakMaps(privateMethods, instance); 3106 unsetWeakMaps(privateProps, instance); 3107 } 3108 }; 3109 3110 const unsetWeakMaps = (obj, instance) => { 3111 for (const i in obj) { 3112 obj[i].delete(instance); 3113 } 3114 }; 3115 3116 3117 3118 var instanceMethods = /*#__PURE__*/Object.freeze({ 3119 hideLoading: hideLoading, 3120 disableLoading: hideLoading, 3121 getInput: getInput$1, 3122 close: close, 3123 isAwaitingPromise: isAwaitingPromise, 3124 rejectPromise: rejectPromise, 3125 closePopup: close, 3126 closeModal: close, 3127 closeToast: close, 3128 enableButtons: enableButtons, 3129 disableButtons: disableButtons, 3130 enableInput: enableInput, 3131 disableInput: disableInput, 3132 showValidationMessage: showValidationMessage, 3133 resetValidationMessage: resetValidationMessage$1, 3134 getProgressSteps: getProgressSteps$1, 3135 _main: _main, 3136 update: update, 3137 _destroy: _destroy 3138 }); 3139 3140 let currentInstance; 3141 3142 class SweetAlert { 3143 constructor() { 3144 // Prevent run in Node env 3145 if (typeof window === 'undefined') { 3146 return; 3147 } 3148 3149 currentInstance = this; 3150 3151 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3152 args[_key] = arguments[_key]; 3153 } 3154 3155 const outerParams = Object.freeze(this.constructor.argsToParams(args)); 3156 Object.defineProperties(this, { 3157 params: { 3158 value: outerParams, 3159 writable: false, 3160 enumerable: true, 3161 configurable: true 3162 } 3163 }); 3164 3165 const promise = this._main(this.params); 3166 3167 privateProps.promise.set(this, promise); 3168 } // `catch` cannot be the name of a module export, so we define our thenable methods here instead 3169 3170 3171 then(onFulfilled) { 3172 const promise = privateProps.promise.get(this); 3173 return promise.then(onFulfilled); 3174 } 3175 3176 finally(onFinally) { 3177 const promise = privateProps.promise.get(this); 3178 return promise.finally(onFinally); 3179 } 3180 3181 } // Assign instance methods from src/instanceMethods/*.js to prototype 3182 3183 3184 Object.assign(SweetAlert.prototype, instanceMethods); // Assign static methods from src/staticMethods/*.js to constructor 3185 3186 Object.assign(SweetAlert, staticMethods); // Proxy to instance methods to constructor, for now, for backwards compatibility 3187 3188 Object.keys(instanceMethods).forEach(key => { 3189 SweetAlert[key] = function () { 3190 if (currentInstance) { 3191 return currentInstance[key](...arguments); 3192 } 3193 }; 3194 }); 3195 SweetAlert.DismissReason = DismissReason; 3196 SweetAlert.version = '11.2.1'; 3197 3198 const Swal = SweetAlert; 3199 Swal.default = Swal; 3200 3201 return Swal; 3202 3203})); 3204if (typeof this !== 'undefined' && this.Sweetalert2){ this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2} 3205 3206"undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,"
vendor: 3,890 bytes, line 3206
3206.swal2-popup.swal2-toast{box-sizing:border-box;grid-column:1/4!important;grid-row:1/4!important;grid-template-columns:1fr 99fr 1fr;padding:1em;overflow-y:hidden;background:#fff;box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-popup.swal2-toast>*{grid-column:2}.swal2-popup.swal2-toast .swal2-title{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.5em;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-popup.swal2-toast .swal2-html-container{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-popup.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:700}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-popup.swal2-toast .swal2-styled{margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.8em;left:-.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-toast-animate-success-line-tip .75s;animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-toast-animate-success-line-long .75s;animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{-webkit-animation:swal2-toast-show .5s;animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{-webkit-animation:swal2-toast-hide .1s forwards;animation:swal2-toast-hide .1s forwards}.swal2-container{display:grid;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;box-sizing:border-box;grid-template-areas:
3206\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto);grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);height:100%;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:0 0!important}.swal2-container.swal2-bottom-start,.swal2-container.swal2-center-start,.swal2-container.swal2-top-start{grid-template-columns:minmax(0,1fr) auto auto}.swal2-container.swal2-bottom,.swal2-container.swal2-center,.swal2-container.swal2-top{grid-template-columns:auto minmax(0,1fr) auto}.swal2-container.swal2-bottom-end,.swal2-container.swal2-center-end,.swal2-container.swal2-top-end{grid-template-columns:auto auto minmax(0,1fr)}.swal2-container.swal2-top-start>.swal2-popup{align-self:start}.swal2-container.swal2-top>.swal2-popup{grid-column:2;align-self:start;justify-self:center}.swal2-container.swal2-top-end>.swal2-popup,.swal2-container.swal2-top-right>.swal2-popup{grid-column:3;align-self:start;justify-self:end}.swal2-container.swal2-center-left>.swal2-popup,.swal2-container.swal2-center-start>.swal2-popup{grid-row:2;align-self:center}.swal2-container.swal2-center>.swal2-popup{grid-column:2;grid-row:2;align-self:center;justify-self:center}.swal2-container.swal2-center-end>.swal2-popup,.swal2-container.swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;align-self:center;justify-self:end}.swal2-container.swal2-bottom-left>.swal2-popup,.swal2-container.swal2-bottom-start>.swal2-popup{grid-column:1;grid-row:3;align-self:end}.swal2-container.swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;justify-self:center;align-self:end}.swal2-container.swal2-bottom-end>.swal2-popup,.swal2-container.swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;align-self:end;justify-self:end}.swal2-container.swal2-grow-fullscreen>.swal2-popup,.swal2-container.swal2-grow-row>.swal2-popup{grid-column:1/4;width:100%}.swal2-container.swal2-grow-column>.swal2-popup,.swal2-container.swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}.swal2-container.swal2-no-transition{transition:none!important}.swal2-popup{display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0,100%);width:32em;max-width:100%;padding:0 0 1.25em;border:none;border-radius:5px;background:#fff;color:#545454;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-title{position:relative;max-width:100%;margin:0;padding:.8em 1em 0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px transparent;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}.swal2-styled.swal2-confirm:focus{box-shadow:0 0 0 3px rgba(112,102,224,.5)}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}.swal2-styled.swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}.swal2-styled.swal2-cancel:focus{box-shadow:0 0 0 3px rgba(110,120,129,.5)}.swal2-styled.swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled:focus{outline:0}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1em 0 0;padding:1em 1em 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto!important;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:2em auto 1em}.swal2-close{z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:color .1s,box-shadow .1s;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-family:monospace;font-size:2.5em;cursor:pointer;justify-self:end}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-html-container{z-index:1;justify-content:center;margin:1em 1.6em .3em;padding:0;overflow:auto;color:#545454;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em 2em 0}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file:-ms-input-placeholder,.swal2-input:-ms-input-placeholder,.swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em 2em 0;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-file{width:75%;margin-right:auto;margin-left:auto;background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{flex-shrink:0;margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto 0}.swal2-validation-message{align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:\"!\
vendor: 12,405 bytes, line 3206
3206";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-warning.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-warning.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .5s;animation:swal2-animate-i-mark .5s}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-info.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-info.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-i-mark .8s;animation:swal2-animate-i-mark .8s}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-question.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-question.swal2-icon-show .swal2-icon-content{-webkit-animation:swal2-animate-question-mark .8s;animation:swal2-animate-question-mark .8s}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-webkit-keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@-webkit-keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{background-color:transparent!important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:transparent;pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}
3206");
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.