dropdown.js 9.15 KB
Newer Older
Mark Otto's avatar
grunt    
Mark Otto committed
1
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
2

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

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

Mark Otto's avatar
grunt    
Mark Otto committed
12
var Dropdown = function ($) {
fat's avatar
fat committed
13
14
15
16
17
18
19
20

  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
   */

  var NAME = 'dropdown';
Mark Otto's avatar
Mark Otto committed
21
  var VERSION = '4.0.0-alpha.6';
fat's avatar
fat committed
22
  var DATA_KEY = 'bs.dropdown';
fat's avatar
fat committed
23
24
  var EVENT_KEY = '.' + DATA_KEY;
  var DATA_API_KEY = '.data-api';
fat's avatar
fat committed
25
  var JQUERY_NO_CONFLICT = $.fn[NAME];
Chris Rebert's avatar
grunt    
Chris Rebert committed
26
  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
Mark Otto's avatar
grunt    
Mark Otto committed
27
  var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
Mark Otto's avatar
grunt    
Mark Otto committed
28
  var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
Chris Rebert's avatar
grunt    
Chris Rebert committed
29
30
31
  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
32
  var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + '|' + ARROW_DOWN_KEYCODE + '|' + ESCAPE_KEYCODE);
fat's avatar
fat committed
33
34

  var Event = {
fat's avatar
fat committed
35
36
37
38
39
    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
40
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
Mark Otto's avatar
grunt    
Mark Otto committed
41
42
    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY,
    KEYUP_DATA_API: 'keyup' + EVENT_KEY + DATA_API_KEY
fat's avatar
fat committed
43
44
45
46
  };

  var ClassName = {
    DISABLED: 'disabled',
Mark Otto's avatar
grunt    
Mark Otto committed
47
    SHOW: 'show'
fat's avatar
fat committed
48
49
50
51
52
  };

  var Selector = {
    DATA_TOGGLE: '[data-toggle="dropdown"]',
    FORM_CHILD: '.dropdown form',
Mark Otto's avatar
grunt    
Mark Otto committed
53
    MENU: '.dropdown-menu',
fat's avatar
fat committed
54
    NAVBAR_NAV: '.navbar-nav',
Mark Otto's avatar
grunt    
Mark Otto committed
55
    VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled)'
fat's avatar
fat committed
56
57
58
59
60
61
62
63
  };

  /**
   * ------------------------------------------------------------------------
   * Class Definition
   * ------------------------------------------------------------------------
   */

Mark Otto's avatar
grunt    
Mark Otto committed
64
  var Dropdown = function () {
fat's avatar
fat committed
65
66
67
    function Dropdown(element) {
      _classCallCheck(this, Dropdown);

fat's avatar
fat committed
68
69
70
      this._element = element;

      this._addEventListeners();
fat's avatar
fat committed
71
72
    }

Jacob Thornton's avatar
Jacob Thornton committed
73
74
    // getters

Mark Otto's avatar
grunt    
Mark Otto committed
75
    // public
fat's avatar
fat committed
76

Mark Otto's avatar
grunt    
Mark Otto committed
77
78
79
80
    Dropdown.prototype.toggle = function toggle() {
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return false;
      }
fat's avatar
fat committed
81

Mark Otto's avatar
grunt    
Mark Otto committed
82
      var parent = Dropdown._getParentFromElement(this);
Mark Otto's avatar
grunt    
Mark Otto committed
83
      var isActive = $(parent).hasClass(ClassName.SHOW);
fat's avatar
fat committed
84

Mark Otto's avatar
grunt    
Mark Otto committed
85
      Dropdown._clearMenus();
fat's avatar
fat committed
86

Mark Otto's avatar
grunt    
Mark Otto committed
87
88
89
      if (isActive) {
        return false;
      }
fat's avatar
fat committed
90

Mark Otto's avatar
grunt    
Mark Otto committed
91
92
93
      var relatedTarget = {
        relatedTarget: this
      };
Mark Otto's avatar
grunt    
Mark Otto committed
94
      var showEvent = $.Event(Event.SHOW, relatedTarget);
fat's avatar
fat committed
95

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

Mark Otto's avatar
grunt    
Mark Otto committed
98
99
100
      if (showEvent.isDefaultPrevented()) {
        return false;
      }
fat's avatar
fat committed
101

Mark Otto's avatar
grunt    
Mark Otto committed
102
103
104
105
      // 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
106
      if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
Mark Otto's avatar
build    
Mark Otto committed
107
        $('body').children().on('mouseover', null, $.noop);
Mark Otto's avatar
grunt    
Mark Otto committed
108
109
      }

