1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | import { Xt } from './xt.mjs'
|
8 | import JSON5 from 'json5'
|
9 | import * as focusTrap from 'focus-trap'
|
10 | Xt.JSON5 = JSON5
|
11 | Xt.focusTrap = focusTrap
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | class Toggle {
|
17 | |
18 |
|
19 |
|
20 | _optionsCustom
|
21 | _optionsDefault
|
22 | _optionsInitial
|
23 | _componentNs
|
24 | _mode
|
25 | _classes = []
|
26 | _classesIn = []
|
27 | _classesOut = []
|
28 | _classesDone = []
|
29 | _classesInitial = []
|
30 | _classesBefore = []
|
31 | _classesAfter = []
|
32 | _initialCurrents = []
|
33 | _destroyElements
|
34 | _containerElements
|
35 | _containerTargets
|
36 | _oldIndex
|
37 | _inverse
|
38 | _queueIn = []
|
39 | _queueOut = []
|
40 | _autoblock
|
41 | _disabledManual
|
42 | _hasHash
|
43 | _autorunning
|
44 | _observer
|
45 | _focusTrap
|
46 | _hasContainer
|
47 | _search = ''
|
48 | componentName
|
49 | ns
|
50 | options
|
51 | initial
|
52 | disabled = false
|
53 | container
|
54 | elements = []
|
55 | targets = []
|
56 | index
|
57 | direction
|
58 |
|
59 |
|
60 | _usedWidth
|
61 | _wrap
|
62 | _keepHeight
|
63 | _autoHeight
|
64 | _groups
|
65 | drag = {}
|
66 | pags
|
67 |
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | constructor(object, optionsCustom = {}) {
|
75 | const self = this
|
76 | self.container = object
|
77 | self._optionsCustom = optionsCustom
|
78 | self.componentName = self.constructor.componentName
|
79 | self._componentNs = self.componentName.replace('-', '.')
|
80 |
|
81 | Xt._set({ name: self.componentName, el: self.container, self })
|
82 |
|
83 | self._init()
|
84 | }
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | |
91 |
|
92 |
|
93 | _init() {
|
94 | const self = this
|
95 |
|
96 | self._initVars()
|
97 | self._initLogic()
|
98 | }
|
99 |
|
100 | |
101 |
|
102 |
|
103 | _initVars() {
|
104 | const self = this
|
105 |
|
106 | self._optionsDefault = Xt.merge([self.constructor.optionsDefaultSuper, self.constructor.optionsDefault])
|
107 | self._optionsDefault = Xt.merge([self._optionsDefault, Xt.options[self.componentName]])
|
108 | self._optionsInitial = self.options = Xt.merge([self._optionsDefault, self._optionsCustom])
|
109 |
|
110 | const options = self.options
|
111 | self._classes = options.class ? [...options.class.split(' ')] : []
|
112 | self._classesIn = options.classIn ? [...options.classIn.split(' ')] : []
|
113 | self._classesOut = options.classOut ? [...options.classOut.split(' ')] : []
|
114 | self._classesDone = options.classDone ? [...options.classDone.split(' ')] : []
|
115 | self._classesInitial = options.classInitial ? [...options.classInitial.split(' ')] : []
|
116 | self._classesBefore = options.classBefore ? [...options.classBefore.split(' ')] : []
|
117 | self._classesAfter = options.classAfter ? [...options.classAfter.split(' ')] : []
|
118 | }
|
119 |
|
120 | |
121 |
|
122 |
|
123 |
|
124 |
|
125 | _initLogic({ save = true } = {}) {
|
126 | const self = this
|
127 |
|
128 | self._destroyElements = [document, window, self.container]
|
129 |
|
130 | self.enable()
|
131 |
|
132 | self._initSetup()
|
133 | Xt._initMatches({ self, optionsInitial: self._optionsInitial })
|
134 | self._initScope()
|
135 | self._initEvents()
|
136 | self._initA11y()
|
137 | self._initStart({ save })
|
138 |
|
139 | if (self.options.disabled || self._disabledManual) {
|
140 | self.disable()
|
141 | }
|
142 | }
|
143 |
|
144 | |
145 |
|
146 |
|
147 | _initSetup() {
|
148 | const self = this
|
149 | const options = self.options
|
150 |
|
151 | self._containerTargets = self.container
|
152 | if (options.targets && options.targets.indexOf('#') !== -1) {
|
153 | self._mode = 'unique'
|
154 | self._containerTargets = document.documentElement
|
155 | self.ns = `${self.componentName}-${options.targets.toString()}-${self._classes.toString()}`
|
156 | } else {
|
157 | self._mode = 'multiple'
|
158 | self.ns = self.ns ?? Xt.uniqueId()
|
159 | }
|
160 |
|
161 | self.ns = self.ns.replace(/^[^a-z]+|[ ,#_:.-]+/gi, '')
|
162 |
|
163 | self._addNamespace()
|
164 |
|
165 | self._setCurrents([])
|
166 | }
|
167 |
|
168 | |
169 |
|
170 |
|
171 | _initScope() {
|
172 | const self = this
|
173 |
|
174 | self._initScopeElements()
|
175 |
|
176 | self._initScopeTargets()
|
177 | }
|
178 |
|
179 | |
180 |
|
181 |
|
182 | _initScopeElements() {
|
183 | const self = this
|
184 | const options = self.options
|
185 |
|
186 | self._containerElements = self.container
|
187 | if (options.elements) {
|
188 | if (options.elements.indexOf('#') !== -1) {
|
189 | self._containerElements = document.documentElement
|
190 | }
|
191 | let arr = Array.from(self._containerElements.querySelectorAll(options.elements))
|
192 | if (options.exclude) {
|
193 | arr = arr.filter(x => !x.matches(options.exclude))
|
194 | }
|
195 | self.elements = arr
|
196 | self._destroyElements.push(...self.elements)
|
197 | }
|
198 |
|
199 | if (!self.elements.length) {
|
200 | self.elements = [self.container]
|
201 | }
|
202 |
|
203 | if (options.elementsInner) {
|
204 | for (const el of self.elements) {
|
205 | const elements = Xt.queryAll({ els: el, query: options.elementsInner })
|
206 | Xt.dataStorage.set(el, `elementsInner/${self.ns}`, elements)
|
207 | }
|
208 | }
|
209 | }
|
210 |
|
211 | |
212 |
|
213 |
|
214 | _initScopeTargets() {
|
215 | const self = this
|
216 | const options = self.options
|
217 |
|
218 | if (options.targets) {
|
219 | let arr = Array.from(self._containerTargets.querySelectorAll(options.targets))
|
220 | if (options.exclude) {
|
221 | arr = arr.filter(x => !x.matches(options.exclude))
|
222 | }
|
223 | self.targets = arr
|
224 | self._destroyElements.push(...self.targets)
|
225 |
|
226 | if (options.targetsInner) {
|
227 | for (const tr of self.targets) {
|
228 | const elements = Xt.queryAll({ els: tr, query: options.targetsInner })
|
229 | Xt.dataStorage.set(tr, `targetsInner/${self.ns}`, elements)
|
230 | }
|
231 | }
|
232 | }
|
233 | }
|
234 |
|
235 | |
236 |
|
237 |
|
238 |
|
239 |
|
240 | _initStart({ save = false } = {}) {
|
241 | const self = this
|
242 | const options = self.options
|
243 |
|
244 | self._setCurrents([])
|
245 |
|
246 | let currents = 0
|
247 | self.initial = true
|
248 | self.index = null
|
249 | self._oldIndex = null
|
250 | Xt._running[self.ns] = []
|
251 |
|
252 |
|
253 | currents = self._initActivate({ save })
|
254 |
|
255 | const todo = options.min - currents
|
256 | const start = 0
|
257 | if (todo > 0) {
|
258 |
|
259 | currents += todo
|
260 | }
|
261 |
|
262 | if (todo > 0) {
|
263 | for (let i = start; i < todo; i++) {
|
264 | const el = self.elements[i]
|
265 | if (el) {
|
266 |
|
267 | if (options.on) {
|
268 | const event = options.on.split(' ')[0]
|
269 | const elEvent = self._getEventParent({ el, event })
|
270 | elEvent.dispatchEvent(new CustomEvent(event, { detail: { force: true } }))
|
271 | } else {
|
272 | self._eventOn({ el, force: true })
|
273 | }
|
274 | }
|
275 | }
|
276 | }
|
277 |
|
278 | if (save) {
|
279 | self._initialCurrents = self._getCurrents().slice(0)
|
280 | }
|
281 |
|
282 | if (currents === 0) {
|
283 |
|
284 |
|
285 | Xt.frameDouble({
|
286 | el: self.container,
|
287 | ns: `${self.ns}Init`,
|
288 | func: () => {
|
289 |
|
290 | self.container.setAttribute(`data-${self.componentName}-init`, '')
|
291 |
|
292 | self.container.dispatchEvent(new CustomEvent(`init.${self._componentNs}`))
|
293 |
|
294 | self._eventAutostart()
|
295 |
|
296 | self.initial = false
|
297 |
|
298 | if (options.debug) {
|
299 |
|
300 | console.debug(`${self.componentName} init`, self)
|
301 | }
|
302 | },
|
303 | })
|
304 | }
|
305 | }
|
306 |
|
307 | |
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 | _initActivate({ save = false } = {}) {
|
314 | const self = this
|
315 | const options = self.options
|
316 |
|
317 | const checkClass = el => {
|
318 | for (const c of self._classes) {
|
319 | if (el.classList.contains(c) || el.checked) {
|
320 | return true
|
321 | }
|
322 | }
|
323 | return false
|
324 | }
|
325 |
|
326 | const obj = self._hashChange({ save })
|
327 | let currents = obj.currents ?? 0
|
328 |
|
329 | for (const el of self.getElementsGroups()) {
|
330 | let activated = false
|
331 |
|
332 | if (save) {
|
333 | if (options.classSkip !== true && !options.classSkip.elements) {
|
334 | activated = checkClass(el)
|
335 | }
|
336 | } else if (self._initialCurrents.includes(el)) {
|
337 | activated = true
|
338 | }
|
339 |
|
340 |
|
341 |
|
342 | if ((activated && currents < options.max) || obj.arr.includes(el)) {
|
343 |
|
344 | el.classList.add(...self._classes)
|
345 | el.classList.add(...self._classesIn)
|
346 | el.classList.add(...self._classesInitial)
|
347 | } else {
|
348 |
|
349 | if (options.classSkip !== true && !options.classSkip.elements) {
|
350 | const elsSame = self.getElements({ el })
|
351 | for (const elSame of elsSame) {
|
352 | elSame.classList.remove(
|
353 | ...self._classes,
|
354 | ...self._classesIn,
|
355 | ...self._classesOut,
|
356 | ...self._classesDone,
|
357 | ...self._classesInitial,
|
358 | ...self._classesBefore,
|
359 | ...self._classesAfter
|
360 | )
|
361 | }
|
362 | }
|
363 | if (options.elementsInner) {
|
364 | if (options.classSkip !== true && !options.classSkip.elementsInner) {
|
365 | const elementsInner = Xt.dataStorage.get(el, `elementsInner/${self.ns}`)
|
366 | for (const elementInner of elementsInner) {
|
367 | elementInner.classList.remove(
|
368 | ...self._classes,
|
369 | ...self._classesIn,
|
370 | ...self._classesOut,
|
371 | ...self._classesDone,
|
372 | ...self._classesInitial,
|
373 | ...self._classesBefore,
|
374 | ...self._classesAfter
|
375 | )
|
376 | }
|
377 | }
|
378 | }
|
379 | }
|
380 |
|
381 | const targets = self.getTargets({ el })
|
382 | for (const tr of targets) {
|
383 |
|
384 | if (save && !activated) {
|
385 | if (options.classSkip !== true && !options.classSkip.targets) {
|
386 | activated = checkClass(tr)
|
387 | }
|
388 | }
|
389 |
|
390 |
|
391 |
|
392 | const els = self.getElements({ el: tr, same: true })
|
393 | if ((activated && currents < options.max) || obj.arr.some(x => els.includes(x))) {
|
394 |
|
395 | tr.classList.add(...self._classes)
|
396 | tr.classList.add(...self._classesIn)
|
397 | tr.classList.add(...self._classesInitial)
|
398 | } else {
|
399 |
|
400 | if (options.classSkip !== true && !options.classSkip.targets) {
|
401 | tr.classList.remove(
|
402 | ...self._classes,
|
403 | ...self._classesIn,
|
404 | ...self._classesOut,
|
405 | ...self._classesDone,
|
406 | ...self._classesInitial,
|
407 | ...self._classesBefore,
|
408 | ...self._classesAfter
|
409 | )
|
410 | }
|
411 | if (options.targetsInner) {
|
412 | if (options.classSkip !== true && !options.classSkip.targetsInner) {
|
413 | const targetsInner = Xt.dataStorage.get(tr, `targetsInner/${self.ns}`)
|
414 | for (const targetInner of targetsInner) {
|
415 | targetInner.classList.remove(
|
416 | ...self._classes,
|
417 | ...self._classesIn,
|
418 | ...self._classesOut,
|
419 | ...self._classesDone,
|
420 | ...self._classesInitial,
|
421 | ...self._classesBefore,
|
422 | ...self._classesAfter
|
423 | )
|
424 | }
|
425 | }
|
426 | }
|
427 | }
|
428 | }
|
429 |
|
430 | if (activated && currents < options.max) {
|
431 |
|
432 | currents++
|
433 |
|
434 | obj.arr.push(el)
|
435 |
|
436 | if (options.on) {
|
437 | const event = options.on.split(' ')[0]
|
438 | const elEvent = self._getEventParent({ el, event })
|
439 | elEvent.dispatchEvent(new CustomEvent(event, { detail: { force: true } }))
|
440 | } else {
|
441 | self._eventOn({ el, force: true })
|
442 | }
|
443 | }
|
444 | }
|
445 |
|
446 | return currents
|
447 | }
|
448 |
|
449 | |
450 |
|
451 |
|
452 | _initEvents() {
|
453 | const self = this
|
454 | const options = self.options
|
455 |
|
456 | self._removeEvents()
|
457 |
|
458 | for (const el of self.elements) {
|
459 |
|
460 | const onHandlerCustom = Xt.dataStorage.put(
|
461 | el,
|
462 | `${options.on}/oncustom/${self.ns}`,
|
463 | self._eventOnHandler.bind(self, { el, force: true })
|
464 | )
|
465 | el.addEventListener(`on.trigger.${self._componentNs}`, onHandlerCustom)
|
466 | if (options.on) {
|
467 | const events = [...options.on.split(' ')]
|
468 | for (const event of events) {
|
469 | const elEvent = self._getEventParent({ el, event })
|
470 | if (elEvent !== el) {
|
471 | self._destroyElements.push(elEvent)
|
472 | }
|
473 | const onHandler = Xt.dataStorage.put(
|
474 | elEvent,
|
475 | `${options.on}/on/${self.ns}`,
|
476 | self._eventOnHandler.bind(self, { el })
|
477 | )
|
478 | elEvent.addEventListener(event, onHandler)
|
479 | }
|
480 | }
|
481 |
|
482 | const offHandlerCustom = Xt.dataStorage.put(
|
483 | el,
|
484 | `${options.off}/offcustom/${self.ns}`,
|
485 | self._eventOffHandler.bind(self, { el, force: true })
|
486 | )
|
487 | el.addEventListener(`off.trigger.${self._componentNs}`, offHandlerCustom)
|
488 | if (options.off) {
|
489 | const events = [...options.off.split(' ')]
|
490 | for (const event of events) {
|
491 |
|
492 | if (![...options.on.split(' ')].includes(event)) {
|
493 | const elEvent = self._getEventParent({ el, event })
|
494 | if (elEvent !== el) {
|
495 | self._destroyElements.push(elEvent)
|
496 | }
|
497 | const offHandler = Xt.dataStorage.put(
|
498 | elEvent,
|
499 | `${options.off}/off/${self.ns}`,
|
500 | self._eventOffHandler.bind(self, { el })
|
501 | )
|
502 | elEvent.addEventListener(event, offHandler)
|
503 | }
|
504 | }
|
505 | }
|
506 |
|
507 | if (options.on) {
|
508 | if (options.preventEvent) {
|
509 | const events = [...options.on.split(' ')]
|
510 | if (events.includes('click') || events.includes('mouseenter') || events.includes('mousehover')) {
|
511 |
|
512 | const preventeventStartHandler = Xt.dataStorage.put(
|
513 | el,
|
514 | `touchend/preventevent/${self.ns}`,
|
515 | self._eventPreventeventStartHandler.bind(self, { el })
|
516 | )
|
517 | el.addEventListener('touchend', preventeventStartHandler)
|
518 | }
|
519 | if (events.includes('click')) {
|
520 |
|
521 | const preventeventStartHandler = Xt.dataStorage.put(
|
522 | el,
|
523 | `mouseup keyup/preventevent/${self.ns}`,
|
524 | self._eventPreventeventStartHandler.bind(self, { el })
|
525 | )
|
526 | el.addEventListener('mouseup', preventeventStartHandler)
|
527 | el.addEventListener('keyup', preventeventStartHandler)
|
528 | }
|
529 | }
|
530 | Xt.dataStorage.put(el, `active/preventevent/${self.ns}`, self.hasCurrent({ el }))
|
531 | }
|
532 | }
|
533 |
|
534 | for (const tr of self.targets) {
|
535 |
|
536 | const onHandlerCustom = Xt.dataStorage.put(
|
537 | tr,
|
538 | `${options.on}/oncustom/${self.ns}`,
|
539 | self._eventOnHandler.bind(self, { el: tr, force: true })
|
540 | )
|
541 | tr.addEventListener(`on.trigger.${self._componentNs}`, onHandlerCustom)
|
542 |
|
543 | const offHandlerCustom = Xt.dataStorage.put(
|
544 | tr,
|
545 | `${options.off}/offcustom/${self.ns}`,
|
546 | self._eventOffHandler.bind(self, { el: tr, force: true })
|
547 | )
|
548 | tr.addEventListener(`off.trigger.${self._componentNs}`, offHandlerCustom)
|
549 | }
|
550 |
|
551 | if (options.auto && options.auto.time) {
|
552 | const autostartHandler = Xt.dataStorage.put(
|
553 | self.container,
|
554 | `autostart/${self.ns}`,
|
555 | self._eventAutostart.bind(self)
|
556 | )
|
557 | const autostopHandler = Xt.dataStorage.put(self.container, `autostop/${self.ns}`, self._eventAutostop.bind(self))
|
558 |
|
559 |
|
560 | const focusHandler = Xt.dataStorage.set(window, `focus/auto/${self.ns}`, autostartHandler)
|
561 | addEventListener('focus', focusHandler)
|
562 |
|
563 |
|
564 | const blurHandler = Xt.dataStorage.set(window, `blur/auto/${self.ns}`, autostopHandler)
|
565 | addEventListener('blur', blurHandler)
|
566 |
|
567 | self.container.addEventListener(`autostart.trigger.${self._componentNs}`, autostartHandler)
|
568 | self.container.addEventListener(`autostop.trigger.${self._componentNs}`, autostopHandler)
|
569 |
|
570 | if (options.auto.pause) {
|
571 | const autopauseEls = self.container.querySelectorAll(options.auto.pause)
|
572 | if (autopauseEls.length) {
|
573 | self._destroyElements.push(...autopauseEls)
|
574 | for (const el of autopauseEls) {
|
575 |
|
576 | const autopauseOnHandler = Xt.dataStorage.put(
|
577 | el,
|
578 | `mouseenter focus/auto/${self.ns}`,
|
579 | self._eventAutostop.bind(self)
|
580 | )
|
581 | const eventsPause = ['mouseenter', 'focus']
|
582 | for (const event of eventsPause) {
|
583 | el.addEventListener(event, autopauseOnHandler)
|
584 | }
|
585 |
|
586 | const autoresumeOnHandler = Xt.dataStorage.put(
|
587 | el,
|
588 | `mouseleave blur/auto/${self.ns}`,
|
589 | self._eventAutostart.bind(self)
|
590 | )
|
591 | const eventsResume = ['mouseleave', 'blur']
|
592 | for (const event of eventsResume) {
|
593 | el.addEventListener(event, autoresumeOnHandler)
|
594 | }
|
595 | }
|
596 | }
|
597 | }
|
598 | }
|
599 |
|
600 | if (options.hash) {
|
601 | for (const el of self.elements) {
|
602 | if (el.getAttribute(options.hash)) {
|
603 | self._hasHash = true
|
604 | break
|
605 | }
|
606 | }
|
607 | if (!self._hasHash) {
|
608 | for (const tr of self.targets) {
|
609 | if (tr.getAttribute(options.hash)) {
|
610 | self._hasHash = true
|
611 | break
|
612 | }
|
613 | }
|
614 | }
|
615 | }
|
616 | if (self._hasHash) {
|
617 |
|
618 | const hashHandler = Xt.dataStorage.put(
|
619 | window,
|
620 | `popstate/${self.ns}`,
|
621 | self._hashChange.bind(self).bind(self, { save: true })
|
622 | )
|
623 | addEventListener('popstate', hashHandler)
|
624 | }
|
625 |
|
626 | if (options.jump) {
|
627 | for (const el of self.targets) {
|
628 | const jumpHandler = Xt.dataStorage.put(
|
629 | el,
|
630 | `click/jump/${self.ns}`,
|
631 | self._eventJumpHandler.bind(self).bind(self, { el })
|
632 | )
|
633 | el.addEventListener('click', jumpHandler, true)
|
634 |
|
635 | if (!self.disabled) {
|
636 | el.classList.add('xt-jump')
|
637 | }
|
638 | }
|
639 | }
|
640 |
|
641 | if (options.navigation) {
|
642 | self.navs = self.container.querySelectorAll(options.navigation)
|
643 | if (self.navs.length) {
|
644 | self._destroyElements.push(...self.navs)
|
645 | for (const el of self.navs) {
|
646 | const navHandler = Xt.dataStorage.put(
|
647 | el,
|
648 | `click/nav/${self.ns}`,
|
649 | self._eventNavHandler.bind(self).bind(self, { el })
|
650 | )
|
651 | el.addEventListener('click', navHandler)
|
652 | }
|
653 | }
|
654 | }
|
655 |
|
656 | if (options.closeauto) {
|
657 |
|
658 | const closeautoHandler = Xt.dataStorage.set(
|
659 | window,
|
660 | `closeauto.trigger.xt/${self.ns}`,
|
661 | self._eventCloseautoHandler.bind(self)
|
662 | )
|
663 | addEventListener('closeauto.trigger.xt', closeautoHandler, true)
|
664 | }
|
665 | if (options.openauto) {
|
666 |
|
667 | const openautoHandler = Xt.dataStorage.set(
|
668 | window,
|
669 | `openauto.trigger.xt/${self.ns}`,
|
670 | self._eventOpenautoHandler.bind(self)
|
671 | )
|
672 | addEventListener('openauto.trigger.xt', openautoHandler, true)
|
673 | }
|
674 |
|
675 | if (options.mediaLoaded || options.mediaLoadedReinit) {
|
676 | for (const el of self.elements) {
|
677 | const imgs = Array.from(el.querySelectorAll('img'))
|
678 | self._destroyElements.push(...imgs)
|
679 | for (const img of imgs) {
|
680 | if (!Xt.dataStorage.get(img, `${self.ns}MedialoadedDone`)) {
|
681 | Xt.dataStorage.set(img, `${self.ns}MedialoadedDone`, true)
|
682 | if (!img.complete) {
|
683 | const medialoadedHandler = Xt.dataStorage.put(
|
684 | img,
|
685 | `load/media/${self.ns}`,
|
686 | self._eventMedialoadedHandler.bind(self).bind(self, { img, el, deferred: true })
|
687 | )
|
688 | img.addEventListener('load', medialoadedHandler)
|
689 | } else {
|
690 | self._eventMedialoadedHandler({ img, el })
|
691 | }
|
692 | }
|
693 | }
|
694 | }
|
695 | for (const tr of self.targets) {
|
696 | const imgs = Array.from(tr.querySelectorAll('img'))
|
697 | self._destroyElements.push(...imgs)
|
698 | for (const img of imgs) {
|
699 | if (!Xt.dataStorage.get(img, `${self.ns}MedialoadedDone`)) {
|
700 | if (!img.complete) {
|
701 | const medialoadedHandler = Xt.dataStorage.put(
|
702 | img,
|
703 | `load/media/${self.ns}`,
|
704 | self._eventMedialoadedHandler.bind(self).bind(self, { img, el: tr, deferred: true, reinit: true })
|
705 | )
|
706 | img.addEventListener('load', medialoadedHandler)
|
707 | } else {
|
708 | self._eventMedialoadedHandler({ img, el: tr })
|
709 | }
|
710 | }
|
711 | }
|
712 | }
|
713 | }
|
714 |
|
715 | if (options.visibleReinit) {
|
716 | if (!Xt.visible({ el: self.container })) {
|
717 |
|
718 | self._observer = new IntersectionObserver(
|
719 | (entries, observer) => {
|
720 | for (const entry of entries) {
|
721 | if (entry.intersectionRatio > 0) {
|
722 | self._eventVisibleReinit()
|
723 | observer.disconnect()
|
724 | self._observer = null
|
725 | }
|
726 | }
|
727 | },
|
728 | { root: null }
|
729 | )
|
730 | self._observer.observe(self.container)
|
731 | }
|
732 | }
|
733 | }
|
734 |
|
735 |
|
736 |
|
737 |
|
738 |
|
739 | |
740 |
|
741 |
|
742 |
|
743 |
|
744 |
|
745 |
|
746 | _eventOnHandler({ el, force = false }, e) {
|
747 | const self = this
|
748 | const options = self.options
|
749 | force = force ? force : e?.detail?.force
|
750 |
|
751 | el = options.groupElements || self.targets.includes(el) ? self.getElements({ el })[0] : el
|
752 |
|
753 | if (!force && options.eventLimit) {
|
754 | const eventLimit = self._containerElements.querySelectorAll(options.eventLimit)
|
755 | if (self._containerElements.matches(options.eventLimit)) {
|
756 | return
|
757 | } else if (eventLimit.length) {
|
758 | if (Xt.contains({ els: eventLimit, tr: e.target })) {
|
759 | return
|
760 | }
|
761 | }
|
762 | }
|
763 | self._eventOn({ el, force }, e)
|
764 | }
|
765 |
|
766 | |
767 |
|
768 |
|
769 |
|
770 |
|
771 |
|
772 |
|
773 | _eventOffHandler({ el, force = false }, e) {
|
774 | const self = this
|
775 | const options = self.options
|
776 | force = force ? force : e?.detail?.force
|
777 |
|
778 | el = options.groupElements || self.targets.includes(el) ? self.getElements({ el })[0] : el
|
779 |
|
780 | if (!force && options.eventLimit) {
|
781 | const eventLimit = self._containerElements.querySelectorAll(options.eventLimit)
|
782 | if (self._containerElements.matches(options.eventLimit)) {
|
783 | return
|
784 | } else if (eventLimit.length) {
|
785 | if (Xt.contains({ els: eventLimit, tr: e.target })) {
|
786 | return
|
787 | }
|
788 | }
|
789 | }
|
790 | self._eventOff({ el, force }, e)
|
791 | }
|
792 |
|
793 | |
794 |
|
795 |
|
796 |
|
797 |
|
798 | _eventPreventeventStartHandler({ el } = {}) {
|
799 | const self = this
|
800 |
|
801 | Xt.dataStorage.put(el, `active/preventevent/${self.ns}`, self.hasCurrent({ el }))
|
802 |
|
803 | const preventeventHandler = Xt.dataStorage.put(
|
804 | el,
|
805 | `click keypress/preventevent/${self.ns}`,
|
806 | self._eventPreventeventHandler.bind(self, { el })
|
807 | )
|
808 | el.addEventListener('click', preventeventHandler)
|
809 | el.addEventListener('keypress', preventeventHandler)
|
810 |
|
811 | const preventeventResetHandler = Xt.dataStorage.put(
|
812 | el,
|
813 | `off/preventevent/${self.ns}`,
|
814 | self._eventPreventeventResetHandler.bind(self, { el })
|
815 | )
|
816 | el.addEventListener(`off.${self._componentNs}`, preventeventResetHandler)
|
817 | }
|
818 |
|
819 | |
820 |
|
821 |
|
822 |
|
823 |
|
824 | _eventPreventeventEndHandler({ el } = {}) {
|
825 | const self = this
|
826 |
|
827 | const preventeventHandler = Xt.dataStorage.get(el, `click/preventevent/${self.ns}`)
|
828 | el.removeEventListener('click', preventeventHandler)
|
829 |
|
830 | const preventeventResetHandler = Xt.dataStorage.get(el, `off/preventevent/${self.ns}`)
|
831 | el.removeEventListener(`off.${self._componentNs}`, preventeventResetHandler)
|
832 | }
|
833 |
|
834 | |
835 |
|
836 |
|
837 |
|
838 |
|
839 |
|
840 | _eventPreventeventHandler({ el }, e) {
|
841 | const self = this
|
842 | const active = Xt.dataStorage.get(el, `active/preventevent/${self.ns}`)
|
843 |
|
844 | if (e.key && e.key !== 'Enter') {
|
845 | return
|
846 | }
|
847 |
|
848 | if (!active && !Xt.dataStorage.get(el, `${self.ns}PreventeventDone`)) {
|
849 | Xt.dataStorage.set(el, `${self.ns}PreventeventDone`, true)
|
850 |
|
851 | e.preventDefault()
|
852 | } else {
|
853 | self._eventPreventeventEndHandler({ el })
|
854 | Xt.dataStorage.remove(el, `${self.ns}PreventeventDone`)
|
855 | Xt.dataStorage.remove(el, `active/preventevent/${self.ns}`)
|
856 | }
|
857 | }
|
858 |
|
859 | |
860 |
|
861 |
|
862 |
|
863 |
|
864 | _eventPreventeventResetHandler({ el } = {}) {
|
865 | const self = this
|
866 | self._eventPreventeventEndHandler({ el })
|
867 | Xt.dataStorage.remove(el, `${self.ns}PreventeventDone`)
|
868 | Xt.dataStorage.remove(el, `active/preventevent/${self.ns}`)
|
869 | }
|
870 |
|
871 | |
872 |
|
873 |
|
874 |
|
875 |
|
876 |
|
877 |
|
878 |
|
879 | _hashChange({ save = false } = {}) {
|
880 | const self = this
|
881 | const options = self.options
|
882 |
|
883 | let currents = 0
|
884 | const arr = []
|
885 |
|
886 | if (self.disabled) {
|
887 | return { currents, arr }
|
888 | }
|
889 |
|
890 | if (self._hasHash) {
|
891 | if (!Xt.dataStorage.get(self.container, `${self.ns}HashSkip`)) {
|
892 | const hash = decodeURI(location.hash.split('#')[1])
|
893 | if (hash) {
|
894 |
|
895 | const checkHash = (el, hash) => {
|
896 | if (el.getAttribute(options.hash) === hash) {
|
897 | return true
|
898 | }
|
899 | return false
|
900 | }
|
901 |
|
902 | for (const el of self.elements) {
|
903 | let activated = false
|
904 |
|
905 | if (save) {
|
906 | activated = checkHash(el, hash)
|
907 | }
|
908 |
|
909 | const targets = self.getTargets({ el })
|
910 | for (const tr of targets) {
|
911 |
|
912 | if (save && !activated) {
|
913 | activated = checkHash(tr, hash)
|
914 | }
|
915 | }
|
916 |
|
917 | if (activated && currents < options.max) {
|
918 |
|
919 | currents++
|
920 | arr.push(el)
|
921 |
|
922 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, true)
|
923 | if (options.on) {
|
924 | const event = options.on.split(' ')[0]
|
925 | el.dispatchEvent(new CustomEvent(event, { detail: { force: true } }))
|
926 | } else {
|
927 | self._eventOn({ el, force: true })
|
928 | }
|
929 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, false)
|
930 | }
|
931 | }
|
932 | }
|
933 | }
|
934 | }
|
935 |
|
936 | return { currents, arr }
|
937 | }
|
938 |
|
939 | |
940 |
|
941 |
|
942 |
|
943 |
|
944 |
|
945 | _eventJumpHandler({ el }, e) {
|
946 | const self = this
|
947 |
|
948 | if (self.disabled) {
|
949 | return
|
950 | }
|
951 |
|
952 | if (self.targets.includes(el)) {
|
953 |
|
954 | self._eventJump({ el }, e)
|
955 | }
|
956 | }
|
957 |
|
958 | |
959 |
|
960 |
|
961 |
|
962 |
|
963 |
|
964 | _eventNavHandler({ el }, e) {
|
965 | const self = this
|
966 |
|
967 | self._eventNav({ el }, e)
|
968 | }
|
969 |
|
970 | |
971 |
|
972 |
|
973 |
|
974 | _eventCloseautoHandler(e) {
|
975 | const self = this
|
976 |
|
977 | if (!e?.detail?.container || e?.detail?.container.contains(self.container)) {
|
978 |
|
979 | const currents = self._getCurrents()
|
980 | for (const current of currents) {
|
981 | self._eventOff({ el: current, force: true }, e)
|
982 | }
|
983 | }
|
984 | }
|
985 |
|
986 | |
987 |
|
988 |
|
989 |
|
990 | _eventOpenautoHandler(e) {
|
991 | const self = this
|
992 |
|
993 | let found
|
994 | for (const el of Array.from(self.elements).filter(x => x.contains(e.target))) {
|
995 | found = el
|
996 | break
|
997 | }
|
998 | if (!found) {
|
999 | for (const tr of Array.from(self.targets).filter(x => x.contains(e.target))) {
|
1000 | found = tr
|
1001 | break
|
1002 | }
|
1003 | }
|
1004 | if (found) {
|
1005 | self._eventOn({ el: found }, e)
|
1006 | }
|
1007 | }
|
1008 |
|
1009 | |
1010 |
|
1011 |
|
1012 |
|
1013 |
|
1014 |
|
1015 |
|
1016 |
|
1017 | _eventMedialoadedHandler({ img, el, deferred = false, reinit = false } = {}) {
|
1018 | const self = this
|
1019 | const options = self.options
|
1020 |
|
1021 | Xt.dataStorage.set(img, `${self.ns}MedialoadedDone`, true)
|
1022 |
|
1023 | if (options.mediaLoadedReinit && deferred && reinit) {
|
1024 | clearTimeout(Xt.dataStorage.get(self.container, `${self.ns}MedialoadedTimeout`))
|
1025 | Xt.dataStorage.set(
|
1026 | self.container,
|
1027 | `${self.ns}MedialoadedTimeout`,
|
1028 | setTimeout(() => {
|
1029 | self._eventMediaLoadedReinit()
|
1030 | }, Xt.medialoadedDelay)
|
1031 | )
|
1032 | }
|
1033 |
|
1034 | if (options.mediaLoaded) {
|
1035 | el.classList.add('xt-medialoaded')
|
1036 | }
|
1037 |
|
1038 | el.dispatchEvent(
|
1039 | new CustomEvent(`medialoaded.${self._componentNs}`, {
|
1040 | detail: { deferred: deferred },
|
1041 | })
|
1042 | )
|
1043 | }
|
1044 |
|
1045 |
|
1046 |
|
1047 |
|
1048 |
|
1049 | |
1050 |
|
1051 |
|
1052 |
|
1053 | getElementsGroups() {
|
1054 | const self = this
|
1055 |
|
1056 | const groups = []
|
1057 | for (const el of self.elements) {
|
1058 |
|
1059 | const group = el.getAttribute('data-xt-group')
|
1060 | if (group) {
|
1061 | const alreadyFound = groups.filter(x => x.getAttribute('data-xt-group') === group)
|
1062 | if (!alreadyFound.length) {
|
1063 | groups.push(el)
|
1064 | }
|
1065 | } else {
|
1066 | groups.push(el)
|
1067 | }
|
1068 | }
|
1069 | return groups
|
1070 | }
|
1071 |
|
1072 | |
1073 |
|
1074 |
|
1075 |
|
1076 |
|
1077 |
|
1078 |
|
1079 |
|
1080 |
|
1081 | _groupFilter({ els, attr, some = false, same = false } = {}) {
|
1082 | const self = this
|
1083 | const options = self.options
|
1084 |
|
1085 | const found = []
|
1086 | for (const el of els) {
|
1087 | let currentAttr = el.getAttribute('data-xt-group')
|
1088 | if (same) {
|
1089 | const currentAttrSame = el.getAttribute('data-xt-group-same')
|
1090 | if (currentAttrSame) {
|
1091 | currentAttr += options.groupSeparator + currentAttrSame
|
1092 | }
|
1093 | }
|
1094 |
|
1095 | if (currentAttr === attr) {
|
1096 | found.push(el)
|
1097 | continue
|
1098 | }
|
1099 |
|
1100 | if (some) {
|
1101 | const groups = attr?.split(options.groupSeparator).filter(x => x)
|
1102 | const currentGroups = currentAttr?.split(options.groupSeparator).filter(x => x)
|
1103 | if (currentGroups && groups && currentGroups.some(x => groups.includes(x))) {
|
1104 | found.push(el)
|
1105 | }
|
1106 | }
|
1107 | }
|
1108 | return found
|
1109 | }
|
1110 |
|
1111 | |
1112 |
|
1113 |
|
1114 |
|
1115 |
|
1116 |
|
1117 |
|
1118 | getElements({ el, same = false } = {}) {
|
1119 | const self = this
|
1120 | const options = self.options
|
1121 |
|
1122 | if (!self.elements || !self.elements.length) {
|
1123 | return []
|
1124 | }
|
1125 | if (!el) {
|
1126 | return []
|
1127 | } else if (self._mode === 'unique') {
|
1128 |
|
1129 | const final = []
|
1130 | const selfs = Xt.dataStorage.get(self.ns, 'xtNamespace')
|
1131 | if (selfs) {
|
1132 | for (const s of selfs) {
|
1133 |
|
1134 | final.push(...s.elements)
|
1135 | }
|
1136 | return final
|
1137 | }
|
1138 | return []
|
1139 | } else if (self._mode === 'multiple') {
|
1140 |
|
1141 | let final
|
1142 | let attr = el.getAttribute('data-xt-group')
|
1143 | if (same) {
|
1144 | const attrSame = el.getAttribute('data-xt-group-same')
|
1145 | if (attrSame) {
|
1146 | attr += options.groupSeparator + attrSame
|
1147 | }
|
1148 | }
|
1149 | const some = self.elements.includes(el) ? false : true
|
1150 | const groupElements = self._groupFilter({ els: self.elements, attr, some, same })
|
1151 | const groupTargets = self._groupFilter({ els: self.targets, attr, some, same })
|
1152 | if (attr) {
|
1153 |
|
1154 | final = groupElements
|
1155 | } else {
|
1156 |
|
1157 | if (Array.from(self.elements).includes(el)) {
|
1158 | final = [el].filter(x => x)
|
1159 | } else {
|
1160 |
|
1161 | const index = groupTargets.findIndex(x => x === el)
|
1162 | final = [groupElements[index]].filter(x => x)
|
1163 | }
|
1164 | }
|
1165 | return final
|
1166 | }
|
1167 | }
|
1168 |
|
1169 | |
1170 |
|
1171 |
|
1172 |
|
1173 |
|
1174 |
|
1175 |
|
1176 | getTargets({ el, same = false } = {}) {
|
1177 | const self = this
|
1178 | const options = self.options
|
1179 |
|
1180 | if (!self.targets || !self.targets.length) {
|
1181 | return []
|
1182 | }
|
1183 | if (!el) {
|
1184 | return []
|
1185 | } else if (self._mode === 'unique') {
|
1186 |
|
1187 | const final = self.targets
|
1188 | return final
|
1189 | } else if (self._mode === 'multiple') {
|
1190 |
|
1191 | let final
|
1192 | let attr = el.getAttribute('data-xt-group')
|
1193 | if (same) {
|
1194 | const attrSame = el.getAttribute('data-xt-group-same')
|
1195 | if (attrSame) {
|
1196 | attr += options.groupSeparator + attrSame
|
1197 | }
|
1198 | }
|
1199 | const some = self.targets.includes(el) ? false : true
|
1200 | const groupElements = self._groupFilter({ els: self.elements, attr, some, same })
|
1201 | const groupTargets = self._groupFilter({ els: self.targets, attr, some, same })
|
1202 | if (attr) {
|
1203 |
|
1204 | final = groupTargets
|
1205 | } else {
|
1206 |
|
1207 | if (Array.from(self.targets).includes(el)) {
|
1208 | final = [el].filter(x => x)
|
1209 | } else {
|
1210 |
|
1211 | const index = groupElements.findIndex(x => x === el)
|
1212 | final = [groupTargets[index]].filter(x => x)
|
1213 | }
|
1214 | }
|
1215 | return final
|
1216 | }
|
1217 | }
|
1218 |
|
1219 | |
1220 |
|
1221 |
|
1222 |
|
1223 |
|
1224 |
|
1225 | _getElementsInner({ els } = {}) {
|
1226 | const self = this
|
1227 | const options = self.options
|
1228 |
|
1229 | let inners = []
|
1230 | if (options.elementsInner) {
|
1231 | for (const el of els) {
|
1232 | const inner = Xt.dataStorage.get(el, `elementsInner/${self.ns}`)
|
1233 | if (inner.length) {
|
1234 | inners = inners.concat(inner)
|
1235 | }
|
1236 | }
|
1237 | }
|
1238 | return inners
|
1239 | }
|
1240 |
|
1241 | |
1242 |
|
1243 |
|
1244 |
|
1245 |
|
1246 |
|
1247 | _getTargetsInner({ els } = {}) {
|
1248 | const self = this
|
1249 | const options = self.options
|
1250 |
|
1251 | let inners = []
|
1252 | if (options.targetsInner) {
|
1253 | for (const el of els) {
|
1254 | const inner = Xt.dataStorage.get(el, `targetsInner/${self.ns}`)
|
1255 | if (inner.length) {
|
1256 | inners = inners.concat(inner)
|
1257 | }
|
1258 | }
|
1259 | }
|
1260 | return inners
|
1261 | }
|
1262 |
|
1263 | |
1264 |
|
1265 |
|
1266 |
|
1267 |
|
1268 |
|
1269 |
|
1270 | _getEventParent({ el, event } = {}) {
|
1271 | const self = this
|
1272 | const options = self.options
|
1273 |
|
1274 | if (options.mouseParent) {
|
1275 | if (['mouseenter', 'mouseleave', 'mousehover', 'mouseout'].includes(event)) {
|
1276 | if (typeof options.mouseParent === 'string') {
|
1277 | return el.closest(options.mouseParent)
|
1278 | } else {
|
1279 | return el.parentNode
|
1280 | }
|
1281 | }
|
1282 | }
|
1283 | return el
|
1284 | }
|
1285 | |
1286 |
|
1287 |
|
1288 |
|
1289 | _getCurrents() {
|
1290 | const self = this
|
1291 |
|
1292 | return Xt._currents[self.ns]
|
1293 | }
|
1294 |
|
1295 | |
1296 |
|
1297 |
|
1298 |
|
1299 | _setCurrents(arr) {
|
1300 | const self = this
|
1301 |
|
1302 | Xt._currents[self.ns] = arr
|
1303 | }
|
1304 |
|
1305 | |
1306 |
|
1307 |
|
1308 |
|
1309 |
|
1310 |
|
1311 | _addCurrent({ el, running = false } = {}) {
|
1312 | const self = this
|
1313 |
|
1314 | if (!self.hasCurrent({ el, running })) {
|
1315 | const arr = running ? Xt._running : Xt._currents
|
1316 | arr[self.ns].push(el)
|
1317 | }
|
1318 | }
|
1319 |
|
1320 | |
1321 |
|
1322 |
|
1323 |
|
1324 |
|
1325 |
|
1326 | _removeCurrent({ el, running = false } = {}) {
|
1327 | const self = this
|
1328 |
|
1329 | const arr = running ? Xt._running : Xt._currents
|
1330 | arr[self.ns] = arr[self.ns].filter(x => x !== el)
|
1331 | }
|
1332 |
|
1333 | |
1334 |
|
1335 |
|
1336 |
|
1337 |
|
1338 |
|
1339 |
|
1340 | hasCurrent({ el, same = false, running = false } = {}) {
|
1341 | const self = this
|
1342 | const options = self.options
|
1343 |
|
1344 | const elements = options.groupElements || self.targets.includes(el) ? self.getElements({ el, same }) : [el]
|
1345 |
|
1346 | const arr = running ? Xt._running : Xt._currents
|
1347 | return arr[self.ns].filter(x => elements.includes(x)).length
|
1348 | }
|
1349 |
|
1350 | |
1351 |
|
1352 |
|
1353 |
|
1354 |
|
1355 |
|
1356 | _checkOn({ el } = {}) {
|
1357 | const self = this
|
1358 |
|
1359 | return !self.hasCurrent({ el })
|
1360 | }
|
1361 |
|
1362 | |
1363 |
|
1364 |
|
1365 |
|
1366 |
|
1367 |
|
1368 | _checkOff({ el } = {}) {
|
1369 | const self = this
|
1370 | const options = self.options
|
1371 |
|
1372 | if (options.min - self._getCurrents().length >= 0) {
|
1373 | return false
|
1374 | }
|
1375 |
|
1376 | return self.hasCurrent({ el })
|
1377 | }
|
1378 |
|
1379 | |
1380 |
|
1381 |
|
1382 |
|
1383 |
|
1384 |
|
1385 | _checkOnRunning({ obj } = {}) {
|
1386 | const self = this
|
1387 |
|
1388 | const check = obj.elements.runningOn || !self.hasCurrent({ el: obj.elements.queueEls[0], running: true })
|
1389 | obj.elements.runningOn = check
|
1390 | return check
|
1391 | }
|
1392 |
|
1393 | |
1394 |
|
1395 |
|
1396 |
|
1397 |
|
1398 |
|
1399 | _checkOffRunning({ obj } = {}) {
|
1400 | const self = this
|
1401 |
|
1402 | const check = obj.elements.runningOff || self.hasCurrent({ el: obj.elements.queueEls[0], running: true })
|
1403 | obj.elements.runningOff = check
|
1404 | return check
|
1405 | }
|
1406 |
|
1407 | |
1408 |
|
1409 |
|
1410 |
|
1411 |
|
1412 | _setIndex({ el } = {}) {
|
1413 | const self = this
|
1414 |
|
1415 | const index = self.getIndex({ el })
|
1416 | self._oldIndex = self.index ?? index
|
1417 | self.index = index
|
1418 | }
|
1419 |
|
1420 | |
1421 |
|
1422 |
|
1423 |
|
1424 |
|
1425 | getIndex({ el } = {}) {
|
1426 | const self = this
|
1427 |
|
1428 | el = self.getElements({ el })[0]
|
1429 |
|
1430 | let index = null
|
1431 | for (const [i, element] of self.getElementsGroups().entries()) {
|
1432 | if (el === element) {
|
1433 | index = i
|
1434 | break
|
1435 | }
|
1436 | }
|
1437 | return index
|
1438 | }
|
1439 |
|
1440 | |
1441 |
|
1442 |
|
1443 | _setDirection() {
|
1444 | const self = this
|
1445 |
|
1446 | if (self.index === null || self.index === self._oldIndex) {
|
1447 |
|
1448 | self.direction = 0
|
1449 | } else if (self._inverse !== null) {
|
1450 |
|
1451 | self.direction = self._inverse ? -1 : 1
|
1452 | } else {
|
1453 | self.direction = self.index < self._oldIndex ? -1 : 1
|
1454 | }
|
1455 | }
|
1456 |
|
1457 | |
1458 |
|
1459 |
|
1460 |
|
1461 |
|
1462 |
|
1463 |
|
1464 | _activate({ el, type, skipSame } = {}) {
|
1465 | const self = this
|
1466 | const options = self.options
|
1467 |
|
1468 | if (!skipSame && options.classSkip !== true && !options.classSkip[type]) {
|
1469 |
|
1470 | el.checked = true
|
1471 |
|
1472 | el.classList.add(...self._classes)
|
1473 | el.classList.remove(...self._classesOut)
|
1474 |
|
1475 | Xt.frameDouble({
|
1476 | el,
|
1477 | func: () => {
|
1478 | el.classList.add(...self._classesIn)
|
1479 | el.classList.remove(...self._classesDone)
|
1480 | },
|
1481 | })
|
1482 |
|
1483 | el.classList.remove(...self._classesBefore, ...self._classesAfter)
|
1484 | if (self.direction < 0) {
|
1485 | el.classList.add(...self._classesBefore)
|
1486 | } else if (self.direction > 0) {
|
1487 | el.classList.add(...self._classesAfter)
|
1488 | }
|
1489 | }
|
1490 | }
|
1491 |
|
1492 | |
1493 |
|
1494 |
|
1495 |
|
1496 |
|
1497 |
|
1498 |
|
1499 | _activateDone({ el, type, skipSame } = {}) {
|
1500 | const self = this
|
1501 | const options = self.options
|
1502 |
|
1503 | if (!skipSame && options.classSkip !== true && !options.classSkip[type]) {
|
1504 |
|
1505 | Xt.frameDouble({ el })
|
1506 | el.classList.add(...self._classesIn, ...self._classesDone)
|
1507 | }
|
1508 | }
|
1509 |
|
1510 | |
1511 |
|
1512 |
|
1513 |
|
1514 |
|
1515 |
|
1516 |
|
1517 | _activateHash({ obj, el, type } = {}) {
|
1518 | const self = this
|
1519 | const options = self.options
|
1520 |
|
1521 | if (!Xt.dataStorage.get(self.container, `${self.ns}HashSkip`)) {
|
1522 | if (self._hasHash && !self.initial) {
|
1523 |
|
1524 | const elMain = obj.elements.queueEls[0]
|
1525 | if (
|
1526 | (type === 'elements' && self.getElements({ el: elMain }).includes(el)) ||
|
1527 | (type === 'targets' && self.getTargets({ el: elMain }).includes(el))
|
1528 | ) {
|
1529 | const attr = el.getAttribute(options.hash)
|
1530 | if (attr) {
|
1531 |
|
1532 | Xt.frame({
|
1533 | el: window,
|
1534 | ns: `${self.ns}Hash`,
|
1535 | func: () => {
|
1536 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, true)
|
1537 | history.pushState({}, '', `#${encodeURIComponent(attr)}`)
|
1538 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, false)
|
1539 | },
|
1540 | })
|
1541 | }
|
1542 | }
|
1543 | }
|
1544 | }
|
1545 | }
|
1546 |
|
1547 | |
1548 |
|
1549 |
|
1550 |
|
1551 |
|
1552 |
|
1553 |
|
1554 | _deactivate({ el, type, skipSame } = {}) {
|
1555 | const self = this
|
1556 | const options = self.options
|
1557 |
|
1558 | if (!skipSame && options.classSkip !== true && !options.classSkip[type]) {
|
1559 |
|
1560 | el.checked = false
|
1561 |
|
1562 | el.classList.remove(...self._classes)
|
1563 |
|
1564 | Xt.frameDouble({
|
1565 | el,
|
1566 | func: () => {
|
1567 | el.classList.remove(...self._classesIn, ...self._classesDone)
|
1568 | el.classList.add(...self._classesOut)
|
1569 | },
|
1570 | })
|
1571 |
|
1572 | el.classList.remove(...self._classesBefore, ...self._classesAfter)
|
1573 | if (self.direction < 0) {
|
1574 | el.classList.add(...self._classesBefore)
|
1575 | } else if (self.direction > 0) {
|
1576 | el.classList.add(...self._classesAfter)
|
1577 | }
|
1578 | }
|
1579 | }
|
1580 |
|
1581 | |
1582 |
|
1583 |
|
1584 |
|
1585 |
|
1586 |
|
1587 |
|
1588 | _deactivateDone({ el, type, skipSame } = {}) {
|
1589 | const self = this
|
1590 | const options = self.options
|
1591 |
|
1592 | if (!skipSame && options.classSkip !== true && !options.classSkip[type]) {
|
1593 |
|
1594 | Xt.frameDouble({ el })
|
1595 | el.classList.remove(...self._classesIn, ...self._classesOut)
|
1596 | }
|
1597 | }
|
1598 |
|
1599 | |
1600 |
|
1601 |
|
1602 |
|
1603 |
|
1604 |
|
1605 |
|
1606 | _deactivateHash({ obj, el, type } = {}) {
|
1607 | const self = this
|
1608 | const options = self.options
|
1609 |
|
1610 | if (!Xt.dataStorage.get(self.container, `${self.ns}HashSkip`)) {
|
1611 | if (options.hash && self._hasHash && !self.initial) {
|
1612 |
|
1613 | const elMain = obj.elements.queueEls[0]
|
1614 | if (
|
1615 | (type === 'elements' && self.getElements({ el: elMain }).includes(el)) ||
|
1616 | (type === 'targets' && self.getTargets({ el: elMain }).includes(el))
|
1617 | ) {
|
1618 | const attr = el.getAttribute(options.hash)
|
1619 | if (attr && attr === location.hash.split('#')[1]) {
|
1620 |
|
1621 | Xt.frame({
|
1622 | el: window,
|
1623 | ns: `${self.ns}Hash`,
|
1624 | func: () => {
|
1625 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, true)
|
1626 | history.pushState({}, '', '#')
|
1627 | Xt.dataStorage.set(self.container, `${self.ns}HashSkip`, false)
|
1628 | },
|
1629 | })
|
1630 | }
|
1631 | }
|
1632 | }
|
1633 | }
|
1634 | }
|
1635 |
|
1636 |
|
1637 |
|
1638 |
|
1639 |
|
1640 | |
1641 |
|
1642 |
|
1643 |
|
1644 |
|
1645 |
|
1646 |
|
1647 |
|
1648 |
|
1649 | _eventOn({ el, force = false, focus = false }, e) {
|
1650 | const self = this
|
1651 | const options = self.options
|
1652 | force = force ? force : e?.detail?.force
|
1653 |
|
1654 | if (self.disabled && !force) {
|
1655 | return false
|
1656 | }
|
1657 |
|
1658 | if (force || self._checkOn({ el })) {
|
1659 |
|
1660 | self._eventAutostop()
|
1661 |
|
1662 | const elements = options.groupElements || self.targets.includes(el) ? self.getElements({ el, same: true }) : [el]
|
1663 | el = elements[0]
|
1664 |
|
1665 | const targets = self.getTargets({ el, same: true })
|
1666 |
|
1667 | const elementsInner = self._getElementsInner({ els: elements })
|
1668 | const targetsInner = self._getTargetsInner({ els: targets })
|
1669 |
|
1670 | self._addCurrent({ el })
|
1671 | self._setIndex({ el })
|
1672 | self._setDirection()
|
1673 |
|
1674 | const actionCurrent = 'In'
|
1675 | const actionOther = 'Out'
|
1676 | let obj = self._eventQueue({ elements, targets, elementsInner, targetsInner, force, e })
|
1677 |
|
1678 | const currents = self._getCurrents()
|
1679 | if (currents.length > options.max) {
|
1680 |
|
1681 | const objFiltered = self._eventOff({ el: currents[0], objFilter: obj })
|
1682 |
|
1683 | if (!options.queue && objFiltered?.obj) {
|
1684 | obj = objFiltered.obj
|
1685 | }
|
1686 | }
|
1687 |
|
1688 | if (!options.queue) {
|
1689 | self[`_queue${actionCurrent}`] = [obj]
|
1690 | } else {
|
1691 | self[`_queue${actionCurrent}`].unshift(obj)
|
1692 | }
|
1693 |
|
1694 | for (const type in self[`_queue${actionCurrent}`][0]) {
|
1695 | self._queueStart({ actionCurrent, actionOther, type, index: 0 })
|
1696 | }
|
1697 |
|
1698 | if (focus) {
|
1699 | el = elementsInner[0] ?? el
|
1700 | el.focus()
|
1701 | }
|
1702 |
|
1703 | return true
|
1704 | } else if (options.off && [...options.off.split(' ')].includes(e?.type)) {
|
1705 |
|
1706 | self._eventOff({ el }, e)
|
1707 | }
|
1708 |
|
1709 | return false
|
1710 | }
|
1711 |
|
1712 | |
1713 |
|
1714 |
|
1715 |
|
1716 |
|
1717 |
|
1718 |
|
1719 |
|
1720 |
|
1721 |
|
1722 | _eventOff({ el, force = false, focus = false, objFilter } = {}, e) {
|
1723 | const self = this
|
1724 | const options = self.options
|
1725 | force = force ? force : e?.detail?.force
|
1726 |
|
1727 | if (self.disabled && !force) {
|
1728 | return false
|
1729 | }
|
1730 |
|
1731 | if (force || self._checkOff({ el })) {
|
1732 |
|
1733 | const elements = options.groupElements || self.targets.includes(el) ? self.getElements({ el, same: true }) : [el]
|
1734 | el = elements[0]
|
1735 |
|
1736 | self._removeCurrent({ el })
|
1737 |
|
1738 | const targets = self.getTargets({ el, same: true })
|
1739 |
|
1740 | const elementsInner = self._getElementsInner({ els: elements })
|
1741 | const targetsInner = self._getTargetsInner({ els: targets })
|
1742 |
|
1743 | if (!self._getCurrents().length) {
|
1744 | self._eventAutostop()
|
1745 | }
|
1746 |
|
1747 | const actionCurrent = 'Out'
|
1748 | const actionOther = 'In'
|
1749 | const obj = self._eventQueue({ elements, targets, elementsInner, targetsInner, force, e })
|
1750 |
|
1751 | if (options.groupSame && !options.queue && objFilter) {
|
1752 | for (const key in obj) {
|
1753 | const item = obj[key]
|
1754 | if (item.queueEls) {
|
1755 | const itemFilter = objFilter[key]
|
1756 | const queueEls = item.queueEls.filter(x => !itemFilter.queueEls.includes(x))
|
1757 |
|
1758 | itemFilter.skipEls = itemFilter.queueEls.filter(x => item.queueEls.includes(x))
|
1759 |
|
1760 | item.queueEls = queueEls
|
1761 | }
|
1762 | }
|
1763 | }
|
1764 |
|
1765 | if (!options.queue) {
|
1766 | self[`_queue${actionCurrent}`] = [obj]
|
1767 | } else {
|
1768 | self[`_queue${actionCurrent}`].unshift(obj)
|
1769 | }
|
1770 |
|
1771 | if (self[`_queue${actionCurrent}`].length > options.max) {
|
1772 |
|
1773 | const removedOn = self[`_queue${actionOther}`].shift()
|
1774 | self._queueStop({ actionCurrent: actionOther, actionOther: actionCurrent, obj: removedOn })
|
1775 |
|
1776 | const removedOff = self[`_queue${actionCurrent}`].shift()
|
1777 | self._queueStop({ actionCurrent, actionOther, obj: removedOff })
|
1778 | }
|
1779 |
|
1780 | for (const type in self[`_queue${actionCurrent}`][0]) {
|
1781 | self._queueStart({ actionCurrent, actionOther, type, index: 0 })
|
1782 | }
|
1783 |
|
1784 | if (focus) {
|
1785 | el = elementsInner[0] ?? el
|
1786 | el.focus()
|
1787 | }
|
1788 |
|
1789 | if (objFilter) {
|
1790 | return { obj: objFilter }
|
1791 | }
|
1792 | return true
|
1793 | }
|
1794 |
|
1795 | return false
|
1796 | }
|
1797 |
|
1798 | |
1799 |
|
1800 |
|
1801 |
|
1802 |
|
1803 |
|
1804 |
|
1805 |
|
1806 |
|
1807 |
|
1808 | _eventQueue({ elements, targets, elementsInner, targetsInner, force, e } = {}) {
|
1809 |
|
1810 | const obj = {}
|
1811 | obj.elements = {
|
1812 | queueEls: elements,
|
1813 | force: force,
|
1814 | e: e,
|
1815 | }
|
1816 | if (targets.length) {
|
1817 | obj.targets = {
|
1818 | queueEls: targets,
|
1819 | }
|
1820 | }
|
1821 | if (elementsInner.length) {
|
1822 | obj.elementsInner = {
|
1823 | queueEls: elementsInner,
|
1824 | }
|
1825 | }
|
1826 | if (targetsInner.length) {
|
1827 | obj.targetsInner = {
|
1828 | queueEls: targetsInner,
|
1829 | }
|
1830 | }
|
1831 | return obj
|
1832 | }
|
1833 |
|
1834 | |
1835 |
|
1836 |
|
1837 | _eventAuto() {
|
1838 | const self = this
|
1839 | const options = self.options
|
1840 |
|
1841 | if (self.disabled) {
|
1842 | return
|
1843 | }
|
1844 |
|
1845 | if (!self._autoblock && self._autorunning) {
|
1846 | if (Xt.visible({ el: self.container })) {
|
1847 |
|
1848 | if (options.auto.inverse) {
|
1849 | self.goToPrev({ amount: options.auto.step, loop: options.auto.loop })
|
1850 | } else {
|
1851 | self.goToNext({ amount: options.auto.step, loop: options.auto.loop })
|
1852 | }
|
1853 | }
|
1854 | }
|
1855 | }
|
1856 |
|
1857 | |
1858 |
|
1859 |
|
1860 | _eventAutostart() {
|
1861 | const self = this
|
1862 | const options = self.options
|
1863 |
|
1864 | if (self.disabled) {
|
1865 | return
|
1866 | }
|
1867 |
|
1868 | if (options.auto && options.auto.time && Xt.autoTimescale) {
|
1869 | if (!self._autoblock && !self._autorunning) {
|
1870 |
|
1871 | if (self.index !== null && (!self.initial || options.auto.initial)) {
|
1872 |
|
1873 | self._autorunning = true
|
1874 |
|
1875 | clearTimeout(Xt.dataStorage.get(self.container, `${self.ns}AutoTimeout`))
|
1876 |
|
1877 | const time = options.auto.time
|
1878 |
|
1879 | if (self.disabled) {
|
1880 | return
|
1881 | }
|
1882 |
|
1883 | Xt.dataStorage.set(
|
1884 | self.container,
|
1885 | `${self.ns}AutoTimeout`,
|
1886 | setTimeout(() => {
|
1887 |
|
1888 | self._eventAuto()
|
1889 | }, time / Xt.autoTimescale)
|
1890 | )
|
1891 |
|
1892 | self.container.dispatchEvent(new CustomEvent(`autostart.${self._componentNs}`))
|
1893 | }
|
1894 | }
|
1895 | }
|
1896 | }
|
1897 |
|
1898 | |
1899 |
|
1900 |
|
1901 | _eventAutostop() {
|
1902 | const self = this
|
1903 | const options = self.options
|
1904 |
|
1905 | if (options.auto && options.auto.time) {
|
1906 | if (!self._autoblock && self._autorunning) {
|
1907 |
|
1908 | self._autorunning = false
|
1909 |
|
1910 | clearTimeout(Xt.dataStorage.get(self.container, `${self.ns}AutoTimeout`))
|
1911 |
|
1912 | self.container.dispatchEvent(new CustomEvent(`autostop.${self._componentNs}`))
|
1913 | }
|
1914 | }
|
1915 | }
|
1916 |
|
1917 | |
1918 |
|
1919 |
|
1920 |
|
1921 |
|
1922 |
|
1923 | _eventJump({ el }, e) {
|
1924 | const self = this
|
1925 |
|
1926 | if (self.disabled) {
|
1927 | return
|
1928 | }
|
1929 |
|
1930 | if (el.classList.contains(...self._classes) || !el.classList.contains('xt-jump')) {
|
1931 | return
|
1932 | }
|
1933 |
|
1934 | e.preventDefault()
|
1935 |
|
1936 | if (self._checkOn({ el })) {
|
1937 | self._eventOn({ el })
|
1938 | }
|
1939 | }
|
1940 |
|
1941 | |
1942 |
|
1943 |
|
1944 |
|
1945 | _eventNav({ el } = {}) {
|
1946 | const self = this
|
1947 |
|
1948 | if (self.disabled) {
|
1949 | return
|
1950 | }
|
1951 |
|
1952 | const step = parseFloat(el.getAttribute('data-xt-nav'))
|
1953 | if (step < 0) {
|
1954 | self.goToPrev({ amount: -step })
|
1955 | } else {
|
1956 | self.goToNext({ amount: step })
|
1957 | }
|
1958 | }
|
1959 |
|
1960 | |
1961 |
|
1962 |
|
1963 | _eventMediaLoadedReinit() {
|
1964 | const self = this
|
1965 |
|
1966 | self.reinit()
|
1967 | }
|
1968 |
|
1969 | |
1970 |
|
1971 |
|
1972 | _eventVisibleReinit() {
|
1973 | const self = this
|
1974 |
|
1975 | self.reinit()
|
1976 | }
|
1977 |
|
1978 |
|
1979 |
|
1980 |
|
1981 |
|
1982 | |
1983 |
|
1984 |
|
1985 |
|
1986 |
|
1987 |
|
1988 |
|
1989 |
|
1990 | _queueStart({ actionCurrent, actionOther, type, index } = {}) {
|
1991 | const self = this
|
1992 | const options = self.options
|
1993 |
|
1994 | const obj = self[`_queue${actionCurrent}`][index]
|
1995 | if (obj && obj[type] && !obj[type].done) {
|
1996 | const queueOther = self[`_queue${actionOther}`]
|
1997 | const objOther = queueOther[queueOther.length - 1]
|
1998 | if (!objOther || !objOther[type] || objOther[type].done) {
|
1999 |
|
2000 | if (self.initial || !options.queue) {
|
2001 | obj[type].instant = true
|
2002 | } else if (options.queue && !options.queue[type]) {
|
2003 | obj[type].instantType = true
|
2004 | }
|
2005 |
|
2006 | self._specialClassBody({ actionCurrent, type })
|
2007 |
|
2008 | self._queueDelay({ actionCurrent, actionOther, obj, type })
|
2009 | }
|
2010 | }
|
2011 | }
|
2012 |
|
2013 | |
2014 |
|
2015 |
|
2016 |
|
2017 |
|
2018 |
|
2019 |
|
2020 | _queueStop({ actionCurrent, actionOther, obj } = {}) {
|
2021 | const self = this
|
2022 |
|
2023 | for (const type in obj) {
|
2024 | if (obj[type].done) {
|
2025 | for (const el of obj[type].queueEls) {
|
2026 |
|
2027 | Xt.frameDouble({ el, ns: `${self.ns}CollapseHeightFrame` })
|
2028 | Xt.frameDouble({ el, ns: `${self.ns}CollapseWidthFrame` })
|
2029 | clearTimeout(Xt.dataStorage.get(el, `${self.ns + type}DelayTimeout`))
|
2030 | clearTimeout(Xt.dataStorage.get(el, `${self.ns + type}AnimTimeout`))
|
2031 |
|
2032 | self._queueDelayDone({
|
2033 | actionCurrent: actionOther,
|
2034 | actionOther: actionCurrent,
|
2035 | obj,
|
2036 | el,
|
2037 | type,
|
2038 | skipQueue: true,
|
2039 | })
|
2040 | self._queueAnimDone({
|
2041 | actionCurrent: actionOther,
|
2042 | actionOther: actionCurrent,
|
2043 | obj,
|
2044 | el,
|
2045 | type,
|
2046 | skipQueue: true,
|
2047 | })
|
2048 | }
|
2049 | }
|
2050 | }
|
2051 | }
|
2052 |
|
2053 | |
2054 |
|
2055 |
|
2056 |
|
2057 |
|
2058 |
|
2059 |
|
2060 |
|
2061 | _queueDelay({ actionCurrent, actionOther, obj, type } = {}) {
|
2062 | const self = this
|
2063 | const options = self.options
|
2064 |
|
2065 | const els = obj[type].queueEls
|
2066 | for (const el of els) {
|
2067 |
|
2068 | const skipSame = obj[type].skipEls?.includes(el)
|
2069 |
|
2070 | let delay =
|
2071 | self.initial || self.disabled
|
2072 | ? false
|
2073 | : Xt.delayTime({ el, duration: options.delay || options[`delay${actionCurrent}`], actionCurrent })
|
2074 | if (delay) {
|
2075 | if (typeof delay === 'function') {
|
2076 | const count = Xt.dataStorage.get(el, `${self.ns + actionCurrent}Count`) || els.findIndex(x => x === el)
|
2077 | const tot = Xt.dataStorage.get(el, `${self.ns + actionCurrent}Tot`) || els.length
|
2078 | delay = delay({ current: count, total: tot - 1, el, self })
|
2079 | }
|
2080 | }
|
2081 |
|
2082 | clearTimeout(Xt.dataStorage.get(el, `${self.ns + type}DelayTimeout`))
|
2083 | clearTimeout(Xt.dataStorage.get(el, `${self.ns + type}AnimTimeout`))
|
2084 | if (!delay) {
|
2085 | self._queueDelayDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2086 | } else if (delay === 'raf') {
|
2087 | Xt.frameDouble({
|
2088 | el,
|
2089 | ns: `${self.ns + type}QueueDelayDone`,
|
2090 | func: () => {
|
2091 | self._queueDelayDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2092 | },
|
2093 | })
|
2094 | } else {
|
2095 | Xt.dataStorage.set(
|
2096 | el,
|
2097 | `${self.ns + type}DelayTimeout`,
|
2098 | setTimeout(() => {
|
2099 | self._queueDelayDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2100 | }, delay)
|
2101 | )
|
2102 | }
|
2103 |
|
2104 | if (obj[type].instant) {
|
2105 |
|
2106 | if (el === els[els.length - 1]) {
|
2107 | self._queueDone({ actionCurrent, actionOther, obj, type })
|
2108 | }
|
2109 | }
|
2110 | }
|
2111 |
|
2112 | if (!els.length) {
|
2113 | self._queueDone({ actionCurrent, actionOther, obj, type })
|
2114 | }
|
2115 | }
|
2116 |
|
2117 | |
2118 |
|
2119 |
|
2120 |
|
2121 |
|
2122 |
|
2123 |
|
2124 |
|
2125 |
|
2126 |
|
2127 |
|
2128 | _queueDelayDone({ actionCurrent, actionOther, obj, el, type, skipSame, skipQueue = false } = {}) {
|
2129 | const self = this
|
2130 |
|
2131 | if (actionCurrent === 'In' && (self._checkOnRunning({ obj }) || obj.elements.force)) {
|
2132 |
|
2133 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2134 | self._addCurrent({ el, running: true })
|
2135 | }
|
2136 |
|
2137 | self._activate({ el, type })
|
2138 | self._activateHash({ obj, el, type })
|
2139 |
|
2140 | self._specialZindex({ actionCurrent, obj, el, type })
|
2141 | self._specialAppendto({ actionCurrent, el, type })
|
2142 | self._specialClose({ actionCurrent, el, type, obj })
|
2143 | if (!self.initial) {
|
2144 | self._specialCollapse({ actionCurrent, el, type })
|
2145 | } else {
|
2146 | self._specialCollapse({ actionCurrent, el, type, reset: true })
|
2147 | }
|
2148 |
|
2149 | if (!skipSame && type !== 'elementsInner' && type !== 'targetsInner') {
|
2150 |
|
2151 | if (!self.disabled) {
|
2152 | Xt.frame({
|
2153 | el,
|
2154 | ns: `${self.ns}${actionCurrent}DelayDone`,
|
2155 | func: () => {
|
2156 | el.dispatchEvent(
|
2157 | new CustomEvent(`on.${self._componentNs}`, {
|
2158 | detail: obj.elements.e,
|
2159 | })
|
2160 | )
|
2161 | },
|
2162 | })
|
2163 | }
|
2164 | }
|
2165 | } else if (actionCurrent === 'Out' && (self._checkOffRunning({ obj }) || obj.elements.force)) {
|
2166 |
|
2167 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2168 | self._removeCurrent({ el, running: true })
|
2169 |
|
2170 | if (!self._getCurrents().length) {
|
2171 |
|
2172 | self.index = null
|
2173 | self._setDirection()
|
2174 | }
|
2175 | }
|
2176 |
|
2177 | self._deactivate({ el, type })
|
2178 | self._deactivateHash({ obj, el, type })
|
2179 |
|
2180 | self._specialCollapse({ actionCurrent, el, type })
|
2181 | self._specialClose({ actionCurrent, el, type, obj })
|
2182 |
|
2183 | if (!skipSame && type !== 'elementsInner' && type !== 'targetsInner') {
|
2184 |
|
2185 | if (!self.disabled) {
|
2186 | Xt.frame({
|
2187 | el,
|
2188 | ns: `${self.ns}${actionCurrent}DelayDone`,
|
2189 | func: () => {
|
2190 | el.dispatchEvent(
|
2191 | new CustomEvent(`off.${self._componentNs}`, {
|
2192 | detail: obj.elements.e,
|
2193 | })
|
2194 | )
|
2195 | },
|
2196 | })
|
2197 | }
|
2198 | }
|
2199 | }
|
2200 |
|
2201 | if (!skipQueue) {
|
2202 |
|
2203 |
|
2204 | if (self.disabled) {
|
2205 | Xt.frame({
|
2206 | el,
|
2207 | ns: `${self.ns + type}QueueAnim`,
|
2208 | })
|
2209 | self._queueAnim({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2210 | } else {
|
2211 |
|
2212 | Xt.frame({
|
2213 | el,
|
2214 | ns: `${self.ns + type}QueueAnim`,
|
2215 | func: () => {
|
2216 | self._queueAnim({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2217 | },
|
2218 | })
|
2219 | }
|
2220 |
|
2221 | if (!obj[type].instant && obj[type].instantType) {
|
2222 | const els = obj[type].queueEls
|
2223 |
|
2224 | if (el === els[els.length - 1]) {
|
2225 | self._queueDone({ actionCurrent, actionOther, obj, type })
|
2226 | }
|
2227 | }
|
2228 | }
|
2229 | }
|
2230 |
|
2231 | |
2232 |
|
2233 |
|
2234 |
|
2235 |
|
2236 |
|
2237 |
|
2238 |
|
2239 |
|
2240 |
|
2241 | _queueAnim({ actionCurrent, actionOther, obj, el, type, skipSame } = {}) {
|
2242 | const self = this
|
2243 | const options = self.options
|
2244 |
|
2245 | const els = obj[type].queueEls
|
2246 | let duration =
|
2247 | self.initial || self.disabled
|
2248 | ? false
|
2249 | : Xt.animTime({ el, duration: options.duration || options[`duration${actionCurrent}`], actionCurrent })
|
2250 | if (duration) {
|
2251 | if (typeof duration === 'function') {
|
2252 | const count = Xt.dataStorage.get(el, `${self.ns + actionCurrent}Count`) || els.findIndex(x => x === el)
|
2253 | const tot = Xt.dataStorage.get(el, `${self.ns + actionCurrent}Tot`) || els.length
|
2254 | duration = duration({ current: count, total: tot - 1, el, self })
|
2255 | }
|
2256 | }
|
2257 |
|
2258 | clearTimeout(Xt.dataStorage.get(el, `${self.ns + type}AnimTimeout`))
|
2259 | if (!duration) {
|
2260 | self._queueAnimDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2261 | } else if (duration === 'raf') {
|
2262 | Xt.frameDouble({
|
2263 | el,
|
2264 | ns: `${self.ns + type}QueueAnimDone`,
|
2265 | func: () => {
|
2266 | self._queueAnimDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2267 | },
|
2268 | })
|
2269 | } else {
|
2270 | Xt.dataStorage.set(
|
2271 | el,
|
2272 | `${self.ns + type}AnimTimeout`,
|
2273 | setTimeout(() => {
|
2274 | self._queueAnimDone({ actionCurrent, actionOther, obj, el, type, skipSame })
|
2275 | }, duration)
|
2276 | )
|
2277 | }
|
2278 | }
|
2279 |
|
2280 | |
2281 |
|
2282 |
|
2283 |
|
2284 |
|
2285 |
|
2286 |
|
2287 |
|
2288 |
|
2289 |
|
2290 |
|
2291 | _queueAnimDone({ actionCurrent, actionOther, obj, el, type, skipSame, skipQueue = false } = {}) {
|
2292 | const self = this
|
2293 |
|
2294 | if (actionCurrent === 'In') {
|
2295 |
|
2296 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2297 |
|
2298 | if (!self[`_queue${actionOther}`].length) {
|
2299 |
|
2300 | for (const type in obj) {
|
2301 | self._specialZindex({ actionCurrent: actionOther, obj, type })
|
2302 | }
|
2303 | }
|
2304 | }
|
2305 |
|
2306 | self._activateDone({ el, type })
|
2307 |
|
2308 | self._specialCollapse({ actionCurrent, el, type, reset: true })
|
2309 | self._specialScrollto({ actionCurrent, el, type, obj })
|
2310 |
|
2311 | if (!skipSame && type !== 'elementsInner' && type !== 'targetsInner') {
|
2312 |
|
2313 | if (!self.disabled) {
|
2314 | Xt.frame({
|
2315 | el,
|
2316 | ns: `${self.ns}${actionCurrent}AnimDone`,
|
2317 | func: () => {
|
2318 | el.dispatchEvent(
|
2319 | new CustomEvent(`ondone.${self._componentNs}`, {
|
2320 | detail: obj.elements.e,
|
2321 | })
|
2322 | )
|
2323 | },
|
2324 | })
|
2325 | }
|
2326 | }
|
2327 | } else if (actionCurrent === 'Out') {
|
2328 |
|
2329 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2330 |
|
2331 | if (!self._getCurrents().length) {
|
2332 |
|
2333 | for (const type in obj) {
|
2334 | self._specialZindex({ actionCurrent, obj, type })
|
2335 | }
|
2336 | }
|
2337 | }
|
2338 |
|
2339 | self._deactivateDone({ el, type })
|
2340 |
|
2341 | self._specialAppendto({ actionCurrent, el, type })
|
2342 | self._specialCollapse({ actionCurrent, el, type, reset: true })
|
2343 |
|
2344 | if (!skipSame && type !== 'elementsInner' && type !== 'targetsInner') {
|
2345 |
|
2346 | if (!self.disabled) {
|
2347 | Xt.frame({
|
2348 | el,
|
2349 | ns: `${self.ns}${actionCurrent}AnimDone`,
|
2350 | func: () => {
|
2351 | el.dispatchEvent(
|
2352 | new CustomEvent(`offdone.${self._componentNs}`, {
|
2353 | detail: obj.elements.e,
|
2354 | })
|
2355 | )
|
2356 | },
|
2357 | })
|
2358 | }
|
2359 | }
|
2360 | }
|
2361 |
|
2362 | if (!skipQueue) {
|
2363 |
|
2364 | if (!obj[type].instant && !obj[type].instantType) {
|
2365 | const els = obj[type].queueEls
|
2366 |
|
2367 | if (el === els[els.length - 1]) {
|
2368 | self._queueDone({ actionCurrent, actionOther, obj, type })
|
2369 | }
|
2370 | }
|
2371 | }
|
2372 | }
|
2373 |
|
2374 | |
2375 |
|
2376 |
|
2377 |
|
2378 |
|
2379 |
|
2380 |
|
2381 |
|
2382 | _queueDone({ actionCurrent, actionOther, obj, type } = {}) {
|
2383 | const self = this
|
2384 |
|
2385 | if (obj[type]) {
|
2386 |
|
2387 | obj[type].done = true
|
2388 |
|
2389 | let done = 0
|
2390 | for (const type in obj) {
|
2391 | if (obj[type].done) {
|
2392 | done++
|
2393 | }
|
2394 | }
|
2395 |
|
2396 | if (done === Object.entries(obj).length) {
|
2397 |
|
2398 | for (const type in obj) {
|
2399 | self._queueStart({
|
2400 | actionCurrent: actionOther,
|
2401 | actionOther: actionCurrent,
|
2402 | type,
|
2403 | index: self[`_queue${actionOther}`].length - 1,
|
2404 | })
|
2405 | }
|
2406 |
|
2407 | self[`_queue${actionCurrent}`].pop()
|
2408 |
|
2409 | self._queueComplete({ actionCurrent, obj })
|
2410 | }
|
2411 | }
|
2412 | }
|
2413 |
|
2414 | |
2415 |
|
2416 |
|
2417 |
|
2418 |
|
2419 |
|
2420 | _queueComplete({ actionCurrent, obj } = {}) {
|
2421 | const self = this
|
2422 | const options = self.options
|
2423 |
|
2424 | if (actionCurrent === 'In') {
|
2425 |
|
2426 |
|
2427 | Xt.frameDouble({
|
2428 | el: self.container,
|
2429 | ns: `${self.ns}Init`,
|
2430 | func: () => {
|
2431 | if (self.initial) {
|
2432 |
|
2433 | self.container.setAttribute(`data-${self.componentName}-init`, '')
|
2434 |
|
2435 | self.container.dispatchEvent(new CustomEvent(`init.${self._componentNs}`))
|
2436 |
|
2437 | for (const type in obj) {
|
2438 | for (const el of obj[type].queueEls) {
|
2439 | el.classList.remove(...self._classesInitial)
|
2440 | }
|
2441 | }
|
2442 |
|
2443 | if (options.debug) {
|
2444 |
|
2445 | console.debug(`${self.componentName} init`, self)
|
2446 | }
|
2447 | }
|
2448 |
|
2449 | self._eventAutostart()
|
2450 |
|
2451 | if (self.initial) {
|
2452 | self.initial = false
|
2453 | }
|
2454 |
|
2455 | self._inverse = null
|
2456 | },
|
2457 | })
|
2458 |
|
2459 | if (options.focusLimit && !self._focusTrap) {
|
2460 | const trs = self.targets.length ? self.targets : self.elements
|
2461 | self._focusTrap = focusTrap.createFocusTrap(trs, options.focusTrap)
|
2462 | self._focusTrap.activate()
|
2463 | }
|
2464 | } else if (actionCurrent === 'Out') {
|
2465 |
|
2466 | if (options.focusLimit && self._focusTrap) {
|
2467 | self._focusTrap.deactivate()
|
2468 | self._focusTrap = null
|
2469 | }
|
2470 | }
|
2471 | }
|
2472 |
|
2473 |
|
2474 |
|
2475 |
|
2476 |
|
2477 | |
2478 |
|
2479 |
|
2480 |
|
2481 |
|
2482 |
|
2483 |
|
2484 |
|
2485 | _specialZindex({ actionCurrent, obj, el, type } = {}) {
|
2486 | const self = this
|
2487 | const options = self.options
|
2488 |
|
2489 | if (!self.targets.length && type === 'elements') {
|
2490 | type = 'targets'
|
2491 | }
|
2492 |
|
2493 | if (options.zIndex && options.zIndex[type]) {
|
2494 | if (actionCurrent === 'In') {
|
2495 | self.zIndex = self.zIndex ? self.zIndex : options.zIndex[type].start
|
2496 | self.zIndex = self.zIndex + options.zIndex[type].factor
|
2497 | el.style.zIndex = self.zIndex
|
2498 | } else if (actionCurrent === 'Out') {
|
2499 | self.zIndex = options.zIndex[type].start
|
2500 |
|
2501 | if (obj[type]) {
|
2502 | for (const el of obj[type].queueEls) {
|
2503 | el.style.zIndex = self.zIndex
|
2504 | }
|
2505 | }
|
2506 | }
|
2507 | }
|
2508 | }
|
2509 |
|
2510 | |
2511 |
|
2512 |
|
2513 |
|
2514 |
|
2515 |
|
2516 | _specialClassBody({ actionCurrent, type } = {}) {
|
2517 | const self = this
|
2518 | const options = self.options
|
2519 | if (options.classBody) {
|
2520 |
|
2521 | if (type === 'targets' || (!self.targets.length && type === 'elements')) {
|
2522 | if (actionCurrent === 'In') {
|
2523 |
|
2524 | Xt.frame({
|
2525 | el: self.container,
|
2526 | ns: `${self.ns}ClassBodyFrame`,
|
2527 | func: () => {
|
2528 | for (const c of options.classBody.split(' ')) {
|
2529 |
|
2530 | Xt._classBody.add({
|
2531 | c: c,
|
2532 | ns: self.ns,
|
2533 | })
|
2534 |
|
2535 | const container = document.documentElement.querySelector('body')
|
2536 | container.classList.add(c)
|
2537 | }
|
2538 | },
|
2539 | })
|
2540 | } else if (actionCurrent === 'Out') {
|
2541 |
|
2542 | Xt.frame({
|
2543 | el: self.container,
|
2544 | ns: `${self.ns}ClassBodyFrame`,
|
2545 | func: () => {
|
2546 | for (const c of options.classBody.split(' ')) {
|
2547 |
|
2548 | Xt._classBody.remove({
|
2549 | c: c,
|
2550 | ns: self.ns,
|
2551 | })
|
2552 | if (!Xt._classBody.get({ c: c }).length) {
|
2553 |
|
2554 | const container = document.documentElement.querySelector('body')
|
2555 | container.classList.remove(c)
|
2556 | }
|
2557 | }
|
2558 | },
|
2559 | })
|
2560 | }
|
2561 | }
|
2562 | }
|
2563 | }
|
2564 |
|
2565 | |
2566 |
|
2567 |
|
2568 |
|
2569 |
|
2570 |
|
2571 |
|
2572 | _specialAppendto({ actionCurrent, el, type } = {}) {
|
2573 | const self = this
|
2574 | const options = self.options
|
2575 | if (options.appendTo) {
|
2576 |
|
2577 | if (type === 'targets' || (!self.targets.length && type === 'elements')) {
|
2578 | if (actionCurrent === 'In') {
|
2579 |
|
2580 | const appendToTarget = document.querySelector(options.appendTo)
|
2581 | const appendOrigin = document.querySelector(`[data-xt-origin="${self.ns}"]`)
|
2582 | if (!appendOrigin) {
|
2583 | el.before(Xt.node({ str: `<div class="xt-ignore hidden" data-xt-origin="${self.ns}"></div>` }))
|
2584 | }
|
2585 | appendToTarget.append(el)
|
2586 | } else if (actionCurrent === 'Out') {
|
2587 |
|
2588 | const appendOrigin = document.querySelector(`[data-xt-origin="${self.ns}"]`)
|
2589 | if (appendOrigin) {
|
2590 | appendOrigin.before(el)
|
2591 | appendOrigin.remove()
|
2592 | } else {
|
2593 | el.remove()
|
2594 | }
|
2595 | }
|
2596 | }
|
2597 | }
|
2598 | }
|
2599 |
|
2600 | |
2601 |
|
2602 |
|
2603 |
|
2604 |
|
2605 |
|
2606 |
|
2607 |
|
2608 | _specialScrollto({ actionCurrent, obj, el, type } = {}) {
|
2609 | const self = this
|
2610 | const options = self.options
|
2611 | if (options.scrollto) {
|
2612 | if (actionCurrent === 'In') {
|
2613 | const scrollto = ({ el }) => {
|
2614 |
|
2615 | if (!self.initial || options.scrolltoInit) {
|
2616 |
|
2617 | const instant = self.initial
|
2618 | Xt.ready({
|
2619 | state: 'complete',
|
2620 | func: () => {
|
2621 | requestAnimationFrame(() => {
|
2622 | if (instant) {
|
2623 | Xt.scrolltoHashforce = true
|
2624 | }
|
2625 | el.dispatchEvent(new CustomEvent('scrollto.trigger.xt.scrollto'))
|
2626 | })
|
2627 | },
|
2628 | })
|
2629 | }
|
2630 | }
|
2631 |
|
2632 | if (typeof options.scrollto === 'string') {
|
2633 | if (type === options.scrollto) {
|
2634 | scrollto({ el })
|
2635 | } else if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2636 | let scrolltoElement = self.container.querySelector(options.scrollto)
|
2637 | scrolltoElement = scrolltoElement ?? document.querySelector(options.scrollto)
|
2638 | if (scrolltoElement) {
|
2639 | scrollto({ el: scrolltoElement })
|
2640 | }
|
2641 | }
|
2642 | } else if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2643 | scrollto({ el: self.container })
|
2644 | }
|
2645 | }
|
2646 | }
|
2647 | }
|
2648 |
|
2649 | |
2650 |
|
2651 |
|
2652 |
|
2653 |
|
2654 |
|
2655 |
|
2656 |
|
2657 | _specialCollapse({ actionCurrent, el, type, reset = false } = {}) {
|
2658 | const self = this
|
2659 | const options = self.options
|
2660 | if (options.collapseHeight) {
|
2661 | if (actionCurrent === 'In') {
|
2662 | if (options.collapseHeight === type) {
|
2663 | if (reset) {
|
2664 | el.style.height = 'inherit'
|
2665 | el.style.maxHeight = 'none'
|
2666 | el.classList.add('xt-collapse-reset')
|
2667 | Xt.frameDouble({ el, ns: `${self.ns}CollapseHeightFrame` })
|
2668 | } else {
|
2669 | el.classList.remove('xt-collapse-reset')
|
2670 | el.style.height = 'auto'
|
2671 | el.style.maxHeight = 'none'
|
2672 | const final = el.offsetHeight
|
2673 | el.style.height = ''
|
2674 | el.style.maxHeight = ''
|
2675 | let initial = el.offsetHeight
|
2676 | initial = initial === final ? 0 : initial
|
2677 | el.style.height = `${initial}px`
|
2678 | el.style.maxHeight = 'none'
|
2679 | Xt.frameDouble({
|
2680 | el,
|
2681 | ns: `${self.ns}CollapseHeightFrame`,
|
2682 | func: () => {
|
2683 | el.style.height = `${final}px`
|
2684 | },
|
2685 | })
|
2686 | }
|
2687 | }
|
2688 | } else if (actionCurrent === 'Out') {
|
2689 | if (options.collapseHeight === type) {
|
2690 | if (reset) {
|
2691 | el.style.height = ''
|
2692 | el.style.maxHeight = ''
|
2693 | Xt.frameDouble({ el, ns: `${self.ns}CollapseHeightFrame` })
|
2694 | } else {
|
2695 | el.classList.remove('xt-collapse-reset')
|
2696 | const current = el.offsetHeight
|
2697 | el.style.height = ''
|
2698 | el.style.maxHeight = ''
|
2699 | let final = el.offsetHeight
|
2700 | el.style.height = 'auto'
|
2701 | el.style.maxHeight = 'none'
|
2702 | const initial = el.offsetHeight
|
2703 | final = initial === final ? 0 : final
|
2704 | el.style.height = `${current}px`
|
2705 | Xt.frameDouble({
|
2706 | el,
|
2707 | ns: `${self.ns}CollapseHeightFrame`,
|
2708 | func: () => {
|
2709 | el.style.height = `${final}px`
|
2710 | },
|
2711 | })
|
2712 | }
|
2713 | }
|
2714 | }
|
2715 | }
|
2716 | if (options.collapseWidth) {
|
2717 | if (actionCurrent === 'In') {
|
2718 | if (options.collapseWidth === type) {
|
2719 | if (reset) {
|
2720 | el.style.width = 'inherit'
|
2721 | el.style.maxWidth = 'none'
|
2722 | el.classList.add('xt-collapse-reset')
|
2723 | Xt.frameDouble({ el, ns: `${self.ns}CollapseWidthFrame` })
|
2724 | } else {
|
2725 | el.classList.remove('xt-collapse-reset')
|
2726 | el.style.width = 'auto'
|
2727 | el.style.maxWidth = 'none'
|
2728 | const final = el.offsetWidth
|
2729 | el.style.width = ''
|
2730 | el.style.maxWidth = ''
|
2731 | let initial = el.offsetWidth
|
2732 | initial = initial === final ? 0 : initial
|
2733 | el.style.width = `${initial}px`
|
2734 | el.style.maxWidth = 'none'
|
2735 | Xt.frameDouble({
|
2736 | el,
|
2737 | ns: `${self.ns}CollapseWidthFrame`,
|
2738 | func: () => {
|
2739 | el.style.width = `${final}px`
|
2740 | },
|
2741 | })
|
2742 | }
|
2743 | }
|
2744 | } else if (actionCurrent === 'Out') {
|
2745 | if (options.collapseWidth === type) {
|
2746 | if (reset) {
|
2747 | el.style.width = ''
|
2748 | el.style.maxWidth = ''
|
2749 | Xt.frameDouble({ el, ns: `${self.ns}CollapseWidthFrame` })
|
2750 | } else {
|
2751 | el.classList.remove('xt-collapse-reset')
|
2752 | const current = el.offsetWidth
|
2753 | el.style.width = ''
|
2754 | el.style.maxWidth = ''
|
2755 | let final = el.offsetWidth
|
2756 | el.style.width = 'auto'
|
2757 | el.style.maxWidth = 'none'
|
2758 | const initial = el.offsetWidth
|
2759 | final = initial === final ? 0 : final
|
2760 | el.style.width = `${current}px`
|
2761 | Xt.frameDouble({
|
2762 | el,
|
2763 | ns: `${self.ns}CollapseWidthFrame`,
|
2764 | func: () => {
|
2765 | el.style.width = `${final}px`
|
2766 | },
|
2767 | })
|
2768 | }
|
2769 | }
|
2770 | }
|
2771 | }
|
2772 | }
|
2773 |
|
2774 | |
2775 |
|
2776 |
|
2777 |
|
2778 |
|
2779 |
|
2780 |
|
2781 |
|
2782 | _specialClose({ actionCurrent, el, type, obj } = {}) {
|
2783 | const self = this
|
2784 | const options = self.options
|
2785 | if (actionCurrent === 'In') {
|
2786 |
|
2787 | if (options.closeInside) {
|
2788 | if (type === 'elements' || type === 'targets') {
|
2789 | const closeElement = el
|
2790 | const specialcloseinsideHandler = Xt.dataStorage.put(
|
2791 | closeElement,
|
2792 | `click/close/${self.ns}`,
|
2793 | self._eventSpecialcloseinsideHandler.bind(self)
|
2794 | )
|
2795 |
|
2796 | requestAnimationFrame(() => {
|
2797 | closeElement.removeEventListener('click', specialcloseinsideHandler)
|
2798 | closeElement.addEventListener('click', specialcloseinsideHandler)
|
2799 | })
|
2800 | }
|
2801 | }
|
2802 |
|
2803 | if (options.closeOutside) {
|
2804 |
|
2805 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2806 | const outsides = document.querySelectorAll(options.closeOutside)
|
2807 | for (const outside of outsides) {
|
2808 | const specialcloseoutsideHandler = Xt.dataStorage.put(
|
2809 | outside,
|
2810 | `mousedown/close/${self.ns}`,
|
2811 | self._eventSpecialcloseoutsideHandler.bind(self)
|
2812 | )
|
2813 |
|
2814 | requestAnimationFrame(() => {
|
2815 | outside.removeEventListener('mousedown', specialcloseoutsideHandler)
|
2816 | outside.addEventListener('mousedown', specialcloseoutsideHandler)
|
2817 | })
|
2818 | }
|
2819 | }
|
2820 | }
|
2821 |
|
2822 | if (options.closeDeep) {
|
2823 |
|
2824 | if (type === 'targets' || (!self.targets.length && type === 'elements')) {
|
2825 | const closeElements = el.querySelectorAll(options.closeDeep)
|
2826 | for (const closeElement of closeElements) {
|
2827 | const specialclosedeepHandler = Xt.dataStorage.put(
|
2828 | closeElement,
|
2829 | `click/close/${self.ns}`,
|
2830 | self._eventSpecialclosedeepHandler.bind(self)
|
2831 | )
|
2832 |
|
2833 | requestAnimationFrame(() => {
|
2834 | closeElement.removeEventListener('click', specialclosedeepHandler)
|
2835 | closeElement.addEventListener('click', specialclosedeepHandler)
|
2836 | })
|
2837 |
|
2838 | const specialclosedeepKeydownHandler = Xt.dataStorage.put(
|
2839 | closeElement,
|
2840 | `keydown/close/${self.ns}`,
|
2841 | self._eventSpecialclosedeepKeydownHandler.bind(self).bind(self, { closeElement })
|
2842 | )
|
2843 |
|
2844 | requestAnimationFrame(() => {
|
2845 | closeElement.addEventListener('keydown', specialclosedeepKeydownHandler)
|
2846 | closeElement.setAttribute('tabindex', '0')
|
2847 | closeElement.setAttribute('role', 'button')
|
2848 | })
|
2849 | }
|
2850 | }
|
2851 | }
|
2852 | } else if (actionCurrent === 'Out') {
|
2853 |
|
2854 | if (options.closeInside) {
|
2855 | if (type === 'elements' || type === 'targets') {
|
2856 | const closeElement = el
|
2857 | const specialcloseinsideHandler = Xt.dataStorage.get(closeElement, `click/close/${self.ns}`)
|
2858 | closeElement.removeEventListener('click', specialcloseinsideHandler)
|
2859 | }
|
2860 | }
|
2861 |
|
2862 | if (options.closeOutside) {
|
2863 |
|
2864 | if (type === 'elements' && el === obj.elements.queueEls[0]) {
|
2865 | const closeElements = document.querySelectorAll(options.closeOutside)
|
2866 | for (const closeElement of closeElements) {
|
2867 | const specialcloseoutsideHandler = Xt.dataStorage.get(closeElement, `mousedown/close/${self.ns}`)
|
2868 | closeElement.removeEventListener('mousedown', specialcloseoutsideHandler)
|
2869 | }
|
2870 | }
|
2871 | }
|
2872 |
|
2873 | if (options.closeDeep) {
|
2874 |
|
2875 | if (type === 'targets' || (!self.targets.length && type === 'elements')) {
|
2876 | const closeElements = el.querySelectorAll(options.closeDeep)
|
2877 | for (const closeElement of closeElements) {
|
2878 | const specialclosedeepHandler = Xt.dataStorage.get(closeElement, `click/close/${self.ns}`)
|
2879 | closeElement.removeEventListener('click', specialclosedeepHandler)
|
2880 |
|
2881 | const specialclosedeepKeydownHandler = Xt.dataStorage.get(closeElement, `keydown/close/${self.ns}`)
|
2882 | closeElement.removeEventListener('keydown', specialclosedeepKeydownHandler)
|
2883 | closeElement.removeAttribute('tabindex')
|
2884 | closeElement.removeAttribute('role')
|
2885 | }
|
2886 | }
|
2887 | }
|
2888 | }
|
2889 | }
|
2890 |
|
2891 | |
2892 |
|
2893 |
|
2894 |
|
2895 | _eventSpecialcloseinsideHandler(e) {
|
2896 | const self = this
|
2897 | const options = self.options
|
2898 |
|
2899 | if (e.target.matches(options.closeInside)) {
|
2900 | const currents = self._getCurrents()
|
2901 | for (const current of currents) {
|
2902 | self._eventOff({ el: current, force: true })
|
2903 | }
|
2904 | }
|
2905 | }
|
2906 |
|
2907 | |
2908 |
|
2909 |
|
2910 |
|
2911 | _eventSpecialcloseoutsideHandler(e) {
|
2912 | const self = this
|
2913 |
|
2914 | if (!Xt.contains({ els: [...self.elements, ...self.targets], tr: e.target })) {
|
2915 | const currents = self._getCurrents()
|
2916 | for (const current of currents) {
|
2917 | self._eventOff({ el: current, force: true })
|
2918 | }
|
2919 | }
|
2920 | }
|
2921 |
|
2922 | |
2923 |
|
2924 |
|
2925 |
|
2926 | _eventSpecialclosedeepHandler(e) {
|
2927 | const self = this
|
2928 |
|
2929 | if (Xt.contains({ els: [...self.elements, ...self.targets], tr: e.target })) {
|
2930 | const currents = self._getCurrents()
|
2931 | for (const current of currents) {
|
2932 | self._eventOff({ el: current, force: true })
|
2933 | }
|
2934 | }
|
2935 | }
|
2936 |
|
2937 | |
2938 |
|
2939 |
|
2940 |
|
2941 |
|
2942 |
|
2943 | _eventSpecialclosedeepKeydownHandler({ closeElement }, e) {
|
2944 | const key = e.key
|
2945 |
|
2946 | if (key === 'Enter' || key === ' ') {
|
2947 | e.preventDefault()
|
2948 | closeElement.dispatchEvent(new CustomEvent('click'))
|
2949 | }
|
2950 | }
|
2951 |
|
2952 |
|
2953 |
|
2954 |
|
2955 |
|
2956 | |
2957 |
|
2958 |
|
2959 |
|
2960 |
|
2961 |
|
2962 |
|
2963 |
|
2964 | getNextIndex({ index = false, amount = 1, loop = null } = {}) {
|
2965 | const self = this
|
2966 |
|
2967 | if (index !== false) {
|
2968 | index = index + amount
|
2969 | } else if (self.index !== null) {
|
2970 | index = self.index + amount
|
2971 | } else {
|
2972 | index = 0
|
2973 | }
|
2974 | return self.getNumIndex({ index, loop })
|
2975 | }
|
2976 |
|
2977 | |
2978 |
|
2979 |
|
2980 |
|
2981 |
|
2982 |
|
2983 |
|
2984 | getNext({ amount = 1, loop = null } = {}) {
|
2985 | const self = this
|
2986 |
|
2987 | const i = self.getNextIndex({ amount, loop })
|
2988 | return self.getElementsGroups()[i]
|
2989 | }
|
2990 |
|
2991 | |
2992 |
|
2993 |
|
2994 |
|
2995 |
|
2996 |
|
2997 |
|
2998 |
|
2999 | goToNext({ amount = 1, force = false, loop = null } = {}) {
|
3000 | const self = this
|
3001 |
|
3002 | self._inverse = false
|
3003 | const index = self.getNextIndex({ amount, loop })
|
3004 | const el = self.goToNum({ index, force, loop })
|
3005 | return el
|
3006 | }
|
3007 |
|
3008 | |
3009 |
|
3010 |
|
3011 |
|
3012 |
|
3013 |
|
3014 |
|
3015 |
|
3016 | getPrevIndex({ index = false, amount = 1, loop = null } = {}) {
|
3017 | const self = this
|
3018 |
|
3019 | if (index !== false) {
|
3020 | index = index - amount
|
3021 | } else if (self.index !== null) {
|
3022 | index = self.index - amount
|
3023 | } else {
|
3024 | index = self.getElementsGroups().length - 1
|
3025 | }
|
3026 | return self.getNumIndex({ index, loop })
|
3027 | }
|
3028 |
|
3029 | |
3030 |
|
3031 |
|
3032 |
|
3033 |
|
3034 |
|
3035 |
|
3036 | getPrev({ amount = 1, loop = null } = {}) {
|
3037 | const self = this
|
3038 |
|
3039 | const i = self.getPrevIndex({ amount, loop })
|
3040 | return self.getElementsGroups()[i]
|
3041 | }
|
3042 |
|
3043 | |
3044 |
|
3045 |
|
3046 |
|
3047 |
|
3048 |
|
3049 |
|
3050 |
|
3051 | goToPrev({ amount = 1, force = false, loop = null } = {}) {
|
3052 | const self = this
|
3053 |
|
3054 | self._inverse = true
|
3055 | const index = self.getPrevIndex({ amount, loop })
|
3056 | const el = self.goToNum({ index, force, loop })
|
3057 | return el
|
3058 | }
|
3059 |
|
3060 | |
3061 |
|
3062 |
|
3063 |
|
3064 |
|
3065 |
|
3066 |
|
3067 | getNumIndex({ index, loop = null } = {}) {
|
3068 | const self = this
|
3069 | const options = self.options
|
3070 |
|
3071 | const min = 0
|
3072 | const max = self.getElementsGroups().length - 1
|
3073 | if (min === max) {
|
3074 |
|
3075 | index = null
|
3076 | } else {
|
3077 | if (index > max) {
|
3078 | if (loop || (loop === null && (options.loop || self._wrap))) {
|
3079 | index = index - max - 1
|
3080 | index = index > max ? max : index
|
3081 | } else {
|
3082 | index = null
|
3083 | }
|
3084 | } else if (index < min) {
|
3085 | if (loop || (loop == null && (options.loop || self._wrap))) {
|
3086 | index = index + max + 1
|
3087 | index = index < min ? min : index
|
3088 | } else {
|
3089 | index = null
|
3090 | }
|
3091 | }
|
3092 | }
|
3093 |
|
3094 | return index
|
3095 | }
|
3096 |
|
3097 | |
3098 |
|
3099 |
|
3100 |
|
3101 |
|
3102 |
|
3103 |
|
3104 | getNum({ index = 1, loop = null } = {}) {
|
3105 | const self = this
|
3106 |
|
3107 | const i = self.getNumIndex({ index, loop })
|
3108 | return self.getElementsGroups()[i]
|
3109 | }
|
3110 |
|
3111 | |
3112 |
|
3113 |
|
3114 |
|
3115 |
|
3116 |
|
3117 |
|
3118 |
|
3119 | goToNum({ index, force = false, loop = null } = {}) {
|
3120 | const self = this
|
3121 |
|
3122 | const el = self.getNum({ index, loop })
|
3123 | if (el) {
|
3124 | self._eventOn({ el, force })
|
3125 | }
|
3126 | return el
|
3127 | }
|
3128 |
|
3129 |
|
3130 |
|
3131 |
|
3132 |
|
3133 | |
3134 |
|
3135 |
|
3136 | enable() {
|
3137 | const self = this
|
3138 | if (self.disabled) {
|
3139 |
|
3140 | self.disabled = false
|
3141 | self.container.removeAttribute(`data-${self.componentName}-disabled`)
|
3142 | for (const el of self.elements) {
|
3143 | el.removeAttribute(`data-${self.componentName}-disabled`)
|
3144 | }
|
3145 | for (const tr of self.targets) {
|
3146 | tr.removeAttribute(`data-${self.componentName}-disabled`)
|
3147 | }
|
3148 |
|
3149 | self.container.dispatchEvent(new CustomEvent(`status.${self._componentNs}`))
|
3150 | }
|
3151 | }
|
3152 |
|
3153 | |
3154 |
|
3155 |
|
3156 |
|
3157 |
|
3158 | disable({ skipEvent = false } = {}) {
|
3159 | const self = this
|
3160 | const options = self.options
|
3161 | if (!self.disabled) {
|
3162 | self.disabled = true
|
3163 |
|
3164 |
|
3165 | if (options.disableDeactivate) {
|
3166 | for (const el of self.elements.filter(x => self.hasCurrent({ el: x }))) {
|
3167 | self._eventOff({ el, force: true })
|
3168 | }
|
3169 | }
|
3170 |
|
3171 | self.container.setAttribute(`data-${self.componentName}-disabled`, '')
|
3172 | for (const el of self.elements) {
|
3173 | el.setAttribute(`data-${self.componentName}-disabled`, '')
|
3174 | }
|
3175 | for (const tr of self.targets) {
|
3176 | tr.setAttribute(`data-${self.componentName}-disabled`, '')
|
3177 | }
|
3178 |
|
3179 | if (options.jump) {
|
3180 | for (const jump of self.targets) {
|
3181 | jump.classList.remove('xt-jump')
|
3182 | }
|
3183 | }
|
3184 |
|
3185 | if (self._observer) {
|
3186 | self._observer.disconnect()
|
3187 | self._observer = null
|
3188 | }
|
3189 |
|
3190 | clearTimeout(Xt.dataStorage.get(self.container, `${self.ns}AutoTimeout`))
|
3191 |
|
3192 | if (!skipEvent) {
|
3193 | self.container.dispatchEvent(new CustomEvent(`status.${self._componentNs}`))
|
3194 | }
|
3195 | }
|
3196 | }
|
3197 |
|
3198 |
|
3199 |
|
3200 |
|
3201 |
|
3202 | |
3203 |
|
3204 |
|
3205 | _initA11y() {
|
3206 | const self = this
|
3207 | const options = self.options
|
3208 |
|
3209 | if (options.a11y) {
|
3210 |
|
3211 | let els = self.elements
|
3212 | let trs = self.targets
|
3213 |
|
3214 | if (!self.targets.length) {
|
3215 | els = []
|
3216 | trs = self.elements
|
3217 | }
|
3218 |
|
3219 | self._hasContainer = self._mode === 'unique' || self.elements.includes(self.container) ? false : true
|
3220 |
|
3221 | self._initA11yRole({ els, trs })
|
3222 | self._initA11yId({ els, trs })
|
3223 | self._initA11ySetup()
|
3224 | self._initA11yAuto()
|
3225 | self._initA11yChange()
|
3226 | self._initA11yStatus({ els })
|
3227 | self._initA11yKeyboard({ els: self.elements })
|
3228 | }
|
3229 | }
|
3230 |
|
3231 | |
3232 |
|
3233 |
|
3234 |
|
3235 |
|
3236 |
|
3237 | _initA11yRole({ els, trs } = {}) {
|
3238 | const self = this
|
3239 | const options = self.options
|
3240 | if (options.a11y.role) {
|
3241 | let multi = false
|
3242 |
|
3243 | if (options.a11y.vertical && self._hasContainer) {
|
3244 | self.container.setAttribute('aria-orientation', 'vertical')
|
3245 | }
|
3246 |
|
3247 | if (options.a11y.role === 'popup') {
|
3248 |
|
3249 | for (const el of els) {
|
3250 | el.setAttribute('aria-haspopup', true)
|
3251 | }
|
3252 | } else if (options.a11y.role === 'dialog') {
|
3253 |
|
3254 | for (const el of els) {
|
3255 | el.setAttribute('aria-haspopup', 'dialog')
|
3256 | }
|
3257 | for (const tr of trs) {
|
3258 | tr.setAttribute('role', 'dialog')
|
3259 | tr.setAttribute('aria-modal', 'true')
|
3260 | }
|
3261 | } else if (options.a11y.role === 'tooltip') {
|
3262 |
|
3263 | for (const tr of trs) {
|
3264 | tr.setAttribute('role', 'tooltip')
|
3265 | }
|
3266 | } else if (options.a11y.role === 'carousel' && self._hasContainer) {
|
3267 |
|
3268 | self.container.setAttribute('role', 'group')
|
3269 | self.container.setAttribute('aria-roledescription', 'carousel')
|
3270 | for (const tr of trs) {
|
3271 | tr.setAttribute('role', 'group')
|
3272 | tr.setAttribute('aria-roledescription', 'slide')
|
3273 | }
|
3274 | } else if (options.a11y.role === 'tablist' && self._hasContainer && self.targets.length) {
|
3275 |
|
3276 | multi = true
|
3277 | self.container.setAttribute('role', 'tablist')
|
3278 | for (const el of els) {
|
3279 | el.setAttribute('role', 'tab')
|
3280 | }
|
3281 | for (const tr of trs) {
|
3282 | tr.setAttribute('role', 'tabpanel')
|
3283 | }
|
3284 | } else if (options.a11y.role === 'menu' && self._hasContainer && self.targets.length) {
|
3285 |
|
3286 | self.container.setAttribute('role', 'menu')
|
3287 | for (const el of els) {
|
3288 | el.setAttribute('role', 'menuitem')
|
3289 | }
|
3290 | for (const tr of trs) {
|
3291 | tr.setAttribute('role', 'menu')
|
3292 | }
|
3293 | } else if (options.a11y.role === 'listbox' && self._hasContainer && self.targets.length) {
|
3294 |
|
3295 | multi = true
|
3296 | self.container.setAttribute('role', 'listbox')
|
3297 | for (const el of els) {
|
3298 | el.setAttribute('role', 'option')
|
3299 | }
|
3300 | }
|
3301 |
|
3302 | if (multi && options.max > 1) {
|
3303 | self.container.setAttribute('aria-multiselectable', 'true')
|
3304 | }
|
3305 | }
|
3306 | }
|
3307 |
|
3308 | |
3309 |
|
3310 |
|
3311 |
|
3312 |
|
3313 |
|
3314 | _initA11yId({ els, trs } = {}) {
|
3315 | const self = this
|
3316 | const options = self.options
|
3317 |
|
3318 | if (self.targets.length) {
|
3319 |
|
3320 | if (options.a11y.labelElements || options.a11y.controls) {
|
3321 |
|
3322 | for (const tr of trs) {
|
3323 | const id = tr.getAttribute('id')
|
3324 | if (!id) {
|
3325 | tr.setAttribute('id', Xt.uniqueId())
|
3326 | }
|
3327 | }
|
3328 | }
|
3329 | if (options.a11y.labelTargets) {
|
3330 |
|
3331 | for (const el of els) {
|
3332 | const id = el.getAttribute('id')
|
3333 | if (!id) {
|
3334 | el.setAttribute('id', Xt.uniqueId())
|
3335 | }
|
3336 | }
|
3337 | }
|
3338 | }
|
3339 | }
|
3340 |
|
3341 | |
3342 |
|
3343 |
|
3344 | _initA11ySetup() {
|
3345 | const self = this
|
3346 | const options = self.options
|
3347 |
|
3348 | if (self.targets.length) {
|
3349 |
|
3350 | if (options.a11y.labelElements || options.a11y.controls) {
|
3351 | for (const el of self.elements) {
|
3352 | const trs = self.getTargets({ el })
|
3353 | let str = ''
|
3354 | for (const tr of trs) {
|
3355 | str += `${tr.getAttribute('id')} `
|
3356 | }
|
3357 | if (options.a11y.labelElements) {
|
3358 | el.setAttribute('aria-labelledby', str.trim())
|
3359 | el.removeAttribute('aria-label')
|
3360 | }
|
3361 | if (options.a11y.controls) {
|
3362 | el.setAttribute('aria-controls', str.trim())
|
3363 | }
|
3364 | }
|
3365 | }
|
3366 |
|
3367 | if (options.a11y.labelTargets) {
|
3368 | for (const tr of self.targets) {
|
3369 | const els = self.getElements({ el: tr })
|
3370 | let str = ''
|
3371 | for (const el of els) {
|
3372 | str += `${el.getAttribute('id')} `
|
3373 | }
|
3374 | tr.setAttribute('aria-labelledby', str.trim())
|
3375 | tr.removeAttribute('aria-label')
|
3376 | }
|
3377 | }
|
3378 | }
|
3379 | }
|
3380 |
|
3381 | |
3382 |
|
3383 |
|
3384 | _initA11yChange() {
|
3385 | const self = this
|
3386 | const options = self.options
|
3387 |
|
3388 | if (options.a11y.selected || options.a11y.expanded) {
|
3389 | if (options.a11y.expanded) {
|
3390 | for (const tr of self.targets) {
|
3391 | tr.setAttribute('aria-expanded', 'false')
|
3392 | }
|
3393 | }
|
3394 | for (const el of self.elements) {
|
3395 | if (options.a11y.selected && self._hasContainer && self.targets.length) {
|
3396 | el.setAttribute('aria-selected', 'false')
|
3397 | }
|
3398 |
|
3399 | const onHandler = Xt.dataStorage.put(
|
3400 | el,
|
3401 | `on.${self._componentNs}/ariaselected/${self.ns}`,
|
3402 | self._eventA11yChangeOn.bind(self).bind(self, { el })
|
3403 | )
|
3404 | el.addEventListener(`on.${self._componentNs}`, onHandler)
|
3405 |
|
3406 | const offHandler = Xt.dataStorage.put(
|
3407 | el,
|
3408 | `off.${self._componentNs}/ariaselected/${self.ns}`,
|
3409 | self._eventA11yChangeOff.bind(self).bind(self, { el })
|
3410 | )
|
3411 | el.addEventListener(`off.${self._componentNs}`, offHandler)
|
3412 | }
|
3413 | }
|
3414 | }
|
3415 |
|
3416 | |
3417 |
|
3418 |
|
3419 |
|
3420 |
|
3421 | _eventA11yChangeOn({ el } = {}) {
|
3422 | const self = this
|
3423 | const options = self.options
|
3424 |
|
3425 | if (options.a11y.expanded) {
|
3426 | const trs = self.getTargets({ el })
|
3427 | for (const tr of trs) {
|
3428 | tr.setAttribute('aria-expanded', 'true')
|
3429 | }
|
3430 | }
|
3431 |
|
3432 | if (options.a11y.selected && self._hasContainer && self.targets.length) {
|
3433 | el.setAttribute('aria-selected', 'true')
|
3434 | }
|
3435 | }
|
3436 |
|
3437 | |
3438 |
|
3439 |
|
3440 |
|
3441 |
|
3442 | _eventA11yChangeOff({ el } = {}) {
|
3443 | const self = this
|
3444 | const options = self.options
|
3445 |
|
3446 | if (options.a11y.expanded) {
|
3447 | const trs = self.getTargets({ el })
|
3448 | for (const tr of trs) {
|
3449 | tr.setAttribute('aria-expanded', 'false')
|
3450 | }
|
3451 | }
|
3452 |
|
3453 | if (options.a11y.selected && self._hasContainer && self.targets.length) {
|
3454 | el.setAttribute('aria-selected', 'false')
|
3455 | }
|
3456 | }
|
3457 |
|
3458 | |
3459 |
|
3460 |
|
3461 | _initA11yAuto() {
|
3462 | const self = this
|
3463 | const options = self.options
|
3464 |
|
3465 | if (options.auto && options.auto.time) {
|
3466 | if (options.a11y.live) {
|
3467 | const container = self.container
|
3468 | container.setAttribute('aria-live', 'polite')
|
3469 |
|
3470 | const onHandler = Xt.dataStorage.put(
|
3471 | container,
|
3472 | `autostart.${self._componentNs}/arialive/${self.ns}`,
|
3473 | self._eventA11yAutostart.bind(self).bind(self, { container })
|
3474 | )
|
3475 | container.addEventListener(`autostart.${self._componentNs}`, onHandler)
|
3476 |
|
3477 | const offHandler = Xt.dataStorage.put(
|
3478 | container,
|
3479 | `autostop.${self._componentNs}/arialive/${self.ns}`,
|
3480 | self._eventA11yAutostop.bind(self).bind(self, { container })
|
3481 | )
|
3482 | container.addEventListener(`autostop.${self._componentNs}`, offHandler)
|
3483 | }
|
3484 | }
|
3485 | }
|
3486 |
|
3487 | |
3488 |
|
3489 |
|
3490 |
|
3491 |
|
3492 | _eventA11yAutostart({ container } = {}) {
|
3493 |
|
3494 | container.setAttribute('aria-live', 'off')
|
3495 | }
|
3496 |
|
3497 | |
3498 |
|
3499 |
|
3500 |
|
3501 |
|
3502 | _eventA11yAutostop({ container } = {}) {
|
3503 |
|
3504 | container.setAttribute('aria-live', 'polite')
|
3505 | }
|
3506 |
|
3507 | |
3508 |
|
3509 |
|
3510 |
|
3511 |
|
3512 | _initA11yStatus({ els } = {}) {
|
3513 | const self = this
|
3514 | const options = self.options
|
3515 |
|
3516 | if (options.a11y.disabled) {
|
3517 | const container = self.container
|
3518 |
|
3519 | const statusHandler = Xt.dataStorage.put(
|
3520 | container,
|
3521 | `status.${self._componentNs}/ariastatus/${self.ns}`,
|
3522 | self._eventA11yStatus.bind(self).bind(self, { els })
|
3523 | )
|
3524 | container.addEventListener(`status.${self._componentNs}`, statusHandler)
|
3525 | }
|
3526 | }
|
3527 |
|
3528 | |
3529 |
|
3530 |
|
3531 |
|
3532 |
|
3533 | _eventA11yStatus({ els } = {}) {
|
3534 | const self = this
|
3535 |
|
3536 | for (const el of els) {
|
3537 | if (self.disabled) {
|
3538 | el.setAttribute('aria-disabled', 'true')
|
3539 | } else {
|
3540 | el.removeAttribute('aria-disabled')
|
3541 | }
|
3542 | }
|
3543 | }
|
3544 |
|
3545 | |
3546 |
|
3547 |
|
3548 |
|
3549 |
|
3550 | _initA11yKeyboard({ els } = {}) {
|
3551 | const self = this
|
3552 | const options = self.options
|
3553 |
|
3554 | if (options.a11y.keyboard) {
|
3555 | for (const el of els) {
|
3556 |
|
3557 | const onHandler = Xt.dataStorage.put(
|
3558 | el,
|
3559 | `on.${self._componentNs}/ariakeyboard/${self.ns}`,
|
3560 | self._eventA11yOn.bind(self).bind(self, { el })
|
3561 | )
|
3562 | el.addEventListener(`on.${self._componentNs}`, onHandler)
|
3563 |
|
3564 | const offHandler = Xt.dataStorage.put(
|
3565 | el,
|
3566 | `off.${self._componentNs}/ariakeyboard/${self.ns}`,
|
3567 | self._eventA11yOff.bind(self).bind(self, { el })
|
3568 | )
|
3569 | el.addEventListener(`off.${self._componentNs}`, offHandler)
|
3570 | }
|
3571 | }
|
3572 | }
|
3573 |
|
3574 | |
3575 |
|
3576 |
|
3577 |
|
3578 |
|
3579 | _eventA11yOn({ el } = {}) {
|
3580 | const self = this
|
3581 | const options = self.options
|
3582 |
|
3583 | const keydownHandler = Xt.dataStorage.put(el, `keydown/ariakeyboard/${self.ns}`, self._eventA11yKeydown.bind(self))
|
3584 | el.addEventListener('keydown', keydownHandler, { passive: false })
|
3585 |
|
3586 | if (options.a11y.role === 'popup' || options.a11y.role === 'dialog' || options.a11y.items) {
|
3587 | const documentKeydownHandler = Xt.dataStorage.put(
|
3588 | document,
|
3589 | `keydown/ariakeyboard/document/${self.ns}`,
|
3590 | self._eventA11yDocumentKeydown.bind(self).bind(self, { el })
|
3591 | )
|
3592 | document.removeEventListener('keydown', documentKeydownHandler)
|
3593 | document.addEventListener('keydown', documentKeydownHandler)
|
3594 | }
|
3595 | }
|
3596 |
|
3597 | |
3598 |
|
3599 |
|
3600 |
|
3601 |
|
3602 | _eventA11yOff({ el } = {}) {
|
3603 | const self = this
|
3604 |
|
3605 | const keydownHandler = Xt.dataStorage.get(el, `keydown/ariakeyboard/${self.ns}`)
|
3606 | el.removeEventListener('keydown', keydownHandler)
|
3607 |
|
3608 | const documentKeydownHandler = Xt.dataStorage.get(el, `keydown/ariakeyboard/document/${self.ns}`)
|
3609 | document.removeEventListener('keydown', documentKeydownHandler)
|
3610 | }
|
3611 |
|
3612 | |
3613 |
|
3614 |
|
3615 |
|
3616 |
|
3617 |
|
3618 | _eventA11yKeydown(e) {
|
3619 | const self = this
|
3620 | const options = self.options
|
3621 |
|
3622 | if (self.disabled) {
|
3623 | return
|
3624 | }
|
3625 |
|
3626 | const key = e.key
|
3627 | const prevKey = options.a11y.vertical ? 'ArrowUp' : 'ArrowLeft'
|
3628 | const nextKey = options.a11y.vertical ? 'ArrowDown' : 'ArrowRight'
|
3629 |
|
3630 | let el
|
3631 | if (options.a11y.vertical) {
|
3632 | if (key === prevKey) {
|
3633 | el = self.getPrev()
|
3634 | } else if (key === nextKey) {
|
3635 | el = self.getNext()
|
3636 | }
|
3637 | } else {
|
3638 | if (key === prevKey) {
|
3639 | el = self.getPrev()
|
3640 | } else if (key === nextKey) {
|
3641 | el = self.getNext()
|
3642 | }
|
3643 | }
|
3644 | if (el) {
|
3645 |
|
3646 | self._eventOn({ el, focus: true })
|
3647 |
|
3648 | e.preventDefault()
|
3649 | return
|
3650 | }
|
3651 | }
|
3652 |
|
3653 | |
3654 |
|
3655 |
|
3656 |
|
3657 |
|
3658 |
|
3659 | _eventA11yDocumentKeydown({ el } = {}, e) {
|
3660 | const self = this
|
3661 | const options = self.options
|
3662 |
|
3663 | if (self.disabled) {
|
3664 | return
|
3665 | }
|
3666 |
|
3667 | const key = e.key
|
3668 | const prevKey = options.a11y.vertical ? 'ArrowLeft' : 'ArrowUp'
|
3669 | const nextKey = options.a11y.vertical ? 'ArrowRight' : 'ArrowDown'
|
3670 |
|
3671 | if (key === 'Escape') {
|
3672 | if (options.a11y.role === 'popup' || options.a11y.role === 'dialog') {
|
3673 |
|
3674 | self._eventOff({ el, focus: true })
|
3675 | return
|
3676 | }
|
3677 | }
|
3678 |
|
3679 | if (options.a11y.items) {
|
3680 | let item
|
3681 | const items = []
|
3682 | const trs = self.targets.filter(x => self.hasCurrent({ el: x }))
|
3683 | for (const tr of trs) {
|
3684 | items.push(...tr.querySelectorAll(options.a11y.items))
|
3685 | }
|
3686 | if (items.length) {
|
3687 | const current = items.indexOf(document.activeElement)
|
3688 | if (key === prevKey) {
|
3689 | if (current === -1) {
|
3690 | item = items[items.length - 1]
|
3691 | } else {
|
3692 | const prev = (current - 1 + items.length) % items.length
|
3693 | item = items[prev]
|
3694 | }
|
3695 |
|
3696 | e.preventDefault()
|
3697 | } else if (key === nextKey) {
|
3698 | if (current === -1) {
|
3699 | item = items[0]
|
3700 | } else {
|
3701 | const next = (current + 1) % items.length
|
3702 | item = items[next]
|
3703 | }
|
3704 |
|
3705 | e.preventDefault()
|
3706 | } else {
|
3707 | self._search = self._search + e.key.toLowerCase()
|
3708 | const found = items.filter(x => x.innerText?.toLowerCase().startsWith(self._search))
|
3709 | if (found.length) {
|
3710 | item = found[0]
|
3711 | }
|
3712 |
|
3713 | clearTimeout(Xt.dataStorage.get(document, `${self.ns}SearchTimeout`))
|
3714 | Xt.dataStorage.set(
|
3715 | document,
|
3716 | `${self.ns}SearchTimeout`,
|
3717 | setTimeout(() => {
|
3718 | self._search = ''
|
3719 | }, 500)
|
3720 | )
|
3721 | }
|
3722 | if (item) {
|
3723 |
|
3724 | item.focus()
|
3725 | return
|
3726 | }
|
3727 | }
|
3728 | }
|
3729 | }
|
3730 |
|
3731 |
|
3732 |
|
3733 |
|
3734 |
|
3735 | |
3736 |
|
3737 |
|
3738 |
|
3739 |
|
3740 | reinit({ save = true } = {}) {
|
3741 | const self = this
|
3742 | const options = self.options
|
3743 |
|
3744 | if (options.disableDeactivate) {
|
3745 | for (const tr of self.targets.filter(x => self.hasCurrent({ el: x }))) {
|
3746 | self._specialAppendto({ actionCurrent: 'Out', el: tr, type: 'targets' })
|
3747 | }
|
3748 | }
|
3749 |
|
3750 | self._initLogic({ save })
|
3751 | }
|
3752 |
|
3753 | |
3754 |
|
3755 |
|
3756 | restart() {
|
3757 | const self = this
|
3758 |
|
3759 | self._initStart()
|
3760 |
|
3761 | self.container.dispatchEvent(new CustomEvent(`restart.${self._componentNs}`))
|
3762 | }
|
3763 |
|
3764 | |
3765 |
|
3766 |
|
3767 | _addNamespace() {
|
3768 | const self = this
|
3769 |
|
3770 | if (self._mode === 'unique') {
|
3771 | const arr = Xt.dataStorage.get(self.ns, 'xtNamespace') ?? []
|
3772 | if (!arr.includes(self)) {
|
3773 | arr.push(self)
|
3774 | Xt.dataStorage.set(self.ns, 'xtNamespace', arr)
|
3775 | }
|
3776 | }
|
3777 | }
|
3778 |
|
3779 | |
3780 |
|
3781 |
|
3782 | _removeNamespace() {
|
3783 | const self = this
|
3784 |
|
3785 | if (self._mode === 'unique') {
|
3786 | let arr = Xt.dataStorage.get(self.ns, 'xtNamespace')
|
3787 | if (arr) {
|
3788 | arr = arr.filter(x => x !== self)
|
3789 | Xt.dataStorage.set(self.ns, 'xtNamespace', arr)
|
3790 | }
|
3791 | }
|
3792 | }
|
3793 |
|
3794 | |
3795 |
|
3796 |
|
3797 | _removeEvents() {
|
3798 | const self = this
|
3799 |
|
3800 | for (const el of self._destroyElements) {
|
3801 | const storages = Xt.dataStorage.getAll(el)
|
3802 | if (storages) {
|
3803 | for (const [key] of storages) {
|
3804 | if (key) {
|
3805 | if (key.endsWith(self.ns)) {
|
3806 | const handler = Xt.dataStorage.get(el, key)
|
3807 | if (typeof handler === 'function') {
|
3808 | const events = key.split('/')[0].split(' ')
|
3809 | for (const event of events) {
|
3810 | el.removeEventListener(event, handler)
|
3811 | el.removeEventListener(event, handler, true)
|
3812 | }
|
3813 |
|
3814 | }
|
3815 | }
|
3816 | }
|
3817 | }
|
3818 | }
|
3819 | }
|
3820 | }
|
3821 |
|
3822 | |
3823 |
|
3824 |
|
3825 |
|
3826 |
|
3827 | destroy({ weak = false } = {}) {
|
3828 | const self = this
|
3829 |
|
3830 | self.disable({ skipEvent: true })
|
3831 |
|
3832 | Xt._removeMatches({ self, optionsInitial: self._optionsInitial })
|
3833 |
|
3834 | self._removeEvents()
|
3835 |
|
3836 | self._removeNamespace()
|
3837 |
|
3838 | if (!weak) {
|
3839 |
|
3840 | self.container.removeAttribute(`data-${self.componentName}-init`)
|
3841 |
|
3842 | Xt._remove({ name: self.componentName, el: self.container })
|
3843 |
|
3844 | self.container.dispatchEvent(new CustomEvent(`destroy.${self._componentNs}`))
|
3845 |
|
3846 | delete this
|
3847 | }
|
3848 | }
|
3849 |
|
3850 |
|
3851 | }
|
3852 |
|
3853 |
|
3854 |
|
3855 |
|
3856 |
|
3857 | Toggle.componentName = 'xt-toggle'
|
3858 | Toggle.optionsDefaultSuper = {
|
3859 | debug: false,
|
3860 |
|
3861 | elements: '[data-xt-toggle-element]',
|
3862 | targets: '[data-xt-toggle-target]',
|
3863 | elementsInner: false,
|
3864 | targetsInner: false,
|
3865 | exclude: false,
|
3866 |
|
3867 | class: 'on',
|
3868 | classIn: 'in',
|
3869 | classOut: 'out',
|
3870 | classDone: 'done',
|
3871 | classInitial: 'initial',
|
3872 | classBefore: 'dir-before',
|
3873 | classAfter: 'dir-after',
|
3874 | classSkip: false,
|
3875 | hash: 'data-xt-hash',
|
3876 | groupSeparator: ',',
|
3877 | groupElements: true,
|
3878 |
|
3879 | min: 0,
|
3880 | max: 1,
|
3881 |
|
3882 | on: 'click',
|
3883 | off: 'click',
|
3884 | mouseParent: false,
|
3885 | eventLimit: '.xt-event-limit',
|
3886 | closeDeep: false,
|
3887 | closeInside: false,
|
3888 | closeOutside: false,
|
3889 | preventEvent: false,
|
3890 |
|
3891 | queue: {
|
3892 | elements: false,
|
3893 | targets: true,
|
3894 | elementsInner: false,
|
3895 | targetsInner: true,
|
3896 | },
|
3897 | delay: false,
|
3898 | delayIn: false,
|
3899 | delayOut: false,
|
3900 | duration: false,
|
3901 | durationIn: false,
|
3902 | durationOut: false,
|
3903 |
|
3904 | auto: {
|
3905 | time: false,
|
3906 | initial: true,
|
3907 | step: 1,
|
3908 | inverse: false,
|
3909 | pause: 'a, button',
|
3910 | loop: true,
|
3911 | },
|
3912 |
|
3913 | disableDeactivate: false,
|
3914 | scrollto: false,
|
3915 | scrolltoInit: false,
|
3916 | matches: false,
|
3917 | disabled: false,
|
3918 | visibleReinit: false,
|
3919 | loop: false,
|
3920 | jump: false,
|
3921 | navigation: false,
|
3922 | appendTo: false,
|
3923 | classBody: false,
|
3924 | closeauto: false,
|
3925 | openauto: false,
|
3926 | mediaLoaded: false,
|
3927 | mediaLoadedReinit: false,
|
3928 | zIndex: false,
|
3929 | focusLimit: false,
|
3930 | focusTrap: {
|
3931 | initialFocus: false,
|
3932 | preventScroll: true,
|
3933 | allowOutsideClick: true,
|
3934 | fallbackFocus: 'body',
|
3935 | },
|
3936 | collapseHeight: false,
|
3937 | collapseWidth: false,
|
3938 | a11y: {
|
3939 | role: false,
|
3940 | labelElements: false,
|
3941 | labelTargets: true,
|
3942 | controls: true,
|
3943 | selected: false,
|
3944 | expanded: false,
|
3945 | live: true,
|
3946 | disabled: true,
|
3947 | keyboard: true,
|
3948 | vertical: false,
|
3949 | items: false,
|
3950 | },
|
3951 | }
|
3952 |
|
3953 |
|
3954 |
|
3955 |
|
3956 |
|
3957 | Xt.Toggle = Toggle
|
3958 |
|
3959 |
|
3960 |
|
3961 |
|
3962 |
|
3963 | if (typeof window !== 'undefined') {
|
3964 | Xt.mount({
|
3965 | matches: `[data-${Xt.Toggle.componentName}]`,
|
3966 | mount: ({ ref }) => {
|
3967 |
|
3968 |
|
3969 | const optionsMarkup = ref.getAttribute(`data-${Xt.Toggle.componentName}`)
|
3970 | const options = optionsMarkup ? JSON5.parse(optionsMarkup) : {}
|
3971 |
|
3972 |
|
3973 |
|
3974 | let self = new Xt.Toggle(ref, options)
|
3975 |
|
3976 |
|
3977 |
|
3978 | return () => {
|
3979 | self.destroy()
|
3980 | self = null
|
3981 | }
|
3982 | },
|
3983 | })
|
3984 | }
|