selectorEngine.js 2.24 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
10
11
import {
  makeArray
} from '../util/index'
12

13
14
15
16
17
/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */
Johann-S's avatar
Johann-S committed
18

19
const findFn = Polyfill.find
20
const findOne = Polyfill.findOne
21
const NODE_TEXT = 3
Johann-S's avatar
Johann-S committed
22

23
24
const SelectorEngine = {
  matches(element, selector) {
25
    return element.matches(selector)
26
  },
Johann-S's avatar
Johann-S committed
27

28
29
30
31
  find(selector, element = document.documentElement) {
    if (typeof selector !== 'string') {
      return null
    }
32

33
    return findFn.call(element, selector)
34
35
36
37
38
39
  },

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

41
42
    return findOne.call(element, selector)
  },
Johann-S's avatar
Johann-S committed
43

44
45
46
47
48
  children(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }

49
    const children = makeArray(element.children)
50

51
52
    return children.filter((child) => this.matches(child, selector))
  },
53

54
55
56
57
  parents(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
58

59
60
    const parents = []
    let ancestor = element.parentNode
61
62

    while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
63
64
      if (this.matches(ancestor, selector)) {
        parents.push(ancestor)
65
66
      }

67
68
      ancestor = ancestor.parentNode
    }
69

70
71
    return parents
  },
72

73
74
75
76
  closest(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
77

78
    return element.closest(selector)
79
  },
80

81
82
83
84
  prev(element, selector) {
    if (typeof selector !== 'string') {
      return null
    }
85

86
87
    const siblings = []
    let previous = element.previousSibling
88
89

    while (previous && previous.nodeType === Node.ELEMENT_NODE && previous.nodeType !== NODE_TEXT) {
90
91
      if (this.matches(previous, selector)) {
        siblings.push(previous)
92
93
      }

94
      previous = previous.previousSibling
Johann-S's avatar
Johann-S committed
95
    }
96
97

    return siblings
Johann-S's avatar
Johann-S committed
98
  }
99
}
Johann-S's avatar
Johann-S committed
100
101

export default SelectorEngine