PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.3.3
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.3.3
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
weforms / assets / wpuf / vendor / sweetalert2 / src / utils / dom.js

dom.js in weForms – Easy Drag & Drop Contact Form Builder For WordPress 1.3.3, at assets/wpuf/vendor/sweetalert2/src/utils/dom.js

333 lines 9.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global MouseEvent */
2
3 import { default as sweetAlert } from '../sweetalert2.js'
4 import { swalClasses, iconTypes } from './classes.js'
5 import { uniqueArray } from './utils.js'
6
7 // Remember state in cases where opening and handling a modal will fiddle with it.
8 export const states = {
9 previousWindowKeyDown: null,
10 previousActiveElement: null,
11 previousBodyPadding: null
12 }
13
14 /*
15 * Add modal + overlay to DOM
16 */
17 export const init = (params) => {
18 if (typeof document === 'undefined') {
19 console.error('SweetAlert2 requires document to initialize')
20 return
21 }
22
23 const container = document.createElement('div')
24 container.className = swalClasses.container
25 container.innerHTML = sweetHTML
26
27 let targetElement = document.querySelector(params.target)
28 if (!targetElement) {
29 console.warn(`SweetAlert2: Can't find the target "${params.target}"`)
30 targetElement = document.body
31 }
32 targetElement.appendChild(container)
33
34 const modal = getModal()
35 const input = getChildByClass(modal, swalClasses.input)
36 const file = getChildByClass(modal, swalClasses.file)
37 const range = modal.querySelector(`.${swalClasses.range} input`)
38 const rangeOutput = modal.querySelector(`.${swalClasses.range} output`)
39 const select = getChildByClass(modal, swalClasses.select)
40 const checkbox = modal.querySelector(`.${swalClasses.checkbox} input`)
41 const textarea = getChildByClass(modal, swalClasses.textarea)
42
43 input.oninput = () => {
44 sweetAlert.resetValidationError()
45 }
46
47 input.onkeydown = (event) => {
48 setTimeout(() => {
49 if (event.keyCode === 13 && params.allowEnterKey) {
50 event.stopPropagation()
51 sweetAlert.clickConfirm()
52 }
53 }, 0)
54 }
55
56 file.onchange = () => {
57 sweetAlert.resetValidationError()
58 }
59
60 range.oninput = () => {
61 sweetAlert.resetValidationError()
62 rangeOutput.value = range.value
63 }
64
65 range.onchange = () => {
66 sweetAlert.resetValidationError()
67 range.previousSibling.value = range.value
68 }
69
70 select.onchange = () => {
71 sweetAlert.resetValidationError()
72 }
73
74 checkbox.onchange = () => {
75 sweetAlert.resetValidationError()
76 }
77
78 textarea.oninput = () => {
79 sweetAlert.resetValidationError()
80 }
81
82 return modal
83 }
84
85 /*
86 * Manipulate DOM
87 */
88
89 const sweetHTML = `
90 <div role="dialog" aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses.content}" class="${swalClasses.modal}" tabindex="-1">
91 <ul class="${swalClasses.progresssteps}"></ul>
92 <div class="${swalClasses.icon} ${iconTypes.error}">
93 <span class="swal2-x-mark"><span class="swal2-x-mark-line-left"></span><span class="swal2-x-mark-line-right"></span></span>
94 </div>
95 <div class="${swalClasses.icon} ${iconTypes.question}">?</div>
96 <div class="${swalClasses.icon} ${iconTypes.warning}">!</div>
97 <div class="${swalClasses.icon} ${iconTypes.info}">i</div>
98 <div class="${swalClasses.icon} ${iconTypes.success}">
99 <div class="swal2-success-circular-line-left"></div>
100 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
101 <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>
102 <div class="swal2-success-circular-line-right"></div>
103 </div>
104 <img class="${swalClasses.image}">
105 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
106 <div id="${swalClasses.content}" class="${swalClasses.content}"></div>
107 <input class="${swalClasses.input}">
108 <input type="file" class="${swalClasses.file}">
109 <div class="${swalClasses.range}">
110 <output></output>
111 <input type="range">
112 </div>
113 <select class="${swalClasses.select}"></select>
114 <div class="${swalClasses.radio}"></div>
115 <label for="${swalClasses.checkbox}" class="${swalClasses.checkbox}">
116 <input type="checkbox">
117 </label>
118 <textarea class="${swalClasses.textarea}"></textarea>
119 <div class="${swalClasses.validationerror}"></div>
120 <div class="${swalClasses.buttonswrapper}">
121 <button type="button" class="${swalClasses.confirm}">OK</button>
122 <button type="button" class="${swalClasses.cancel}">Cancel</button>
123 </div>
124 <button type="button" class="${swalClasses.close}" aria-label="Close this dialog">&times;</button>
125 </div>
126 `.replace(/(^|\n)\s*/g, '')
127
128 export const getContainer = () => document.body.querySelector('.' + swalClasses.container)
129
130 export const getModal = () => getContainer() ? getContainer().querySelector('.' + swalClasses.modal) : null
131
132 export const getIcons = () => {
133 const modal = getModal()
134 return modal.querySelectorAll('.' + swalClasses.icon)
135 }
136
137 export const elementByClass = (className) => getContainer() ? getContainer().querySelector('.' + className) : null
138
139 export const getTitle = () => elementByClass(swalClasses.title)
140
141 export const getContent = () => elementByClass(swalClasses.content)
142
143 export const getImage = () => elementByClass(swalClasses.image)
144
145 export const getButtonsWrapper = () => elementByClass(swalClasses.buttonswrapper)
146
147 export const getProgressSteps = () => elementByClass(swalClasses.progresssteps)
148
149 export const getValidationError = () => elementByClass(swalClasses.validationerror)
150
151 export const getConfirmButton = () => elementByClass(swalClasses.confirm)
152
153 export const getCancelButton = () => elementByClass(swalClasses.cancel)
154
155 export const getCloseButton = () => elementByClass(swalClasses.close)
156
157 export const getFocusableElements = (focusCancel) => {
158 const buttons = [getConfirmButton(), getCancelButton()]
159 if (focusCancel) {
160 buttons.reverse()
161 }
162 const focusableElements = buttons.concat(Array.prototype.slice.call(
163 getModal().querySelectorAll('button, input:not([type=hidden]), textarea, select, a, *[tabindex]:not([tabindex="-1"])')
164 ))
165 return uniqueArray(focusableElements)
166 }
167
168 export const hasClass = (elem, className) => {
169 if (elem.classList) {
170 return elem.classList.contains(className)
171 }
172 return false
173 }
174
175 export const focusInput = (input) => {
176 input.focus()
177
178 // place cursor at end of text in text input
179 if (input.type !== 'file') {
180 // http://stackoverflow.com/a/2345915/1331425
181 const val = input.value
182 input.value = ''
183 input.value = val
184 }
185 }
186
187 export const addClass = (elem, className) => {
188 if (!elem || !className) {
189 return
190 }
191 const classes = className.split(/\s+/).filter(Boolean)
192 classes.forEach((className) => {
193 elem.classList.add(className)
194 })
195 }
196
197 export const removeClass = (elem, className) => {
198 if (!elem || !className) {
199 return
200 }
201 const classes = className.split(/\s+/).filter(Boolean)
202 classes.forEach((className) => {
203 elem.classList.remove(className)
204 })
205 }
206
207 export const getChildByClass = (elem, className) => {
208 for (let i = 0; i < elem.childNodes.length; i++) {
209 if (hasClass(elem.childNodes[i], className)) {
210 return elem.childNodes[i]
211 }
212 }
213 }
214
215 export const show = (elem, display) => {
216 if (!display) {
217 display = 'block'
218 }
219 elem.style.opacity = ''
220 elem.style.display = display
221 }
222
223 export const hide = (elem) => {
224 elem.style.opacity = ''
225 elem.style.display = 'none'
226 }
227
228 export const empty = (elem) => {
229 while (elem.firstChild) {
230 elem.removeChild(elem.firstChild)
231 }
232 }
233
234 // borrowed from jqeury $(elem).is(':visible') implementation
235 export const isVisible = (elem) => elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length
236
237 export const removeStyleProperty = (elem, property) => {
238 if (elem.style.removeProperty) {
239 elem.style.removeProperty(property)
240 } else {
241 elem.style.removeAttribute(property)
242 }
243 }
244
245 export const fireClick = (node) => {
246 if (!isVisible(node)) {
247 return false
248 }
249
250 // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/
251 // Then fixed for today's Chrome browser.
252 if (typeof MouseEvent === 'function') {
253 // Up-to-date approach
254 const mevt = new MouseEvent('click', {
255 view: window,
256 bubbles: false,
257 cancelable: true
258 })
259 node.dispatchEvent(mevt)
260 } else if (document.createEvent) {
261 // Fallback
262 const evt = document.createEvent('MouseEvents')
263 evt.initEvent('click', false, false)
264 node.dispatchEvent(evt)
265 } else if (document.createEventObject) {
266 node.fireEvent('onclick')
267 } else if (typeof node.onclick === 'function') {
268 node.onclick()
269 }
270 }
271
272 export const animationEndEvent = (() => {
273 const testEl = document.createElement('div')
274 const transEndEventNames = {
275 'WebkitAnimation': 'webkitAnimationEnd',
276 'OAnimation': 'oAnimationEnd oanimationend',
277 'msAnimation': 'MSAnimationEnd',
278 'animation': 'animationend'
279 }
280 for (const i in transEndEventNames) {
281 if (transEndEventNames.hasOwnProperty(i) &&
282 testEl.style[i] !== undefined) {
283 return transEndEventNames[i]
284 }
285 }
286
287 return false
288 })()
289
290 // Reset previous window keydown handler and focued element
291 export const resetPrevState = () => {
292 window.onkeydown = states.previousWindowKeyDown
293 if (states.previousActiveElement && states.previousActiveElement.focus) {
294 let x = window.scrollX
295 let y = window.scrollY
296 states.previousActiveElement.focus()
297 if (x && y) { // IE has no scrollX/scrollY support
298 window.scrollTo(x, y)
299 }
300 }
301 }
302
303 // Measure width of scrollbar
304 // https://github.com/twbs/bootstrap/blob/master/js/modal.js#L279-L286
305 export const measureScrollbar = () => {
306 var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints
307 if (supportsTouch) {
308 return 0
309 }
310 const scrollDiv = document.createElement('div')
311 scrollDiv.style.width = '50px'
312 scrollDiv.style.height = '50px'
313 scrollDiv.style.overflow = 'scroll'
314 document.body.appendChild(scrollDiv)
315 const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
316 document.body.removeChild(scrollDiv)
317 return scrollbarWidth
318 }
319
320 // JavaScript Debounce Function
321 // Simplivied version of https://davidwalsh.name/javascript-debounce-function
322 export const debounce = (func, wait) => {
323 let timeout
324 return () => {
325 const later = () => {
326 timeout = null
327 func()
328 }
329 clearTimeout(timeout)
330 timeout = setTimeout(later, wait)
331 }
332 }
333