dropdown.js 13.1 KB
Newer Older
Johann-S's avatar
build    
Johann-S committed
1
2
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

Mark Otto's avatar
grunt    
Mark Otto committed
3
var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
fat's avatar
fat committed
4

Mark Otto's avatar
grunt    
Mark Otto committed
5
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
fat's avatar
fat committed
6
7
8

/**
 * --------------------------------------------------------------------------
Mark Otto's avatar
Mark Otto committed
9
 * Bootstrap (v4.0.0-alpha.6): dropdown.js
fat's avatar
fat committed
10
11
12
13
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

Mark Otto's avatar
grunt    
Mark Otto committed
14
var Dropdown = function ($) {
fat's avatar
fat committed
15

Johann-S's avatar
build    
Johann-S committed
16
17
18
19
20
21
22
23
  /**
   * Check for Popper dependency
   * Popper - https://popper.js.org
   */
  if (typeof Popper === 'undefined') {
    throw new Error('Bootstrap dropdown require Popper.js (https://popper.js.org)');
  }

fat's avatar
fat committed
24
25
26
27
28
29
30
  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
   */

  var NAME = 'dropdown';
Mark Otto's avatar
Mark Otto committed
31
  var VERSION = '4.0.0-alpha.6';
fat's avatar
fat committed
32
  var DATA_KEY = 'bs.dropdown';
fat's avatar
fat committed
33
34
  var EVENT_KEY = '.' + DATA_KEY;
  var DATA_API_KEY = '.data-api';
fat's avatar
fat committed
35
  var JQUERY_NO_CONFLICT = $.fn[NAME];
Chris Rebert's avatar
grunt    
Chris Rebert committed
36
  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
Mark Otto's avatar
grunt    
Mark Otto committed
37
  var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
Mark Otto's avatar
grunt    
Mark Otto committed
38
  var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
Chris Rebert's avatar
grunt    
Chris Rebert committed
39
40
41
  var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
  var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
  var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
Mark Otto's avatar
grunt    
Mark Otto committed
42
  var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + '|' + ARROW_DOWN_KEYCODE + '|' + ESCAPE_KEYCODE);
fat's avatar
fat committed
43
44

  var Event = {
fat's avatar
fat committed
45
46
47
48
49
    HIDE: 'hide' + EVENT_KEY,
    HIDDEN: 'hidden' + EVENT_KEY,
    SHOW: 'show' + EVENT_KEY,
    SHOWN: 'shown' + EVENT_KEY,
    CLICK: 'click' + EVENT_KEY,
Jacob Thornton's avatar
Jacob Thornton committed
50
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
Mark Otto's avatar
grunt    
Mark Otto committed
51
52
    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY,
    KEYUP_DATA_API: 'keyup' + EVENT_KEY + DATA_API_KEY
fat's avatar
fat committed
53
54
55
56
  };

  var ClassName = {
    DISABLED: 'disabled',
Mark Otto's avatar
build    
Mark Otto committed
57
58
59
60
    SHOW: 'show',
    DROPUP: 'dropup',
    MENURIGHT: 'dropdown-menu-right',
    MENULEFT: 'dropdown-menu-left'
fat's avatar
fat committed
61
62
63
64
65
  };

  var Selector = {
    DATA_TOGGLE: '[data-toggle="dropdown"]',
    FORM_CHILD: '.dropdown form',
Mark Otto's avatar
grunt    
Mark Otto committed
66
    MENU: '.dropdown-menu',
fat's avatar
fat committed
67
    NAVBAR_NAV: '.navbar-nav',
Mark Otto's avatar
grunt    
Mark Otto committed
68
    VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled)'
fat's avatar
fat committed
69
70
  };

Johann-S's avatar
build    
Johann-S committed
71
72
  var AttachmentMap = {
    TOP: 'top-start',
Mark Otto's avatar
build    
Mark Otto committed
73
74
75
    TOPEND: 'top-end',
    BOTTOM: 'bottom-start',
    BOTTOMEND: 'bottom-end'
Johann-S's avatar
build    
Johann-S committed
76
77
78
79
80
81
82
83
84
85
86
87
88
  };

  var Default = {
    placement: AttachmentMap.BOTTOM,
    offset: 0,
    flip: true
  };

  var DefaultType = {
    placement: 'string',
    offset: '(number|string)',
    flip: 'boolean'

Mark Otto's avatar
build    
Mark Otto committed
89
90
91
92
93
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
fat's avatar
fat committed
94

Mark Otto's avatar
build    
Mark Otto committed
95
  };
