UNPKG

15.8 kBJavaScriptView Raw
1function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
2
3function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
5function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
6
7function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
8
9/**
10 * --------------------------------------------------------------------------
11 * Bootstrap (v4.1.0): dropdown.js
12 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13 * --------------------------------------------------------------------------
14 */
15var Dropdown = function ($) {
16 /**
17 * ------------------------------------------------------------------------
18 * Constants
19 * ------------------------------------------------------------------------
20 */
21 var NAME = 'dropdown';
22 var VERSION = '4.1.0';
23 var DATA_KEY = 'bs.dropdown';
24 var EVENT_KEY = "." + DATA_KEY;
25 var DATA_API_KEY = '.data-api';
26 var JQUERY_NO_CONFLICT = $.fn[NAME];
27 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
28
29 var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
30
31 var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
32
33 var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
34
35 var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
36
37 var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
38
39 var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
40 var Event = {
41 HIDE: "hide" + EVENT_KEY,
42 HIDDEN: "hidden" + EVENT_KEY,
43 SHOW: "show" + EVENT_KEY,
44 SHOWN: "shown" + EVENT_KEY,
45 CLICK: "click" + EVENT_KEY,
46 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY,
47 KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY,
48 KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY
49 };
50 var ClassName = {
51 DISABLED: 'disabled',
52 SHOW: 'show',
53 DROPUP: 'dropup',
54 DROPRIGHT: 'dropright',
55 DROPLEFT: 'dropleft',
56 MENURIGHT: 'dropdown-menu-right',
57 MENULEFT: 'dropdown-menu-left',
58 POSITION_STATIC: 'position-static'
59 };
60 var Selector = {
61 DATA_TOGGLE: '[data-toggle="dropdown"]',
62 FORM_CHILD: '.dropdown form',
63 MENU: '.dropdown-menu',
64 NAVBAR_NAV: '.navbar-nav',
65 VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
66 };
67 var AttachmentMap = {
68 TOP: 'top-start',
69 TOPEND: 'top-end',
70 BOTTOM: 'bottom-start',
71 BOTTOMEND: 'bottom-end',
72 RIGHT: 'right-start',
73 RIGHTEND: 'right-end',
74 LEFT: 'left-start',
75 LEFTEND: 'left-end'
76 };
77 var Default = {
78 offset: 0,
79 flip: true,
80 boundary: 'scrollParent',
81 reference: 'toggle',
82 display: 'dynamic'
83 };
84 var DefaultType = {
85 offset: '(number|string|function)',
86 flip: 'boolean',
87 boundary: '(string|element)',
88 reference: '(string|element)',
89 display: 'string'
90 /**
91 * ------------------------------------------------------------------------
92 * Class Definition
93 * ------------------------------------------------------------------------
94 */
95
96 };
97
98 var Dropdown =
99 /*#__PURE__*/
100 function () {
101 function Dropdown(element, config) {
102 this._element = element;
103 this._popper = null;
104 this._config = this._getConfig(config);
105 this._menu = this._getMenuElement();
106 this._inNavbar = this._detectNavbar();
107
108 this._addEventListeners();
109 } // Getters
110
111
112 var _proto = Dropdown.prototype;
113
114 // Public
115 _proto.toggle = function toggle() {
116 if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
117 return;
118 }
119
120 var parent = Dropdown._getParentFromElement(this._element);
121
122 var isActive = $(this._menu).hasClass(ClassName.SHOW);
123
124 Dropdown._clearMenus();
125
126 if (isActive) {
127 return;
128 }
129
130 var relatedTarget = {
131 relatedTarget: this._element
132 };
133 var showEvent = $.Event(Event.SHOW, relatedTarget);
134 $(parent).trigger(showEvent);
135
136 if (showEvent.isDefaultPrevented()) {
137 return;
138 } // Disable totally Popper.js for Dropdown in Navbar
139
140
141 if (!this._inNavbar) {
142 /**
143 * Check for Popper dependency
144 * Popper - https://popper.js.org
145 */
146 if (typeof Popper === 'undefined') {
147 throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)');
148 }
149
150 var referenceElement = this._element;
151
152 if (this._config.reference === 'parent') {
153 referenceElement = parent;
154 } else if (Util.isElement(this._config.reference)) {
155 referenceElement = this._config.reference; // Check if it's jQuery element
156
157 if (typeof this._config.reference.jquery !== 'undefined') {
158 referenceElement = this._config.reference[0];
159 }
160 } // If boundary is not `scrollParent`, then set position to `static`
161 // to allow the menu to "escape" the scroll parent's boundaries
162 // https://github.com/twbs/bootstrap/issues/24251
163
164
165 if (this._config.boundary !== 'scrollParent') {
166 $(parent).addClass(ClassName.POSITION_STATIC);
167 }
168
169 this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
170 } // If this is a touch-enabled device we add extra
171 // empty mouseover listeners to the body's immediate children;
172 // only needed because of broken event delegation on iOS
173 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
174
175
176 if ('ontouchstart' in document.documentElement && $(parent).closest(Selector.NAVBAR_NAV).length === 0) {
177 $(document.body).children().on('mouseover', null, $.noop);
178 }
179
180 this._element.focus();
181
182 this._element.setAttribute('aria-expanded', true);
183
184 $(this._menu).toggleClass(ClassName.SHOW);
185 $(parent).toggleClass(ClassName.SHOW).trigger($.Event(Event.SHOWN, relatedTarget));
186 };
187
188 _proto.dispose = function dispose() {
189 $.removeData(this._element, DATA_KEY);
190 $(this._element).off(EVENT_KEY);
191 this._element = null;
192 this._menu = null;
193
194 if (this._popper !== null) {
195 this._popper.destroy();
196
197 this._popper = null;
198 }
199 };
200
201 _proto.update = function update() {
202 this._inNavbar = this._detectNavbar();
203
204 if (this._popper !== null) {
205 this._popper.scheduleUpdate();
206 }
207 }; // Private
208
209
210 _proto._addEventListeners = function _addEventListeners() {
211 var _this = this;
212
213 $(this._element).on(Event.CLICK, function (event) {
214 event.preventDefault();
215 event.stopPropagation();
216
217 _this.toggle();
218 });
219 };
220
221 _proto._getConfig = function _getConfig(config) {
222 config = _objectSpread({}, this.constructor.Default, $(this._element).data(), config);
223 Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
224 return config;
225 };
226
227 _proto._getMenuElement = function _getMenuElement() {
228 if (!this._menu) {
229 var parent = Dropdown._getParentFromElement(this._element);
230
231 this._menu = $(parent).find(Selector.MENU)[0];
232 }
233
234 return this._menu;
235 };
236
237 _proto._getPlacement = function _getPlacement() {
238 var $parentDropdown = $(this._element).parent();
239 var placement = AttachmentMap.BOTTOM; // Handle dropup
240
241 if ($parentDropdown.hasClass(ClassName.DROPUP)) {
242 placement = AttachmentMap.TOP;
243
244 if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
245 placement = AttachmentMap.TOPEND;
246 }
247 } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {
248 placement = AttachmentMap.RIGHT;
249 } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {
250 placement = AttachmentMap.LEFT;
251 } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
252 placement = AttachmentMap.BOTTOMEND;
253 }
254
255 return placement;
256 };
257
258 _proto._detectNavbar = function _detectNavbar() {
259 return $(this._element).closest('.navbar').length > 0;
260 };
261
262 _proto._getPopperConfig = function _getPopperConfig() {
263 var _this2 = this;
264
265 var offsetConf = {};
266
267 if (typeof this._config.offset === 'function') {
268 offsetConf.fn = function (data) {
269 data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets) || {});
270 return data;
271 };
272 } else {
273 offsetConf.offset = this._config.offset;
274 }
275
276 var popperConfig = {
277 placement: this._getPlacement(),
278 modifiers: {
279 offset: offsetConf,
280 flip: {
281 enabled: this._config.flip
282 },
283 preventOverflow: {
284 boundariesElement: this._config.boundary
285 }
286 } // Disable Popper.js if we have a static display
287
288 };
289
290 if (this._config.display === 'static') {
291 popperConfig.modifiers.applyStyle = {
292 enabled: false
293 };
294 }
295
296 return popperConfig;
297 }; // Static
298
299
300 Dropdown._jQueryInterface = function _jQueryInterface(config) {
301 return this.each(function () {
302 var data = $(this).data(DATA_KEY);
303
304 var _config = typeof config === 'object' ? config : null;
305
306 if (!data) {
307 data = new Dropdown(this, _config);
308 $(this).data(DATA_KEY, data);
309 }
310
311 if (typeof config === 'string') {
312 if (typeof data[config] === 'undefined') {
313 throw new TypeError("No method named \"" + config + "\"");
314 }
315
316 data[config]();
317 }
318 });
319 };
320
321 Dropdown._clearMenus = function _clearMenus(event) {
322 if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
323 return;
324 }
325
326 var toggles = $.makeArray($(Selector.DATA_TOGGLE));
327
328 for (var i = 0; i < toggles.length; i++) {
329 var parent = Dropdown._getParentFromElement(toggles[i]);
330
331 var context = $(toggles[i]).data(DATA_KEY);
332 var relatedTarget = {
333 relatedTarget: toggles[i]
334 };
335
336 if (!context) {
337 continue;
338 }
339
340 var dropdownMenu = context._menu;
341
342 if (!$(parent).hasClass(ClassName.SHOW)) {
343 continue;
344 }
345
346 if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
347 continue;
348 }
349
350 var hideEvent = $.Event(Event.HIDE, relatedTarget);
351 $(parent).trigger(hideEvent);
352
353 if (hideEvent.isDefaultPrevented()) {
354 continue;
355 } // If this is a touch-enabled device we remove the extra
356 // empty mouseover listeners we added for iOS support
357
358
359 if ('ontouchstart' in document.documentElement) {
360 $(document.body).children().off('mouseover', null, $.noop);
361 }
362
363 toggles[i].setAttribute('aria-expanded', 'false');
364 $(dropdownMenu).removeClass(ClassName.SHOW);
365 $(parent).removeClass(ClassName.SHOW).trigger($.Event(Event.HIDDEN, relatedTarget));
366 }
367 };
368
369 Dropdown._getParentFromElement = function _getParentFromElement(element) {
370 var parent;
371 var selector = Util.getSelectorFromElement(element);
372
373 if (selector) {
374 parent = $(selector)[0];
375 }
376
377 return parent || element.parentNode;
378 }; // eslint-disable-next-line complexity
379
380
381 Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
382 // If not input/textarea:
383 // - And not a key in REGEXP_KEYDOWN => not a dropdown command
384 // If input/textarea:
385 // - If space key => not a dropdown command
386 // - If key is other than escape
387 // - If key is not up or down => not a dropdown command
388 // - If trigger inside the menu => not a dropdown command
389 if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
390 return;
391 }
392
393 event.preventDefault();
394 event.stopPropagation();
395
396 if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
397 return;
398 }
399
400 var parent = Dropdown._getParentFromElement(this);
401
402 var isActive = $(parent).hasClass(ClassName.SHOW);
403
404 if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
405 if (event.which === ESCAPE_KEYCODE) {
406 var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
407 $(toggle).trigger('focus');
408 }
409
410 $(this).trigger('click');
411 return;
412 }
413
414 var items = $(parent).find(Selector.VISIBLE_ITEMS).get();
415
416 if (items.length === 0) {
417 return;
418 }
419
420 var index = items.indexOf(event.target);
421
422 if (event.which === ARROW_UP_KEYCODE && index > 0) {
423 // Up
424 index--;
425 }
426
427 if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
428 // Down
429 index++;
430 }
431
432 if (index < 0) {
433 index = 0;
434 }
435
436 items[index].focus();
437 };
438
439 _createClass(Dropdown, null, [{
440 key: "VERSION",
441 get: function get() {
442 return VERSION;
443 }
444 }, {
445 key: "Default",
446 get: function get() {
447 return Default;
448 }
449 }, {
450 key: "DefaultType",
451 get: function get() {
452 return DefaultType;
453 }
454 }]);
455
456 return Dropdown;
457 }();
458 /**
459 * ------------------------------------------------------------------------
460 * Data Api implementation
461 * ------------------------------------------------------------------------
462 */
463
464
465 $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
466 event.preventDefault();
467 event.stopPropagation();
468
469 Dropdown._jQueryInterface.call($(this), 'toggle');
470 }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
471 e.stopPropagation();
472 });
473 /**
474 * ------------------------------------------------------------------------
475 * jQuery
476 * ------------------------------------------------------------------------
477 */
478
479 $.fn[NAME] = Dropdown._jQueryInterface;
480 $.fn[NAME].Constructor = Dropdown;
481
482 $.fn[NAME].noConflict = function () {
483 $.fn[NAME] = JQUERY_NO_CONFLICT;
484 return Dropdown._jQueryInterface;
485 };
486
487 return Dropdown;
488}($, Popper);
489//# sourceMappingURL=dropdown.js.map
\No newline at end of file