sweetalert2 11.3.3 → 11.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +2257 -0
  2. package/README.md +8 -10
  3. package/dist/sweetalert2.all.js +175 -78
  4. package/dist/sweetalert2.all.min.js +1 -1
  5. package/dist/sweetalert2.js +175 -78
  6. package/dist/sweetalert2.min.js +1 -1
  7. package/package.json +12 -8
  8. package/src/SweetAlert.js +12 -11
  9. package/src/buttons-handlers.js +32 -29
  10. package/src/globalState.js +1 -1
  11. package/src/instanceMethods/_destroy.js +2 -2
  12. package/src/instanceMethods/close.js +25 -23
  13. package/src/instanceMethods/enable-disable-elements.js +7 -7
  14. package/src/instanceMethods/getInput.js +1 -1
  15. package/src/instanceMethods/hideLoading.js +2 -5
  16. package/src/instanceMethods/progress-steps.js +1 -1
  17. package/src/instanceMethods/update.js +20 -13
  18. package/src/instanceMethods/validation-message.js +2 -2
  19. package/src/keydown-handler.js +22 -16
  20. package/src/popup-click-handler.js +3 -1
  21. package/src/privateMethods.js +1 -1
  22. package/src/privateProps.js +1 -1
  23. package/src/staticMethods/argsToParams.js +1 -1
  24. package/src/staticMethods/bindClickHandler.js +1 -1
  25. package/src/staticMethods/dom.js +1 -1
  26. package/src/staticMethods/fire.js +2 -2
  27. package/src/staticMethods/mixin.js +2 -2
  28. package/src/staticMethods/showLoading.js +1 -4
  29. package/src/staticMethods.js +1 -5
  30. package/src/utils/DismissReason.js +1 -1
  31. package/src/utils/Timer.js +6 -6
  32. package/src/utils/aria.js +2 -2
  33. package/src/utils/classes.js +1 -7
  34. package/src/utils/defaultInputValidators.js +1 -1
  35. package/src/utils/dom/animationEndEvent.js +2 -3
  36. package/src/utils/dom/domUtils.js +16 -9
  37. package/src/utils/dom/getters.js +11 -11
  38. package/src/utils/dom/init.js +3 -7
  39. package/src/utils/dom/inputUtils.js +26 -19
  40. package/src/utils/dom/parseHtmlToContainer.js +14 -3
  41. package/src/utils/dom/renderers/renderActions.js +3 -3
  42. package/src/utils/dom/renderers/renderContainer.js +3 -3
  43. package/src/utils/dom/renderers/renderContent.js +4 -2
  44. package/src/utils/dom/renderers/renderIcon.js +26 -17
  45. package/src/utils/dom/renderers/renderInput.js +30 -21
  46. package/src/utils/dom/renderers/renderPopup.js +2 -1
  47. package/src/utils/dom/renderers/renderProgressSteps.js +1 -1
  48. package/src/utils/getTemplateParams.js +43 -9
  49. package/src/utils/iosFix.js +33 -10
  50. package/src/utils/isNodeEnv.js +5 -1
  51. package/src/utils/openPopup.js +1 -1
  52. package/src/utils/params.js +2 -2
  53. package/src/utils/setParameters.js +5 -5
  54. package/src/utils/utils.js +14 -11
@@ -33,15 +33,17 @@ export const getInputValue = (instance, innerParams) => {
33
33
  }
34
34
  }
35
35
 
36
- const getCheckboxValue = (input) => input.checked ? 1 : 0
36
+ const getCheckboxValue = (input) => (input.checked ? 1 : 0)
37
37
 
38
- const getRadioValue = (input) => input.checked ? input.value : null
38
+ const getRadioValue = (input) => (input.checked ? input.value : null)
39
39
 
40
- const getFileValue = (input) => input.files.length ? (input.getAttribute('multiple') !== null ? input.files : input.files[0]) : null
40
+ const getFileValue = (input) =>
41
+ input.files.length ? (input.getAttribute('multiple') !== null ? input.files : input.files[0]) : null
41
42
 