Mark Otto's avatar
grunt    
Mark Otto committed
96
  var Dropdown = function () {
Johann-S's avatar
build    
Johann-S committed
97
    function Dropdown(element, config) {
fat's avatar
fat committed
98
99
      _classCallCheck(this, Dropdown);

fat's avatar
fat committed
100
      this._element = element;
Johann-S's avatar
build    
Johann-S committed
101
102
103
      this._popper = null;
      this._config = this._getConfig(config);
      this._menu = this._getMenuElement();
fat's avatar
fat committed
104
105

      this._addEventListeners();
fat's avatar
fat committed
106
107
    }

Jacob Thornton's avatar
Jacob Thornton committed
108
109
    // getters

Mark Otto's avatar
grunt    
Mark Otto committed
110
    // public
fat's avatar
fat committed
111

Mark Otto's avatar
grunt    
Mark Otto committed
112
    Dropdown.prototype.toggle = function toggle() {
Johann-S's avatar
build    
Johann-S committed
113
114
      if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
        return;
Mark Otto's avatar
grunt    
Mark Otto committed
115
      }
fat's avatar
fat committed
116

Johann-S's avatar
build    
Johann-S committed
117
118
      var parent = Dropdown._getParentFromElement(this._element);
      var isActive = $(this._menu).hasClass(ClassName.SHOW);
fat's avatar
fat committed
119

Mark Otto's avatar
grunt    
Mark Otto committed
120
      Dropdown._clearMenus();
fat's avatar
fat committed
121

Mark Otto's avatar
grunt    
Mark Otto committed
122
      if (isActive) {
Johann-S's avatar
build    
Johann-S committed
123
        return;
Mark Otto's avatar
grunt    
Mark Otto committed
124
      }
fat's avatar
fat committed
125

Mark Otto's avatar
grunt    
Mark Otto committed
126
      var relatedTarget = {
Johann-S's avatar
build    
Johann-S committed
127
        relatedTarget: this._element
Mark Otto's avatar
grunt    
Mark Otto committed
128
      };
Mark Otto's avatar
grunt    
Mark Otto committed
129
      var showEvent = $.Event(Event.SHOW, relatedTarget);
fat's avatar
fat committed
130

Mark Otto's avatar
grunt    
Mark Otto committed
131
      $(parent).trigger(showEvent);
fat's avatar
fat committed
132

Mark Otto's avatar
grunt    
Mark Otto committed
133
      if (showEvent.isDefaultPrevented()) {
Johann-S's avatar
build    
Johann-S committed
134
        return;
Mark Otto's avatar
grunt    
Mark Otto committed
135
      }
fat's avatar
fat committed
136

Mark Otto's avatar
build    
Mark Otto committed
137
138
139
140
141
142
143
144
145
      var element = this._element;
      // for dropup with alignment we use the parent as popper container
      if ($(parent).hasClass(ClassName.DROPUP)) {
        if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {
          element = parent;
        }
      }
      this._popper = new Popper(element, this._menu, {
        placement: this._getPlacement(),
Johann-S's avatar
build    
Johann-S committed
146
147
148
149
150
151
152
153
154
155
        modifiers: {
          offset: {
            offset: this._config.offset
          },
          flip: {
            enabled: this._config.flip
          }
        }
      });

Mark Otto's avatar
grunt    
Mark Otto committed
156
157
158
159
      // if this is a touch-enabled device we add extra
      // empty mouseover listeners to the body's immediate children;
      // only needed because of broken event delegation on iOS
      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
Mark Otto's avatar
grunt    
Mark Otto committed
160
      if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
Mark Otto's avatar
build    
Mark Otto committed
161
        $('body').children().on('mouseover', null, $.noop);
Mark Otto's avatar
grunt    
Mark Otto committed
162
163
      }

Johann-S's avatar
build    
Johann-S committed
164
165
      this._element.focus();
      this._element.setAttribute('aria-expanded', true);
