dropdown.js 8.75 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
27
28
29
  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
  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)
fat's avatar
fat committed
30
31

  var Event = {
fat's avatar
fat committed
32
33
34
35
36
    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
37
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
Mark Otto's avatar
grunt    
Mark Otto committed
38
    FOCUSIN_DATA_API: 'focusin' + EVENT_KEY + DATA_API_KEY,
Jacob Thornton's avatar
Jacob Thornton committed
39
    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY
fat's avatar
fat committed
40
41
42
43
44
  };

  var ClassName = {
    BACKDROP: 'dropdown-backdrop',
    DISABLED: 'disabled',
Mark Otto's avatar
grunt    
Mark Otto committed
45
    SHOW: 'show'
fat's avatar
fat committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  };

  var Selector = {
    BACKDROP: '.dropdown-backdrop',
    DATA_TOGGLE: '[data-toggle="dropdown"]',
    FORM_CHILD: '.dropdown form',
    ROLE_MENU: '[role="menu"]',
    ROLE_LISTBOX: '[role="listbox"]',
    NAVBAR_NAV: '.navbar-nav',
    VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a'
  };

  /**
   * ------------------------------------------------------------------------
   * 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
      if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
fat's avatar
fat committed
92

Mark Otto's avatar
grunt    
Mark Otto committed
93
94
95
96
97
98
        // if mobile we use a backdrop because click events don't delegate
        var dropdown = document.createElement('div');
        dropdown.className = ClassName.BACKDROP;
        $(dropdown).insertBefore(this);
        $(dropdown).on('click', Dropdown._clearMenus);
      }
fat's avatar
fat committed
99

Mark Otto's avatar
grunt    
Mark Otto committed
100
101
102
      var relatedTarget = {
        relatedTarget: this
      };
Mark Otto's avatar
grunt    
Mark Otto committed
103
      var showEvent = $.Event(Event.SHOW, relatedTarget);
fat's avatar
fat committed
104

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

Mark Otto's avatar
grunt    
Mark Otto committed
107
108
109
      if (showEvent.isDefaultPrevented()) {
        return false;
      }
fat's avatar
fat committed
110

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

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

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

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

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

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

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

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

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

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

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

Mark Otto's avatar
grunt    
Mark Otto committed
157
158
159
160
      var backdrop = $(Selector.BACKDROP)[0];
      if (backdrop) {
        backdrop.parentNode.removeChild(backdrop);
      }
fat's avatar
fat committed
161

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

Mark Otto's avatar
grunt    
Mark Otto committed
164
165
      for (var i = 0; i < toggles.length; i++) {
        var parent = Dropdown._getParentFromElement(toggles[i]);
Mark Otto's avatar
grunt    
Mark Otto committed
166
167
168
        var relatedTarget = {
          relatedTarget: toggles[i]
        };
fat's avatar
fat committed
169

Mark Otto's avatar
grunt    
Mark Otto committed
170
        if (!$(parent).hasClass(ClassName.SHOW)) {
Mark Otto's avatar
grunt    
Mark Otto committed
171
172
          continue;
        }
fat's avatar
fat committed
173

Mark Otto's avatar
grunt    
Mark Otto committed
174
        if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'focusin') && $.contains(parent, event.target)) {
Mark Otto's avatar
grunt    
Mark Otto committed
175
176
          continue;
        }
fat's avatar
fat committed
177

Mark Otto's avatar
grunt    
Mark Otto committed
178
179
180
181
        var hideEvent = $.Event(Event.HIDE, relatedTarget);
        $(parent).trigger(hideEvent);
        if (hideEvent.isDefaultPrevented()) {
          continue;
fat's avatar
fat committed
182
        }
Mark Otto's avatar
grunt    
Mark Otto committed
183
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
202
203
204
    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
      if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
        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
217
218
219
220
      if (!isActive && event.which !== ESCAPE_KEYCODE || isActive && event.which === ESCAPE_KEYCODE) {

        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.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + ' ' + Event.FOCUSIN_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);
Jacob Thornton's avatar
Jacob Thornton committed
287
//# sourceMappingURL=dropdown.js.map