42
43
  const handleInputOptions = (instance, params) => {
43
44
  const popup = dom.getPopup()
44
- const processInputOptions = (inputOptions) => populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params)
45
+ const processInputOptions = (inputOptions) =>
46
+ populateInputOptions[params.input](popup, formatInputOptions(inputOptions), params)
45
47
  if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
46
48
  showLoading(dom.getConfirmButton())
47
49
  asPromise(params.inputOptions).then((inputOptions) => {
@@ -58,12 +60,13 @@ const handleInputOptions = (instance, params) => {
58
60
  const handleInputValue = (instance, params) => {
59
61
  const input = instance.getInput()
60
62
  dom.hide(input)
61
- asPromise(params.inputValue).then((inputValue) => {
62
- input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : `${inputValue}`
63
- dom.show(input)
64
- input.focus()
65
- instance.hideLoading()
66
- })
63
+ asPromise(params.inputValue)
64
+ .then((inputValue) => {
65
+ input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : `${inputValue}`
66
+ dom.show(input)
67
+ input.focus()
68
+ instance.hideLoading()
69
+ })
67
70
  .catch((err) => {
68
71
  error(`Error in inputValue promise: ${err}`)
69
72
  input.value = ''
@@ -83,20 +86,22 @@ const populateInputOptions = {
83
86
  option.selected = isSelected(optionValue, params.inputValue)
84
87
  parent.appendChild(option)
85
88
  }
86
- inputOptions.forEach(inputOption => {
89
+ inputOptions.forEach((inputOption) => {
87
90
  const optionValue = inputOption[0]
88
91
  const optionLabel = inputOption[1]
89
92
  // <optgroup> spec:
90
93
  // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
91
94
  // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
92
95
  // check whether this is a <optgroup>
93
- if (Array.isArray(optionLabel)) { // if it is an array, then it is an <optgroup>
96
+ if (Array.isArray(optionLabel)) {
97
+ // if it is an array, then it is an <optgroup>
94
98
  const optgroup = document.createElement('optgroup')
95
99
  optgroup.label = optionValue
96
100
  optgroup.disabled = false // not configurable for now
97
101
  select.appendChild(optgroup)
98
- optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]))
99
- } else { // case of <option>
102
+ optionLabel.forEach((o) => renderOption(optgroup, o[1], o[0]))
103
+ } else {
104
+ // case of <option>
100
105
  renderOption(select, optionLabel, optionValue)
101
106
  }
102
107
  })
@@ -105,7 +110,7 @@ const populateInputOptions = {
105
110
 
106
111
  radio: (popup, inputOptions, params) => {
107
112
  const radio = getDirectChildByClass(popup, swalClasses.radio)
108
- inputOptions.forEach(inputOption => {
113
+ inputOptions.forEach((inputOption) => {
109
114
  const radioValue = inputOption[0]
110
115
  const radioLabel = inputOption[1]
111
116
  const radioInput = document.createElement('input')
@@ -127,7 +132,7 @@ const populateInputOptions = {
127
132
  if (radios.length) {
128
133
  radios[0].focus()
129
134
  }
130
- }
135
+ },
131
136
  }
132
137
 
133
138
  /**
@@ -139,15 +144,17 @@ const formatInputOptions = (inputOptions) => {
139
144
  if (typeof Map !== 'undefined' && inputOptions instanceof Map) {
140
145
  inputOptions.forEach((value, key) => {
141
146
  let valueFormatted = value
142
- if (typeof valueFormatted === 'object') { // case of <optgroup>
147
+ if (typeof valueFormatted === 'object') {
148
+ // case of <optgroup>
143
149
  valueFormatted = formatInputOptions(valueFormatted)
144
150
  }
145
151
  result.push([key, valueFormatted])
146
152
  })
147
153
  } else {
148
- Object.keys(inputOptions).forEach(key => {
154
+ Object.keys(inputOptions).forEach((key) => {
149
155
  let valueFormatted = inputOptions[key]
150
- if (typeof valueFormatted === 'object') { // case of <optgroup>
156
+ if (typeof valueFormatted === 'object') {
157
+ // case of <optgroup>
151
158
  valueFormatted = formatInputOptions(valueFormatted)
152
159
  }
153
160
  result.push([key, valueFormatted])
@@ -1,27 +1,38 @@
1
1
  import { setInnerHtml } from './domUtils.js'
2
2
 
3
+ /**
4
+ * @param {HTMLElement | object | string} param
5
+ * @param {HTMLElement} target
6
+ */
3
7
  export const parseHtmlToContainer = (param, target) => {
4
8
  // DOM element
5
9
  if (param instanceof HTMLElement) {
6
10
  target.appendChild(param)
11
+ }
7
12
 
8
13
  // Object
9
- } else if (typeof param === 'object') {
14
+ else if (typeof param === 'object') {
10
15
  handleObject(param, target)
16
+ }
11
17
 
12
18
  // Plain string
13
- } else if (param) {
19
+ else if (param) {
14
20
  setInnerHtml(target, param)
15
21
  }
16
22
  }
17
23
 
24
+ /**
25
+ * @param {object} param
26
+ * @param {HTMLElement} target
27
+ */
18
28
  const handleObject = (param, target) => {
19
29
  // JQuery element(s)
20
30
  if (param.jquery) {
21
31
  handleJqueryElem(target, param)
32
+ }
22
33
 
23
34
  // For other objects use their string representation
24
- } else {
35
+ else {
25
36
  setInnerHtml(target, param.toString())
26
37
  }
27
38
  }
@@ -24,7 +24,7 @@ export const renderActions = (instance, params) => {
24
24
  dom.applyCustomClass(loader, params, 'loader')
25
25
  }
26
26
 
27
- function renderButtons (actions, loader, params) {
27
+ function renderButtons(actions, loader, params) {
28
28
  const confirmButton = dom.getConfirmButton()
29
29
  const denyButton = dom.getDenyButton()
30
30
  const cancelButton = dom.getCancelButton()
@@ -47,7 +47,7 @@ function renderButtons (actions, loader, params) {
47
47
  }
48
48
  }
49
49
 
50
- function handleButtonsStyling (confirmButton, denyButton, cancelButton, params) {
50
+ function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
51
51
  if (!params.buttonsStyling) {
52
52
  return dom.removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled)
53
53
  }
@@ -69,7 +69,7 @@ function handleButtonsStyling (confirmButton, denyButton, cancelButton, params)
69
69
  }
70
70
  }
71
71
 
72
- function renderButton (button, buttonType, params) {
72
+ function renderButton(button, buttonType, params) {
73
73
  dom.toggle(button, params[`show${capitalizeFirstLetter(buttonType)}Button`], 'inline-block')
74
74
  dom.setInnerHtml(button, params[`${buttonType}ButtonText`]) // Set caption text
75
75
  button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`]) // ARIA label
@@ -2,7 +2,7 @@ import { swalClasses } from '../../classes.js'
2
2
  import { warn } from '../../utils.js'
3
3
  import * as dom from '../../dom/index.js'
4
4
 
5
- function handleBackdropParam (container, backdrop) {
5
+ function handleBackdropParam(container, backdrop) {
6
6
  if (typeof backdrop === 'string') {
7
7
  container.style.background = backdrop
8
8
  } else if (!backdrop) {
@@ -10,7 +10,7 @@ function handleBackdropParam (container, backdrop) {
10
10
  }
11
11
  }
12
12
 
13
- function handlePositionParam (container, position) {
13
+ function handlePositionParam(container, position) {
14
14
  if (position in swalClasses) {
15
15
  dom.addClass(container, swalClasses[position])
16
16
  } else {
@@ -19,7 +19,7 @@ function handlePositionParam (container, position) {
19
19
  }
20
20
  }
21
21
 
22
- function handleGrowParam (container, grow) {
22
+ function handleGrowParam(container, grow) {
23
23
  if (grow && typeof grow === 'string') {
24
24
  const growClass = `grow-${grow}`
25
25
  if (growClass in swalClasses) {
@@ -10,14 +10,16 @@ export const renderContent = (instance, params) => {
10
10
  if (params.html) {
11
11
  dom.parseHtmlToContainer(params.html, htmlContainer)
12
12
  dom.show(htmlContainer, 'block')
13
+ }
13
14
 
14
15
  // Content as plain text
15
- } else if (params.text) {
16
+ else if (params.text) {
16
17
  htmlContainer.textContent = params.text
17
18
  dom.show(htmlContainer, 'block')
19
+ }
18
20
 
19
21
  // No content
20
- } else {
22
+ else {
21
23
  dom.hide(htmlContainer)
22
24
  }
23
25
 
@@ -1,4 +1,4 @@
1
- import { swalClasses, iconTypes } from '../../classes.js'
1
+ import { iconTypes, swalClasses } from '../../classes.js'
2
2
  import { error } from '../../utils.js'
3
3
  import * as dom from '../../dom/index.js'
4
4
  import privateProps from '../../../privateProps.js'
@@ -48,14 +48,14 @@ const applyStyles = (icon, params) => {
48
48
  setColor(icon, params)
49
49
 
50
50
  // Success icon background color
51
- adjustSuccessIconBackgoundColor()
51
+ adjustSuccessIconBackgroundColor()
52
52
 
53
53
  // Custom class
54
54
  dom.applyCustomClass(icon, params, 'icon')
55
55
  }
56
56
 
57
57
  // Adjust success icon background color to match the popup background color
58
- const adjustSuccessIconBackgoundColor = () => {
58
+ const adjustSuccessIconBackgroundColor = () => {
59
59
  const popup = dom.getPopup()
60
60
  const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color')
61
61
  const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix')
@@ -64,30 +64,34 @@ const adjustSuccessIconBackgoundColor = () => {
64
64
  }
65
65
  }
66
66
 
67
+ const successIconHtml = `
68
+ <div class="swal2-success-circular-line-left"></div>
69
+ <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
70
+ <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>
71
+ <div class="swal2-success-circular-line-right"></div>
72
+ `
73
+
74
+ const errorIconHtml = `
75
+ <span class="swal2-x-mark">
76
+ <span class="swal2-x-mark-line-left"></span>
77
+ <span class="swal2-x-mark-line-right"></span>
78
+ </span>
79
+ `
80
+
67
81
  const setContent = (icon, params) => {
68
82
  icon.textContent = ''
69
83
 
70
84
  if (params.iconHtml) {
71
85
  dom.setInnerHtml(icon, iconContent(params.iconHtml))
72
86
  } else if (params.icon === 'success') {
73
- dom.setInnerHtml(icon, `
74
- <div class="swal2-success-circular-line-left"></div>
75
- <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
76
- <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>
77
- <div class="swal2-success-circular-line-right"></div>
78
- `)
87
+ dom.setInnerHtml(icon, successIconHtml)
79
88
  } else if (params.icon === 'error') {
80
- dom.setInnerHtml(icon, `
81
- <span class="swal2-x-mark">
82
- <span class="swal2-x-mark-line-left"></span>
83
- <span class="swal2-x-mark-line-right"></span>
84
- </span>
85
- `)
89
+ dom.setInnerHtml(icon, errorIconHtml)
86
90
  } else {
87
91
  const defaultIconHtml = {
88
92
  question: '?',
89
93
  warning: '!',
90
- info: 'i'
94
+ info: 'i',
91
95
  }
92
96
  dom.setInnerHtml(icon, iconContent(defaultIconHtml[params.icon]))
93
97
  }
@@ -99,7 +103,12 @@ const setColor = (icon, params) => {
99
103
  }
100
104
  icon.style.color = params.iconColor
101
105
  icon.style.borderColor = params.iconColor
102
- for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
106
+ for (const sel of [
107
+ '.swal2-success-line-tip',
108
+ '.swal2-success-line-long',
109
+ '.swal2-x-mark-line-left',
110
+ '.swal2-x-mark-line-right',
111
+ ]) {
103
112
  dom.setStyle(icon, sel, 'backgroundColor', params.iconColor)
104
113
  }
105
114
  dom.setStyle(icon, '.swal2-success-ring', 'borderColor', params.iconColor)
@@ -1,5 +1,5 @@
1
1
  import { swalClasses } from '../../classes.js'
2
- import { warn, error, isPromise } from '../../utils.js'
2
+ import { error, isPromise, warn } from '../../utils.js'
3
3
  import * as dom from '../../dom/index.js'
4
4
  import privateProps from '../../../privateProps.js'
5
5
 
@@ -36,7 +36,9 @@ export const renderInput = (instance, params) => {
36
36
 
37
37
  const showInput = (params) => {
38
38
  if (!renderInputType[params.input]) {
39
- return error(`Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "${params.input}"`)
39
+ return error(
40
+ `Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "${params.input}"`
41
+ )
40
42
  }
41
43
 
42
44
  const inputContainer = getInputContainer(params.input)
@@ -105,21 +107,24 @@ const getInputContainer = (inputType) => {
105
107
  const renderInputType = {}
106
108
 
107
109
  renderInputType.text =
108
- renderInputType.email =
109
- renderInputType.password =
110
- renderInputType.number =
111
- renderInputType.tel =
112
- renderInputType.url = (input, params) => {
113
- if (typeof params.inputValue === 'string' || typeof params.inputValue === 'number') {
114
- input.value = params.inputValue
115
- } else if (!isPromise(params.inputValue)) {
116
- warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof params.inputValue}"`)
117
- }
118
- setInputLabel(input, input, params)
119
- setInputPlaceholder(input, params)
120
- input.type = params.input
121
- return input
122
- }
110
+ renderInputType.email =
111
+ renderInputType.password =
112
+ renderInputType.number =
113
+ renderInputType.tel =
114
+ renderInputType.url =
115
+ (input, params) => {
116
+ if (typeof params.inputValue === 'string' || typeof params.inputValue === 'number') {
117
+ input.value = params.inputValue
118
+ } else if (!isPromise(params.inputValue)) {
119
+ warn(
120
+ `Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof params.inputValue}"`
121
+ )
122
+ }
123
+ setInputLabel(input, input, params)
124
+ setInputPlaceholder(input, params)
125
+ input.type = params.input
126
+ return input
127
+ }
123
128
 
124
129
  renderInputType.file = (input, params) => {
125
130
  setInputLabel(input, input, params)
@@ -172,10 +177,13 @@ renderInputType.textarea = (textarea, params) => {
172
177
  setInputPlaceholder(textarea, params)
173
178
  setInputLabel(textarea, textarea, params)
174
179
 
175
- const getMargin = (el) => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight)
180
+ const getMargin = (el) =>
181
+ parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight)
176
182
 
177
- setTimeout(() => { // #2291
178
- if ('MutationObserver' in window) { // #1699
183
+ // https://github.com/sweetalert2/sweetalert2/issues/2291
184
+ setTimeout(() => {
185
+ // https://github.com/sweetalert2/sweetalert2/issues/1699
186
+ if ('MutationObserver' in window) {
179
187
  const initialPopupWidth = parseInt(window.getComputedStyle(dom.getPopup()).width)
180
188
  const textareaResizeHandler = () => {
181
189
  const textareaWidth = textarea.offsetWidth + getMargin(textarea)
@@ -186,7 +194,8 @@ renderInputType.textarea = (textarea, params) => {
186
194
  }
187
195
  }
188
196
  new MutationObserver(textareaResizeHandler).observe(textarea, {
189
- attributes: true, attributeFilter: ['style']
197
+ attributes: true,
198
+ attributeFilter: ['style'],
190
199
  })
191
200
  }
192
201
  })
@@ -6,7 +6,8 @@ export const renderPopup = (instance, params) => {
6
6
  const popup = dom.getPopup()
7
7
 
8
8
  // Width
9
- if (params.toast) { // #2170
9
+ // https://github.com/sweetalert2/sweetalert2/issues/2170
10
+ if (params.toast) {
10
11
  dom.applyNumericalStyle(container, 'width', params.width)
11
12
  popup.style.width = '100%'
12
13
  popup.insertBefore(dom.getLoader(), dom.getIcon())
@@ -29,7 +29,7 @@ export const renderProgressSteps = (instance, params) => {
29
29
  if (params.currentProgressStep >= params.progressSteps.length) {
30
30
  warn(
31
31
  'Invalid currentProgressStep parameter, it should be less than progressSteps.length ' +
32
- '(currentProgressStep like JS arrays starts from 0)'
32
+ '(currentProgressStep like JS arrays starts from 0)'
33
33
  )
34
34
  }
35
35
 
@@ -1,5 +1,5 @@
1
1
  import defaultParams from './params.js'
2
- import { toArray, capitalizeFirstLetter, warn } from './utils.js'
2
+ import { capitalizeFirstLetter, toArray, warn } from './utils.js'
3
3
 
4
4
  const swalStringParams = ['swal-title', 'swal-html', 'swal-footer']
5
5
 
@@ -8,6 +8,7 @@ export const getTemplateParams = (params) => {
8
8
  if (!template) {
9
9
  return {}
10
10
  }
11
+ /** @type {DocumentFragment} */
11
12
  const templateContent = template.content
12
13
 
13
14
  showWarningsForElements(templateContent)
@@ -18,28 +19,33 @@ export const getTemplateParams = (params) => {
18
19
  getSwalImage(templateContent),
19
20
  getSwalIcon(templateContent),
20
21
  getSwalInput(templateContent),
21
- getSwalStringParams(templateContent, swalStringParams),
22
+ getSwalStringParams(templateContent, swalStringParams)
22
23
  )
23
24
  return result
24
25
  }
25
26
 
27
+ /**
28
+ * @param {DocumentFragment} templateContent
29
+ */
26
30
  const getSwalParams = (templateContent) => {
27
31
  const result = {}
28
32
  toArray(templateContent.querySelectorAll('swal-param')).forEach((param) => {
29
33
  showWarningsForAttributes(param, ['name', 'value'])
30
34
  const paramName = param.getAttribute('name')
31
- let value = param.getAttribute('value')
35
+ const value = param.getAttribute('value')
32
36
  if (typeof defaultParams[paramName] === 'boolean' && value === 'false') {
33
- value = false
37
+ result[paramName] = false
34
38
  }
35
39
  if (typeof defaultParams[paramName] === 'object') {
36
- value = JSON.parse(value)
40
+ result[paramName] = JSON.parse(value)
37
41
  }
38
- result[paramName] = value
39
42
  })
40
43
  return result
41
44
  }
42
45
 
46
+ /**
47
+ * @param {DocumentFragment} templateContent
48
+ */
43
49
  const getSwalButtons = (templateContent) => {
44
50
  const result = {}
45
51
  toArray(templateContent.querySelectorAll('swal-button')).forEach((button) => {
@@ -57,8 +63,12 @@ const getSwalButtons = (templateContent) => {
57
63
  return result
58
64
  }
59
65
 
66
+ /**
67
+ * @param {DocumentFragment} templateContent
68
+ */
60
69
  const getSwalImage = (templateContent) => {
61
70
  const result = {}
71
+ /** @type {HTMLElement} */
62
72
  const image = templateContent.querySelector('swal-image')
63
73
  if (image) {
64
74
  showWarningsForAttributes(image, ['src', 'width', 'height', 'alt'])
@@ -78,8 +88,12 @@ const getSwalImage = (templateContent) => {
78
88
  return result
79
89
  }
80
90
 
91
+ /**
92
+ * @param {DocumentFragment} templateContent
93
+ */
81
94
  const getSwalIcon = (templateContent) => {
82
95
  const result = {}
96
+ /** @type {HTMLElement} */
83
97
  const icon = templateContent.querySelector('swal-icon')
84
98
  if (icon) {
85
99
  showWarningsForAttributes(icon, ['type', 'color'])
@@ -94,8 +108,12 @@ const getSwalIcon = (templateContent) => {
94
108
  return result
95
109
  }
96
110
 
111
+ /**
112
+ * @param {DocumentFragment} templateContent
113
+ */
97
114
  const getSwalInput = (templateContent) => {
98
115
  const result = {}
116
+ /** @type {HTMLElement} */
99
117
  const input = templateContent.querySelector('swal-input')
100
118
  if (input) {
101
119
  showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value'])
@@ -123,10 +141,15 @@ const getSwalInput = (templateContent) => {
123
141
  return result
124
142
  }
125
143
 
144
+ /**
145
+ * @param {DocumentFragment} templateContent
146
+ * @param {string[]} paramNames
147
+ */
126
148
  const getSwalStringParams = (templateContent, paramNames) => {
127
149
  const result = {}
128
150
  for (const i in paramNames) {
129
151
  const paramName = paramNames[i]
152
+ /** @type {HTMLElement} */
130
153
  const tag = templateContent.querySelector(paramName)
131
154
  if (tag) {
132
155
  showWarningsForAttributes(tag, [])
@@ -136,7 +159,10 @@ const getSwalStringParams = (templateContent, paramNames) => {
136
159
  return result
137
160
  }
138
161
 
139
- const showWarningsForElements = (template) => {
162
+ /**
163
+ * @param {DocumentFragment} templateContent
164
+ */
165
+ const showWarningsForElements = (templateContent) => {
140
166
  const allowedElements = swalStringParams.concat([
141
167
  'swal-param',
142
168
  'swal-button',
@@ -145,7 +171,7 @@ const showWarningsForElements = (template) => {
145
171
  'swal-input',
146
172
  'swal-input-option',
147
173
  ])
148
- toArray(template.children).forEach((el) => {
174
+ toArray(templateContent.children).forEach((el) => {
149
175
  const tagName = el.tagName.toLowerCase()
150
176
  if (allowedElements.indexOf(tagName) === -1) {
151
177
  warn(`Unrecognized element <${tagName}>`)
@@ -153,12 +179,20 @@ const showWarningsForElements = (template) => {
153
179
  })
154
180
  }
155
181
 
182
+ /**
183
+ * @param {HTMLElement} el
184
+ * @param {string[]} allowedAttributes
185
+ */
156
186
  const showWarningsForAttributes = (el, allowedAttributes) => {
157
187
  toArray(el.attributes).forEach((attribute) => {
158
188
  if (allowedAttributes.indexOf(attribute.name) === -1) {
159
189
  warn([
160
190
  `Unrecognized attribute "${attribute.name}" on <${el.tagName.toLowerCase()}>.`,
161
- `${allowedAttributes.length ? `Allowed attributes are: ${allowedAttributes.join(', ')}` : 'To set the value, use HTML within the element.'}`
191
+ `${
192
+ allowedAttributes.length
193
+ ? `Allowed attributes are: ${allowedAttributes.join(', ')}`
194
+ : 'To set the value, use HTML within the element.'
195
+ }`,
162
196
  ])
163
197
  }
164
198
  })
@@ -5,20 +5,28 @@ import { swalClasses } from '../utils/classes.js'
5
5
  // Fix iOS scrolling http://stackoverflow.com/q/39626302
6
6
 
7
7
  export const iOSfix = () => {
8
- // @ts-ignore
9
- const iOS = (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
8
+ const iOS =
9
+ // @ts-ignore
10
+ (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) ||
11
+ (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
10
12
  if (iOS && !dom.hasClass(document.body, swalClasses.iosfix)) {
11
13
  const offset = document.body.scrollTop
12
14
  document.body.style.top = `${offset * -1}px`
13
15
  dom.addClass(document.body, swalClasses.iosfix)
14
16
  lockBodyScroll()
15
- addBottomPaddingForTallPopups() // #1948
17
+ addBottomPaddingForTallPopups()
16
18
  }
17
19
  }
18
20
 
21
+ /**
22
+ * https://github.com/sweetalert2/sweetalert2/issues/1948
23
+ */
19
24
  const addBottomPaddingForTallPopups = () => {
20
- const safari = !navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i)
21
- if (safari) {
25
+ const ua = navigator.userAgent
26
+ const iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i)
27
+ const webkit = !!ua.match(/WebKit/i)
28
+ const iOSSafari = iOS && webkit && !ua.match(/CriOS/i)
29
+ if (iOSSafari) {
22
30
  const bottomPanelHeight = 44
23
31
  if (dom.getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) {
24
32
  dom.getContainer().style.paddingBottom = `${bottomPanelHeight}px`
@@ -26,7 +34,10 @@ const addBottomPaddingForTallPopups = () => {
26
34
  }
27
35
  }
28
36
 
29
- const lockBodyScroll = () => { // #1246
37
+ /**
38
+ * https://github.com/sweetalert2/sweetalert2/issues/1246
39
+ */
40
+ const lockBodyScroll = () => {
30
41
  const container = dom.getContainer()
31
42
  let preventTouchMove
32
43
  container.ontouchstart = (e) => {
@@ -43,7 +54,7 @@ const lockBodyScroll = () => { // #1246
43
54
  const shouldPreventTouchMove = (event) => {
44
55
  const target = event.target
45
56
  const container = dom.getContainer()
46
- if (isStylys(event) || isZoom(event)) {
57
+ if (isStylus(event) || isZoom(event)) {
47
58
  return false
48
59
  }
49
60
  if (target === container) {
@@ -63,11 +74,23 @@ const shouldPreventTouchMove = (event) => {
63
74
  return false
64
75
  }
65
76
 
66
- const isStylys = (event) => { // #1786
77
+ /**
78
+ * https://github.com/sweetalert2/sweetalert2/issues/1786
79
+ *
80
+ * @param {*} event
81
+ * @returns {boolean}
82
+ */
83
+ const isStylus = (event) => {
67
84
  return event.touches && event.touches.length && event.touches[0].touchType === 'stylus'
68
85
  }
69
86
 
70
- const isZoom = (event) => { // #1891
87
+ /**
88
+ * https://github.com/sweetalert2/sweetalert2/issues/1891
89
+ *
90
+ * @param {TouchEvent} event
91
+ * @returns {boolean}
92
+ */
93
+ const isZoom = (event) => {
71
94
  return event.touches && event.touches.length > 1
72
95
  }
73
96
 
@@ -76,6 +99,6 @@ export const undoIOSfix = () => {
76
99
  const offset = parseInt(document.body.style.top, 10)
77
100
  dom.removeClass(document.body, swalClasses.iosfix)
78
101
  document.body.style.top = ''
79
- document.body.scrollTop = (offset * -1)
102
+ document.body.scrollTop = offset * -1
80
103
  }
81
104
  }
@@ -1,2 +1,6 @@
1
- // Detect Node env
1
+ /**
2
+ * Detect Node env
3
+ *
4
+ * @returns {boolean}
5
+ */
2
6
  export const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined'
@@ -79,7 +79,7 @@ const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) =>
79
79
 
80
80
  const addClasses = (container, popup, params) => {
81
81
  dom.addClass(container, params.showClass.backdrop)
82
- // the workaround with setting/unsetting opacity is needed for #2019 and 2059
82
+ // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
83
83
  popup.style.setProperty('opacity', '0', 'important')
84
84
  dom.show(popup, 'grid')
85
85
  setTimeout(() => {