migrate to new git
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import { isNodeEnv } from '../isNodeEnv.js'
|
||||
|
||||
export const animationEndEvent = (() => {
|
||||
// Prevent run in Node env
|
||||
/* istanbul ignore if */
|
||||
if (isNodeEnv()) {
|
||||
return false
|
||||
}
|
||||
|
||||
const testEl = document.createElement('div')
|
||||
const transEndEventNames = {
|
||||
WebkitAnimation: 'webkitAnimationEnd',
|
||||
OAnimation: 'oAnimationEnd oanimationend',
|
||||
animation: 'animationend'
|
||||
}
|
||||
for (const i in transEndEventNames) {
|
||||
if (Object.prototype.hasOwnProperty.call(transEndEventNames, i) && typeof testEl.style[i] !== 'undefined') {
|
||||
return transEndEventNames[i]
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})()
|
||||
195
web/App_Script/sweetalert2-9.10.9/src/utils/dom/domUtils.js
Normal file
195
web/App_Script/sweetalert2-9.10.9/src/utils/dom/domUtils.js
Normal file
@@ -0,0 +1,195 @@
|
||||
import { getTimerProgressBar } from './getters.js'
|
||||
import { swalClasses, iconTypes } from '../classes.js'
|
||||
import { toArray, objectValues, warn } from '../utils.js'
|
||||
|
||||
// Remember state in cases where opening and handling a modal will fiddle with it.
|
||||
export const states = {
|
||||
previousBodyPadding: null
|
||||
}
|
||||
|
||||
export const setInnerHtml = (elem, html) => { // #1926
|
||||
elem.textContent = ''
|
||||
if (html) {
|
||||
const parser = new DOMParser()
|
||||
const parsed = parser.parseFromString(html, `text/html`)
|
||||
toArray(parsed.querySelector('head').childNodes).forEach((child) => {
|
||||
elem.appendChild(child)
|
||||
})
|
||||
toArray(parsed.querySelector('body').childNodes).forEach((child) => {
|
||||
elem.appendChild(child)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const hasClass = (elem, className) => {
|
||||
if (!className) {
|
||||
return false
|
||||
}
|
||||
const classList = className.split(/\s+/)
|
||||
for (let i = 0; i < classList.length; i++) {
|
||||
if (!elem.classList.contains(classList[i])) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const removeCustomClasses = (elem, params) => {
|
||||
toArray(elem.classList).forEach(className => {
|
||||
if (
|
||||
!objectValues(swalClasses).includes(className) &&
|
||||
!objectValues(iconTypes).includes(className) &&
|
||||
!objectValues(params.showClass).includes(className)
|
||||
) {
|
||||
elem.classList.remove(className)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const applyCustomClass = (elem, params, className) => {
|
||||
removeCustomClasses(elem, params)
|
||||
|
||||
if (params.customClass && params.customClass[className]) {
|
||||
if (typeof params.customClass[className] !== 'string' && !params.customClass[className].forEach) {
|
||||
return warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof params.customClass[className]}"`)
|
||||
}
|
||||
|
||||
addClass(elem, params.customClass[className])
|
||||
}
|
||||
}
|
||||
|
||||
export function getInput (content, inputType) {
|
||||
if (!inputType) {
|
||||
return null
|
||||
}
|
||||
switch (inputType) {
|
||||
case 'select':
|
||||
case 'textarea':
|
||||
case 'file':
|
||||
return getChildByClass(content, swalClasses[inputType])
|
||||
case 'checkbox':
|
||||
return content.querySelector(`.${swalClasses.checkbox} input`)
|
||||
case 'radio':
|
||||
return content.querySelector(`.${swalClasses.radio} input:checked`) ||
|
||||
content.querySelector(`.${swalClasses.radio} input:first-child`)
|
||||
case 'range':
|
||||
return content.querySelector(`.${swalClasses.range} input`)
|
||||
default:
|
||||
return getChildByClass(content, swalClasses.input)
|
||||
}
|
||||
}
|
||||
|
||||
export const focusInput = (input) => {
|
||||
input.focus()
|
||||
|
||||
// place cursor at end of text in text input
|
||||
if (input.type !== 'file') {
|
||||
// http://stackoverflow.com/a/2345915
|
||||
const val = input.value
|
||||
input.value = ''
|
||||
input.value = val
|
||||
}
|
||||
}
|
||||
|
||||
export const toggleClass = (target, classList, condition) => {
|
||||
if (!target || !classList) {
|
||||
return
|
||||
}
|
||||
if (typeof classList === 'string') {
|
||||
classList = classList.split(/\s+/).filter(Boolean)
|
||||
}
|
||||
classList.forEach((className) => {
|
||||
if (target.forEach) {
|
||||
target.forEach((elem) => {
|
||||
condition ? elem.classList.add(className) : elem.classList.remove(className)
|
||||
})
|
||||
} else {
|
||||
condition ? target.classList.add(className) : target.classList.remove(className)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const addClass = (target, classList) => {
|
||||
toggleClass(target, classList, true)
|
||||
}
|
||||
|
||||
export const removeClass = (target, classList) => {
|
||||
toggleClass(target, classList, false)
|
||||
}
|
||||
|
||||
export const getChildByClass = (elem, className) => {
|
||||
for (let i = 0; i < elem.childNodes.length; i++) {
|
||||
if (hasClass(elem.childNodes[i], className)) {
|
||||
return elem.childNodes[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const applyNumericalStyle = (elem, property, value) => {
|
||||
if (value || parseInt(value) === 0) {
|
||||
elem.style[property] = (typeof value === 'number') ? `${value}px` : value
|
||||
} else {
|
||||
elem.style.removeProperty(property)
|
||||
}
|
||||
}
|
||||
|
||||
export const show = (elem, display = 'flex') => {
|
||||
elem.style.opacity = ''
|
||||
elem.style.display = display
|
||||
}
|
||||
|
||||
export const hide = (elem) => {
|
||||
elem.style.opacity = ''
|
||||
elem.style.display = 'none'
|
||||
}
|
||||
|
||||
export const toggle = (elem, condition, display) => {
|
||||
condition ? show(elem, display) : hide(elem)
|
||||
}
|
||||
|
||||
// borrowed from jquery $(elem).is(':visible') implementation
|
||||
export const isVisible = (elem) => !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length))
|
||||
|
||||
/* istanbul ignore next */
|
||||
export const isScrollable = (elem) => !!(elem.scrollHeight > elem.clientHeight)
|
||||
|
||||
// borrowed from https://stackoverflow.com/a/46352119
|
||||
export const hasCssAnimation = (elem) => {
|
||||
const style = window.getComputedStyle(elem)
|
||||
|
||||
const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0')
|
||||
const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0')
|
||||
|
||||
return animDuration > 0 || transDuration > 0
|
||||
}
|
||||
|
||||
export const contains = (haystack, needle) => {
|
||||
if (typeof haystack.contains === 'function') {
|
||||
return haystack.contains(needle)
|
||||
}
|
||||
}
|
||||
|
||||
export const animateTimerProgressBar = (timer, reset = false) => {
|
||||
const timerProgressBar = getTimerProgressBar()
|
||||
if (isVisible(timerProgressBar)) {
|
||||
if (reset) {
|
||||
timerProgressBar.style.transition = 'none'
|
||||
timerProgressBar.style.width = '100%'
|
||||
}
|
||||
setTimeout(() => {
|
||||
timerProgressBar.style.transition = `width ${timer / 1000}s linear`
|
||||
timerProgressBar.style.width = '0%'
|
||||
}, 10)
|
||||
}
|
||||
}
|
||||
|
||||
export const stopTimerProgressBar = () => {
|
||||
const timerProgressBar = getTimerProgressBar()
|
||||
const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width)
|
||||
timerProgressBar.style.removeProperty('transition')
|
||||
timerProgressBar.style.width = '100%'
|
||||
const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width)
|
||||
const timerProgressBarPercent = parseInt(timerProgressBarWidth / timerProgressBarFullWidth * 100)
|
||||
timerProgressBar.style.removeProperty('transition')
|
||||
timerProgressBar.style.width = `${timerProgressBarPercent}%`
|
||||
}
|
||||
105
web/App_Script/sweetalert2-9.10.9/src/utils/dom/getters.js
Normal file
105
web/App_Script/sweetalert2-9.10.9/src/utils/dom/getters.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import { swalClasses } from '../classes.js'
|
||||
import { uniqueArray, toArray } from '../utils.js'
|
||||
import { isVisible } from './domUtils.js'
|
||||
|
||||
export const getContainer = () => document.body.querySelector(`.${swalClasses.container}`)
|
||||
|
||||
export const elementBySelector = (selectorString) => {
|
||||
const container = getContainer()
|
||||
return container ? container.querySelector(selectorString) : null
|
||||
}
|
||||
|
||||
const elementByClass = (className) => {
|
||||
return elementBySelector(`.${className}`)
|
||||
}
|
||||
|
||||
export const getPopup = () => elementByClass(swalClasses.popup)
|
||||
|
||||
export const getIcons = () => {
|
||||
const popup = getPopup()
|
||||
return toArray(popup.querySelectorAll(`.${swalClasses.icon}`))
|
||||
}
|
||||
|
||||
export const getIcon = () => {
|
||||
const visibleIcon = getIcons().filter(icon => isVisible(icon))
|
||||
return visibleIcon.length ? visibleIcon[0] : null
|
||||
}
|
||||
|
||||
export const getTitle = () => elementByClass(swalClasses.title)
|
||||
|
||||
export const getContent = () => elementByClass(swalClasses.content)
|
||||
|
||||
export const getHtmlContainer = () => elementByClass(swalClasses['html-container'])
|
||||
|
||||
export const getImage = () => elementByClass(swalClasses.image)
|
||||
|
||||
export const getProgressSteps = () => elementByClass(swalClasses['progress-steps'])
|
||||
|
||||
export const getValidationMessage = () => elementByClass(swalClasses['validation-message'])
|
||||
|
||||
export const getConfirmButton = () => elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`)
|
||||
|
||||
export const getCancelButton = () => elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`)
|
||||
|
||||
export const getActions = () => elementByClass(swalClasses.actions)
|
||||
|
||||
export const getHeader = () => elementByClass(swalClasses.header)
|
||||
|
||||
export const getFooter = () => elementByClass(swalClasses.footer)
|
||||
|
||||
export const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar'])
|
||||
|
||||
export const getCloseButton = () => elementByClass(swalClasses.close)
|
||||
|
||||
// https://github.com/jkup/focusable/blob/master/index.js
|
||||
const focusable = `
|
||||
a[href],
|
||||
area[href],
|
||||
input:not([disabled]),
|
||||
select:not([disabled]),
|
||||
textarea:not([disabled]),
|
||||
button:not([disabled]),
|
||||
iframe,
|
||||
object,
|
||||
embed,
|
||||
[tabindex="0"],
|
||||
[contenteditable],
|
||||
audio[controls],
|
||||
video[controls],
|
||||
summary
|
||||
`
|
||||
|
||||
export const getFocusableElements = () => {
|
||||
const focusableElementsWithTabindex = toArray(
|
||||
getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')
|
||||
)
|
||||
// sort according to tabindex
|
||||
.sort((a, b) => {
|
||||
a = parseInt(a.getAttribute('tabindex'))
|
||||
b = parseInt(b.getAttribute('tabindex'))
|
||||
if (a > b) {
|
||||
return 1
|
||||
} else if (a < b) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
|
||||
const otherFocusableElements = toArray(
|
||||
getPopup().querySelectorAll(focusable)
|
||||
).filter(el => el.getAttribute('tabindex') !== '-1')
|
||||
|
||||
return uniqueArray(focusableElementsWithTabindex.concat(otherFocusableElements)).filter(el => isVisible(el))
|
||||
}
|
||||
|
||||
export const isModal = () => {
|
||||
return !isToast() && !document.body.classList.contains(swalClasses['no-backdrop'])
|
||||
}
|
||||
|
||||
export const isToast = () => {
|
||||
return document.body.classList.contains(swalClasses['toast-shown'])
|
||||
}
|
||||
|
||||
export const isLoading = () => {
|
||||
return getPopup().hasAttribute('data-loading')
|
||||
}
|
||||
7
web/App_Script/sweetalert2-9.10.9/src/utils/dom/index.js
Normal file
7
web/App_Script/sweetalert2-9.10.9/src/utils/dom/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export * from './domUtils.js'
|
||||
export * from './init.js'
|
||||
export * from './getters.js'
|
||||
export * from './parseHtmlToContainer.js'
|
||||
export * from './animationEndEvent.js'
|
||||
export * from './measureScrollbar.js'
|
||||
export * from './renderers/render.js'
|
||||
148
web/App_Script/sweetalert2-9.10.9/src/utils/dom/init.js
Normal file
148
web/App_Script/sweetalert2-9.10.9/src/utils/dom/init.js
Normal file
@@ -0,0 +1,148 @@
|
||||
import { swalClasses, iconTypes } from '../classes.js'
|
||||
import { getContainer, getPopup, getContent } from './getters.js'
|
||||
import { addClass, removeClass, getChildByClass, setInnerHtml } from './domUtils.js'
|
||||
import { isNodeEnv } from '../isNodeEnv.js'
|
||||
import { error } from '../utils.js'
|
||||
import sweetAlert from '../../sweetalert2.js'
|
||||
|
||||
const sweetHTML = `
|
||||
<div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses.content}" class="${swalClasses.popup}" tabindex="-1">
|
||||
<div class="${swalClasses.header}">
|
||||
<ul class="${swalClasses['progress-steps']}"></ul>
|
||||
<div class="${swalClasses.icon} ${iconTypes.error}"></div>
|
||||
<div class="${swalClasses.icon} ${iconTypes.question}"></div>
|
||||
<div class="${swalClasses.icon} ${iconTypes.warning}"></div>
|
||||
<div class="${swalClasses.icon} ${iconTypes.info}"></div>
|
||||
<div class="${swalClasses.icon} ${iconTypes.success}"></div>
|
||||
<img class="${swalClasses.image}" />
|
||||
<h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
|
||||
<button type="button" class="${swalClasses.close}"></button>
|
||||
</div>
|
||||
<div class="${swalClasses.content}">
|
||||
<div id="${swalClasses.content}" class="${swalClasses['html-container']}"></div>
|
||||
<input class="${swalClasses.input}" />
|
||||
<input type="file" class="${swalClasses.file}" />
|
||||
<div class="${swalClasses.range}">
|
||||
<input type="range" />
|
||||
<output></output>
|
||||
</div>
|
||||
<select class="${swalClasses.select}"></select>
|
||||
<div class="${swalClasses.radio}"></div>
|
||||
<label for="${swalClasses.checkbox}" class="${swalClasses.checkbox}">
|
||||
<input type="checkbox" />
|
||||
<span class="${swalClasses.label}"></span>
|
||||
</label>
|
||||
<textarea class="${swalClasses.textarea}"></textarea>
|
||||
<div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
|
||||
</div>
|
||||
<div class="${swalClasses.actions}">
|
||||
<button type="button" class="${swalClasses.confirm}">OK</button>
|
||||
<button type="button" class="${swalClasses.cancel}">Cancel</button>
|
||||
</div>
|
||||
<div class="${swalClasses.footer}"></div>
|
||||
<div class="${swalClasses['timer-progress-bar-container']}">
|
||||
<div class="${swalClasses['timer-progress-bar']}"></div>
|
||||
</div>
|
||||
</div>
|
||||
`.replace(/(^|\n)\s*/g, '')
|
||||
|
||||
const resetOldContainer = () => {
|
||||
const oldContainer = getContainer()
|
||||
if (!oldContainer) {
|
||||
return false
|
||||
}
|
||||
|
||||
oldContainer.parentNode.removeChild(oldContainer)
|
||||
removeClass(
|
||||
[document.documentElement, document.body],
|
||||
[
|
||||
swalClasses['no-backdrop'],
|
||||
swalClasses['toast-shown'],
|
||||
swalClasses['has-column']
|
||||
]
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let oldInputVal // IE11 workaround, see #1109 for details
|
||||
const resetValidationMessage = (e) => {
|
||||
if (sweetAlert.isVisible() && oldInputVal !== e.target.value) {
|
||||
sweetAlert.resetValidationMessage()
|
||||
}
|
||||
oldInputVal = e.target.value
|
||||
}
|
||||
|
||||
const addInputChangeListeners = () => {
|
||||
const content = getContent()
|
||||
|
||||
const input = getChildByClass(content, swalClasses.input)
|
||||
const file = getChildByClass(content, swalClasses.file)
|
||||
const range = content.querySelector(`.${swalClasses.range} input`)
|
||||
const rangeOutput = content.querySelector(`.${swalClasses.range} output`)
|
||||
const select = getChildByClass(content, swalClasses.select)
|
||||
const checkbox = content.querySelector(`.${swalClasses.checkbox} input`)
|
||||
const textarea = getChildByClass(content, swalClasses.textarea)
|
||||
|
||||
input.oninput = resetValidationMessage
|
||||
file.onchange = resetValidationMessage
|
||||
select.onchange = resetValidationMessage
|
||||
checkbox.onchange = resetValidationMessage
|
||||
textarea.oninput = resetValidationMessage
|
||||
|
||||
range.oninput = (e) => {
|
||||
resetValidationMessage(e)
|
||||
rangeOutput.value = range.value
|
||||
}
|
||||
|
||||
range.onchange = (e) => {
|
||||
resetValidationMessage(e)
|
||||
range.nextSibling.value = range.value
|
||||
}
|
||||
}
|
||||
|
||||
const getTarget = (target) => typeof target === 'string' ? document.querySelector(target) : target
|
||||
|
||||
const setupAccessibility = (params) => {
|
||||
const popup = getPopup()
|
||||
|
||||
popup.setAttribute('role', params.toast ? 'alert' : 'dialog')
|
||||
popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive')
|
||||
if (!params.toast) {
|
||||
popup.setAttribute('aria-modal', 'true')
|
||||
}
|
||||
}
|
||||
|
||||
const setupRTL = (targetElement) => {
|
||||
if (window.getComputedStyle(targetElement).direction === 'rtl') {
|
||||
addClass(getContainer(), swalClasses.rtl)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add modal + backdrop to DOM
|
||||
*/
|
||||
export const init = (params) => {
|
||||
// Clean up the old popup container if it exists
|
||||
const oldContainerExisted = resetOldContainer()
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (isNodeEnv()) {
|
||||
error('SweetAlert2 requires document to initialize')
|
||||
return
|
||||
}
|
||||
|
||||
const container = document.createElement('div')
|
||||
container.className = swalClasses.container
|
||||
if (oldContainerExisted) {
|
||||
addClass(container, swalClasses['no-transition'])
|
||||
}
|
||||
setInnerHtml(container, sweetHTML)
|
||||
|
||||
const targetElement = getTarget(params.target)
|
||||
targetElement.appendChild(container)
|
||||
|
||||
setupAccessibility(params)
|
||||
setupRTL(targetElement)
|
||||
addInputChangeListeners()
|
||||
}
|
||||
132
web/App_Script/sweetalert2-9.10.9/src/utils/dom/inputUtils.js
Normal file
132
web/App_Script/sweetalert2-9.10.9/src/utils/dom/inputUtils.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import * as dom from './index.js'
|
||||
import { swalClasses } from '../classes.js'
|
||||
import { getChildByClass } from './domUtils.js'
|
||||
import { error, isPromise } from '../utils.js'
|
||||
import { showLoading } from '../../staticMethods/showLoading.js'
|
||||
|
||||
export const handleInputOptionsAndValue = (instance, params) => {
|
||||
if (params.input === 'select' || params.input === 'radio') {
|
||||
handleInputOptions(instance, params)
|
||||
} else if (['text', 'email', 'number', 'tel', 'textarea'].includes(params.input) && isPromise(params.inputValue)) {
|
||||
handleInputValue(instance, params)
|
||||
}
|
||||
}
|
||||
|
||||
export const getInputValue = (instance, innerParams) => {
|
||||
const input = instance.getInput()
|
||||
if (!input) {
|
||||
return null
|
||||
}
|
||||
switch (innerParams.input) {
|
||||
case 'checkbox':
|
||||
return getCheckboxValue(input)
|
||||
case 'radio':
|
||||
return getRadioValue(input)
|
||||
case 'file':
|
||||
return getFileValue(input)
|
||||
default:
|
||||
return innerParams.inputAutoTrim ? input.value.trim() : input.value
|
||||
}
|
||||
}
|
||||
|
||||
const getCheckboxValue = (input) => input.checked ? 1 : 0
|
||||
|
||||
const getRadioValue = (input) => input.checked ? input.value : null
|
||||
|
||||
const getFileValue = (input) => input.files.length ? (input.getAttribute('multiple') !== null ? input.files : input.files[0]) : null
|
||||
|
||||
const handleInputOptions = (instance, params) => {
|
||||
const content = dom.getContent()
|
||||
const processInputOptions = (inputOptions) => populateInputOptions[params.input](content, formatInputOptions(inputOptions), params)
|
||||
if (isPromise(params.inputOptions)) {
|
||||
showLoading()
|
||||
params.inputOptions.then((inputOptions) => {
|
||||
instance.hideLoading()
|
||||
processInputOptions(inputOptions)
|
||||
})
|
||||
} else if (typeof params.inputOptions === 'object') {
|
||||
processInputOptions(params.inputOptions)
|
||||
} else {
|
||||
error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleInputValue = (instance, params) => {
|
||||
const input = instance.getInput()
|
||||
dom.hide(input)
|
||||
params.inputValue.then((inputValue) => {
|
||||
input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : `${inputValue}`
|
||||
dom.show(input)
|
||||
input.focus()
|
||||
instance.hideLoading()
|
||||
})
|
||||
.catch((err) => {
|
||||
error(`Error in inputValue promise: ${err}`)
|
||||
input.value = ''
|
||||
dom.show(input)
|
||||
input.focus()
|
||||
instance.hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
const populateInputOptions = {
|
||||
select: (content, inputOptions, params) => {
|
||||
const select = getChildByClass(content, swalClasses.select)
|
||||
inputOptions.forEach(inputOption => {
|
||||
const optionValue = inputOption[0]
|
||||
const optionLabel = inputOption[1]
|
||||
const option = document.createElement('option')
|
||||
option.value = optionValue
|
||||
dom.setInnerHtml(option, optionLabel)
|
||||
if (params.inputValue.toString() === optionValue.toString()) {
|
||||
option.selected = true
|
||||
}
|
||||
select.appendChild(option)
|
||||
})
|
||||
select.focus()
|
||||
},
|
||||
|
||||
radio: (content, inputOptions, params) => {
|
||||
const radio = getChildByClass(content, swalClasses.radio)
|
||||
inputOptions.forEach(inputOption => {
|
||||
const radioValue = inputOption[0]
|
||||
const radioLabel = inputOption[1]
|
||||
const radioInput = document.createElement('input')
|
||||
const radioLabelElement = document.createElement('label')
|
||||
radioInput.type = 'radio'
|
||||
radioInput.name = swalClasses.radio
|
||||
radioInput.value = radioValue
|
||||
if (params.inputValue.toString() === radioValue.toString()) {
|
||||
radioInput.checked = true
|
||||
}
|
||||
const label = document.createElement('span')
|
||||
dom.setInnerHtml(label, radioLabel)
|
||||
label.className = swalClasses.label
|
||||
radioLabelElement.appendChild(radioInput)
|
||||
radioLabelElement.appendChild(label)
|
||||
radio.appendChild(radioLabelElement)
|
||||
})
|
||||
const radios = radio.querySelectorAll('input')
|
||||
if (radios.length) {
|
||||
radios[0].focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts `inputOptions` into an array of `[value, label]`s
|
||||
* @param inputOptions
|
||||
*/
|
||||
const formatInputOptions = (inputOptions) => {
|
||||
const result = []
|
||||
if (typeof Map !== 'undefined' && inputOptions instanceof Map) {
|
||||
inputOptions.forEach((value, key) => {
|
||||
result.push([key, value])
|
||||
})
|
||||
} else {
|
||||
Object.keys(inputOptions).forEach(key => {
|
||||
result.push([key, inputOptions[key]])
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { swalClasses } from '../classes.js'
|
||||
|
||||
// Measure scrollbar width for padding body during modal show/hide
|
||||
// https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
|
||||
export const measureScrollbar = () => {
|
||||
const scrollDiv = document.createElement('div')
|
||||
scrollDiv.className = swalClasses['scrollbar-measure']
|
||||
document.body.appendChild(scrollDiv)
|
||||
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
|
||||
document.body.removeChild(scrollDiv)
|
||||
return scrollbarWidth
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { setInnerHtml } from './domUtils.js'
|
||||
|
||||
export const parseHtmlToContainer = (param, target) => {
|
||||
// DOM element
|
||||
if (param instanceof HTMLElement) {
|
||||
target.appendChild(param)
|
||||
|
||||
// Object
|
||||
} else if (typeof param === 'object') {
|
||||
handleObject(param, target)
|
||||
|
||||
// Plain string
|
||||
} else if (param) {
|
||||
setInnerHtml(target, param)
|
||||
}
|
||||
}
|
||||
|
||||
const handleObject = (param, target) => {
|
||||
// JQuery element(s)
|
||||
if (param.jquery) {
|
||||
handleJqueryElem(target, param)
|
||||
|
||||
// For other objects use their string representation
|
||||
} else {
|
||||
setInnerHtml(target, param.toString())
|
||||
}
|
||||
}
|
||||
|
||||
const handleJqueryElem = (target, elem) => {
|
||||
target.textContent = ''
|
||||
if (0 in elem) {
|
||||
for (let i = 0; i in elem; i++) {
|
||||
target.appendChild(elem[i].cloneNode(true))
|
||||
}
|
||||
} else {
|
||||
target.appendChild(elem.cloneNode(true))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { getPopup } from '../getters.js'
|
||||
import { renderActions } from './renderActions.js'
|
||||
import { renderContainer } from './renderContainer.js'
|
||||
import { renderContent } from './renderContent.js'
|
||||
import { renderFooter } from './renderFooter.js'
|
||||
import { renderHeader } from './renderHeader.js'
|
||||
import { renderPopup } from './renderPopup.js'
|
||||
|
||||
export const render = (instance, params) => {
|
||||
renderPopup(instance, params)
|
||||
renderContainer(instance, params)
|
||||
|
||||
renderHeader(instance, params)
|
||||
renderContent(instance, params)
|
||||
renderActions(instance, params)
|
||||
renderFooter(instance, params)
|
||||
|
||||
if (typeof params.onRender === 'function') {
|
||||
params.onRender(getPopup())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
import { capitalizeFirstLetter } from '../../utils.js'
|
||||
|
||||
export const renderActions = (instance, params) => {
|
||||
const actions = dom.getActions()
|
||||
const confirmButton = dom.getConfirmButton()
|
||||
const cancelButton = dom.getCancelButton()
|
||||
|
||||
// Actions (buttons) wrapper
|
||||
if (!params.showConfirmButton && !params.showCancelButton) {
|
||||
dom.hide(actions)
|
||||
}
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(actions, params, 'actions')
|
||||
|
||||
// Render confirm button
|
||||
renderButton(confirmButton, 'confirm', params)
|
||||
// render Cancel Button
|
||||
renderButton(cancelButton, 'cancel', params)
|
||||
|
||||
if (params.buttonsStyling) {
|
||||
handleButtonsStyling(confirmButton, cancelButton, params)
|
||||
} else {
|
||||
dom.removeClass([confirmButton, cancelButton], swalClasses.styled)
|
||||
confirmButton.style.backgroundColor = confirmButton.style.borderLeftColor = confirmButton.style.borderRightColor = ''
|
||||
cancelButton.style.backgroundColor = cancelButton.style.borderLeftColor = cancelButton.style.borderRightColor = ''
|
||||
}
|
||||
|
||||
if (params.reverseButtons) {
|
||||
confirmButton.parentNode.insertBefore(cancelButton, confirmButton)
|
||||
}
|
||||
}
|
||||
|
||||
function handleButtonsStyling (confirmButton, cancelButton, params) {
|
||||
dom.addClass([confirmButton, cancelButton], swalClasses.styled)
|
||||
|
||||
// Buttons background colors
|
||||
if (params.confirmButtonColor) {
|
||||
confirmButton.style.backgroundColor = params.confirmButtonColor
|
||||
}
|
||||
if (params.cancelButtonColor) {
|
||||
cancelButton.style.backgroundColor = params.cancelButtonColor
|
||||
}
|
||||
|
||||
// Loading state
|
||||
const confirmButtonBackgroundColor = window.getComputedStyle(confirmButton).getPropertyValue('background-color')
|
||||
confirmButton.style.borderLeftColor = confirmButtonBackgroundColor
|
||||
confirmButton.style.borderRightColor = confirmButtonBackgroundColor
|
||||
}
|
||||
|
||||
function renderButton (button, buttonType, params) {
|
||||
dom.toggle(button, params[`show${capitalizeFirstLetter(buttonType)}Button`], 'inline-block')
|
||||
dom.setInnerHtml(button, params[`${buttonType}ButtonText`]) // Set caption text
|
||||
button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`]) // ARIA label
|
||||
|
||||
// Add buttons custom classes
|
||||
button.className = swalClasses[buttonType]
|
||||
dom.applyCustomClass(button, params, `${buttonType}Button`)
|
||||
dom.addClass(button, params[`${buttonType}ButtonClass`])
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
export const renderCloseButton = (instance, params) => {
|
||||
const closeButton = dom.getCloseButton()
|
||||
|
||||
dom.setInnerHtml(closeButton, params.closeButtonHtml)
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(closeButton, params, 'closeButton')
|
||||
|
||||
dom.toggle(closeButton, params.showCloseButton)
|
||||
closeButton.setAttribute('aria-label', params.closeButtonAriaLabel)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import { warn } from '../../utils.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
function handleBackdropParam (container, backdrop) {
|
||||
if (typeof backdrop === 'string') {
|
||||
container.style.background = backdrop
|
||||
} else if (!backdrop) {
|
||||
dom.addClass([document.documentElement, document.body], swalClasses['no-backdrop'])
|
||||
}
|
||||
}
|
||||
|
||||
function handlePositionParam (container, position) {
|
||||
if (position in swalClasses) {
|
||||
dom.addClass(container, swalClasses[position])
|
||||
} else {
|
||||
warn('The "position" parameter is not valid, defaulting to "center"')
|
||||
dom.addClass(container, swalClasses.center)
|
||||
}
|
||||
}
|
||||
|
||||
function handleGrowParam (container, grow) {
|
||||
if (grow && typeof grow === 'string') {
|
||||
const growClass = `grow-${grow}`
|
||||
if (growClass in swalClasses) {
|
||||
dom.addClass(container, swalClasses[growClass])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const renderContainer = (instance, params) => {
|
||||
const container = dom.getContainer()
|
||||
|
||||
if (!container) {
|
||||
return
|
||||
}
|
||||
|
||||
handleBackdropParam(container, params.backdrop)
|
||||
|
||||
if (!params.backdrop && params.allowOutsideClick) {
|
||||
warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`')
|
||||
}
|
||||
|
||||
handlePositionParam(container, params.position)
|
||||
handleGrowParam(container, params.grow)
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(container, params, 'container')
|
||||
|
||||
// Set queue step attribute for getQueueStep() method
|
||||
const queueStep = document.body.getAttribute('data-swal2-queue-step')
|
||||
if (queueStep) {
|
||||
container.setAttribute('data-queue-step', queueStep)
|
||||
document.body.removeAttribute('data-swal2-queue-step')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
import { renderInput } from './renderInput.js'
|
||||
|
||||
export const renderContent = (instance, params) => {
|
||||
const content = dom.getContent().querySelector(`#${swalClasses.content}`)
|
||||
|
||||
// Content as HTML
|
||||
if (params.html) {
|
||||
dom.parseHtmlToContainer(params.html, content)
|
||||
dom.show(content, 'block')
|
||||
|
||||
// Content as plain text
|
||||
} else if (params.text) {
|
||||
content.textContent = params.text
|
||||
dom.show(content, 'block')
|
||||
|
||||
// No content
|
||||
} else {
|
||||
dom.hide(content)
|
||||
}
|
||||
|
||||
renderInput(instance, params)
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(dom.getContent(), params, 'content')
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
export const renderFooter = (instance, params) => {
|
||||
const footer = dom.getFooter()
|
||||
|
||||
dom.toggle(footer, params.footer)
|
||||
|
||||
if (params.footer) {
|
||||
dom.parseHtmlToContainer(params.footer, footer)
|
||||
}
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(footer, params, 'footer')
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import * as dom from '../../dom/index.js'
|
||||
import { renderCloseButton } from './renderCloseButton.js'
|
||||
import { renderIcon } from './renderIcon.js'
|
||||
import { renderImage } from './renderImage.js'
|
||||
import { renderProgressSteps } from './renderProgressSteps.js'
|
||||
import { renderTitle } from './renderTitle.js'
|
||||
|
||||
export const renderHeader = (instance, params) => {
|
||||
const header = dom.getHeader()
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(header, params, 'header')
|
||||
|
||||
// Progress steps
|
||||
renderProgressSteps(instance, params)
|
||||
|
||||
// Icon
|
||||
renderIcon(instance, params)
|
||||
|
||||
// Image
|
||||
renderImage(instance, params)
|
||||
|
||||
// Title
|
||||
renderTitle(instance, params)
|
||||
|
||||
// Close button
|
||||
renderCloseButton(instance, params)
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { swalClasses, iconTypes } from '../../classes.js'
|
||||
import { error } from '../../utils.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
import privateProps from '../../../privateProps.js'
|
||||
|
||||
export const renderIcon = (instance, params) => {
|
||||
const innerParams = privateProps.innerParams.get(instance)
|
||||
|
||||
// if the give icon already rendered, apply the custom class without re-rendering the icon
|
||||
if (innerParams && params.icon === innerParams.icon && dom.getIcon()) {
|
||||
dom.applyCustomClass(dom.getIcon(), params, 'icon')
|
||||
return
|
||||
}
|
||||
|
||||
hideAllIcons()
|
||||
|
||||
if (!params.icon) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Object.keys(iconTypes).indexOf(params.icon) !== -1) {
|
||||
const icon = dom.elementBySelector(`.${swalClasses.icon}.${iconTypes[params.icon]}`)
|
||||
dom.show(icon)
|
||||
|
||||
// Custom or default content
|
||||
setContent(icon, params)
|
||||
adjustSuccessIconBackgoundColor()
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(icon, params, 'icon')
|
||||
|
||||
// Animate icon
|
||||
dom.addClass(icon, params.showClass.icon)
|
||||
} else {
|
||||
error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`)
|
||||
}
|
||||
}
|
||||
|
||||
const hideAllIcons = () => {
|
||||
const icons = dom.getIcons()
|
||||
for (let i = 0; i < icons.length; i++) {
|
||||
dom.hide(icons[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust success icon background color to match the popup background color
|
||||
const adjustSuccessIconBackgoundColor = () => {
|
||||
const popup = dom.getPopup()
|
||||
const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color')
|
||||
const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix')
|
||||
for (let i = 0; i < successIconParts.length; i++) {
|
||||
successIconParts[i].style.backgroundColor = popupBackgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
const setContent = (icon, params) => {
|
||||
icon.textContent = ''
|
||||
|
||||
if (params.iconHtml) {
|
||||
dom.setInnerHtml(icon, iconContent(params.iconHtml))
|
||||
} else if (params.icon === 'success') {
|
||||
dom.setInnerHtml(icon, `
|
||||
<div class="swal2-success-circular-line-left"></div>
|
||||
<span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
|
||||
<div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>
|
||||
<div class="swal2-success-circular-line-right"></div>
|
||||
`)
|
||||
} else if (params.icon === 'error') {
|
||||
dom.setInnerHtml(icon, `
|
||||
<span class="swal2-x-mark">
|
||||
<span class="swal2-x-mark-line-left"></span>
|
||||
<span class="swal2-x-mark-line-right"></span>
|
||||
</span>
|
||||
`)
|
||||
} else {
|
||||
const defaultIconHtml = {
|
||||
question: '?',
|
||||
warning: '!',
|
||||
info: 'i'
|
||||
}
|
||||
dom.setInnerHtml(icon, iconContent(defaultIconHtml[params.icon]))
|
||||
}
|
||||
}
|
||||
|
||||
const iconContent = (content) => `<div class="${swalClasses['icon-content']}">${content}</div>`
|
||||
@@ -0,0 +1,24 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
export const renderImage = (instance, params) => {
|
||||
const image = dom.getImage()
|
||||
|
||||
if (!params.imageUrl) {
|
||||
return dom.hide(image)
|
||||
}
|
||||
|
||||
dom.show(image)
|
||||
|
||||
// Src, alt
|
||||
image.setAttribute('src', params.imageUrl)
|
||||
image.setAttribute('alt', params.imageAlt)
|
||||
|
||||
// Width, height
|
||||
dom.applyNumericalStyle(image, 'width', params.imageWidth)
|
||||
dom.applyNumericalStyle(image, 'height', params.imageHeight)
|
||||
|
||||
// Class
|
||||
image.className = swalClasses.image
|
||||
dom.applyCustomClass(image, params, 'image')
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import { warn, error, isPromise } from '../../utils.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
import privateProps from '../../../privateProps.js'
|
||||
|
||||
const inputTypes = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea']
|
||||
|
||||
export const renderInput = (instance, params) => {
|
||||
const content = dom.getContent()
|
||||
const innerParams = privateProps.innerParams.get(instance)
|
||||
const rerender = !innerParams || params.input !== innerParams.input
|
||||
|
||||
inputTypes.forEach((inputType) => {
|
||||
const inputClass = swalClasses[inputType]
|
||||
const inputContainer = dom.getChildByClass(content, inputClass)
|
||||
|
||||
// set attributes
|
||||
setAttributes(inputType, params.inputAttributes)
|
||||
|
||||
// set class
|
||||
inputContainer.className = inputClass
|
||||
|
||||
if (rerender) {
|
||||
dom.hide(inputContainer)
|
||||
}
|
||||
})
|
||||
|
||||
if (params.input) {
|
||||
if (rerender) {
|
||||
showInput(params)
|
||||
}
|
||||
// set custom class
|
||||
setCustomClass(params)
|
||||
}
|
||||
}
|
||||
|
||||
const showInput = (params) => {
|
||||
if (!renderInputType[params.input]) {
|
||||
return error(`Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "${params.input}"`)
|
||||
}
|
||||
|
||||
const inputContainer = getInputContainer(params.input)
|
||||
const input = renderInputType[params.input](inputContainer, params)
|
||||
dom.show(input)
|
||||
|
||||
// input autofocus
|
||||
setTimeout(() => {
|
||||
dom.focusInput(input)
|
||||
})
|
||||
}
|
||||
|
||||
const removeAttributes = (input) => {
|
||||
for (let i = 0; i < input.attributes.length; i++) {
|
||||
const attrName = input.attributes[i].name
|
||||
if (!['type', 'value', 'style'].includes(attrName)) {
|
||||
input.removeAttribute(attrName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setAttributes = (inputType, inputAttributes) => {
|
||||
const input = dom.getInput(dom.getContent(), inputType)
|
||||
if (!input) {
|
||||
return
|
||||
}
|
||||
|
||||
removeAttributes(input)
|
||||
|
||||
for (const attr in inputAttributes) {
|
||||
// Do not set a placeholder for <input type="range">
|
||||
// it'll crash Edge, #1298
|
||||
if (inputType === 'range' && attr === 'placeholder') {
|
||||
continue
|
||||
}
|
||||
|
||||
input.setAttribute(attr, inputAttributes[attr])
|
||||
}
|
||||
}
|
||||
|
||||
const setCustomClass = (params) => {
|
||||
const inputContainer = getInputContainer(params.input)
|
||||
if (params.customClass) {
|
||||
dom.addClass(inputContainer, params.customClass.input)
|
||||
}
|
||||
}
|
||||
|
||||
const setInputPlaceholder = (input, params) => {
|
||||
if (!input.placeholder || params.inputPlaceholder) {
|
||||
input.placeholder = params.inputPlaceholder
|
||||
}
|
||||
}
|
||||
|
||||
const getInputContainer = (inputType) => {
|
||||
const inputClass = swalClasses[inputType] ? swalClasses[inputType] : swalClasses.input
|
||||
return dom.getChildByClass(dom.getContent(), inputClass)
|
||||
}
|
||||
|
||||
const renderInputType = {}
|
||||
|
||||
renderInputType.text =
|
||||
renderInputType.email =
|
||||
renderInputType.password =
|
||||
renderInputType.number =
|
||||
renderInputType.tel =
|
||||
renderInputType.url = (input, params) => {
|
||||
if (typeof params.inputValue === 'string' || typeof params.inputValue === 'number') {
|
||||
input.value = params.inputValue
|
||||
} else if (!isPromise(params.inputValue)) {
|
||||
warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof params.inputValue}"`)
|
||||
}
|
||||
setInputPlaceholder(input, params)
|
||||
input.type = params.input
|
||||
return input
|
||||
}
|
||||
|
||||
renderInputType.file = (input, params) => {
|
||||
setInputPlaceholder(input, params)
|
||||
return input
|
||||
}
|
||||
|
||||
renderInputType.range = (range, params) => {
|
||||
const rangeInput = range.querySelector('input')
|
||||
const rangeOutput = range.querySelector('output')
|
||||
rangeInput.value = params.inputValue
|
||||
rangeInput.type = params.input
|
||||
rangeOutput.value = params.inputValue
|
||||
return range
|
||||
}
|
||||
|
||||
renderInputType.select = (select, params) => {
|
||||
select.textContent = ''
|
||||
if (params.inputPlaceholder) {
|
||||
const placeholder = document.createElement('option')
|
||||
dom.setInnerHtml(placeholder, params.inputPlaceholder)
|
||||
placeholder.value = ''
|
||||
placeholder.disabled = true
|
||||
placeholder.selected = true
|
||||
select.appendChild(placeholder)
|
||||
}
|
||||
return select
|
||||
}
|
||||
|
||||
renderInputType.radio = (radio) => {
|
||||
radio.textContent = ''
|
||||
return radio
|
||||
}
|
||||
|
||||
renderInputType.checkbox = (checkboxContainer, params) => {
|
||||
const checkbox = dom.getInput(dom.getContent(), 'checkbox')
|
||||
checkbox.value = 1
|
||||
checkbox.id = swalClasses.checkbox
|
||||
checkbox.checked = Boolean(params.inputValue)
|
||||
const label = checkboxContainer.querySelector('span')
|
||||
dom.setInnerHtml(label, params.inputPlaceholder)
|
||||
return checkboxContainer
|
||||
}
|
||||
|
||||
renderInputType.textarea = (textarea, params) => {
|
||||
textarea.value = params.inputValue
|
||||
setInputPlaceholder(textarea, params)
|
||||
|
||||
if ('MutationObserver' in window) { // #1699
|
||||
const initialPopupWidth = parseInt(window.getComputedStyle(dom.getPopup()).width)
|
||||
const popupPadding = parseInt(window.getComputedStyle(dom.getPopup()).paddingLeft) + parseInt(window.getComputedStyle(dom.getPopup()).paddingRight)
|
||||
const outputsize = () => {
|
||||
const contentWidth = textarea.offsetWidth + popupPadding
|
||||
if (contentWidth > initialPopupWidth) {
|
||||
dom.getPopup().style.width = `${contentWidth}px`
|
||||
} else {
|
||||
dom.getPopup().style.width = null
|
||||
}
|
||||
}
|
||||
new MutationObserver(outputsize).observe(textarea, {
|
||||
attributes: true, attributeFilter: ['style']
|
||||
})
|
||||
}
|
||||
|
||||
return textarea
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
export const renderPopup = (instance, params) => {
|
||||
const popup = dom.getPopup()
|
||||
|
||||
// Width
|
||||
dom.applyNumericalStyle(popup, 'width', params.width)
|
||||
|
||||
// Padding
|
||||
dom.applyNumericalStyle(popup, 'padding', params.padding)
|
||||
|
||||
// Background
|
||||
if (params.background) {
|
||||
popup.style.background = params.background
|
||||
}
|
||||
|
||||
// Classes
|
||||
addClasses(popup, params)
|
||||
}
|
||||
|
||||
const addClasses = (popup, params) => {
|
||||
// Default Class + showClass when updating Swal.update({})
|
||||
popup.className = `${swalClasses.popup} ${dom.isVisible(popup) ? params.showClass.popup : ''}`
|
||||
|
||||
if (params.toast) {
|
||||
dom.addClass([document.documentElement, document.body], swalClasses['toast-shown'])
|
||||
dom.addClass(popup, swalClasses.toast)
|
||||
} else {
|
||||
dom.addClass(popup, swalClasses.modal)
|
||||
}
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(popup, params, 'popup')
|
||||
if (typeof params.customClass === 'string') {
|
||||
dom.addClass(popup, params.customClass)
|
||||
}
|
||||
|
||||
// Icon class (#1842)
|
||||
if (params.icon) {
|
||||
dom.addClass(popup, swalClasses[`icon-${params.icon}`])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { swalClasses } from '../../classes.js'
|
||||
import { warn } from '../../utils.js'
|
||||
import * as dom from '../../dom/index.js'
|
||||
import { getQueueStep } from '../../../staticMethods/queue.js'
|
||||
|
||||
const createStepElement = (step) => {
|
||||
const stepEl = document.createElement('li')
|
||||
dom.addClass(stepEl, swalClasses['progress-step'])
|
||||
dom.setInnerHtml(stepEl, step)
|
||||
return stepEl
|
||||
}
|
||||
|
||||
const createLineElement = (params) => {
|
||||
const lineEl = document.createElement('li')
|
||||
dom.addClass(lineEl, swalClasses['progress-step-line'])
|
||||
if (params.progressStepsDistance) {
|
||||
lineEl.style.width = params.progressStepsDistance
|
||||
}
|
||||
return lineEl
|
||||
}
|
||||
|
||||
export const renderProgressSteps = (instance, params) => {
|
||||
const progressStepsContainer = dom.getProgressSteps()
|
||||
if (!params.progressSteps || params.progressSteps.length === 0) {
|
||||
return dom.hide(progressStepsContainer)
|
||||
}
|
||||
|
||||
dom.show(progressStepsContainer)
|
||||
progressStepsContainer.textContent = ''
|
||||
const currentProgressStep = parseInt(params.currentProgressStep === undefined ? getQueueStep() : params.currentProgressStep)
|
||||
if (currentProgressStep >= params.progressSteps.length) {
|
||||
warn(
|
||||
'Invalid currentProgressStep parameter, it should be less than progressSteps.length ' +
|
||||
'(currentProgressStep like JS arrays starts from 0)'
|
||||
)
|
||||
}
|
||||
|
||||
params.progressSteps.forEach((step, index) => {
|
||||
const stepEl = createStepElement(step)
|
||||
progressStepsContainer.appendChild(stepEl)
|
||||
if (index === currentProgressStep) {
|
||||
dom.addClass(stepEl, swalClasses['active-progress-step'])
|
||||
}
|
||||
|
||||
if (index !== params.progressSteps.length - 1) {
|
||||
const lineEl = createLineElement(step)
|
||||
progressStepsContainer.appendChild(lineEl)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import * as dom from '../../dom/index.js'
|
||||
|
||||
export const renderTitle = (instance, params) => {
|
||||
const title = dom.getTitle()
|
||||
|
||||
dom.toggle(title, params.title || params.titleText)
|
||||
|
||||
if (params.title) {
|
||||
dom.parseHtmlToContainer(params.title, title)
|
||||
}
|
||||
|
||||
if (params.titleText) {
|
||||
title.innerText = params.titleText
|
||||
}
|
||||
|
||||
// Custom class
|
||||
dom.applyCustomClass(title, params, 'title')
|
||||
}
|
||||
Reference in New Issue
Block a user