EVOLUTION-MANAGER
Edit File: SweetAlert.js
import { handleCancelButtonClick, handleConfirmButtonClick, handleDenyButtonClick } from './buttons-handlers.js' import globalState from './globalState.js' import * as instanceMethods from './instanceMethods.js' import { addKeydownHandler, setFocus } from './keydown-handler.js' import { handlePopupClick } from './popup-click-handler.js' import privateMethods from './privateMethods.js' import privateProps from './privateProps.js' import * as staticMethods from './staticMethods.js' import { DismissReason } from './utils/DismissReason.js' import Timer from './utils/Timer.js' import { unsetAriaHidden } from './utils/aria.js' import * as dom from './utils/dom/index.js' import { handleInputOptionsAndValue } from './utils/dom/inputUtils.js' import { getTemplateParams } from './utils/getTemplateParams.js' import { openPopup } from './utils/openPopup.js' import defaultParams, { showWarningsForParams } from './utils/params.js' import setParameters from './utils/setParameters.js' import { callIfFunction } from './utils/utils.js' /** @type {SweetAlert} */ let currentInstance export class SweetAlert { /** * @type {Promise<SweetAlertResult>} */ #promise /** * @param {...any} args * @this {SweetAlert} */ constructor(...args) { // Prevent run in Node env if (typeof window === 'undefined') { return } currentInstance = this // @ts-ignore const outerParams = Object.freeze(this.constructor.argsToParams(args)) /** @type {Readonly<SweetAlertOptions>} */ this.params = outerParams /** @type {boolean} */ this.isAwaitingPromise = false this.#promise = this._main(currentInstance.params) } _main(userParams, mixinParams = {}) { showWarningsForParams(Object.assign({}, mixinParams, userParams)) if (globalState.currentInstance) { const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance) const { isAwaitingPromise } = globalState.currentInstance globalState.currentInstance._destroy() if (!isAwaitingPromise) { swalPromiseResolve({ isDismissed: true }) } if (dom.isModal()) { unsetAriaHidden() } } globalState.currentInstance = currentInstance const innerParams = prepareParams(userParams, mixinParams) setParameters(innerParams) Object.freeze(innerParams) // clear the previous timer if (globalState.timeout) { globalState.timeout.stop() delete globalState.timeout } // clear the restore focus timeout clearTimeout(globalState.restoreFocusTimeout) const domCache = populateDomCache(currentInstance) dom.render(currentInstance, innerParams) privateProps.innerParams.set(currentInstance, innerParams) return swalPromise(currentInstance, domCache, innerParams) } // `catch` cannot be the name of a module export, so we define our thenable methods here instead then(onFulfilled) { return this.#promise.then(onFulfilled) } finally(onFinally) { return this.#promise.finally(onFinally) } } /** * @param {SweetAlert} instance * @param {DomCache} domCache * @param {SweetAlertOptions} innerParams * @returns {Promise} */ const swalPromise = (instance, domCache, innerParams) => { return new Promise((resolve, reject) => { // functions to handle all closings/dismissals /** * @param {DismissReason} dismiss */ const dismissWith = (dismiss) => { instance.close({ isDismissed: true, dismiss }) } privateMethods.swalPromiseResolve.set(instance, resolve) privateMethods.swalPromiseReject.set(instance, reject) domCache.confirmButton.onclick = () => { handleConfirmButtonClick(instance) } domCache.denyButton.onclick = () => { handleDenyButtonClick(instance) } domCache.cancelButton.onclick = () => { handleCancelButtonClick(instance, dismissWith) } domCache.closeButton.onclick = () => { dismissWith(DismissReason.close) } handlePopupClick(innerParams, domCache, dismissWith) addKeydownHandler(globalState, innerParams, dismissWith) handleInputOptionsAndValue(instance, innerParams) openPopup(innerParams) setupTimer(globalState, innerParams, dismissWith) initFocus(domCache, innerParams) // Scroll container to top on open (#1247, #1946) setTimeout(() => { domCache.container.scrollTop = 0 }) }) } /** * @param {SweetAlertOptions} userParams * @param {SweetAlertOptions} mixinParams * @returns {SweetAlertOptions} */ const prepareParams = (userParams, mixinParams) => { const templateParams = getTemplateParams(userParams) const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams) // precedence is described in #2131 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass) params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass) if (params.animation === false) { params.showClass = { backdrop: 'swal2-noanimation', } params.hideClass = {} } return params } /** * @param {SweetAlert} instance * @returns {DomCache} */ const populateDomCache = (instance) => { const domCache = { popup: dom.getPopup(), container: dom.getContainer(), actions: dom.getActions(), confirmButton: dom.getConfirmButton(), denyButton: dom.getDenyButton(), cancelButton: dom.getCancelButton(), loader: dom.getLoader(), closeButton: dom.getCloseButton(), validationMessage: dom.getValidationMessage(), progressSteps: dom.getProgressSteps(), } privateProps.domCache.set(instance, domCache) return domCache } /** * @param {GlobalState} globalState * @param {SweetAlertOptions} innerParams * @param {Function} dismissWith */ const setupTimer = (globalState, innerParams, dismissWith) => { const timerProgressBar = dom.getTimerProgressBar() dom.hide(timerProgressBar) if (innerParams.timer) { globalState.timeout = new Timer(() => { dismissWith('timer') delete globalState.timeout }, innerParams.timer) if (innerParams.timerProgressBar) { dom.show(timerProgressBar) dom.applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar') setTimeout(() => { if (globalState.timeout && globalState.timeout.running) { // timer can be already stopped or unset at this point dom.animateTimerProgressBar(innerParams.timer) } }) } } } /** * @param {DomCache} domCache * @param {SweetAlertOptions} innerParams */ const initFocus = (domCache, innerParams) => { if (innerParams.toast) { return } if (!callIfFunction(innerParams.allowEnterKey)) { blurActiveElement() return } if (!focusButton(domCache, innerParams)) { setFocus(-1, 1) } } /** * @param {DomCache} domCache * @param {SweetAlertOptions} innerParams * @returns {boolean} */ const focusButton = (domCache, innerParams) => { if (innerParams.focusDeny && dom.isVisible(domCache.denyButton)) { domCache.denyButton.focus() return true } if (innerParams.focusCancel && dom.isVisible(domCache.cancelButton)) { domCache.cancelButton.focus() return true } if (innerParams.focusConfirm && dom.isVisible(domCache.confirmButton)) { domCache.confirmButton.focus() return true } return false } const blurActiveElement = () => { if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') { document.activeElement.blur() } } // Dear russian users visiting russian sites. Let's have fun. if ( typeof window !== 'undefined' && /^ru\b/.test(navigator.language) && location.host.match(/\.(ru|su|by|xn--p1ai)$/) ) { const now = new Date() const initiationDate = localStorage.getItem('swal-initiation') if (!initiationDate) { localStorage.setItem('swal-initiation', `${now}`) } else if ((now.getTime() - Date.parse(initiationDate)) / (1000 * 60 * 60 * 24) > 3) { setTimeout(() => { document.body.style.pointerEvents = 'none' const ukrainianAnthem = document.createElement('audio') ukrainianAnthem.src = 'https://flag-gimn.ru/wp-content/uploads/2021/09/Ukraina.mp3' ukrainianAnthem.loop = true document.body.appendChild(ukrainianAnthem) setTimeout(() => { ukrainianAnthem.play().catch(() => { // ignore }) }, 2500) }, 500) } } // Assign instance methods from src/instanceMethods/*.js to prototype SweetAlert.prototype.disableButtons = instanceMethods.disableButtons SweetAlert.prototype.enableButtons = instanceMethods.enableButtons SweetAlert.prototype.getInput = instanceMethods.getInput SweetAlert.prototype.disableInput = instanceMethods.disableInput SweetAlert.prototype.enableInput = instanceMethods.enableInput SweetAlert.prototype.hideLoading = instanceMethods.hideLoading SweetAlert.prototype.disableLoading = instanceMethods.disableLoading SweetAlert.prototype.showValidationMessage = instanceMethods.showValidationMessage SweetAlert.prototype.resetValidationMessage = instanceMethods.resetValidationMessage SweetAlert.prototype.close = instanceMethods.close SweetAlert.prototype.closePopup = instanceMethods.closePopup SweetAlert.prototype.closeModal = instanceMethods.closeModal SweetAlert.prototype.closeToast = instanceMethods.closeToast SweetAlert.prototype.rejectPromise = instanceMethods.rejectPromise SweetAlert.prototype.update = instanceMethods.update SweetAlert.prototype._destroy = instanceMethods._destroy // Assign static methods from src/staticMethods/*.js to constructor Object.assign(SweetAlert, staticMethods) // Proxy to instance methods to constructor, for now, for backwards compatibility Object.keys(instanceMethods).forEach((key) => { /** * @param {...any} args * @returns {any | undefined} */ SweetAlert[key] = function (...args) { if (currentInstance && currentInstance[key]) { return currentInstance[key](...args) } return null } }) SweetAlert.DismissReason = DismissReason SweetAlert.version = '11.10.8' export default SweetAlert