selectorEngine.js 2.22 KB
Newer Older
Johann-S's avatar
Johann-S committed
1
2
/**
 * --------------------------------------------------------------------------
XhmikosR's avatar
4.3.1.    
XhmikosR committed
3
 * Bootstrap (v4.3.1): dom/selectorEngine.js
Johann-S's avatar
Johann-S committed
4
5
6
7
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

8
import Polyfill from './polyfill'
9
import { makeArray } from '../util/index'
10

11
12
13
14
15
/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */
Johann-S's avatar
Johann-S committed
16

XhmikosR's avatar
XhmikosR committed
17
const { find: findFn, findOne } = Polyfill
18
const NODE_TEXT = 3
Johann-S's avatar
Johann-S committed
19

20
21
const SelectorEngine = {
  matches(element, selector) {
22
    return element.matches(selector)
23
  },
Johann-S's avatar
Johann-S committed
24

25
26
27
28
  find(selector, element = document.documentElement) {
    if (typeof selector !== 'string') {
      return null
    }
29

30
    return findFn.call(element, selector)
31
32
33
34
35
36
  },

  findOne(selector, element = document.documentElement) {
    if (typeof selector !== 'string') {
      return null
    }
Johann-S's avatar
Johann-S committed
37

38
39
    return findOne.call(element, selector)
  },
Johann-S's avatar
Johann-S committed
40

41
42
43
44
45
  children(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }

46
    const children = makeArray(element.children)
47

XhmikosR's avatar
XhmikosR committed
48
    return children.filter(child => this.matches(child, selector))
49
  },
50

51
52
53
54
  parents(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
55

56
57
    const parents = []
    let ancestor = element.parentNode
58
59

    while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
60
61
      if (this.matches(ancestor, selector)) {
        parents.push(ancestor)
62
63
      }

64
65
      ancestor = ancestor.parentNode
    }
66

67
68
    return parents
  },
69

70
71
72
73
  closest(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
74

75
    return element.closest(selector)
76
  },
77

78
79
80
81
  prev(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
82

83
84
    const siblings = []
    let previous = element.previousSibling
85
86

    while (previous && previous.nodeType === Node.ELEMENT_NODE && previous.nodeType !== NODE_TEXT) {
87
88
      if (this.matches(previous, selector)) {
        siblings.push(previous)
89
90
      }

91
      previous = previous.previousSibling
Johann-S's avatar
Johann-S committed
92
    }
93
94

    return siblings
Johann-S's avatar
Johann-S committed
95
  }
96
}
Johann-S's avatar
Johann-S committed
97
98

export default SelectorEngine