util.js 3.8 KB
Newer Older
1
2
import $ from 'jquery'

fat's avatar
fat committed
3
4
/**
 * --------------------------------------------------------------------------
Mark Otto's avatar
Mark Otto committed
5
 * Bootstrap (v4.1.3): util.js
fat's avatar
fat committed
6
7
8
9
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

fat's avatar
fat committed
10

Johann-S's avatar
Johann-S committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * ------------------------------------------------------------------------
 * Private TransitionEnd Helpers
 * ------------------------------------------------------------------------
 */

const TRANSITION_END = 'transitionend'
const MAX_UID = 1000000
const MILLISECONDS_MULTIPLIER = 1000

// Shoutout AngusCroll (https://goo.gl/pxwQGp)
function toType(obj) {
  return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
}

function getSpecialTransitionEndEvent() {
  return {
    bindType: TRANSITION_END,
    delegateType: TRANSITION_END,
    handle(event) {
      if ($(event.target).is(this)) {
        return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
33
      }
Johann-S's avatar
Johann-S committed
34
      return undefined // eslint-disable-line no-undefined
35
36
    }
  }
Johann-S's avatar
Johann-S committed
37
}
fat's avatar
fat committed
38

Johann-S's avatar
Johann-S committed
39
40
function transitionEndEmulator(duration) {
  let called = false
fat's avatar
fat committed
41

Johann-S's avatar
Johann-S committed
42
43
44
  $(this).one(Util.TRANSITION_END, () => {
    called = true
  })
fat's avatar
fat committed
45

Johann-S's avatar
Johann-S committed
46
47
48
49
50
  setTimeout(() => {
    if (!called) {
      Util.triggerTransitionEnd(this)
    }
  }, duration)
fat's avatar
fat committed
51

Johann-S's avatar
Johann-S committed
52
53
  return this
}
fat's avatar
fat committed
54

Johann-S's avatar
Johann-S committed
55
56
57
58
function setTransitionEndSupport() {
  $.fn.emulateTransitionEnd = transitionEndEmulator
  $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
}
fat's avatar
fat committed
59

Johann-S's avatar
Johann-S committed
60
61
62
63
64
/**
 * --------------------------------------------------------------------------
 * Public Util Api
 * --------------------------------------------------------------------------
 */
fat's avatar
fat committed
65

Johann-S's avatar
Johann-S committed
66
const Util = {
fat's avatar
fat committed
67

Johann-S's avatar
Johann-S committed
68
  TRANSITION_END: 'bsTransitionEnd',
69

Johann-S's avatar
Johann-S committed
70
71
72
73
74
75
76
  getUID(prefix) {
    do {
      // eslint-disable-next-line no-bitwise
      prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
    } while (document.getElementById(prefix))
    return prefix
  },
fat's avatar
fat committed
77

Johann-S's avatar
Johann-S committed
78
79
  getSelectorFromElement(element) {
    let selector = element.getAttribute('data-target')
80

Johann-S's avatar
Johann-S committed
81
82
83
84
    if (!selector || selector === '#') {
      const hrefAttr = element.getAttribute('href')
      selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''
    }
85

Johann-S's avatar
Johann-S committed
86
87
    return selector && document.querySelector(selector) ? selector : null
  },
fat's avatar
fat committed
88

Johann-S's avatar
Johann-S committed
89
90
91
92
  getTransitionDurationFromElement(element) {
    if (!element) {
      return 0
    }
93

Johann-S's avatar
Johann-S committed
94
95
96
    // Get transition-duration of the element
    let transitionDuration = $(element).css('transition-duration')
    const floatTransitionDuration = parseFloat(transitionDuration)
97

Johann-S's avatar
Johann-S committed
98
99
100
101
    // Return 0 if element or transition duration is not found
    if (!floatTransitionDuration) {
      return 0
    }
102

Johann-S's avatar
Johann-S committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    // If multiple durations are defined, take the first
    transitionDuration = transitionDuration.split(',')[0]

    return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER
  },

  reflow(element) {
    return element.offsetHeight
  },

  triggerTransitionEnd(element) {
    $(element).trigger(TRANSITION_END)
  },

  // TODO: Remove in v5
  supportsTransitionEnd() {
    return Boolean(TRANSITION_END)
  },

  isElement(obj) {
    return (obj[0] || obj).nodeType
  },

  typeCheckConfig(componentName, config, configTypes) {
    for (const property in configTypes) {
      if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
        const expectedTypes = configTypes[property]
        const value         = config[property]
        const valueType     = value && Util.isElement(value)
          ? 'element' : toType(value)

        if (!new RegExp(expectedTypes).test(valueType)) {
          throw new Error(
            `${componentName.toUpperCase()}: ` +
            `Option "${property}" provided type "${valueType}" ` +
            `but expected type "${expectedTypes}".`)
fat's avatar
fat committed
139
140
        }
      }
141
    }
fat's avatar
fat committed
142
  }
Johann-S's avatar
Johann-S committed
143
}
fat's avatar
fat committed
144

Johann-S's avatar
Johann-S committed
145
setTransitionEndSupport()
146
147

export default Util