modal.js 15.3 KB
Newer Older
Mark Otto's avatar
grunt    
Mark Otto committed
1
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; };
2

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; }; }();
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"); } }
6
7
8

/**
 * --------------------------------------------------------------------------
Mark Otto's avatar
Mark Otto committed
9
 * Bootstrap (v4.0.0-alpha.5): modal.js
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 Modal = function ($) {
15
16
17
18
19
20
21
22

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

  var NAME = 'modal';
Mark Otto's avatar
Mark Otto committed
23
  var VERSION = '4.0.0-alpha.5';
24
  var DATA_KEY = 'bs.modal';
fat's avatar
fat committed
25
26
  var EVENT_KEY = '.' + DATA_KEY;
  var DATA_API_KEY = '.data-api';
27
28
29
  var JQUERY_NO_CONFLICT = $.fn[NAME];
  var TRANSITION_DURATION = 300;
  var BACKDROP_TRANSITION_DURATION = 150;
Chris Rebert's avatar
grunt    
Chris Rebert committed
30
  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
31
32
33
34

  var Default = {
    backdrop: true,
    keyboard: true,
fat's avatar
fat committed
35
    focus: true,
36
37
38
    show: true
  };

fat's avatar
fat committed
39
40
41
42
43
44
45
  var DefaultType = {
    backdrop: '(boolean|string)',
    keyboard: 'boolean',
    focus: 'boolean',
    show: 'boolean'
  };

46
  var Event = {
fat's avatar
fat committed
47
48
49
50
51
52
53
54
55
56
    HIDE: 'hide' + EVENT_KEY,
    HIDDEN: 'hidden' + EVENT_KEY,
    SHOW: 'show' + EVENT_KEY,
    SHOWN: 'shown' + EVENT_KEY,
    FOCUSIN: 'focusin' + EVENT_KEY,
    RESIZE: 'resize' + EVENT_KEY,
    CLICK_DISMISS: 'click.dismiss' + EVENT_KEY,
    KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY,
    MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY,
    MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY,
Jacob Thornton's avatar
Jacob Thornton committed
57
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
58
59
60
  };

  var ClassName = {
61
    SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
62
63
64
65
66
67
68
69
70
71
    BACKDROP: 'modal-backdrop',
    OPEN: 'modal-open',
    FADE: 'fade',
    IN: 'in'
  };

  var Selector = {
    DIALOG: '.modal-dialog',
    DATA_TOGGLE: '[data-toggle="modal"]',
    DATA_DISMISS: '[data-dismiss="modal"]',
72
    FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
73
74
75
76
77
78
79
80
  };

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

Mark Otto's avatar
grunt    
Mark Otto committed
81
  var Modal = function () {
82
83
84
    function Modal(element, config) {
      _classCallCheck(this, Modal);

fat's avatar
fat committed
85
      this._config = this._getConfig(config);
86
87
88
89
90
91
92
93
94
95
      this._element = element;
      this._dialog = $(element).find(Selector.DIALOG)[0];
      this._backdrop = null;
      this._isShown = false;
      this._isBodyOverflowing = false;
      this._ignoreBackdropClick = false;
      this._originalBodyPadding = 0;
      this._scrollbarWidth = 0;
    }

Jacob Thornton's avatar
Jacob Thornton committed
96
97
    // getters

Mark Otto's avatar
grunt    
Mark Otto committed
98
    // public
99

Mark Otto's avatar
grunt    
Mark Otto committed
100
101
102
    Modal.prototype.toggle = function toggle(relatedTarget) {
      return this._isShown ? this.hide() : this.show(relatedTarget);
    };
103

Mark Otto's avatar
grunt    
Mark Otto committed
104
105
    Modal.prototype.show = function show(relatedTarget) {
      var _this = this;
106

Mark Otto's avatar
grunt    
Mark Otto committed
107
108
109
      var showEvent = $.Event(Event.SHOW, {
        relatedTarget: relatedTarget
      });
110

Mark Otto's avatar
grunt    
Mark Otto committed
111
      $(this._element).trigger(showEvent);
112

Mark Otto's avatar
grunt    
Mark Otto committed
113
114
115
      if (this._isShown || showEvent.isDefaultPrevented()) {
        return;
      }
116

Mark Otto's avatar
grunt    
Mark Otto committed
117
      this._isShown = true;
118

Mark Otto's avatar
grunt    
Mark Otto committed
119
120
      this._checkScrollbar();
      this._setScrollbar();
121

Mark Otto's avatar
grunt    
Mark Otto committed
122
      $(document.body).addClass(ClassName.OPEN);
123

Mark Otto's avatar
grunt    
Mark Otto committed
124
125
      this._setEscapeEvent();
      this._setResizeEvent();
126

Mark Otto's avatar
grunt    
Mark Otto committed
127
      $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this));
128

Mark Otto's avatar
grunt    
Mark Otto committed
129
130
131
132
133
      $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
        $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
          if ($(event.target).is(_this._element)) {
            _this._ignoreBackdropClick = true;
          }
134
        });
Mark Otto's avatar
grunt    
Mark Otto committed
135
136
137
138
      });

      this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
    };
139

Mark Otto's avatar
grunt    
Mark Otto committed
140
141
142
    Modal.prototype.hide = function hide(event) {
      if (event) {
        event.preventDefault();
143
144
      }

Mark Otto's avatar
grunt    
Mark Otto committed
145
      var hideEvent = $.Event(Event.HIDE);
146

Mark Otto's avatar
grunt    
Mark Otto committed
147
      $(this._element).trigger(hideEvent);
148

Mark Otto's avatar
grunt    
Mark Otto committed
149
150
151
      if (!this._isShown || hideEvent.isDefaultPrevented()) {
        return;
      }
152

Mark Otto's avatar
grunt    
Mark Otto committed
153
      this._isShown = false;
154

Mark Otto's avatar
grunt    
Mark Otto committed
155
156
      this._setEscapeEvent();
      this._setResizeEvent();
157

Mark Otto's avatar
grunt    
Mark Otto committed
158
      $(document).off(Event.FOCUSIN);
159

Mark Otto's avatar
grunt    
Mark Otto committed
160
      $(this._element).removeClass(ClassName.IN);
161

Mark Otto's avatar
grunt    
Mark Otto committed
162
163
      $(this._element).off(Event.CLICK_DISMISS);
      $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
164

Mark Otto's avatar
grunt    
Mark Otto committed
165
      if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
166

Mark Otto's avatar
grunt    
Mark Otto committed
167
168
169
        $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
      } else {
        this._hideModal();
fat's avatar
fat committed
170
      }
Mark Otto's avatar
grunt    
Mark Otto committed
171
    };
172

Mark Otto's avatar
grunt    
Mark Otto committed
173
174
    Modal.prototype.dispose = function dispose() {
      $.removeData(this._element, DATA_KEY);
175

Mark Otto's avatar
grunt    
Mark Otto committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
      $(window).off(EVENT_KEY);
      $(document).off(EVENT_KEY);
      $(this._element).off(EVENT_KEY);
      $(this._backdrop).off(EVENT_KEY);

      this._config = null;
      this._element = null;
      this._dialog = null;
      this._backdrop = null;
      this._isShown = null;
      this._isBodyOverflowing = null;
      this._ignoreBackdropClick = null;
      this._originalBodyPadding = null;
      this._scrollbarWidth = null;
    };

    // private

    Modal.prototype._getConfig = function _getConfig(config) {
      config = $.extend({}, Default, config);
      Util.typeCheckConfig(NAME, config, DefaultType);
      return config;
    };

    Modal.prototype._showElement = function _showElement(relatedTarget) {
      var _this2 = this;

      var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);

      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
        // don't move modals dom position
        document.body.appendChild(this._element);
fat's avatar
fat committed
208
      }
209

Mark Otto's avatar
grunt    
Mark Otto committed
210
211
212
      this._element.style.display = 'block';
      this._element.removeAttribute('aria-hidden');
      this._element.scrollTop = 0;
213

Mark Otto's avatar
grunt    
Mark Otto committed
214
215
216
      if (transition) {
        Util.reflow(this._element);
      }
217

Mark Otto's avatar
grunt    
Mark Otto committed
218
      $(this._element).addClass(ClassName.IN);
219

Mark Otto's avatar
grunt    
Mark Otto committed
220
221
222
      if (this._config.focus) {
        this._enforceFocus();
      }
223

Mark Otto's avatar
grunt    
Mark Otto committed
224
225
226
      var shownEvent = $.Event(Event.SHOWN, {
        relatedTarget: relatedTarget
      });
227

Mark Otto's avatar
grunt    
Mark Otto committed
228
229
230
      var transitionComplete = function transitionComplete() {
        if (_this2._config.focus) {
          _this2._element.focus();
Mark Otto's avatar
Mark Otto committed
231
        }
Mark Otto's avatar
grunt    
Mark Otto committed
232
233
        $(_this2._element).trigger(shownEvent);
      };
234

Mark Otto's avatar
grunt    
Mark Otto committed
235
236
237
238
239
240
      if (transition) {
        $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
      } else {
        transitionComplete();
      }
    };
241

Mark Otto's avatar
grunt    
Mark Otto committed
242
243
    Modal.prototype._enforceFocus = function _enforceFocus() {
      var _this3 = this;
244

Mark Otto's avatar
grunt    
Mark Otto committed
245
246
247
248
      $(document).off(Event.FOCUSIN) // guard against infinite focus loop
      .on(Event.FOCUSIN, function (event) {
        if (document !== event.target && _this3._element !== event.target && !$(_this3._element).has(event.target).length) {
          _this3._element.focus();
249
        }
Mark Otto's avatar
grunt    
Mark Otto committed
250
251
252
253
254
255
256
257
258
259
      });
    };

    Modal.prototype._setEscapeEvent = function _setEscapeEvent() {
      var _this4 = this;

      if (this._isShown && this._config.keyboard) {
        $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
          if (event.which === ESCAPE_KEYCODE) {
            _this4.hide();
260
261
          }
        });
Mark Otto's avatar
grunt    
Mark Otto committed
262
263
      } else if (!this._isShown) {
        $(this._element).off(Event.KEYDOWN_DISMISS);
264
      }
Mark Otto's avatar
grunt    
Mark Otto committed
265
266
267
268
269
270
271
    };

    Modal.prototype._setResizeEvent = function _setResizeEvent() {
      if (this._isShown) {
        $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
      } else {
        $(window).off(Event.RESIZE);
272
      }
Mark Otto's avatar
grunt    
Mark Otto committed
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    };

    Modal.prototype._hideModal = function _hideModal() {
      var _this5 = this;

      this._element.style.display = 'none';
      this._element.setAttribute('aria-hidden', 'true');
      this._showBackdrop(function () {
        $(document.body).removeClass(ClassName.OPEN);
        _this5._resetAdjustments();
        _this5._resetScrollbar();
        $(_this5._element).trigger(Event.HIDDEN);
      });
    };

    Modal.prototype._removeBackdrop = function _removeBackdrop() {
      if (this._backdrop) {
        $(this._backdrop).remove();
        this._backdrop = null;
292
      }
Mark Otto's avatar
grunt    
Mark Otto committed
293
    };
294

Mark Otto's avatar
grunt    
Mark Otto committed
295
296
    Modal.prototype._showBackdrop = function _showBackdrop(callback) {
      var _this6 = this;
297

Mark Otto's avatar
grunt    
Mark Otto committed
298
      var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
299

Mark Otto's avatar
grunt    
Mark Otto committed
300
301
      if (this._isShown && this._config.backdrop) {
        var doAnimate = Util.supportsTransitionEnd() && animate;
302

Mark Otto's avatar
grunt    
Mark Otto committed
303
304
        this._backdrop = document.createElement('div');
        this._backdrop.className = ClassName.BACKDROP;
305

Mark Otto's avatar
grunt    
Mark Otto committed
306
307
308
        if (animate) {
          $(this._backdrop).addClass(animate);
        }
309

Mark Otto's avatar
grunt    
Mark Otto committed
310
        $(this._backdrop).appendTo(document.body);
311

Mark Otto's avatar
grunt    
Mark Otto committed
312
313
314
        $(this._element).on(Event.CLICK_DISMISS, function (event) {
          if (_this6._ignoreBackdropClick) {
            _this6._ignoreBackdropClick = false;
315
316
            return;
          }
Mark Otto's avatar
grunt    
Mark Otto committed
317
          if (event.target !== event.currentTarget) {
318
319
            return;
          }
Mark Otto's avatar
grunt    
Mark Otto committed
320
321
          if (_this6._config.backdrop === 'static') {
            _this6._element.focus();
322
          } else {
Mark Otto's avatar
grunt    
Mark Otto committed
323
            _this6.hide();
324
          }
Mark Otto's avatar
grunt    
Mark Otto committed
325
        });
326

Mark Otto's avatar
grunt    
Mark Otto committed
327
328
329
        if (doAnimate) {
          Util.reflow(this._backdrop);
        }
330

Mark Otto's avatar
grunt    
Mark Otto committed
331
        $(this._backdrop).addClass(ClassName.IN);
332

Mark Otto's avatar
grunt    
Mark Otto committed
333
334
        if (!callback) {
          return;
335
336
        }

Mark Otto's avatar
grunt    
Mark Otto committed
337
338
339
        if (!doAnimate) {
          callback();
          return;
340
341
        }

Mark Otto's avatar
grunt    
Mark Otto committed
342
343
344
        $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
      } else if (!this._isShown && this._backdrop) {
        $(this._backdrop).removeClass(ClassName.IN);
345

Mark Otto's avatar
grunt    
Mark Otto committed
346
347
348
349
350
351
352
353
354
355
356
        var callbackRemove = function callbackRemove() {
          _this6._removeBackdrop();
          if (callback) {
            callback();
          }
        };

        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
          $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
        } else {
          callbackRemove();
357
        }
Mark Otto's avatar
grunt    
Mark Otto committed
358
359
      } else if (callback) {
        callback();
360
      }
Mark Otto's avatar
grunt    
Mark Otto committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    };

    // ----------------------------------------------------------------------
    // the following methods are used to handle overflowing modals
    // todo (fat): these should probably be refactored out of modal.js
    // ----------------------------------------------------------------------

    Modal.prototype._handleUpdate = function _handleUpdate() {
      this._adjustDialog();
    };

    Modal.prototype._adjustDialog = function _adjustDialog() {
      var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;

      if (!this._isBodyOverflowing && isModalOverflowing) {
        this._element.style.paddingLeft = this._scrollbarWidth + 'px';
377
      }
Mark Otto's avatar
grunt    
Mark Otto committed
378
379
380

      if (this._isBodyOverflowing && !isModalOverflowing) {
        this._element.style.paddingRight = this._scrollbarWidth + 'px';
381
      }
Mark Otto's avatar
grunt    
Mark Otto committed
382
    };
383

Mark Otto's avatar
grunt    
Mark Otto committed
384
385
386
387
    Modal.prototype._resetAdjustments = function _resetAdjustments() {
      this._element.style.paddingLeft = '';
      this._element.style.paddingRight = '';
    };
388

Mark Otto's avatar
grunt    
Mark Otto committed
389
390
391
392
    Modal.prototype._checkScrollbar = function _checkScrollbar() {
      this._isBodyOverflowing = document.body.clientWidth < window.innerWidth;
      this._scrollbarWidth = this._getScrollbarWidth();
    };
393

Mark Otto's avatar
grunt    
Mark Otto committed
394
395
    Modal.prototype._setScrollbar = function _setScrollbar() {
      var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10);
396

Mark Otto's avatar
grunt    
Mark Otto committed
397
398
399
400
      this._originalBodyPadding = document.body.style.paddingRight || '';

      if (this._isBodyOverflowing) {
        document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
401
      }
Mark Otto's avatar
grunt    
Mark Otto committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    };

    Modal.prototype._resetScrollbar = function _resetScrollbar() {
      document.body.style.paddingRight = this._originalBodyPadding;
    };

    Modal.prototype._getScrollbarWidth = function _getScrollbarWidth() {
      // thx d.walsh
      var scrollDiv = document.createElement('div');
      scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
      document.body.appendChild(scrollDiv);
      var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
      document.body.removeChild(scrollDiv);
      return scrollbarWidth;
    };

    // static

    Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
      return this.each(function () {
        var data = $(this).data(DATA_KEY);
        var _config = $.extend({}, Modal.Default, $(this).data(), (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' && config);

        if (!data) {
          data = new Modal(this, _config);
          $(this).data(DATA_KEY, data);
        }

        if (typeof config === 'string') {
          if (data[config] === undefined) {
            throw new Error('No method named "' + config + '"');
          }
          data[config](relatedTarget);
        } else if (_config.show) {
          data.show(relatedTarget);
        }
      });
    };

    _createClass(Modal, null, [{
Jacob Thornton's avatar
Jacob Thornton committed
442
443
444
445
446
447
448
449
450
      key: 'VERSION',
      get: function get() {
        return VERSION;
      }
    }, {
      key: 'Default',
      get: function get() {
        return Default;
      }
451
452
453
    }]);

    return Modal;
Mark Otto's avatar
grunt    
Mark Otto committed
454
455
456
457
458
459
460
  }();

  /**
   * ------------------------------------------------------------------------
   * Data Api implementation
   * ------------------------------------------------------------------------
   */
461

fat's avatar
fat committed
462
  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
463
464
    var _this7 = this;

Mark Otto's avatar
grunt    
Mark Otto committed
465
    var target = void 0;
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    var selector = Util.getSelectorFromElement(this);

    if (selector) {
      target = $(selector)[0];
    }

    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());

    if (this.tagName === 'A') {
      event.preventDefault();
    }

    var $target = $(target).one(Event.SHOW, function (showEvent) {
      if (showEvent.isDefaultPrevented()) {
        // only register focus restorer if modal will actually get shown
        return;
      }

      $target.one(Event.HIDDEN, function () {
        if ($(_this7).is(':visible')) {
          _this7.focus();
        }
      });
    });

    Modal._jQueryInterface.call($(target), config, this);
  });

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

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

  return Modal;
Mark Otto's avatar
grunt    
Mark Otto committed
508
}(jQuery);
Jacob Thornton's avatar
Jacob Thornton committed
509
//# sourceMappingURL=modal.js.map