fat's avatar
fat committed
166

Johann-S's avatar
build    
Johann-S committed
167
168
      $(this._menu).toggleClass(ClassName.SHOW);
      $(parent).toggleClass(ClassName.SHOW).trigger($.Event(Event.SHOWN, relatedTarget));
Mark Otto's avatar
grunt    
Mark Otto committed
169
    };
fat's avatar
fat committed
170

Mark Otto's avatar
grunt    
Mark Otto committed
171
172
173
174
    Dropdown.prototype.dispose = function dispose() {
      $.removeData(this._element, DATA_KEY);
      $(this._element).off(EVENT_KEY);
      this._element = null;
Johann-S's avatar
build    
Johann-S committed
175
176
177
178
179
180
181
182
183
184
185
      this._menu = null;
      if (this._popper !== null) {
        this._popper.destroy();
      }
      this._popper = null;
    };

    Dropdown.prototype.update = function update() {
      if (this._popper !== null) {
        this._popper.scheduleUpdate();
      }
Mark Otto's avatar
grunt    
Mark Otto committed
186
    };
fat's avatar
fat committed
187

Mark Otto's avatar
grunt    
Mark Otto committed
188
    // private
fat's avatar
fat committed
189

Mark Otto's avatar
grunt    
Mark Otto committed
190
    Dropdown.prototype._addEventListeners = function _addEventListeners() {
Johann-S's avatar
build    
Johann-S committed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
      var _this = this;

      $(this._element).on(Event.CLICK, function (event) {
        event.preventDefault();
        event.stopPropagation();
        _this.toggle();
      });
    };

    Dropdown.prototype._getConfig = function _getConfig(config) {
      var elementData = $(this._element).data();
      if (elementData.placement !== undefined) {
        elementData.placement = AttachmentMap[elementData.placement.toUpperCase()];
      }

      config = $.extend({}, this.constructor.Default, $(this._element).data(), config);

      Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);

      return config;
    };

    Dropdown.prototype._getMenuElement = function _getMenuElement() {
      if (!this._menu) {
        var parent = Dropdown._getParentFromElement(this._element);
        this._menu = $(parent).find(Selector.MENU)[0];
      }
      return this._menu;
Mark Otto's avatar
grunt    
Mark Otto committed
219
    };
fat's avatar
fat committed
220

Mark Otto's avatar
build    
Mark Otto committed
221
222
223
224
225
226
227
228
229
230
    Dropdown.prototype._getPlacement = function _getPlacement() {
      var $parentDropdown = $(this._element).parent();
      var placement = this._config.placement;

      // Handle dropup
      if ($parentDropdown.hasClass(ClassName.DROPUP) || this._config.placement === AttachmentMap.TOP) {
        placement = AttachmentMap.TOP;
        if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
          placement = AttachmentMap.TOPEND;
        }
Mark Otto's avatar
build    
Mark Otto committed
231
232
      } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
        placement = AttachmentMap.BOTTOMEND;
Mark Otto's avatar
build    
Mark Otto committed
233
      }
Mark Otto's avatar
build    
Mark Otto committed
234

Mark Otto's avatar
build    
Mark Otto committed
235
236
237
      return placement;
    };

Mark Otto's avatar
grunt    
Mark Otto committed
238
    // static
fat's avatar
fat committed
239