Mark Otto's avatar
grunt    
Mark Otto committed
110
      this.focus();
Mark Otto's avatar
grunt    
Mark Otto committed
111
      this.setAttribute('aria-expanded', true);
fat's avatar
fat committed
112

Mark Otto's avatar
grunt    
Mark Otto committed
113
      $(parent).toggleClass(ClassName.SHOW);
Mark Otto's avatar
grunt    
Mark Otto committed
114
      $(parent).trigger($.Event(Event.SHOWN, relatedTarget));
fat's avatar
fat committed
115

Mark Otto's avatar
grunt    
Mark Otto committed
116
117
      return false;
    };
fat's avatar
fat committed
118

Mark Otto's avatar
grunt    
Mark Otto committed
119
120
121
122
123
    Dropdown.prototype.dispose = function dispose() {
      $.removeData(this._element, DATA_KEY);
      $(this._element).off(EVENT_KEY);
      this._element = null;
    };
fat's avatar
fat committed
124

Mark Otto's avatar
grunt    
Mark Otto committed
125
    // private
fat's avatar
fat committed
126

Mark Otto's avatar
grunt    
Mark Otto committed
127
128
129
    Dropdown.prototype._addEventListeners = function _addEventListeners() {
      $(this._element).on(Event.CLICK, this.toggle);
    };
fat's avatar
fat committed
130

Mark Otto's avatar
grunt    
Mark Otto committed
131
    // static
fat's avatar
fat committed
132

Mark Otto's avatar
grunt    
Mark Otto committed
133
134
135
    Dropdown._jQueryInterface = function _jQueryInterface(config) {
      return this.each(function () {
        var data = $(this).data(DATA_KEY);
fat's avatar
fat committed
136

Mark Otto's avatar
grunt    
Mark Otto committed
137
        if (!data) {
Mark Otto's avatar
grunt    
Mark Otto committed
138
139
          data = new Dropdown(this);
          $(this).data(DATA_KEY, data);
fat's avatar
fat committed
140
141
        }

Mark Otto's avatar
grunt    
Mark Otto committed
142
143
144
145
146
        if (typeof config === 'string') {
          if (data[config] === undefined) {
            throw new Error('No method named "' + config + '"');
          }
          data[config].call(this);
fat's avatar
fat committed
147
        }
Mark Otto's avatar
grunt    
Mark Otto committed
148
149
      });
    };
fat's avatar
fat committed
150

Mark Otto's avatar
grunt    
Mark Otto committed
151
    Dropdown._clearMenus = function _clearMenus(event) {
Mark Otto's avatar
grunt    
Mark Otto committed
152
      if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
Mark Otto's avatar
grunt    
Mark Otto committed
153
154
        return;
      }
fat's avatar
fat committed
155

Mark Otto's avatar
grunt    
Mark Otto committed
156
      var toggles = $.makeArray($(Selector.DATA_TOGGLE));
fat's avatar
fat committed
157

Mark Otto's avatar
grunt    
Mark Otto committed
158
159
      for (var i = 0; i < toggles.length; i++) {
        var parent = Dropdown._getParentFromElement(toggles[i]);
Mark Otto's avatar
grunt    
Mark Otto committed
160
161
162
        var relatedTarget = {
          relatedTarget: toggles[i]
        };
fat's avatar
fat committed
163

Mark Otto's avatar
grunt    
Mark Otto committed
164
        if (!$(parent).hasClass(ClassName.SHOW)) {
Mark Otto's avatar
grunt    
Mark Otto committed
165
166
          continue;
        }
fat's avatar
fat committed
167

Mark Otto's avatar
grunt    
Mark Otto committed
168
        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
169
170
          continue;
        }
fat's avatar
fat committed
171

