ngx-bootstrap-modal.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. import { Injectable, Component, ElementRef, Renderer2, HostListener, Directive, ViewContainerRef, Input, Output, EventEmitter, RendererFactory2, NgModule } from '@angular/core';
  2. import { isBs3, Utils, document as document$1, window as window$1 } from 'ngx-bootstrap/utils';
  3. import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
  4. import { PositioningService } from 'ngx-bootstrap/positioning';
  5. /**
  6. * @fileoverview added by tsickle
  7. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8. */
  9. var BsModalRef = /** @class */ (function () {
  10. function BsModalRef() {
  11. /**
  12. * Hides the modal
  13. */
  14. this.hide = Function;
  15. /**
  16. * Sets new class to modal window
  17. */
  18. this.setClass = Function;
  19. }
  20. BsModalRef.decorators = [
  21. { type: Injectable }
  22. ];
  23. return BsModalRef;
  24. }());
  25. /**
  26. * @fileoverview added by tsickle
  27. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  28. */
  29. var ModalBackdropOptions = /** @class */ (function () {
  30. function ModalBackdropOptions(options) {
  31. this.animate = true;
  32. Object.assign(this, options);
  33. }
  34. return ModalBackdropOptions;
  35. }());
  36. /**
  37. * @fileoverview added by tsickle
  38. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  39. */
  40. var ModalOptions = /** @class */ (function () {
  41. function ModalOptions() {
  42. }
  43. ModalOptions.decorators = [
  44. { type: Injectable }
  45. ];
  46. return ModalOptions;
  47. }());
  48. /** @type {?} */
  49. var modalConfigDefaults = {
  50. backdrop: true,
  51. keyboard: true,
  52. focus: true,
  53. show: false,
  54. ignoreBackdropClick: false,
  55. class: '',
  56. animated: true,
  57. initialState: {}
  58. };
  59. /** @type {?} */
  60. var CLASS_NAME = {
  61. SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
  62. BACKDROP: 'modal-backdrop',
  63. OPEN: 'modal-open',
  64. FADE: 'fade',
  65. IN: 'in',
  66. // bs3
  67. SHOW: 'show' // bs4
  68. };
  69. /** @type {?} */
  70. var TRANSITION_DURATIONS = {
  71. MODAL: 300,
  72. BACKDROP: 150
  73. };
  74. /** @type {?} */
  75. var DISMISS_REASONS = {
  76. BACKRDOP: 'backdrop-click',
  77. ESC: 'esc'
  78. };
  79. /**
  80. * @fileoverview added by tsickle
  81. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  82. */
  83. var ModalContainerComponent = /** @class */ (function () {
  84. function ModalContainerComponent(options, _element, _renderer) {
  85. this._element = _element;
  86. this._renderer = _renderer;
  87. this.isShown = false;
  88. this.isModalHiding = false;
  89. this.config = Object.assign({}, options);
  90. }
  91. /**
  92. * @return {?}
  93. */
  94. ModalContainerComponent.prototype.ngOnInit = /**
  95. * @return {?}
  96. */
  97. function () {
  98. var _this = this;
  99. if (this.isAnimated) {
  100. this._renderer.addClass(this._element.nativeElement, CLASS_NAME.FADE);
  101. }
  102. this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
  103. setTimeout((/**
  104. * @return {?}
  105. */
  106. function () {
  107. _this.isShown = true;
  108. _this._renderer.addClass(_this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
  109. }), this.isAnimated ? TRANSITION_DURATIONS.BACKDROP : 0);
  110. if (document && document.body) {
  111. if (this.bsModalService.getModalsCount() === 1) {
  112. this.bsModalService.checkScrollbar();
  113. this.bsModalService.setScrollbar();
  114. }
  115. this._renderer.addClass(document.body, CLASS_NAME.OPEN);
  116. }
  117. if (this._element.nativeElement) {
  118. this._element.nativeElement.focus();
  119. }
  120. };
  121. /**
  122. * @param {?} event
  123. * @return {?}
  124. */
  125. ModalContainerComponent.prototype.onClick = /**
  126. * @param {?} event
  127. * @return {?}
  128. */
  129. function (event) {
  130. if (this.config.ignoreBackdropClick ||
  131. this.config.backdrop === 'static' ||
  132. event.target !== this._element.nativeElement) {
  133. return;
  134. }
  135. this.bsModalService.setDismissReason(DISMISS_REASONS.BACKRDOP);
  136. this.hide();
  137. };
  138. /**
  139. * @param {?} event
  140. * @return {?}
  141. */
  142. ModalContainerComponent.prototype.onEsc = /**
  143. * @param {?} event
  144. * @return {?}
  145. */
  146. function (event) {
  147. if (!this.isShown) {
  148. return;
  149. }
  150. // tslint:disable-next-line:deprecation
  151. if (event.keyCode === 27 || event.key === 'Escape') {
  152. event.preventDefault();
  153. }
  154. if (this.config.keyboard &&
  155. this.level === this.bsModalService.getModalsCount()) {
  156. this.bsModalService.setDismissReason(DISMISS_REASONS.ESC);
  157. this.hide();
  158. }
  159. };
  160. /**
  161. * @return {?}
  162. */
  163. ModalContainerComponent.prototype.ngOnDestroy = /**
  164. * @return {?}
  165. */
  166. function () {
  167. if (this.isShown) {
  168. this.hide();
  169. }
  170. };
  171. /**
  172. * @return {?}
  173. */
  174. ModalContainerComponent.prototype.hide = /**
  175. * @return {?}
  176. */
  177. function () {
  178. var _this = this;
  179. if (this.isModalHiding || !this.isShown) {
  180. return;
  181. }
  182. this.isModalHiding = true;
  183. this._renderer.removeClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
  184. setTimeout((/**
  185. * @return {?}
  186. */
  187. function () {
  188. _this.isShown = false;
  189. if (document &&
  190. document.body &&
  191. _this.bsModalService.getModalsCount() === 1) {
  192. _this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
  193. }
  194. _this.bsModalService.hide(_this.level);
  195. _this.isModalHiding = false;
  196. }), this.isAnimated ? TRANSITION_DURATIONS.MODAL : 0);
  197. };
  198. ModalContainerComponent.decorators = [
  199. { type: Component, args: [{
  200. selector: 'modal-container',
  201. template: "\n <div [class]=\"'modal-dialog' + (config.class ? ' ' + config.class : '')\" role=\"document\">\n <div class=\"modal-content\">\n <ng-content></ng-content>\n </div>\n </div>\n ",
  202. host: {
  203. class: 'modal',
  204. role: 'dialog',
  205. tabindex: '-1',
  206. '[attr.aria-modal]': 'true'
  207. }
  208. }] }
  209. ];
  210. /** @nocollapse */
  211. ModalContainerComponent.ctorParameters = function () { return [
  212. { type: ModalOptions },
  213. { type: ElementRef },
  214. { type: Renderer2 }
  215. ]; };
  216. ModalContainerComponent.propDecorators = {
  217. onClick: [{ type: HostListener, args: ['click', ['$event'],] }],
  218. onEsc: [{ type: HostListener, args: ['window:keydown.esc', ['$event'],] }]
  219. };
  220. return ModalContainerComponent;
  221. }());
  222. /**
  223. * @fileoverview added by tsickle
  224. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  225. */
  226. /**
  227. * This component will be added as background layout for modals if enabled
  228. */
  229. var ModalBackdropComponent = /** @class */ (function () {
  230. function ModalBackdropComponent(element, renderer) {
  231. this._isShown = false;
  232. this.element = element;
  233. this.renderer = renderer;
  234. }
  235. Object.defineProperty(ModalBackdropComponent.prototype, "isAnimated", {
  236. get: /**
  237. * @return {?}
  238. */
  239. function () {
  240. return this._isAnimated;
  241. },
  242. set: /**
  243. * @param {?} value
  244. * @return {?}
  245. */
  246. function (value) {
  247. this._isAnimated = value;
  248. // this.renderer.setElementClass(this.element.nativeElement, `${ClassName.FADE}`, value);
  249. },
  250. enumerable: true,
  251. configurable: true
  252. });
  253. Object.defineProperty(ModalBackdropComponent.prototype, "isShown", {
  254. get: /**
  255. * @return {?}
  256. */
  257. function () {
  258. return this._isShown;
  259. },
  260. set: /**
  261. * @param {?} value
  262. * @return {?}
  263. */
  264. function (value) {
  265. this._isShown = value;
  266. if (value) {
  267. this.renderer.addClass(this.element.nativeElement, "" + CLASS_NAME.IN);
  268. }
  269. else {
  270. this.renderer.removeClass(this.element.nativeElement, "" + CLASS_NAME.IN);
  271. }
  272. if (!isBs3()) {
  273. if (value) {
  274. this.renderer.addClass(this.element.nativeElement, "" + CLASS_NAME.SHOW);
  275. }
  276. else {
  277. this.renderer.removeClass(this.element.nativeElement, "" + CLASS_NAME.SHOW);
  278. }
  279. }
  280. },
  281. enumerable: true,
  282. configurable: true
  283. });
  284. /**
  285. * @return {?}
  286. */
  287. ModalBackdropComponent.prototype.ngOnInit = /**
  288. * @return {?}
  289. */
  290. function () {
  291. if (this.isAnimated) {
  292. this.renderer.addClass(this.element.nativeElement, "" + CLASS_NAME.FADE);
  293. Utils.reflow(this.element.nativeElement);
  294. }
  295. this.isShown = true;
  296. };
  297. ModalBackdropComponent.decorators = [
  298. { type: Component, args: [{
  299. selector: 'bs-modal-backdrop',
  300. template: ' ',
  301. host: { class: CLASS_NAME.BACKDROP }
  302. }] }
  303. ];
  304. /** @nocollapse */
  305. ModalBackdropComponent.ctorParameters = function () { return [
  306. { type: ElementRef },
  307. { type: Renderer2 }
  308. ]; };
  309. return ModalBackdropComponent;
  310. }());
  311. /**
  312. * @fileoverview added by tsickle
  313. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  314. */
  315. /** @type {?} */
  316. var TRANSITION_DURATION = 300;
  317. /** @type {?} */
  318. var BACKDROP_TRANSITION_DURATION = 150;
  319. /**
  320. * Mark any code with directive to show it's content in modal
  321. */
  322. var ModalDirective = /** @class */ (function () {
  323. function ModalDirective(_element, _viewContainerRef, _renderer, clf) {
  324. this._element = _element;
  325. this._renderer = _renderer;
  326. /**
  327. * This event fires immediately when the `show` instance method is called.
  328. */
  329. this.onShow = new EventEmitter();
  330. /**
  331. * This event is fired when the modal has been made visible to the user
  332. * (will wait for CSS transitions to complete)
  333. */
  334. this.onShown = new EventEmitter();
  335. /**
  336. * This event is fired immediately when
  337. * the hide instance method has been called.
  338. */
  339. this.onHide = new EventEmitter();
  340. /**
  341. * This event is fired when the modal has finished being
  342. * hidden from the user (will wait for CSS transitions to complete).
  343. */
  344. this.onHidden = new EventEmitter();
  345. this._isShown = false;
  346. this.isBodyOverflowing = false;
  347. this.originalBodyPadding = 0;
  348. this.scrollbarWidth = 0;
  349. this.timerHideModal = 0;
  350. this.timerRmBackDrop = 0;
  351. this.isNested = false;
  352. this._backdrop = clf.createLoader(_element, _viewContainerRef, _renderer);
  353. }
  354. Object.defineProperty(ModalDirective.prototype, "config", {
  355. get: /**
  356. * @return {?}
  357. */
  358. function () {
  359. return this._config;
  360. },
  361. /** allows to set modal configuration via element property */
  362. set: /**
  363. * allows to set modal configuration via element property
  364. * @param {?} conf
  365. * @return {?}
  366. */
  367. function (conf) {
  368. this._config = this.getConfig(conf);
  369. },
  370. enumerable: true,
  371. configurable: true
  372. });
  373. Object.defineProperty(ModalDirective.prototype, "isShown", {
  374. get: /**
  375. * @return {?}
  376. */
  377. function () {
  378. return this._isShown;
  379. },
  380. enumerable: true,
  381. configurable: true
  382. });
  383. /**
  384. * @param {?} event
  385. * @return {?}
  386. */
  387. ModalDirective.prototype.onClick = /**
  388. * @param {?} event
  389. * @return {?}
  390. */
  391. function (event) {
  392. if (this.config.ignoreBackdropClick ||
  393. this.config.backdrop === 'static' ||
  394. event.target !== this._element.nativeElement) {
  395. return;
  396. }
  397. this.dismissReason = DISMISS_REASONS.BACKRDOP;
  398. this.hide(event);
  399. };
  400. // todo: consider preventing default and stopping propagation
  401. // todo: consider preventing default and stopping propagation
  402. /**
  403. * @param {?} event
  404. * @return {?}
  405. */
  406. ModalDirective.prototype.onEsc =
  407. // todo: consider preventing default and stopping propagation
  408. /**
  409. * @param {?} event
  410. * @return {?}
  411. */
  412. function (event) {
  413. if (!this._isShown) {
  414. return;
  415. }
  416. // tslint:disable-next-line:deprecation
  417. if (event.keyCode === 27 || event.key === 'Escape') {
  418. event.preventDefault();
  419. }
  420. if (this.config.keyboard) {
  421. this.dismissReason = DISMISS_REASONS.ESC;
  422. this.hide();
  423. }
  424. };
  425. /**
  426. * @return {?}
  427. */
  428. ModalDirective.prototype.ngOnDestroy = /**
  429. * @return {?}
  430. */
  431. function () {
  432. this.config = void 0;
  433. if (this._isShown) {
  434. this._isShown = false;
  435. this.hideModal();
  436. this._backdrop.dispose();
  437. }
  438. };
  439. /**
  440. * @return {?}
  441. */
  442. ModalDirective.prototype.ngOnInit = /**
  443. * @return {?}
  444. */
  445. function () {
  446. var _this = this;
  447. this._config = this._config || this.getConfig();
  448. setTimeout((/**
  449. * @return {?}
  450. */
  451. function () {
  452. if (_this._config.show) {
  453. _this.show();
  454. }
  455. }), 0);
  456. };
  457. /* Public methods */
  458. /** Allows to manually toggle modal visibility */
  459. /* Public methods */
  460. /**
  461. * Allows to manually toggle modal visibility
  462. * @return {?}
  463. */
  464. ModalDirective.prototype.toggle = /* Public methods */
  465. /**
  466. * Allows to manually toggle modal visibility
  467. * @return {?}
  468. */
  469. function () {
  470. return this._isShown ? this.hide() : this.show();
  471. };
  472. /** Allows to manually open modal */
  473. /**
  474. * Allows to manually open modal
  475. * @return {?}
  476. */
  477. ModalDirective.prototype.show = /**
  478. * Allows to manually open modal
  479. * @return {?}
  480. */
  481. function () {
  482. var _this = this;
  483. this.dismissReason = null;
  484. this.onShow.emit(this);
  485. if (this._isShown) {
  486. return;
  487. }
  488. clearTimeout(this.timerHideModal);
  489. clearTimeout(this.timerRmBackDrop);
  490. this._isShown = true;
  491. this.checkScrollbar();
  492. this.setScrollbar();
  493. if (document$1 && document$1.body) {
  494. if (document$1.body.classList.contains(CLASS_NAME.OPEN)) {
  495. this.isNested = true;
  496. }
  497. else {
  498. this._renderer.addClass(document$1.body, CLASS_NAME.OPEN);
  499. }
  500. }
  501. this.showBackdrop((/**
  502. * @return {?}
  503. */
  504. function () {
  505. _this.showElement();
  506. }));
  507. };
  508. /** Allows to manually close modal */
  509. /**
  510. * Allows to manually close modal
  511. * @param {?=} event
  512. * @return {?}
  513. */
  514. ModalDirective.prototype.hide = /**
  515. * Allows to manually close modal
  516. * @param {?=} event
  517. * @return {?}
  518. */
  519. function (event) {
  520. var _this = this;
  521. if (event) {
  522. event.preventDefault();
  523. }
  524. this.onHide.emit(this);
  525. // todo: add an option to prevent hiding
  526. if (!this._isShown) {
  527. return;
  528. }
  529. window$1.clearTimeout(this.timerHideModal);
  530. window$1.clearTimeout(this.timerRmBackDrop);
  531. this._isShown = false;
  532. this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.IN);
  533. if (!isBs3()) {
  534. this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.SHOW);
  535. }
  536. // this._addClassIn = false;
  537. if (this._config.animated) {
  538. this.timerHideModal = window$1.setTimeout((/**
  539. * @return {?}
  540. */
  541. function () { return _this.hideModal(); }), TRANSITION_DURATION);
  542. }
  543. else {
  544. this.hideModal();
  545. }
  546. };
  547. /** Private methods @internal */
  548. /**
  549. * Private methods \@internal
  550. * @protected
  551. * @param {?=} config
  552. * @return {?}
  553. */
  554. ModalDirective.prototype.getConfig = /**
  555. * Private methods \@internal
  556. * @protected
  557. * @param {?=} config
  558. * @return {?}
  559. */
  560. function (config) {
  561. return Object.assign({}, modalConfigDefaults, config);
  562. };
  563. /**
  564. * Show dialog
  565. * @internal
  566. */
  567. /**
  568. * Show dialog
  569. * \@internal
  570. * @protected
  571. * @return {?}
  572. */
  573. ModalDirective.prototype.showElement = /**
  574. * Show dialog
  575. * \@internal
  576. * @protected
  577. * @return {?}
  578. */
  579. function () {
  580. var _this = this;
  581. // todo: replace this with component loader usage
  582. if (!this._element.nativeElement.parentNode ||
  583. this._element.nativeElement.parentNode.nodeType !== Node.ELEMENT_NODE) {
  584. // don't move modals dom position
  585. if (document$1 && document$1.body) {
  586. document$1.body.appendChild(this._element.nativeElement);
  587. }
  588. }
  589. this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'false');
  590. this._renderer.setAttribute(this._element.nativeElement, 'aria-modal', 'true');
  591. this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
  592. this._renderer.setProperty(this._element.nativeElement, 'scrollTop', 0);
  593. if (this._config.animated) {
  594. Utils.reflow(this._element.nativeElement);
  595. }
  596. // this._addClassIn = true;
  597. this._renderer.addClass(this._element.nativeElement, CLASS_NAME.IN);
  598. if (!isBs3()) {
  599. this._renderer.addClass(this._element.nativeElement, CLASS_NAME.SHOW);
  600. }
  601. /** @type {?} */
  602. var transitionComplete = (/**
  603. * @return {?}
  604. */
  605. function () {
  606. if (_this._config.focus) {
  607. _this._element.nativeElement.focus();
  608. }
  609. _this.onShown.emit(_this);
  610. });
  611. if (this._config.animated) {
  612. setTimeout(transitionComplete, TRANSITION_DURATION);
  613. }
  614. else {
  615. transitionComplete();
  616. }
  617. };
  618. /** @internal */
  619. /**
  620. * \@internal
  621. * @protected
  622. * @return {?}
  623. */
  624. ModalDirective.prototype.hideModal = /**
  625. * \@internal
  626. * @protected
  627. * @return {?}
  628. */
  629. function () {
  630. var _this = this;
  631. this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'true');
  632. this._renderer.setStyle(this._element.nativeElement, 'display', 'none');
  633. this.showBackdrop((/**
  634. * @return {?}
  635. */
  636. function () {
  637. if (!_this.isNested) {
  638. if (document$1 && document$1.body) {
  639. _this._renderer.removeClass(document$1.body, CLASS_NAME.OPEN);
  640. }
  641. _this.resetScrollbar();
  642. }
  643. _this.resetAdjustments();
  644. _this.focusOtherModal();
  645. _this.onHidden.emit(_this);
  646. }));
  647. };
  648. // todo: original show was calling a callback when done, but we can use
  649. // promise
  650. /** @internal */
  651. // todo: original show was calling a callback when done, but we can use
  652. // promise
  653. /**
  654. * \@internal
  655. * @protected
  656. * @param {?=} callback
  657. * @return {?}
  658. */
  659. ModalDirective.prototype.showBackdrop =
  660. // todo: original show was calling a callback when done, but we can use
  661. // promise
  662. /**
  663. * \@internal
  664. * @protected
  665. * @param {?=} callback
  666. * @return {?}
  667. */
  668. function (callback) {
  669. var _this = this;
  670. if (this._isShown &&
  671. this.config.backdrop &&
  672. (!this.backdrop || !this.backdrop.instance.isShown)) {
  673. this.removeBackdrop();
  674. this._backdrop
  675. .attach(ModalBackdropComponent)
  676. .to('body')
  677. .show({ isAnimated: this._config.animated });
  678. this.backdrop = this._backdrop._componentRef;
  679. if (!callback) {
  680. return;
  681. }
  682. if (!this._config.animated) {
  683. callback();
  684. return;
  685. }
  686. setTimeout(callback, BACKDROP_TRANSITION_DURATION);
  687. }
  688. else if (!this._isShown && this.backdrop) {
  689. this.backdrop.instance.isShown = false;
  690. /** @type {?} */
  691. var callbackRemove = (/**
  692. * @return {?}
  693. */
  694. function () {
  695. _this.removeBackdrop();
  696. if (callback) {
  697. callback();
  698. }
  699. });
  700. if (this.backdrop.instance.isAnimated) {
  701. this.timerRmBackDrop = window$1.setTimeout(callbackRemove, BACKDROP_TRANSITION_DURATION);
  702. }
  703. else {
  704. callbackRemove();
  705. }
  706. }
  707. else if (callback) {
  708. callback();
  709. }
  710. };
  711. /** @internal */
  712. /**
  713. * \@internal
  714. * @protected
  715. * @return {?}
  716. */
  717. ModalDirective.prototype.removeBackdrop = /**
  718. * \@internal
  719. * @protected
  720. * @return {?}
  721. */
  722. function () {
  723. this._backdrop.hide();
  724. };
  725. /** Events tricks */
  726. // no need for it
  727. // protected setEscapeEvent():void {
  728. // if (this._isShown && this._config.keyboard) {
  729. // $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
  730. // if (event.which === 27) {
  731. // this.hide()
  732. // }
  733. // })
  734. //
  735. // } else if (!this._isShown) {
  736. // $(this._element).off(Event.KEYDOWN_DISMISS)
  737. // }
  738. // }
  739. // protected setResizeEvent():void {
  740. // console.log(this.renderer.listenGlobal('', Event.RESIZE));
  741. // if (this._isShown) {
  742. // $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
  743. // } else {
  744. // $(window).off(Event.RESIZE)
  745. // }
  746. // }
  747. /**
  748. * Events tricks
  749. * @protected
  750. * @return {?}
  751. */
  752. // no need for it
  753. // protected setEscapeEvent():void {
  754. // if (this._isShown && this._config.keyboard) {
  755. // $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
  756. // if (event.which === 27) {
  757. // this.hide()
  758. // }
  759. // })
  760. //
  761. // } else if (!this._isShown) {
  762. // $(this._element).off(Event.KEYDOWN_DISMISS)
  763. // }
  764. // }
  765. // protected setResizeEvent():void {
  766. // console.log(this.renderer.listenGlobal('', Event.RESIZE));
  767. // if (this._isShown) {
  768. // $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
  769. // } else {
  770. // $(window).off(Event.RESIZE)
  771. // }
  772. // }
  773. ModalDirective.prototype.focusOtherModal = /**
  774. * Events tricks
  775. * @protected
  776. * @return {?}
  777. */
  778. // no need for it
  779. // protected setEscapeEvent():void {
  780. // if (this._isShown && this._config.keyboard) {
  781. // $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
  782. // if (event.which === 27) {
  783. // this.hide()
  784. // }
  785. // })
  786. //
  787. // } else if (!this._isShown) {
  788. // $(this._element).off(Event.KEYDOWN_DISMISS)
  789. // }
  790. // }
  791. // protected setResizeEvent():void {
  792. // console.log(this.renderer.listenGlobal('', Event.RESIZE));
  793. // if (this._isShown) {
  794. // $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
  795. // } else {
  796. // $(window).off(Event.RESIZE)
  797. // }
  798. // }
  799. function () {
  800. if (this._element.nativeElement.parentElement == null) {
  801. return;
  802. }
  803. /** @type {?} */
  804. var otherOpenedModals = this._element.nativeElement.parentElement.querySelectorAll('.in[bsModal]');
  805. if (!otherOpenedModals.length) {
  806. return;
  807. }
  808. otherOpenedModals[otherOpenedModals.length - 1].focus();
  809. };
  810. /** @internal */
  811. /**
  812. * \@internal
  813. * @protected
  814. * @return {?}
  815. */
  816. ModalDirective.prototype.resetAdjustments = /**
  817. * \@internal
  818. * @protected
  819. * @return {?}
  820. */
  821. function () {
  822. this._renderer.setStyle(this._element.nativeElement, 'paddingLeft', '');
  823. this._renderer.setStyle(this._element.nativeElement, 'paddingRight', '');
  824. };
  825. /** Scroll bar tricks */
  826. /** @internal */
  827. /** Scroll bar tricks */
  828. /**
  829. * \@internal
  830. * @protected
  831. * @return {?}
  832. */
  833. ModalDirective.prototype.checkScrollbar = /** Scroll bar tricks */
  834. /**
  835. * \@internal
  836. * @protected
  837. * @return {?}
  838. */
  839. function () {
  840. this.isBodyOverflowing = document$1.body.clientWidth < window$1.innerWidth;
  841. this.scrollbarWidth = this.getScrollbarWidth();
  842. };
  843. /**
  844. * @protected
  845. * @return {?}
  846. */
  847. ModalDirective.prototype.setScrollbar = /**
  848. * @protected
  849. * @return {?}
  850. */
  851. function () {
  852. if (!document$1) {
  853. return;
  854. }
  855. this.originalBodyPadding = parseInt(window$1
  856. .getComputedStyle(document$1.body)
  857. .getPropertyValue('padding-right') || 0, 10);
  858. if (this.isBodyOverflowing) {
  859. document$1.body.style.paddingRight = this.originalBodyPadding +
  860. this.scrollbarWidth + "px";
  861. }
  862. };
  863. /**
  864. * @protected
  865. * @return {?}
  866. */
  867. ModalDirective.prototype.resetScrollbar = /**
  868. * @protected
  869. * @return {?}
  870. */
  871. function () {
  872. document$1.body.style.paddingRight = this.originalBodyPadding + "px";
  873. };
  874. // thx d.walsh
  875. // thx d.walsh
  876. /**
  877. * @protected
  878. * @return {?}
  879. */
  880. ModalDirective.prototype.getScrollbarWidth =
  881. // thx d.walsh
  882. /**
  883. * @protected
  884. * @return {?}
  885. */
  886. function () {
  887. /** @type {?} */
  888. var scrollDiv = this._renderer.createElement('div');
  889. this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
  890. this._renderer.appendChild(document$1.body, scrollDiv);
  891. /** @type {?} */
  892. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  893. this._renderer.removeChild(document$1.body, scrollDiv);
  894. return scrollbarWidth;
  895. };
  896. ModalDirective.decorators = [
  897. { type: Directive, args: [{
  898. selector: '[bsModal]',
  899. exportAs: 'bs-modal'
  900. },] }
  901. ];
  902. /** @nocollapse */
  903. ModalDirective.ctorParameters = function () { return [
  904. { type: ElementRef },
  905. { type: ViewContainerRef },
  906. { type: Renderer2 },
  907. { type: ComponentLoaderFactory }
  908. ]; };
  909. ModalDirective.propDecorators = {
  910. config: [{ type: Input }],
  911. onShow: [{ type: Output }],
  912. onShown: [{ type: Output }],
  913. onHide: [{ type: Output }],
  914. onHidden: [{ type: Output }],
  915. onClick: [{ type: HostListener, args: ['click', ['$event'],] }],
  916. onEsc: [{ type: HostListener, args: ['keydown.esc', ['$event'],] }]
  917. };
  918. return ModalDirective;
  919. }());
  920. /**
  921. * @fileoverview added by tsickle
  922. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  923. */
  924. var BsModalService = /** @class */ (function () {
  925. function BsModalService(rendererFactory, clf) {
  926. this.clf = clf;
  927. // constructor props
  928. this.config = modalConfigDefaults;
  929. // tslint:disable-next-line:no-any
  930. this.onShow = new EventEmitter();
  931. // tslint:disable-next-line:no-any
  932. this.onShown = new EventEmitter();
  933. // tslint:disable-next-line:no-any
  934. this.onHide = new EventEmitter();
  935. // tslint:disable-next-line:no-any
  936. this.onHidden = new EventEmitter();
  937. this.isBodyOverflowing = false;
  938. this.originalBodyPadding = 0;
  939. this.scrollbarWidth = 0;
  940. this.modalsCount = 0;
  941. this.lastDismissReason = '';
  942. this.loaders = [];
  943. this._backdropLoader = this.clf.createLoader(null, null, null);
  944. this._renderer = rendererFactory.createRenderer(null, null);
  945. }
  946. /** Shows a modal */
  947. // tslint:disable-next-line:no-any
  948. /**
  949. * Shows a modal
  950. * @param {?} content
  951. * @param {?=} config
  952. * @return {?}
  953. */
  954. // tslint:disable-next-line:no-any
  955. BsModalService.prototype.show = /**
  956. * Shows a modal
  957. * @param {?} content
  958. * @param {?=} config
  959. * @return {?}
  960. */
  961. // tslint:disable-next-line:no-any
  962. function (content, config) {
  963. this.modalsCount++;
  964. this._createLoaders();
  965. this.config = Object.assign({}, modalConfigDefaults, config);
  966. this._showBackdrop();
  967. this.lastDismissReason = null;
  968. return this._showModal(content);
  969. };
  970. /**
  971. * @param {?} level
  972. * @return {?}
  973. */
  974. BsModalService.prototype.hide = /**
  975. * @param {?} level
  976. * @return {?}
  977. */
  978. function (level) {
  979. var _this = this;
  980. if (this.modalsCount === 1) {
  981. this._hideBackdrop();
  982. this.resetScrollbar();
  983. }
  984. this.modalsCount = this.modalsCount >= 1 ? this.modalsCount - 1 : 0;
  985. setTimeout((/**
  986. * @return {?}
  987. */
  988. function () {
  989. _this._hideModal(level);
  990. _this.removeLoaders(level);
  991. }), this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0);
  992. };
  993. /**
  994. * @return {?}
  995. */
  996. BsModalService.prototype._showBackdrop = /**
  997. * @return {?}
  998. */
  999. function () {
  1000. /** @type {?} */
  1001. var isBackdropEnabled = this.config.backdrop || this.config.backdrop === 'static';
  1002. /** @type {?} */
  1003. var isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
  1004. if (this.modalsCount === 1) {
  1005. this.removeBackdrop();
  1006. if (isBackdropEnabled && isBackdropInDOM) {
  1007. this._backdropLoader
  1008. .attach(ModalBackdropComponent)
  1009. .to('body')
  1010. .show({ isAnimated: this.config.animated });
  1011. this.backdropRef = this._backdropLoader._componentRef;
  1012. }
  1013. }
  1014. };
  1015. /**
  1016. * @return {?}
  1017. */
  1018. BsModalService.prototype._hideBackdrop = /**
  1019. * @return {?}
  1020. */
  1021. function () {
  1022. var _this = this;
  1023. if (!this.backdropRef) {
  1024. return;
  1025. }
  1026. this.backdropRef.instance.isShown = false;
  1027. /** @type {?} */
  1028. var duration = this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0;
  1029. setTimeout((/**
  1030. * @return {?}
  1031. */
  1032. function () { return _this.removeBackdrop(); }), duration);
  1033. };
  1034. // tslint:disable-next-line:no-any
  1035. // tslint:disable-next-line:no-any
  1036. /**
  1037. * @param {?} content
  1038. * @return {?}
  1039. */
  1040. BsModalService.prototype._showModal =
  1041. // tslint:disable-next-line:no-any
  1042. /**
  1043. * @param {?} content
  1044. * @return {?}
  1045. */
  1046. function (content) {
  1047. /** @type {?} */
  1048. var modalLoader = this.loaders[this.loaders.length - 1];
  1049. /** @type {?} */
  1050. var bsModalRef = new BsModalRef();
  1051. /** @type {?} */
  1052. var modalContainerRef = modalLoader
  1053. .provide({ provide: ModalOptions, useValue: this.config })
  1054. .provide({ provide: BsModalRef, useValue: bsModalRef })
  1055. .attach(ModalContainerComponent)
  1056. .to('body')
  1057. .show({ content: content, isAnimated: this.config.animated, initialState: this.config.initialState, bsModalService: this });
  1058. modalContainerRef.instance.level = this.getModalsCount();
  1059. bsModalRef.hide = (/**
  1060. * @return {?}
  1061. */
  1062. function () {
  1063. modalContainerRef.instance.hide();
  1064. });
  1065. bsModalRef.content = modalLoader.getInnerComponent() || null;
  1066. bsModalRef.setClass = (/**
  1067. * @param {?} newClass
  1068. * @return {?}
  1069. */
  1070. function (newClass) {
  1071. modalContainerRef.instance.config.class = newClass;
  1072. });
  1073. return bsModalRef;
  1074. };
  1075. /**
  1076. * @param {?} level
  1077. * @return {?}
  1078. */
  1079. BsModalService.prototype._hideModal = /**
  1080. * @param {?} level
  1081. * @return {?}
  1082. */
  1083. function (level) {
  1084. /** @type {?} */
  1085. var modalLoader = this.loaders[level - 1];
  1086. if (modalLoader) {
  1087. modalLoader.hide();
  1088. }
  1089. };
  1090. /**
  1091. * @return {?}
  1092. */
  1093. BsModalService.prototype.getModalsCount = /**
  1094. * @return {?}
  1095. */
  1096. function () {
  1097. return this.modalsCount;
  1098. };
  1099. /**
  1100. * @param {?} reason
  1101. * @return {?}
  1102. */
  1103. BsModalService.prototype.setDismissReason = /**
  1104. * @param {?} reason
  1105. * @return {?}
  1106. */
  1107. function (reason) {
  1108. this.lastDismissReason = reason;
  1109. };
  1110. /**
  1111. * @return {?}
  1112. */
  1113. BsModalService.prototype.removeBackdrop = /**
  1114. * @return {?}
  1115. */
  1116. function () {
  1117. this._backdropLoader.hide();
  1118. this.backdropRef = null;
  1119. };
  1120. /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  1121. /** Scroll bar tricks */
  1122. /** @internal */
  1123. /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  1124. /** Scroll bar tricks */
  1125. /**
  1126. * \@internal
  1127. * @return {?}
  1128. */
  1129. BsModalService.prototype.checkScrollbar = /** AFTER PR MERGE MODAL.COMPONENT WILL BE USING THIS CODE */
  1130. /** Scroll bar tricks */
  1131. /**
  1132. * \@internal
  1133. * @return {?}
  1134. */
  1135. function () {
  1136. this.isBodyOverflowing = document.body.clientWidth < window.innerWidth;
  1137. this.scrollbarWidth = this.getScrollbarWidth();
  1138. };
  1139. /**
  1140. * @return {?}
  1141. */
  1142. BsModalService.prototype.setScrollbar = /**
  1143. * @return {?}
  1144. */
  1145. function () {
  1146. if (!document) {
  1147. return;
  1148. }
  1149. this.originalBodyPadding = parseInt(window
  1150. .getComputedStyle(document.body)
  1151. .getPropertyValue('padding-right') || '0', 10);
  1152. if (this.isBodyOverflowing) {
  1153. document.body.style.paddingRight = this.originalBodyPadding +
  1154. this.scrollbarWidth + "px";
  1155. }
  1156. };
  1157. /**
  1158. * @private
  1159. * @return {?}
  1160. */
  1161. BsModalService.prototype.resetScrollbar = /**
  1162. * @private
  1163. * @return {?}
  1164. */
  1165. function () {
  1166. document.body.style.paddingRight = this.originalBodyPadding + "px";
  1167. };
  1168. // thx d.walsh
  1169. // thx d.walsh
  1170. /**
  1171. * @private
  1172. * @return {?}
  1173. */
  1174. BsModalService.prototype.getScrollbarWidth =
  1175. // thx d.walsh
  1176. /**
  1177. * @private
  1178. * @return {?}
  1179. */
  1180. function () {
  1181. /** @type {?} */
  1182. var scrollDiv = this._renderer.createElement('div');
  1183. this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
  1184. this._renderer.appendChild(document.body, scrollDiv);
  1185. /** @type {?} */
  1186. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  1187. this._renderer.removeChild(document.body, scrollDiv);
  1188. return scrollbarWidth;
  1189. };
  1190. /**
  1191. * @private
  1192. * @return {?}
  1193. */
  1194. BsModalService.prototype._createLoaders = /**
  1195. * @private
  1196. * @return {?}
  1197. */
  1198. function () {
  1199. /** @type {?} */
  1200. var loader = this.clf.createLoader(null, null, null);
  1201. this.copyEvent(loader.onBeforeShow, this.onShow);
  1202. this.copyEvent(loader.onShown, this.onShown);
  1203. this.copyEvent(loader.onBeforeHide, this.onHide);
  1204. this.copyEvent(loader.onHidden, this.onHidden);
  1205. this.loaders.push(loader);
  1206. };
  1207. /**
  1208. * @private
  1209. * @param {?} level
  1210. * @return {?}
  1211. */
  1212. BsModalService.prototype.removeLoaders = /**
  1213. * @private
  1214. * @param {?} level
  1215. * @return {?}
  1216. */
  1217. function (level) {
  1218. this.loaders.splice(level - 1, 1);
  1219. this.loaders.forEach((/**
  1220. * @param {?} loader
  1221. * @param {?} i
  1222. * @return {?}
  1223. */
  1224. function (loader, i) {
  1225. loader.instance.level = i + 1;
  1226. }));
  1227. };
  1228. // tslint:disable-next-line:no-any
  1229. // tslint:disable-next-line:no-any
  1230. /**
  1231. * @private
  1232. * @param {?} from
  1233. * @param {?} to
  1234. * @return {?}
  1235. */
  1236. BsModalService.prototype.copyEvent =
  1237. // tslint:disable-next-line:no-any
  1238. /**
  1239. * @private
  1240. * @param {?} from
  1241. * @param {?} to
  1242. * @return {?}
  1243. */
  1244. function (from, to) {
  1245. var _this = this;
  1246. from.subscribe((/**
  1247. * @return {?}
  1248. */
  1249. function () {
  1250. to.emit(_this.lastDismissReason);
  1251. }));
  1252. };
  1253. BsModalService.decorators = [
  1254. { type: Injectable }
  1255. ];
  1256. /** @nocollapse */
  1257. BsModalService.ctorParameters = function () { return [
  1258. { type: RendererFactory2 },
  1259. { type: ComponentLoaderFactory }
  1260. ]; };
  1261. return BsModalService;
  1262. }());
  1263. /**
  1264. * @fileoverview added by tsickle
  1265. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1266. */
  1267. var ModalModule = /** @class */ (function () {
  1268. function ModalModule() {
  1269. }
  1270. /**
  1271. * @return {?}
  1272. */
  1273. ModalModule.forRoot = /**
  1274. * @return {?}
  1275. */
  1276. function () {
  1277. return {
  1278. ngModule: ModalModule,
  1279. providers: [BsModalService, ComponentLoaderFactory, PositioningService]
  1280. };
  1281. };
  1282. ModalModule.decorators = [
  1283. { type: NgModule, args: [{
  1284. declarations: [
  1285. ModalBackdropComponent,
  1286. ModalDirective,
  1287. ModalContainerComponent
  1288. ],
  1289. exports: [ModalBackdropComponent, ModalDirective],
  1290. entryComponents: [ModalBackdropComponent, ModalContainerComponent]
  1291. },] }
  1292. ];
  1293. return ModalModule;
  1294. }());
  1295. export { BsModalRef, BsModalService, ModalBackdropComponent, ModalBackdropOptions, ModalContainerComponent, ModalDirective, ModalModule, ModalOptions, CLASS_NAME as ɵa };
  1296. //# sourceMappingURL=ngx-bootstrap-modal.js.map