Mark Otto's avatar
grunt    
Mark Otto committed
240
241
242
    Dropdown._jQueryInterface = function _jQueryInterface(config) {
      return this.each(function () {
        var data = $(this).data(DATA_KEY);
Johann-S's avatar
build    
Johann-S committed
243
        var _config = (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' ? config : null;
fat's avatar
fat committed
244

Mark Otto's avatar
grunt    
Mark Otto committed
245
        if (!data) {
Johann-S's avatar
build    
Johann-S committed
246
          data = new Dropdown(this, _config);
Mark Otto's avatar
grunt    
Mark Otto committed
247
          $(this).data(DATA_KEY, data);
fat's avatar
fat committed
248
249
        }

Mark Otto's avatar
grunt    
Mark Otto committed
250
251
252
253
        if (typeof config === 'string') {
          if (data[config] === undefined) {
            throw new Error('No method named "' + config + '"');
          }
Johann-S's avatar
build    
Johann-S committed
254
          data[config]();
fat's avatar
fat committed
255
        }
Mark Otto's avatar
grunt    
Mark Otto committed
256
257
      });
    };
fat's avatar
fat committed
258

Mark Otto's avatar
grunt    
Mark Otto committed
259
    Dropdown._clearMenus = function _clearMenus(event) {
Mark Otto's avatar
grunt    
Mark Otto committed
260
      if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
Mark Otto's avatar
grunt    
Mark Otto committed
261
262
        return;
      }
fat's avatar
fat committed
263

Mark Otto's avatar
grunt    
Mark Otto committed
264
265
266
      var toggles = $.makeArray($(Selector.DATA_TOGGLE));
      for (var i = 0; i < toggles.length; i++) {
        var parent = Dropdown._getParentFromElement(toggles[i]);
Johann-S's avatar
build    
Johann-S committed
267
        var context = $(toggles[i]).data(DATA_KEY);
Mark Otto's avatar
grunt    
Mark Otto committed
268
269
270
        var relatedTarget = {
          relatedTarget: toggles[i]
        };
fat's avatar
fat committed
271

Johann-S's avatar
build    
Johann-S committed
272
273
274
275
276
        if (!context) {
          continue;
        }

        var dropdownMenu = context._menu;
Mark Otto's avatar
grunt    
Mark Otto committed
277
        if (!$(parent).hasClass(ClassName.SHOW)) {
Mark Otto's avatar
grunt    
Mark Otto committed
278
279
          continue;
        }
fat's avatar
fat committed
280

Mark Otto's avatar
grunt    
Mark Otto committed
281
        if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
Mark Otto's avatar
grunt    
Mark Otto committed
282
283
          continue;
        }
fat's avatar
fat committed
284

Mark Otto's avatar
grunt    
Mark Otto committed
285
286
287
288
        var hideEvent = $.Event(Event.HIDE, relatedTarget);
        $(parent).trigger(hideEvent);
        if (hideEvent.isDefaultPrevented()) {
          continue;
fat's avatar
fat committed
289
        }
Mark Otto's avatar
grunt    
Mark Otto committed
290

Mark Otto's avatar
grunt    
Mark Otto committed
291
292
293
        // if this is a touch-enabled device we remove the extra
        // empty mouseover listeners we added for iOS support
        if ('ontouchstart' in document.documentElement) {
Mark Otto's avatar
build    
Mark Otto committed
294
          $('body').children().off('mouseover', null, $.noop);
Mark Otto's avatar
grunt    
Mark Otto committed
295
296
        }

Mark Otto's avatar
grunt    
Mark Otto committed
297
298
        toggles[i].setAttribute('aria-expanded', 'false');

Johann-S's avatar
build    
Johann-S committed
299
        $(dropdownMenu).removeClass(ClassName.SHOW);
Mark Otto's avatar
grunt    
Mark Otto committed
300
        $(parent).removeClass(ClassName.SHOW).trigger($.Event(Event.HIDDEN, relatedTarget));
fat's avatar
fat committed
301
      }
Mark Otto's avatar
grunt    
Mark Otto committed
302
303
304
305
306
    };

    Dropdown._getParentFromElement = function _getParentFromElement(element) {
      var parent = void 0;
      var selector = Util.getSelectorFromElement(element);
fat's avatar
fat committed
307

Mark Otto's avatar
grunt    
Mark Otto committed
308
309
      if (selector) {
        parent = $(selector)[0];
fat's avatar
fat committed
310
311
      }

Mark Otto's avatar
grunt    
Mark Otto committed
312
313
      return parent || element.parentNode;
    };
fat's avatar
fat committed
314

Mark Otto's avatar
grunt    
Mark Otto committed
315
    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
Mark Otto's avatar
grunt    
Mark Otto committed
316
      if (!REGEXP_KEYDOWN.test(event.which) || /button/i.test(event.target.tagName) && event.which === SPACE_KEYCODE || /input|textarea/i.test(event.target.tagName)) {
Mark Otto's avatar
grunt    
Mark Otto committed
317
318
        return;
      }
fat's avatar
fat committed
319

