]> git.ipfire.org Git - ipfire.org.git/blob - src/scss/bootstrap-4.0.0-alpha.6/js/dist/modal.js
.gitignore: Add .vscode
[ipfire.org.git] / src / scss / bootstrap-4.0.0-alpha.6 / js / dist / modal.js
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
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
5 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7 /**
8 * --------------------------------------------------------------------------
9 * Bootstrap (v4.0.0-alpha.6): modal.js
10 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11 * --------------------------------------------------------------------------
12 */
13
14 var Modal = function ($) {
15
16 /**
17 * ------------------------------------------------------------------------
18 * Constants
19 * ------------------------------------------------------------------------
20 */
21
22 var NAME = 'modal';
23 var VERSION = '4.0.0-alpha.6';
24 var DATA_KEY = 'bs.modal';
25 var EVENT_KEY = '.' + DATA_KEY;
26 var DATA_API_KEY = '.data-api';
27 var JQUERY_NO_CONFLICT = $.fn[NAME];
28 var TRANSITION_DURATION = 300;
29 var BACKDROP_TRANSITION_DURATION = 150;
30 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
31
32 var Default = {
33 backdrop: true,
34 keyboard: true,
35 focus: true,
36 show: true
37 };
38
39 var DefaultType = {
40 backdrop: '(boolean|string)',
41 keyboard: 'boolean',
42 focus: 'boolean',
43 show: 'boolean'
44 };
45
46 var Event = {
47 HIDE: 'hide' + EVENT_KEY,
48 HIDDEN: 'hidden' + EVENT_KEY,
49 SHOW: 'show' + EVENT_KEY,
50 SHOWN: 'shown' + EVENT_KEY,
51 FOCUSIN: 'focusin' + EVENT_KEY,
52 RESIZE: 'resize' + EVENT_KEY,
53 CLICK_DISMISS: 'click.dismiss' + EVENT_KEY,
54 KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY,
55 MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY,
56 MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY,
57 CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
58 };
59
60 var ClassName = {
61 SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
62 BACKDROP: 'modal-backdrop',
63 OPEN: 'modal-open',
64 FADE: 'fade',
65 SHOW: 'show'
66 };
67
68 var Selector = {
69 DIALOG: '.modal-dialog',
70 DATA_TOGGLE: '[data-toggle="modal"]',
71 DATA_DISMISS: '[data-dismiss="modal"]',
72 FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
73 };
74
75 /**
76 * ------------------------------------------------------------------------
77 * Class Definition
78 * ------------------------------------------------------------------------
79 */
80
81 var Modal = function () {
82 function Modal(element, config) {
83 _classCallCheck(this, Modal);
84
85 this._config = this._getConfig(config);
86 this._element = element;
87 this._dialog = $(element).find(Selector.DIALOG)[0];
88 this._backdrop = null;
89 this._isShown = false;
90 this._isBodyOverflowing = false;
91 this._ignoreBackdropClick = false;
92 this._isTransitioning = false;
93 this._originalBodyPadding = 0;
94 this._scrollbarWidth = 0;
95 }
96
97 // getters
98
99 // public
100
101 Modal.prototype.toggle = function toggle(relatedTarget) {
102 return this._isShown ? this.hide() : this.show(relatedTarget);
103 };
104
105 Modal.prototype.show = function show(relatedTarget) {
106 var _this = this;
107
108 if (this._isTransitioning) {
109 throw new Error('Modal is transitioning');
110 }
111
112 if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
113 this._isTransitioning = true;
114 }
115 var showEvent = $.Event(Event.SHOW, {
116 relatedTarget: relatedTarget
117 });
118
119 $(this._element).trigger(showEvent);
120
121 if (this._isShown || showEvent.isDefaultPrevented()) {
122 return;
123 }
124
125 this._isShown = true;
126
127 this._checkScrollbar();
128 this._setScrollbar();
129
130 $(document.body).addClass(ClassName.OPEN);
131
132 this._setEscapeEvent();
133 this._setResizeEvent();
134
135 $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) {
136 return _this.hide(event);
137 });
138
139 $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
140 $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
141 if ($(event.target).is(_this._element)) {
142 _this._ignoreBackdropClick = true;
143 }
144 });
145 });
146
147 this._showBackdrop(function () {
148 return _this._showElement(relatedTarget);
149 });
150 };
151
152 Modal.prototype.hide = function hide(event) {
153 var _this2 = this;
154
155 if (event) {
156 event.preventDefault();
157 }
158
159 if (this._isTransitioning) {
160 throw new Error('Modal is transitioning');
161 }
162
163 var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
164 if (transition) {
165 this._isTransitioning = true;
166 }
167
168 var hideEvent = $.Event(Event.HIDE);
169 $(this._element).trigger(hideEvent);
170
171 if (!this._isShown || hideEvent.isDefaultPrevented()) {
172 return;
173 }
174
175 this._isShown = false;
176
177 this._setEscapeEvent();
178 this._setResizeEvent();
179
180 $(document).off(Event.FOCUSIN);
181
182 $(this._element).removeClass(ClassName.SHOW);
183
184 $(this._element).off(Event.CLICK_DISMISS);
185 $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
186
187 if (transition) {
188 $(this._element).one(Util.TRANSITION_END, function (event) {
189 return _this2._hideModal(event);
190 }).emulateTransitionEnd(TRANSITION_DURATION);
191 } else {
192 this._hideModal();
193 }
194 };
195
196 Modal.prototype.dispose = function dispose() {
197 $.removeData(this._element, DATA_KEY);
198
199 $(window, document, this._element, this._backdrop).off(EVENT_KEY);
200
201 this._config = null;
202 this._element = null;
203 this._dialog = null;
204 this._backdrop = null;
205 this._isShown = null;
206 this._isBodyOverflowing = null;
207 this._ignoreBackdropClick = null;
208 this._originalBodyPadding = null;
209 this._scrollbarWidth = null;
210 };
211
212 // private
213
214 Modal.prototype._getConfig = function _getConfig(config) {
215 config = $.extend({}, Default, config);
216 Util.typeCheckConfig(NAME, config, DefaultType);
217 return config;
218 };
219
220 Modal.prototype._showElement = function _showElement(relatedTarget) {
221 var _this3 = this;
222
223 var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
224
225 if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
226 // don't move modals dom position
227 document.body.appendChild(this._element);
228 }
229
230 this._element.style.display = 'block';
231 this._element.removeAttribute('aria-hidden');
232 this._element.scrollTop = 0;
233
234 if (transition) {
235 Util.reflow(this._element);
236 }
237
238 $(this._element).addClass(ClassName.SHOW);
239
240 if (this._config.focus) {
241 this._enforceFocus();
242 }
243
244 var shownEvent = $.Event(Event.SHOWN, {
245 relatedTarget: relatedTarget
246 });
247
248 var transitionComplete = function transitionComplete() {
249 if (_this3._config.focus) {
250 _this3._element.focus();
251 }
252 _this3._isTransitioning = false;
253 $(_this3._element).trigger(shownEvent);
254 };
255
256 if (transition) {
257 $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
258 } else {
259 transitionComplete();
260 }
261 };
262
263 Modal.prototype._enforceFocus = function _enforceFocus() {
264 var _this4 = this;
265
266 $(document).off(Event.FOCUSIN) // guard against infinite focus loop
267 .on(Event.FOCUSIN, function (event) {
268 if (document !== event.target && _this4._element !== event.target && !$(_this4._element).has(event.target).length) {
269 _this4._element.focus();
270 }
271 });
272 };
273
274 Modal.prototype._setEscapeEvent = function _setEscapeEvent() {
275 var _this5 = this;
276
277 if (this._isShown && this._config.keyboard) {
278 $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
279 if (event.which === ESCAPE_KEYCODE) {
280 _this5.hide();
281 }
282 });
283 } else if (!this._isShown) {
284 $(this._element).off(Event.KEYDOWN_DISMISS);
285 }
286 };
287
288 Modal.prototype._setResizeEvent = function _setResizeEvent() {
289 var _this6 = this;
290
291 if (this._isShown) {
292 $(window).on(Event.RESIZE, function (event) {
293 return _this6._handleUpdate(event);
294 });
295 } else {
296 $(window).off(Event.RESIZE);
297 }
298 };
299
300 Modal.prototype._hideModal = function _hideModal() {
301 var _this7 = this;
302
303 this._element.style.display = 'none';
304 this._element.setAttribute('aria-hidden', 'true');
305 this._isTransitioning = false;
306 this._showBackdrop(function () {
307 $(document.body).removeClass(ClassName.OPEN);
308 _this7._resetAdjustments();
309 _this7._resetScrollbar();
310 $(_this7._element).trigger(Event.HIDDEN);
311 });
312 };
313
314 Modal.prototype._removeBackdrop = function _removeBackdrop() {
315 if (this._backdrop) {
316 $(this._backdrop).remove();
317 this._backdrop = null;
318 }
319 };
320
321 Modal.prototype._showBackdrop = function _showBackdrop(callback) {
322 var _this8 = this;
323
324 var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
325
326 if (this._isShown && this._config.backdrop) {
327 var doAnimate = Util.supportsTransitionEnd() && animate;
328
329 this._backdrop = document.createElement('div');
330 this._backdrop.className = ClassName.BACKDROP;
331
332 if (animate) {
333 $(this._backdrop).addClass(animate);
334 }
335
336 $(this._backdrop).appendTo(document.body);
337
338 $(this._element).on(Event.CLICK_DISMISS, function (event) {
339 if (_this8._ignoreBackdropClick) {
340 _this8._ignoreBackdropClick = false;
341 return;
342 }
343 if (event.target !== event.currentTarget) {
344 return;
345 }
346 if (_this8._config.backdrop === 'static') {
347 _this8._element.focus();
348 } else {
349 _this8.hide();
350 }
351 });
352
353 if (doAnimate) {
354 Util.reflow(this._backdrop);
355 }
356
357 $(this._backdrop).addClass(ClassName.SHOW);
358
359 if (!callback) {
360 return;
361 }
362
363 if (!doAnimate) {
364 callback();
365 return;
366 }
367
368 $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
369 } else if (!this._isShown && this._backdrop) {
370 $(this._backdrop).removeClass(ClassName.SHOW);
371
372 var callbackRemove = function callbackRemove() {
373 _this8._removeBackdrop();
374 if (callback) {
375 callback();
376 }
377 };
378
379 if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
380 $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
381 } else {
382 callbackRemove();
383 }
384 } else if (callback) {
385 callback();
386 }
387 };
388
389 // ----------------------------------------------------------------------
390 // the following methods are used to handle overflowing modals
391 // todo (fat): these should probably be refactored out of modal.js
392 // ----------------------------------------------------------------------
393
394 Modal.prototype._handleUpdate = function _handleUpdate() {
395 this._adjustDialog();
396 };
397
398 Modal.prototype._adjustDialog = function _adjustDialog() {
399 var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
400
401 if (!this._isBodyOverflowing && isModalOverflowing) {
402 this._element.style.paddingLeft = this._scrollbarWidth + 'px';
403 }
404
405 if (this._isBodyOverflowing && !isModalOverflowing) {
406 this._element.style.paddingRight = this._scrollbarWidth + 'px';
407 }
408 };
409
410 Modal.prototype._resetAdjustments = function _resetAdjustments() {
411 this._element.style.paddingLeft = '';
412 this._element.style.paddingRight = '';
413 };
414
415 Modal.prototype._checkScrollbar = function _checkScrollbar() {
416 this._isBodyOverflowing = document.body.clientWidth < window.innerWidth;
417 this._scrollbarWidth = this._getScrollbarWidth();
418 };
419
420 Modal.prototype._setScrollbar = function _setScrollbar() {
421 var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10);
422
423 this._originalBodyPadding = document.body.style.paddingRight || '';
424
425 if (this._isBodyOverflowing) {
426 document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
427 }
428 };
429
430 Modal.prototype._resetScrollbar = function _resetScrollbar() {
431 document.body.style.paddingRight = this._originalBodyPadding;
432 };
433
434 Modal.prototype._getScrollbarWidth = function _getScrollbarWidth() {
435 // thx d.walsh
436 var scrollDiv = document.createElement('div');
437 scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
438 document.body.appendChild(scrollDiv);
439 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
440 document.body.removeChild(scrollDiv);
441 return scrollbarWidth;
442 };
443
444 // static
445
446 Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
447 return this.each(function () {
448 var data = $(this).data(DATA_KEY);
449 var _config = $.extend({}, Modal.Default, $(this).data(), (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' && config);
450
451 if (!data) {
452 data = new Modal(this, _config);
453 $(this).data(DATA_KEY, data);
454 }
455
456 if (typeof config === 'string') {
457 if (data[config] === undefined) {
458 throw new Error('No method named "' + config + '"');
459 }
460 data[config](relatedTarget);
461 } else if (_config.show) {
462 data.show(relatedTarget);
463 }
464 });
465 };
466
467 _createClass(Modal, null, [{
468 key: 'VERSION',
469 get: function get() {
470 return VERSION;
471 }
472 }, {
473 key: 'Default',
474 get: function get() {
475 return Default;
476 }
477 }]);
478
479 return Modal;
480 }();
481
482 /**
483 * ------------------------------------------------------------------------
484 * Data Api implementation
485 * ------------------------------------------------------------------------
486 */
487
488 $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
489 var _this9 = this;
490
491 var target = void 0;
492 var selector = Util.getSelectorFromElement(this);
493
494 if (selector) {
495 target = $(selector)[0];
496 }
497
498 var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
499
500 if (this.tagName === 'A' || this.tagName === 'AREA') {
501 event.preventDefault();
502 }
503
504 var $target = $(target).one(Event.SHOW, function (showEvent) {
505 if (showEvent.isDefaultPrevented()) {
506 // only register focus restorer if modal will actually get shown
507 return;
508 }
509
510 $target.one(Event.HIDDEN, function () {
511 if ($(_this9).is(':visible')) {
512 _this9.focus();
513 }
514 });
515 });
516
517 Modal._jQueryInterface.call($(target), config, this);
518 });
519
520 /**
521 * ------------------------------------------------------------------------
522 * jQuery
523 * ------------------------------------------------------------------------
524 */
525
526 $.fn[NAME] = Modal._jQueryInterface;
527 $.fn[NAME].Constructor = Modal;
528 $.fn[NAME].noConflict = function () {
529 $.fn[NAME] = JQUERY_NO_CONFLICT;
530 return Modal._jQueryInterface;
531 };
532
533 return Modal;
534 }(jQuery);
535 //# sourceMappingURL=modal.js.map