modal.js 20 KB

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