Mark Otto's avatar
grunt    
Mark Otto committed
320
321
      event.preventDefault();
      event.stopPropagation();
fat's avatar
fat committed
322

Mark Otto's avatar
grunt    
Mark Otto committed
323
324
325
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return;
      }
fat's avatar
fat committed
326

Mark Otto's avatar
grunt    
Mark Otto committed
327
      var parent = Dropdown._getParentFromElement(this);
Mark Otto's avatar
grunt    
Mark Otto committed
328
      var isActive = $(parent).hasClass(ClassName.SHOW);
fat's avatar
fat committed
329

Mark Otto's avatar
grunt    
Mark Otto committed
330
      if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
Mark Otto's avatar
grunt    
Mark Otto committed
331
332
333
334

        if (event.which === ESCAPE_KEYCODE) {
          var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
          $(toggle).trigger('focus');
fat's avatar
fat committed
335
336
        }

Mark Otto's avatar
grunt    
Mark Otto committed
337
338
339
        $(this).trigger('click');
        return;
      }
fat's avatar
fat committed
340

Mark Otto's avatar
grunt    
Mark Otto committed
341
      var items = $(parent).find(Selector.VISIBLE_ITEMS).get();
fat's avatar
fat committed
342

Mark Otto's avatar
grunt    
Mark Otto committed
343
344
345
      if (!items.length) {
        return;
      }
fat's avatar
fat committed
346

Mark Otto's avatar
grunt    
Mark Otto committed
347
      var index = items.indexOf(event.target);
Mark Otto's avatar
Mark Otto committed
348

Mark Otto's avatar
grunt    
Mark Otto committed
349
350
351
352
      if (event.which === ARROW_UP_KEYCODE && index > 0) {
        // up
        index--;
      }
Mark Otto's avatar
Mark Otto committed
353

Mark Otto's avatar
grunt    
Mark Otto committed
354
355
356
357
      if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
        // down
        index++;
      }
fat's avatar
fat committed
358

Mark Otto's avatar
grunt    
Mark Otto committed
359
360
      if (index < 0) {
        index = 0;
fat's avatar
fat committed
361
      }
Mark Otto's avatar
grunt    
Mark Otto committed
362
363
364
365
366

      items[index].focus();
    };

    _createClass(Dropdown, null, [{
Jacob Thornton's avatar
Jacob Thornton committed
367
368
369
370
      key: 'VERSION',
      get: function get() {
        return VERSION;
      }
Johann-S's avatar
build    
Johann-S committed
371
372
373
374
375
376
377
378
379
380
    }, {
      key: 'Default',
      get: function get() {
        return Default;
      }
    }, {
      key: 'DefaultType',
      get: function get() {
        return DefaultType;
      }
fat's avatar
fat committed
381
382
383
    }]);

    return Dropdown;
Mark Otto's avatar
grunt    
Mark Otto committed
384
385
386
387
388
389
390
  }();

  /**
   * ------------------------------------------------------------------------
   * Data Api implementation
   * ------------------------------------------------------------------------
   */
fat's avatar
fat committed
391

Johann-S's avatar
build    
Johann-S committed
392
393
394
395
396
  $(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) {
    event.preventDefault();
    event.stopPropagation();
    Dropdown._jQueryInterface.call($(this), 'toggle');
  }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
fat's avatar
fat committed
397
    e.stopPropagation();
Mark Otto's avatar
build    
Mark Otto committed
398
  }
fat's avatar
fat committed
399
400
401
402
403
404
405

  /**
   * ------------------------------------------------------------------------
   * jQuery
   * ------------------------------------------------------------------------
   */

Mark Otto's avatar
build    
Mark Otto committed
406
  );$.fn[NAME] = Dropdown._jQueryInterface;
fat's avatar
fat committed
407
408
409
410
411
412
413
  $.fn[NAME].Constructor = Dropdown;
  $.fn[NAME].noConflict = function () {
    $.fn[NAME] = JQUERY_NO_CONFLICT;
    return Dropdown._jQueryInterface;
  };

  return Dropdown;
Johann-S's avatar
build    
Johann-S committed
414
}(jQuery); /* global Popper */
Mark Otto's avatar
build    
Mark Otto committed
415
//# sourceMappingURL=dropdown.js.map