Mark Otto's avatar
grunt    
Mark Otto committed
172
173
174
175
        var hideEvent = $.Event(Event.HIDE, relatedTarget);
        $(parent).trigger(hideEvent);
        if (hideEvent.isDefaultPrevented()) {
          continue;
fat's avatar
fat committed
176
        }
Mark Otto's avatar
grunt    
Mark Otto committed
177

Mark Otto's avatar
grunt    
Mark Otto committed
178
179
180
        // 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
181
          $('body').children().off('mouseover', null, $.noop);
Mark Otto's avatar
grunt    
Mark Otto committed
182
183
        }

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

Mark Otto's avatar
grunt    
Mark Otto committed
186
        $(parent).removeClass(ClassName.SHOW).trigger($.Event(Event.HIDDEN, relatedTarget));
fat's avatar
fat committed
187
      }
Mark Otto's avatar
grunt    
Mark Otto committed
188
189
190
191
192
    };

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

Mark Otto's avatar
grunt    
Mark Otto committed
194
195
      if (selector) {
        parent = $(selector)[0];
fat's avatar
fat committed
196
197
      }

Mark Otto's avatar
grunt    
Mark Otto committed
198
199
      return parent || element.parentNode;
    };
fat's avatar
fat committed
200

Mark Otto's avatar
grunt    
Mark Otto committed
201
    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
Mark Otto's avatar
grunt    
Mark Otto committed
202
      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
203
204
        return;
      }
fat's avatar
fat committed
205

Mark Otto's avatar
grunt    
Mark Otto committed
206
207
      event.preventDefault();
      event.stopPropagation();
fat's avatar
fat committed
208

Mark Otto's avatar
grunt    
Mark Otto committed
209
210
211
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return;
      }
fat's avatar
fat committed
212

Mark Otto's avatar
grunt    
Mark Otto committed
213
      var parent = Dropdown._getParentFromElement(this);
Mark Otto's avatar
grunt    
Mark Otto committed
214
      var isActive = $(parent).hasClass(ClassName.SHOW);
fat's avatar
fat committed
215

Mark Otto's avatar
grunt    
Mark Otto committed
216
      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
217
218
219
220

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

Mark Otto's avatar
grunt    
Mark Otto committed
223
224
225
        $(this).trigger('click');
        return;
      }
fat's avatar
fat committed
226

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

Mark Otto's avatar
grunt    
Mark Otto committed
229
230
231
      if (!items.length) {
        return;
      }
fat's avatar
fat committed
232

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

Mark Otto's avatar
grunt    
Mark Otto committed
235
236
237
238
      if (event.which === ARROW_UP_KEYCODE && index > 0) {
        // up
        index--;
      }
Mark Otto's avatar
Mark Otto committed
239

Mark Otto's avatar
grunt    
Mark Otto committed
240
241
242
243
      if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
        // down
        index++;
      }
fat's avatar
fat committed
244

Mark Otto's avatar
grunt    
Mark Otto committed
245
246
      if (index < 0) {
        index = 0;
fat's avatar
fat committed
247
      }
Mark Otto's avatar
grunt    
Mark Otto committed
248
249
250
251
252

      items[index].focus();
    };

    _createClass(Dropdown, null, [{
Jacob Thornton's avatar
Jacob Thornton committed
253
254
255
256
      key: 'VERSION',
      get: function get() {
        return VERSION;
      }
fat's avatar
fat committed
257
258
259
    }]);

    return Dropdown;
Mark Otto's avatar
grunt    
Mark Otto committed
260
261
262
263
264
265
266
  }();

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

Mark Otto's avatar
grunt    
Mark Otto committed
268
  $(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, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
fat's avatar
fat committed
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    e.stopPropagation();
  });

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

  $.fn[NAME] = Dropdown._jQueryInterface;
  $.fn[NAME].Constructor = Dropdown;
  $.fn[NAME].noConflict = function () {
    $.fn[NAME] = JQUERY_NO_CONFLICT;
    return Dropdown._jQueryInterface;
  };

  return Dropdown;
Mark Otto's avatar
grunt    
Mark Otto committed
286
}(jQuery);
Mark Otto's avatar
build    
Mark Otto committed
287
//# sourceMappingURL=dropdown.js.map