modal.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
  2. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  3. 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); } }
  4. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  5. /**
  6. * --------------------------------------------------------------------------
  7. * Bootstrap (v4.1.1): modal.js
  8. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9. * --------------------------------------------------------------------------
  10. */
  11. var Modal = function ($) {
  12. /**
  13. * ------------------------------------------------------------------------
  14. * Constants
  15. * ------------------------------------------------------------------------
  16. */
  17. var NAME = 'modal';
  18. var VERSION = '4.1.1';
  19. var DATA_KEY = 'bs.modal';
  20. var EVENT_KEY = "." + DATA_KEY;
  21. var DATA_API_KEY = '.data-api';
  22. var JQUERY_NO_CONFLICT = $.fn[NAME];
  23. var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
  24. var Default = {
  25. backdrop: true,
  26. keyboard: true,
  27. focus: true,
  28. show: true
  29. };
  30. var DefaultType = {
  31. backdrop: '(boolean|string)',
  32. keyboard: 'boolean',
  33. focus: 'boolean',
  34. show: 'boolean'
  35. };
  36. var Event = {
  37. HIDE: "hide" + EVENT_KEY,
  38. HIDDEN: "hidden" + EVENT_KEY,
  39. SHOW: "show" + EVENT_KEY,
  40. SHOWN: "shown" + EVENT_KEY,
  41. FOCUSIN: "focusin" + EVENT_KEY,
  42. RESIZE: "resize" + EVENT_KEY,
  43. CLICK_DISMISS: "click.dismiss" + EVENT_KEY,
  44. KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY,
  45. MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY,
  46. MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY,
  47. CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
  48. };
  49. var ClassName = {
  50. SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
  51. BACKDROP: 'modal-backdrop',
  52. OPEN: 'modal-open',
  53. FADE: 'fade',
  54. SHOW: 'show'
  55. };
  56. var Selector = {
  57. DIALOG: '.modal-dialog',
  58. DATA_TOGGLE: '[data-toggle="modal"]',
  59. DATA_DISMISS: '[data-dismiss="modal"]',
  60. FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
  61. STICKY_CONTENT: '.sticky-top',
  62. NAVBAR_TOGGLER: '.navbar-toggler'
  63. /**
  64. * ------------------------------------------------------------------------
  65. * Class Definition
  66. * ------------------------------------------------------------------------
  67. */
  68. };
  69. var Modal =
  70. /*#__PURE__*/
  71. function () {
  72. function Modal(element, config) {
  73. this._config = this._getConfig(config);
  74. this._element = element;
  75. this._dialog = $(element).find(Selector.DIALOG)[0];
  76. this._backdrop = null;
  77. this._isShown = false;
  78. this._isBodyOverflowing = false;
  79. this._ignoreBackdropClick = false;
  80. this._scrollbarWidth = 0;
  81. } // Getters
  82. var _proto = Modal.prototype;
  83. // Public
  84. _proto.toggle = function toggle(relatedTarget) {
  85. return this._isShown ? this.hide() : this.show(relatedTarget);
  86. };
  87. _proto.show = function show(relatedTarget) {
  88. var _this = this;
  89. if (this._isTransitioning || this._isShown) {
  90. return;
  91. }
  92. if ($(this._element).hasClass(ClassName.FADE)) {
  93. this._isTransitioning = true;
  94. }
  95. var showEvent = $.Event(Event.SHOW, {
  96. relatedTarget: relatedTarget
  97. });
  98. $(this._element).trigger(showEvent);
  99. if (this._isShown || showEvent.isDefaultPrevented()) {
  100. return;
  101. }
  102. this._isShown = true;
  103. this._checkScrollbar();
  104. this._setScrollbar();
  105. this._adjustDialog();
  106. $(document.body).addClass(ClassName.OPEN);
  107. this._setEscapeEvent();
  108. this._setResizeEvent();
  109. $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) {
  110. return _this.hide(event);
  111. });
  112. $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
  113. $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
  114. if ($(event.target).is(_this._element)) {
  115. _this._ignoreBackdropClick = true;
  116. }
  117. });
  118. });
  119. this._showBackdrop(function () {
  120. return _this._showElement(relatedTarget);
  121. });
  122. };
  123. _proto.hide = function hide(event) {
  124. var _this2 = this;
  125. if (event) {
  126. event.preventDefault();
  127. }
  128. if (this._isTransitioning || !this._isShown) {
  129. return;
  130. }
  131. var hideEvent = $.Event(Event.HIDE);
  132. $(this._element).trigger(hideEvent);
  133. if (!this._isShown || hideEvent.isDefaultPrevented()) {
  134. return;
  135. }
  136. this._isShown = false;
  137. var transition = $(this._element).hasClass(ClassName.FADE);
  138. if (transition) {
  139. this._isTransitioning = true;
  140. }
  141. this._setEscapeEvent();
  142. this._setResizeEvent();
  143. $(document).off(Event.FOCUSIN);
  144. $(this._element).removeClass(ClassName.SHOW);
  145. $(this._element).off(Event.CLICK_DISMISS);
  146. $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
  147. if (transition) {
  148. var transitionDuration = Util.getTransitionDurationFromElement(this._element);
  149. $(this._element).one(Util.TRANSITION_END, function (event) {
  150. return _this2._hideModal(event);
  151. }).emulateTransitionEnd(transitionDuration);
  152. } else {
  153. this._hideModal();
  154. }
  155. };
  156. _proto.dispose = function dispose() {
  157. $.removeData(this._element, DATA_KEY);
  158. $(window, document, this._element, this._backdrop).off(EVENT_KEY);
  159. this._config = null;
  160. this._element = null;
  161. this._dialog = null;
  162. this._backdrop = null;
  163. this._isShown = null;
  164. this._isBodyOverflowing = null;
  165. this._ignoreBackdropClick = null;
  166. this._scrollbarWidth = null;
  167. };
  168. _proto.handleUpdate = function handleUpdate() {
  169. this._adjustDialog();
  170. }; // Private
  171. _proto._getConfig = function _getConfig(config) {
  172. config = _objectSpread({}, Default, config);
  173. Util.typeCheckConfig(NAME, config, DefaultType);
  174. return config;
  175. };
  176. _proto._showElement = function _showElement(relatedTarget) {
  177. var _this3 = this;
  178. var transition = $(this._element).hasClass(ClassName.FADE);
  179. if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
  180. // Don't move modal's DOM position
  181. document.body.appendChild(this._element);
  182. }
  183. this._element.style.display = 'block';
  184. this._element.removeAttribute('aria-hidden');
  185. this._element.scrollTop = 0;
  186. if (transition) {
  187. Util.reflow(this._element);
  188. }
  189. $(this._element).addClass(ClassName.SHOW);
  190. if (this._config.focus) {
  191. this._enforceFocus();
  192. }
  193. var shownEvent = $.Event(Event.SHOWN, {
  194. relatedTarget: relatedTarget
  195. });
  196. var transitionComplete = function transitionComplete() {
  197. if (_this3._config.focus) {
  198. _this3._element.focus();
  199. }
  200. _this3._isTransitioning = false;
  201. $(_this3._element).trigger(shownEvent);
  202. };
  203. if (transition) {
  204. var transitionDuration = Util.getTransitionDurationFromElement(this._element);
  205. $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
  206. } else {
  207. transitionComplete();
  208. }
  209. };
  210. _proto._enforceFocus = function _enforceFocus() {
  211. var _this4 = this;
  212. $(document).off(Event.FOCUSIN) // Guard against infinite focus loop
  213. .on(Event.FOCUSIN, function (event) {
  214. if (document !== event.target && _this4._element !== event.target && $(_this4._element).has(event.target).length === 0) {
  215. _this4._element.focus();
  216. }
  217. });
  218. };
  219. _proto._setEscapeEvent = function _setEscapeEvent() {
  220. var _this5 = this;
  221. if (this._isShown && this._config.keyboard) {
  222. $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
  223. if (event.which === ESCAPE_KEYCODE) {
  224. event.preventDefault();
  225. _this5.hide();
  226. }
  227. });
  228. } else if (!this._isShown) {
  229. $(this._element).off(Event.KEYDOWN_DISMISS);
  230. }
  231. };
  232. _proto._setResizeEvent = function _setResizeEvent() {
  233. var _this6 = this;
  234. if (this._isShown) {
  235. $(window).on(Event.RESIZE, function (event) {
  236. return _this6.handleUpdate(event);
  237. });
  238. } else {
  239. $(window).off(Event.RESIZE);
  240. }
  241. };
  242. _proto._hideModal = function _hideModal() {
  243. var _this7 = this;
  244. this._element.style.display = 'none';
  245. this._element.setAttribute('aria-hidden', true);
  246. this._isTransitioning = false;
  247. this._showBackdrop(function () {
  248. $(document.body).removeClass(ClassName.OPEN);
  249. _this7._resetAdjustments();
  250. _this7._resetScrollbar();
  251. $(_this7._element).trigger(Event.HIDDEN);
  252. });
  253. };
  254. _proto._removeBackdrop = function _removeBackdrop() {
  255. if (this._backdrop) {
  256. $(this._backdrop).remove();
  257. this._backdrop = null;
  258. }
  259. };
  260. _proto._showBackdrop = function _showBackdrop(callback) {
  261. var _this8 = this;
  262. var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
  263. if (this._isShown && this._config.backdrop) {
  264. this._backdrop = document.createElement('div');
  265. this._backdrop.className = ClassName.BACKDROP;
  266. if (animate) {
  267. $(this._backdrop).addClass(animate);
  268. }
  269. $(this._backdrop).appendTo(document.body);
  270. $(this._element).on(Event.CLICK_DISMISS, function (event) {
  271. if (_this8._ignoreBackdropClick) {
  272. _this8._ignoreBackdropClick = false;
  273. return;
  274. }
  275. if (event.target !== event.currentTarget) {
  276. return;
  277. }
  278. if (_this8._config.backdrop === 'static') {
  279. _this8._element.focus();
  280. } else {
  281. _this8.hide();
  282. }
  283. });
  284. if (animate) {
  285. Util.reflow(this._backdrop);
  286. }
  287. $(this._backdrop).addClass(ClassName.SHOW);
  288. if (!callback) {
  289. return;
  290. }
  291. if (!animate) {
  292. callback();
  293. return;
  294. }
  295. var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
  296. $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
  297. } else if (!this._isShown && this._backdrop) {
  298. $(this._backdrop).removeClass(ClassName.SHOW);
  299. var callbackRemove = function callbackRemove() {
  300. _this8._removeBackdrop();
  301. if (callback) {
  302. callback();
  303. }
  304. };
  305. if ($(this._element).hasClass(ClassName.FADE)) {
  306. var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
  307. $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
  308. } else {
  309. callbackRemove();
  310. }
  311. } else if (callback) {
  312. callback();
  313. }
  314. }; // ----------------------------------------------------------------------
  315. // the following methods are used to handle overflowing modals
  316. // todo (fat): these should probably be refactored out of modal.js
  317. // ----------------------------------------------------------------------
  318. _proto._adjustDialog = function _adjustDialog() {
  319. var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
  320. if (!this._isBodyOverflowing && isModalOverflowing) {
  321. this._element.style.paddingLeft = this._scrollbarWidth + "px";
  322. }
  323. if (this._isBodyOverflowing && !isModalOverflowing) {
  324. this._element.style.paddingRight = this._scrollbarWidth + "px";
  325. }
  326. };
  327. _proto._resetAdjustments = function _resetAdjustments() {
  328. this._element.style.paddingLeft = '';
  329. this._element.style.paddingRight = '';
  330. };
  331. _proto._checkScrollbar = function _checkScrollbar() {
  332. var rect = document.body.getBoundingClientRect();
  333. this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;
  334. this._scrollbarWidth = this._getScrollbarWidth();
  335. };
  336. _proto._setScrollbar = function _setScrollbar() {
  337. var _this9 = this;
  338. if (this._isBodyOverflowing) {
  339. // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
  340. // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
  341. // Adjust fixed content padding
  342. $(Selector.FIXED_CONTENT).each(function (index, element) {
  343. var actualPadding = $(element)[0].style.paddingRight;
  344. var calculatedPadding = $(element).css('padding-right');
  345. $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px");
  346. }); // Adjust sticky content margin
  347. $(Selector.STICKY_CONTENT).each(function (index, element) {
  348. var actualMargin = $(element)[0].style.marginRight;
  349. var calculatedMargin = $(element).css('margin-right');
  350. $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px");
  351. }); // Adjust navbar-toggler margin
  352. $(Selector.NAVBAR_TOGGLER).each(function (index, element) {
  353. var actualMargin = $(element)[0].style.marginRight;
  354. var calculatedMargin = $(element).css('margin-right');
  355. $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this9._scrollbarWidth + "px");
  356. }); // Adjust body padding
  357. var actualPadding = document.body.style.paddingRight;
  358. var calculatedPadding = $(document.body).css('padding-right');
  359. $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
  360. }
  361. };
  362. _proto._resetScrollbar = function _resetScrollbar() {
  363. // Restore fixed content padding
  364. $(Selector.FIXED_CONTENT).each(function (index, element) {
  365. var padding = $(element).data('padding-right');
  366. if (typeof padding !== 'undefined') {
  367. $(element).css('padding-right', padding).removeData('padding-right');
  368. }
  369. }); // Restore sticky content and navbar-toggler margin
  370. $(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) {
  371. var margin = $(element).data('margin-right');
  372. if (typeof margin !== 'undefined') {
  373. $(element).css('margin-right', margin).removeData('margin-right');
  374. }
  375. }); // Restore body padding
  376. var padding = $(document.body).data('padding-right');
  377. if (typeof padding !== 'undefined') {
  378. $(document.body).css('padding-right', padding).removeData('padding-right');
  379. }
  380. };
  381. _proto._getScrollbarWidth = function _getScrollbarWidth() {
  382. // thx d.walsh
  383. var scrollDiv = document.createElement('div');
  384. scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
  385. document.body.appendChild(scrollDiv);
  386. var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
  387. document.body.removeChild(scrollDiv);
  388. return scrollbarWidth;
  389. }; // Static
  390. Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
  391. return this.each(function () {
  392. var data = $(this).data(DATA_KEY);
  393. var _config = _objectSpread({}, Default, $(this).data(), typeof config === 'object' && config ? config : {});
  394. if (!data) {
  395. data = new Modal(this, _config);
  396. $(this).data(DATA_KEY, data);
  397. }
  398. if (typeof config === 'string') {
  399. if (typeof data[config] === 'undefined') {
  400. throw new TypeError("No method named \"" + config + "\"");
  401. }
  402. data[config](relatedTarget);
  403. } else if (_config.show) {
  404. data.show(relatedTarget);
  405. }
  406. });
  407. };
  408. _createClass(Modal, null, [{
  409. key: "VERSION",
  410. get: function get() {
  411. return VERSION;
  412. }
  413. }, {
  414. key: "Default",
  415. get: function get() {
  416. return Default;
  417. }
  418. }]);
  419. return Modal;
  420. }();
  421. /**
  422. * ------------------------------------------------------------------------
  423. * Data Api implementation
  424. * ------------------------------------------------------------------------
  425. */
  426. $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
  427. var _this10 = this;
  428. var target;
  429. var selector = Util.getSelectorFromElement(this);
  430. if (selector) {
  431. target = $(selector)[0];
  432. }
  433. var config = $(target).data(DATA_KEY) ? 'toggle' : _objectSpread({}, $(target).data(), $(this).data());
  434. if (this.tagName === 'A' || this.tagName === 'AREA') {
  435. event.preventDefault();
  436. }
  437. var $target = $(target).one(Event.SHOW, function (showEvent) {
  438. if (showEvent.isDefaultPrevented()) {
  439. // Only register focus restorer if modal will actually get shown
  440. return;
  441. }
  442. $target.one(Event.HIDDEN, function () {
  443. if ($(_this10).is(':visible')) {
  444. _this10.focus();
  445. }
  446. });
  447. });
  448. Modal._jQueryInterface.call($(target), config, this);
  449. });
  450. /**
  451. * ------------------------------------------------------------------------
  452. * jQuery
  453. * ------------------------------------------------------------------------
  454. */
  455. $.fn[NAME] = Modal._jQueryInterface;
  456. $.fn[NAME].Constructor = Modal;
  457. $.fn[NAME].noConflict = function () {
  458. $.fn[NAME] = JQUERY_NO_CONFLICT;
  459. return Modal._jQueryInterface;
  460. };
  461. return Modal;
  462. }($);
  463. //# sourceMappingURL=modal.js.map