]>
Commit | Line | Data |
---|---|---|
91e44d91 S |
1 | /** |
2 | * -------------------------------------------------------------------------- | |
3 | * Bootstrap (v4.0.0-alpha.6): util.js | |
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | |
5 | * -------------------------------------------------------------------------- | |
6 | */ | |
7 | ||
8 | const Util = (($) => { | |
9 | ||
10 | ||
11 | /** | |
12 | * ------------------------------------------------------------------------ | |
13 | * Private TransitionEnd Helpers | |
14 | * ------------------------------------------------------------------------ | |
15 | */ | |
16 | ||
17 | let transition = false | |
18 | ||
19 | const MAX_UID = 1000000 | |
20 | ||
21 | const TransitionEndEvent = { | |
22 | WebkitTransition : 'webkitTransitionEnd', | |
23 | MozTransition : 'transitionend', | |
24 | OTransition : 'oTransitionEnd otransitionend', | |
25 | transition : 'transitionend' | |
26 | } | |
27 | ||
28 | // shoutout AngusCroll (https://goo.gl/pxwQGp) | |
29 | function toType(obj) { | |
30 | return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase() | |
31 | } | |
32 | ||
33 | function isElement(obj) { | |
34 | return (obj[0] || obj).nodeType | |
35 | } | |
36 | ||
37 | function getSpecialTransitionEndEvent() { | |
38 | return { | |
39 | bindType: transition.end, | |
40 | delegateType: transition.end, | |
41 | handle(event) { | |
42 | if ($(event.target).is(this)) { | |
43 | return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params | |
44 | } | |
45 | return undefined | |
46 | } | |
47 | } | |
48 | } | |
49 | ||
50 | function transitionEndTest() { | |
51 | if (window.QUnit) { | |
52 | return false | |
53 | } | |
54 | ||
55 | const el = document.createElement('bootstrap') | |
56 | ||
57 | for (const name in TransitionEndEvent) { | |
58 | if (el.style[name] !== undefined) { | |
59 | return { | |
60 | end: TransitionEndEvent[name] | |
61 | } | |
62 | } | |
63 | } | |
64 | ||
65 | return false | |
66 | } | |
67 | ||
68 | function transitionEndEmulator(duration) { | |
69 | let called = false | |
70 | ||
71 | $(this).one(Util.TRANSITION_END, () => { | |
72 | called = true | |
73 | }) | |
74 | ||
75 | setTimeout(() => { | |
76 | if (!called) { | |
77 | Util.triggerTransitionEnd(this) | |
78 | } | |
79 | }, duration) | |
80 | ||
81 | return this | |
82 | } | |
83 | ||
84 | function setTransitionEndSupport() { | |
85 | transition = transitionEndTest() | |
86 | ||
87 | $.fn.emulateTransitionEnd = transitionEndEmulator | |
88 | ||
89 | if (Util.supportsTransitionEnd()) { | |
90 | $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent() | |
91 | } | |
92 | } | |
93 | ||
94 | ||
95 | /** | |
96 | * -------------------------------------------------------------------------- | |
97 | * Public Util Api | |
98 | * -------------------------------------------------------------------------- | |
99 | */ | |
100 | ||
101 | const Util = { | |
102 | ||
103 | TRANSITION_END: 'bsTransitionEnd', | |
104 | ||
105 | getUID(prefix) { | |
106 | do { | |
107 | // eslint-disable-next-line no-bitwise | |
108 | prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here | |
109 | } while (document.getElementById(prefix)) | |
110 | return prefix | |
111 | }, | |
112 | ||
113 | getSelectorFromElement(element) { | |
114 | let selector = element.getAttribute('data-target') | |
115 | ||
116 | if (!selector) { | |
117 | selector = element.getAttribute('href') || '' | |
118 | selector = /^#[a-z]/i.test(selector) ? selector : null | |
119 | } | |
120 | ||
121 | return selector | |
122 | }, | |
123 | ||
124 | reflow(element) { | |
125 | return element.offsetHeight | |
126 | }, | |
127 | ||
128 | triggerTransitionEnd(element) { | |
129 | $(element).trigger(transition.end) | |
130 | }, | |
131 | ||
132 | supportsTransitionEnd() { | |
133 | return Boolean(transition) | |
134 | }, | |
135 | ||
136 | typeCheckConfig(componentName, config, configTypes) { | |
137 | for (const property in configTypes) { | |
138 | if (configTypes.hasOwnProperty(property)) { | |
139 | const expectedTypes = configTypes[property] | |
140 | const value = config[property] | |
141 | const valueType = value && isElement(value) ? | |
142 | 'element' : toType(value) | |
143 | ||
144 | if (!new RegExp(expectedTypes).test(valueType)) { | |
145 | throw new Error( | |
146 | `${componentName.toUpperCase()}: ` + | |
147 | `Option "${property}" provided type "${valueType}" ` + | |
148 | `but expected type "${expectedTypes}".`) | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | } | |
154 | ||
155 | setTransitionEndSupport() | |
156 | ||
157 | return Util | |
158 | ||
159 | })(jQuery) | |
160 | ||
161 | export default Util |