source: imaps-frontend/node_modules/bootstrap/js/src/dom/selector-engine.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 3.4 KB
Line 
1/**
2 * --------------------------------------------------------------------------
3 * Bootstrap dom/selector-engine.js
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 * --------------------------------------------------------------------------
6 */
7
8import { isDisabled, isVisible, parseSelector } from '../util/index.js'
9
10const getSelector = element => {
11 let selector = element.getAttribute('data-bs-target')
12
13 if (!selector || selector === '#') {
14 let hrefAttribute = element.getAttribute('href')
15
16 // The only valid content that could double as a selector are IDs or classes,
17 // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
18 // `document.querySelector` will rightfully complain it is invalid.
19 // See https://github.com/twbs/bootstrap/issues/32273
20 if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {
21 return null
22 }
23
24 // Just in case some CMS puts out a full URL with the anchor appended
25 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
26 hrefAttribute = `#${hrefAttribute.split('#')[1]}`
27 }
28
29 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null
30 }
31
32 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null
33}
34
35const SelectorEngine = {
36 find(selector, element = document.documentElement) {
37 return [].concat(...Element.prototype.querySelectorAll.call(element, selector))
38 },
39
40 findOne(selector, element = document.documentElement) {
41 return Element.prototype.querySelector.call(element, selector)
42 },
43
44 children(element, selector) {
45 return [].concat(...element.children).filter(child => child.matches(selector))
46 },
47
48 parents(element, selector) {
49 const parents = []
50 let ancestor = element.parentNode.closest(selector)
51
52 while (ancestor) {
53 parents.push(ancestor)
54 ancestor = ancestor.parentNode.closest(selector)
55 }
56
57 return parents
58 },
59
60 prev(element, selector) {
61 let previous = element.previousElementSibling
62
63 while (previous) {
64 if (previous.matches(selector)) {
65 return [previous]
66 }
67
68 previous = previous.previousElementSibling
69 }
70
71 return []
72 },
73 // TODO: this is now unused; remove later along with prev()
74 next(element, selector) {
75 let next = element.nextElementSibling
76
77 while (next) {
78 if (next.matches(selector)) {
79 return [next]
80 }
81
82 next = next.nextElementSibling
83 }
84
85 return []
86 },
87
88 focusableChildren(element) {
89 const focusables = [
90 'a',
91 'button',
92 'input',
93 'textarea',
94 'select',
95 'details',
96 '[tabindex]',
97 '[contenteditable="true"]'
98 ].map(selector => `${selector}:not([tabindex^="-"])`).join(',')
99
100 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))
101 },
102
103 getSelectorFromElement(element) {
104 const selector = getSelector(element)
105
106 if (selector) {
107 return SelectorEngine.findOne(selector) ? selector : null
108 }
109
110 return null
111 },
112
113 getElementFromSelector(element) {
114 const selector = getSelector(element)
115
116 return selector ? SelectorEngine.findOne(selector) : null
117 },
118
119 getMultipleElementsFromSelector(element) {
120 const selector = getSelector(element)
121
122 return selector ? SelectorEngine.find(selector) : []
123 }
124}
125
126export default SelectorEngine
Note: See TracBrowser for help on using the repository browser.