Skip to content

Commit

Permalink
refactor(modules): extract static methods from main module into src/s…
Browse files Browse the repository at this point in the history
…taticMethods/ (#1026)

* refactor(modules): extract "mixin" and "argsToParams" static methods from main module

* refactor(modules): extract dom-related static methods from main module

* refactor(modules): extract tiny adaptInputValidator method from main module into staticMethods/misc.js

* refactor(modules): extract most params related functions from main module

* refactor(modules): extract setDefaults and resetDefaults static methods from main module

* refactor(modules): extract "close" static method (aka closePopup, closeModal, closeToast) from main module

* refactor(modules): extract queue-related static methods from main module

* refactor(modules): extract last static method, showLoading, from main module

* refactor(modules): organize staticMethods modules
  • Loading branch information
zenflow authored and limonte committed Mar 19, 2018
1 parent be9c14e commit 78f8830
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 295 deletions.
5 changes: 5 additions & 0 deletions src/globalState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import defaultParams from './utils/params.js'

export default {
popupParams: Object.assign({}, defaultParams)
}
12 changes: 12 additions & 0 deletions src/staticMethods.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export * from './staticMethods/argsToParams'
export * from './staticMethods/adaptInputValidator'
export * from './staticMethods/close'
export * from './staticMethods/dom'
export * from './staticMethods/mixin'
export * from './staticMethods/queue'
export * from './staticMethods/set-reset-defaults'
export * from './staticMethods/showLoading'
export {
isValidParameter,
isDeprecatedParameter
} from './utils/params'
9 changes: 9 additions & 0 deletions src/staticMethods/adaptInputValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Adapt a legacy inputValidator for use with expectRejections=false
*/
export const adaptInputValidator = (legacyValidator) => {
return function adaptedInputValidator (inputValue, extraParams) {
return legacyValidator.call(this, inputValue, extraParams)
.then(() => undefined, validationError => validationError)
}
}
23 changes: 23 additions & 0 deletions src/staticMethods/argsToParams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { error } from '../utils/utils.js'

export const argsToParams = (args) => {
const params = {}
switch (typeof args[0]) {
case 'string':
['title', 'html', 'type'].forEach((name, index) => {
if (args[index] !== undefined) {
params[name] = args[index]
}
})
break

case 'object':
Object.assign(params, args[0])
break

default:
error('Unexpected type of argument! Expected "string" or "object", got ' + typeof args[0])
return false
}
return params
}
69 changes: 69 additions & 0 deletions src/staticMethods/close.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {undoScrollbar} from '../utils/scrollbarFix'
import {undoIOSfix} from '../utils/iosFix'
import * as dom from '../utils/dom/index'
import { swalClasses } from '../utils/classes.js'
import globalState from '../globalState'

/*
* Global function to close sweetAlert
*/
const close = (onComplete) => {
const container = dom.getContainer()
const popup = dom.getPopup()
if (!popup) {
return
}
dom.removeClass(popup, swalClasses.show)
dom.addClass(popup, swalClasses.hide)
clearTimeout(popup.timeout)

if (!dom.isToast()) {
dom.resetPrevState()
window.onkeydown = globalState.previousWindowKeyDown
globalState.windowOnkeydownOverridden = false
}

const removePopupAndResetState = () => {
if (container.parentNode) {
container.parentNode.removeChild(container)
}
dom.removeClass(
[document.documentElement, document.body],
[
swalClasses.shown,
swalClasses['no-backdrop'],
swalClasses['has-input'],
swalClasses['toast-shown']
]
)

if (dom.isModal()) {
undoScrollbar()
undoIOSfix()
}
}

// If animation is supported, animate
if (dom.animationEndEvent && !dom.hasClass(popup, swalClasses.noanimation)) {
popup.addEventListener(dom.animationEndEvent, function swalCloseEventFinished () {
popup.removeEventListener(dom.animationEndEvent, swalCloseEventFinished)
if (dom.hasClass(popup, swalClasses.hide)) {
removePopupAndResetState()
}
})
} else {
// Otherwise, remove immediately
removePopupAndResetState()
}
if (onComplete !== null && typeof onComplete === 'function') {
setTimeout(() => {
onComplete(popup)
})
}
}
export {
close,
close as closePopup,
close as closeModal,
close as closeToast
}
30 changes: 30 additions & 0 deletions src/staticMethods/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as dom from '../utils/dom/index'

export {
getTitle,
getContent,
getImage,
getButtonsWrapper,
getActions,
getConfirmButton,
getCancelButton,
getFooter,
isLoading
} from '../utils/dom/index'

/*
* Global function to determine if swal2 popup is shown
*/
export const isVisible = () => {
return !!dom.getPopup()
}

/*
* Global function to click 'Confirm' button
*/
export const clickConfirm = () => dom.getConfirmButton().click()

/*
* Global function to click 'Cancel' button
*/
export const clickCancel = () => dom.getCancelButton().click()
24 changes: 24 additions & 0 deletions src/staticMethods/mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Returns a wrapped instance of `swal` containing `params` as defaults.
* Useful for reusing swal configuration.
*
* For example:
*
* Before:
* const textPromptOptions = { input: 'text', showCancelButton: true }
* const {value: firstName} = await swal({ ...textPromptOptions, title: 'What is your first name?' })
* const {value: lastName} = await swal({ ...textPromptOptions, title: 'What is your last name?' })
*
* After:
* const myTextPrompt = swal.mixin({ input: 'text', showCancelButton: true })
* const {value: firstName} = await myTextPrompt('What is your first name?')
* const {value: lastName} = await myTextPrompt('What is your last name?')
*
* @param params
*/
export const mixin = function (params) {
const parentSwal = this
const childSwal = (...args) =>
parentSwal(Object.assign({}, params, parentSwal.argsToParams(args)))
return Object.assign(childSwal, parentSwal)
}
59 changes: 59 additions & 0 deletions src/staticMethods/queue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// private global state for the queue feature
let currentSteps = []

/*
* Global function for chaining sweetAlert popups
*/
export const queue = function (steps) {
const swal = this
currentSteps = steps
const resetQueue = () => {
currentSteps = []
document.body.removeAttribute('data-swal2-queue-step')
}
let queueResult = []
return new Promise((resolve, reject) => {
(function step (i, callback) {
if (i < currentSteps.length) {
document.body.setAttribute('data-swal2-queue-step', i)

swal(currentSteps[i]).then((result) => {
if (typeof result.value !== 'undefined') {
queueResult.push(result.value)
step(i + 1, callback)
} else {
resetQueue()
resolve({dismiss: result.dismiss})
}
})
} else {
resetQueue()
resolve({value: queueResult})
}
})(0)
})
}

/*
* Global function for getting the index of current popup in queue
*/
export const getQueueStep = () => document.body.getAttribute('data-swal2-queue-step')

/*
* Global function for inserting a popup to the queue
*/
export const insertQueueStep = (step, index) => {
if (index && index < currentSteps.length) {
return currentSteps.splice(index, 0, step)
}
return currentSteps.push(step)
}

/*
* Global function for deleting a popup from the queue
*/
export const deleteQueueStep = (index) => {
if (typeof currentSteps[index] !== 'undefined') {
currentSteps.splice(index, 1)
}
}
29 changes: 29 additions & 0 deletions src/staticMethods/set-reset-defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { error } from '../utils/utils'
import defaultParams, {showWarningsForParams, isValidParameter} from '../utils/params'
import globalState from '../globalState'

/**
* Set default params for each popup
* @param {Object} userParams
*/
export const setDefaults = (userParams) => {
if (!userParams || typeof userParams !== 'object') {
return error('the argument for setDefaults() is required and has to be a object')
}

showWarningsForParams(userParams)

// assign valid params from userParams to popupParams
for (const param in userParams) {
if (isValidParameter(param)) {
globalState.popupParams[param] = userParams[param]
}
}
}

/**
* Reset default params for each popup
*/
export const resetDefaults = () => {
globalState.popupParams = Object.assign({}, defaultParams)
}
32 changes: 32 additions & 0 deletions src/staticMethods/showLoading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as dom from '../utils/dom/index'
import sweetAlert from '../sweetalert2'
import { swalClasses } from '../utils/classes'

/**
* Show spinner instead of Confirm button and disable Cancel button
*/
const showLoading = () => {
let popup = dom.getPopup()
if (!popup) {
sweetAlert('')
}
popup = dom.getPopup()
const actions = dom.getActions()
const confirmButton = dom.getConfirmButton()
const cancelButton = dom.getCancelButton()

dom.show(actions)
dom.show(confirmButton)
dom.addClass([popup, actions], swalClasses.loading)
confirmButton.disabled = true
cancelButton.disabled = true

popup.setAttribute('data-loading', true)
popup.setAttribute('aria-busy', true)
popup.focus()
}

export {
showLoading,
showLoading as enableLoading
}
Loading

0 comments on commit 78f8830

Please sign in to comment.