1 | import { Injectable, InjectionToken, Component, ElementRef, Renderer2, HostListener, EventEmitter, Directive, ViewContainerRef, Optional, Inject, Input, Output, 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 | import { FocusTrapModule } from 'ngx-bootstrap/focus-trap';
|
6 |
|
7 |
|
8 | class BsModalRef {
|
9 | constructor() {
|
10 | |
11 |
|
12 |
|
13 | this.hide = () => void 0;
|
14 | |
15 |
|
16 |
|
17 | this.setClass = () => void 0;
|
18 | }
|
19 | }
|
20 | BsModalRef.decorators = [
|
21 | { type: Injectable }
|
22 | ];
|
23 |
|
24 | class ModalBackdropOptions {
|
25 | constructor(options) {
|
26 | this.animate = true;
|
27 | Object.assign(this, options);
|
28 | }
|
29 | }
|
30 |
|
31 | class ModalOptions {
|
32 | }
|
33 | ModalOptions.decorators = [
|
34 | { type: Injectable }
|
35 | ];
|
36 | const modalConfigDefaults = {
|
37 | backdrop: true,
|
38 | keyboard: true,
|
39 | focus: true,
|
40 | show: false,
|
41 | ignoreBackdropClick: false,
|
42 | class: '',
|
43 | animated: true,
|
44 | initialState: {},
|
45 | closeInterceptor: void 0
|
46 | };
|
47 | const MODAL_CONFIG_DEFAULT_OVERRIDE = new InjectionToken('override-default-config');
|
48 | const CLASS_NAME = {
|
49 | SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
|
50 | BACKDROP: 'modal-backdrop',
|
51 | OPEN: 'modal-open',
|
52 | FADE: 'fade',
|
53 | IN: 'in',
|
54 | SHOW: 'show'
|
55 | };
|
56 | const SELECTOR = {
|
57 | DIALOG: '.modal-dialog',
|
58 | DATA_TOGGLE: '[data-toggle="modal"]',
|
59 | DATA_DISMISS: '[data-dismiss="modal"]',
|
60 | FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
|
61 | };
|
62 | const TRANSITION_DURATIONS = {
|
63 | MODAL: 300,
|
64 | BACKDROP: 150
|
65 | };
|
66 | const DISMISS_REASONS = {
|
67 | BACKRDOP: 'backdrop-click',
|
68 | ESC: 'esc',
|
69 | BACK: 'browser-back-navigation-clicked'
|
70 | };
|
71 |
|
72 | class ModalContainerComponent {
|
73 | constructor(options, _element, _renderer) {
|
74 | this._element = _element;
|
75 | this._renderer = _renderer;
|
76 | this.isShown = false;
|
77 | this.isAnimated = false;
|
78 | this.isModalHiding = false;
|
79 | this.clickStartedInContent = false;
|
80 | this.config = Object.assign({}, options);
|
81 | }
|
82 | ngOnInit() {
|
83 | if (this.isAnimated) {
|
84 | this._renderer.addClass(this._element.nativeElement, CLASS_NAME.FADE);
|
85 | }
|
86 | this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
|
87 | setTimeout(() => {
|
88 | this.isShown = true;
|
89 | this._renderer.addClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
|
90 | }, this.isAnimated ? TRANSITION_DURATIONS.BACKDROP : 0);
|
91 | if (document && document.body) {
|
92 | if (this.bsModalService && this.bsModalService.getModalsCount() === 1) {
|
93 | this.bsModalService.checkScrollbar();
|
94 | this.bsModalService.setScrollbar();
|
95 | }
|
96 | this._renderer.addClass(document.body, CLASS_NAME.OPEN);
|
97 | this._renderer.setStyle(document.body, 'overflow-y', 'hidden');
|
98 | }
|
99 | if (this._element.nativeElement) {
|
100 | this._element.nativeElement.focus();
|
101 | }
|
102 | }
|
103 | onClickStarted(event) {
|
104 | this.clickStartedInContent = event.target !== this._element.nativeElement;
|
105 | }
|
106 | onClickStop(event) {
|
107 | var _a;
|
108 | const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
|
109 | if (this.config.ignoreBackdropClick ||
|
110 | this.config.backdrop === 'static' ||
|
111 | !clickedInBackdrop) {
|
112 | this.clickStartedInContent = false;
|
113 | return;
|
114 | }
|
115 | (_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.setDismissReason(DISMISS_REASONS.BACKRDOP);
|
116 | this.hide();
|
117 | }
|
118 | onPopState() {
|
119 | var _a;
|
120 | (_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.setDismissReason(DISMISS_REASONS.BACK);
|
121 | this.hide();
|
122 | }
|
123 | onEsc(event) {
|
124 | var _a, _b;
|
125 | if (!this.isShown) {
|
126 | return;
|
127 | }
|
128 | if (event.keyCode === 27 || event.key === 'Escape') {
|
129 | event.preventDefault();
|
130 | }
|
131 | if (this.config.keyboard &&
|
132 | this.level === ((_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.getModalsCount())) {
|
133 | (_b = this.bsModalService) === null || _b === void 0 ? void 0 : _b.setDismissReason(DISMISS_REASONS.ESC);
|
134 | this.hide();
|
135 | }
|
136 | }
|
137 | ngOnDestroy() {
|
138 | if (this.isShown) {
|
139 | this._hide();
|
140 | }
|
141 | }
|
142 | hide() {
|
143 | if (this.isModalHiding || !this.isShown) {
|
144 | return;
|
145 | }
|
146 | if (this.config.closeInterceptor) {
|
147 | this.config.closeInterceptor().then(() => this._hide(), () => undefined);
|
148 | return;
|
149 | }
|
150 | this._hide();
|
151 | }
|
152 | _hide() {
|
153 | this.isModalHiding = true;
|
154 | this._renderer.removeClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
|
155 | setTimeout(() => {
|
156 | var _a, _b;
|
157 | this.isShown = false;
|
158 | if (document &&
|
159 | document.body &&
|
160 | ((_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.getModalsCount()) === 1) {
|
161 | this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
|
162 | this._renderer.setStyle(document.body, 'overflow-y', '');
|
163 | }
|
164 | (_b = this.bsModalService) === null || _b === void 0 ? void 0 : _b.hide(this.config.id);
|
165 | this.isModalHiding = false;
|
166 | }, this.isAnimated ? TRANSITION_DURATIONS.MODAL : 0);
|
167 | }
|
168 | }
|
169 | ModalContainerComponent.decorators = [
|
170 | { type: Component, args: [{
|
171 | selector: 'modal-container',
|
172 | template: `
|
173 | <div [class]="'modal-dialog' + (config.class ? ' ' + config.class : '')"
|
174 | role="document"
|
175 | focusTrap>
|
176 | <div class="modal-content">
|
177 | <ng-content></ng-content>
|
178 | </div>
|
179 | </div>
|
180 | `,
|
181 |
|
182 | host: {
|
183 | class: 'modal',
|
184 | role: 'dialog',
|
185 | tabindex: '-1',
|
186 | '[attr.aria-modal]': 'true',
|
187 | '[attr.aria-labelledby]': 'config.ariaLabelledBy',
|
188 | '[attr.aria-describedby]': 'config.ariaDescribedby'
|
189 | }
|
190 | },] }
|
191 | ];
|
192 | ModalContainerComponent.ctorParameters = () => [
|
193 | { type: ModalOptions },
|
194 | { type: ElementRef },
|
195 | { type: Renderer2 }
|
196 | ];
|
197 | ModalContainerComponent.propDecorators = {
|
198 | onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
|
199 | onClickStop: [{ type: HostListener, args: ['click', ['$event'],] }],
|
200 | onPopState: [{ type: HostListener, args: ['window:popstate',] }],
|
201 | onEsc: [{ type: HostListener, args: ['window:keydown.esc', ['$event'],] }]
|
202 | };
|
203 |
|
204 |
|
205 | class ModalBackdropComponent {
|
206 | constructor(element, renderer) {
|
207 | this._isAnimated = false;
|
208 | this._isShown = false;
|
209 | this.element = element;
|
210 | this.renderer = renderer;
|
211 | }
|
212 | get isAnimated() {
|
213 | return this._isAnimated;
|
214 | }
|
215 | set isAnimated(value) {
|
216 | this._isAnimated = value;
|
217 | }
|
218 | get isShown() {
|
219 | return this._isShown;
|
220 | }
|
221 | set isShown(value) {
|
222 | this._isShown = value;
|
223 | if (value) {
|
224 | this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
|
225 | }
|
226 | else {
|
227 | this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
|
228 | }
|
229 | if (!isBs3()) {
|
230 | if (value) {
|
231 | this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
|
232 | }
|
233 | else {
|
234 | this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
|
235 | }
|
236 | }
|
237 | }
|
238 | ngOnInit() {
|
239 | if (this.isAnimated) {
|
240 | this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.FADE}`);
|
241 | Utils.reflow(this.element.nativeElement);
|
242 | }
|
243 | this.isShown = true;
|
244 | }
|
245 | }
|
246 | ModalBackdropComponent.decorators = [
|
247 | { type: Component, args: [{
|
248 | selector: 'bs-modal-backdrop',
|
249 | template: ' ',
|
250 |
|
251 | host: { class: CLASS_NAME.BACKDROP }
|
252 | },] }
|
253 | ];
|
254 | ModalBackdropComponent.ctorParameters = () => [
|
255 | { type: ElementRef },
|
256 | { type: Renderer2 }
|
257 | ];
|
258 |
|
259 |
|
260 | const TRANSITION_DURATION = 300;
|
261 | const BACKDROP_TRANSITION_DURATION = 150;
|
262 |
|
263 | class ModalDirective {
|
264 | constructor(_element, _viewContainerRef, _renderer, clf, modalDefaultOption) {
|
265 | this._element = _element;
|
266 | this._renderer = _renderer;
|
267 |
|
268 | this.onShow = new EventEmitter();
|
269 | |
270 |
|
271 |
|
272 | this.onShown = new EventEmitter();
|
273 | |
274 |
|
275 |
|
276 | this.onHide = new EventEmitter();
|
277 | |
278 |
|
279 |
|
280 | this.onHidden = new EventEmitter();
|
281 | this._isShown = false;
|
282 | this.isBodyOverflowing = false;
|
283 | this.originalBodyPadding = 0;
|
284 | this.scrollbarWidth = 0;
|
285 | this.timerHideModal = 0;
|
286 | this.timerRmBackDrop = 0;
|
287 | this.isNested = false;
|
288 | this.clickStartedInContent = false;
|
289 | this._backdrop = clf.createLoader(_element, _viewContainerRef, _renderer);
|
290 | this._config = modalDefaultOption || modalConfigDefaults;
|
291 | }
|
292 |
|
293 | set config(conf) {
|
294 | this._config = this.getConfig(conf);
|
295 | }
|
296 | get config() {
|
297 | return this._config;
|
298 | }
|
299 | get isShown() {
|
300 | return this._isShown;
|
301 | }
|
302 | onClickStarted(event) {
|
303 | this.clickStartedInContent = event.target !== this._element.nativeElement;
|
304 | }
|
305 | onClickStop(event) {
|
306 | const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
|
307 | if (this.config.ignoreBackdropClick ||
|
308 | this.config.backdrop === 'static' ||
|
309 | !clickedInBackdrop) {
|
310 | this.clickStartedInContent = false;
|
311 | return;
|
312 | }
|
313 | this.dismissReason = DISMISS_REASONS.BACKRDOP;
|
314 | this.hide(event);
|
315 | }
|
316 |
|
317 | onEsc(event) {
|
318 | if (!this._isShown) {
|
319 | return;
|
320 | }
|
321 | if (event.keyCode === 27 || event.key === 'Escape') {
|
322 | event.preventDefault();
|
323 | }
|
324 | if (this.config.keyboard) {
|
325 | this.dismissReason = DISMISS_REASONS.ESC;
|
326 | this.hide();
|
327 | }
|
328 | }
|
329 | ngOnDestroy() {
|
330 | if (this._isShown) {
|
331 | this._isShown = false;
|
332 | this.hideModal();
|
333 | this._backdrop.dispose();
|
334 | }
|
335 | }
|
336 | ngOnInit() {
|
337 | this._config = this._config || this.getConfig();
|
338 | setTimeout(() => {
|
339 | if (this._config.show) {
|
340 | this.show();
|
341 | }
|
342 | }, 0);
|
343 | }
|
344 |
|
345 |
|
346 | toggle() {
|
347 | return this._isShown ? this.hide() : this.show();
|
348 | }
|
349 |
|
350 | show() {
|
351 | this.dismissReason = void 0;
|
352 | this.onShow.emit(this);
|
353 | if (this._isShown) {
|
354 | return;
|
355 | }
|
356 | clearTimeout(this.timerHideModal);
|
357 | clearTimeout(this.timerRmBackDrop);
|
358 | this._isShown = true;
|
359 | this.checkScrollbar();
|
360 | this.setScrollbar();
|
361 | if (document$1 && document$1.body) {
|
362 | if (document$1.body.classList.contains(CLASS_NAME.OPEN)) {
|
363 | this.isNested = true;
|
364 | }
|
365 | else {
|
366 | this._renderer.addClass(document$1.body, CLASS_NAME.OPEN);
|
367 | this._renderer.setStyle(document$1.body, 'overflow-y', 'hidden');
|
368 | }
|
369 | }
|
370 | this.showBackdrop(() => {
|
371 | this.showElement();
|
372 | });
|
373 | }
|
374 |
|
375 | hide(event) {
|
376 | if (!this._isShown) {
|
377 | return;
|
378 | }
|
379 | if (event) {
|
380 | event.preventDefault();
|
381 | }
|
382 | if (this.config.closeInterceptor) {
|
383 | this.config.closeInterceptor().then(() => this._hide(), () => undefined);
|
384 | return;
|
385 | }
|
386 | this._hide();
|
387 | }
|
388 |
|
389 | |
390 |
|
391 |
|
392 |
|
393 | _hide() {
|
394 | this.onHide.emit(this);
|
395 | window$1.clearTimeout(this.timerHideModal);
|
396 | window$1.clearTimeout(this.timerRmBackDrop);
|
397 | this._isShown = false;
|
398 | this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.IN);
|
399 | if (!isBs3()) {
|
400 | this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.SHOW);
|
401 | }
|
402 |
|
403 | if (this._config.animated) {
|
404 | this.timerHideModal = window$1.setTimeout(() => this.hideModal(), TRANSITION_DURATION);
|
405 | }
|
406 | else {
|
407 | this.hideModal();
|
408 | }
|
409 | }
|
410 | getConfig(config) {
|
411 | return Object.assign({}, this._config, config);
|
412 | }
|
413 | |
414 |
|
415 |
|
416 |
|
417 | showElement() {
|
418 |
|
419 | if (!this._element.nativeElement.parentNode ||
|
420 | this._element.nativeElement.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
421 |
|
422 | if (document$1 && document$1.body) {
|
423 | document$1.body.appendChild(this._element.nativeElement);
|
424 | }
|
425 | }
|
426 | this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'false');
|
427 | this._renderer.setAttribute(this._element.nativeElement, 'aria-modal', 'true');
|
428 | this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
|
429 | this._renderer.setProperty(this._element.nativeElement, 'scrollTop', 0);
|
430 | if (this._config.animated) {
|
431 | Utils.reflow(this._element.nativeElement);
|
432 | }
|
433 |
|
434 | this._renderer.addClass(this._element.nativeElement, CLASS_NAME.IN);
|
435 | if (!isBs3()) {
|
436 | this._renderer.addClass(this._element.nativeElement, CLASS_NAME.SHOW);
|
437 | }
|
438 | const transitionComplete = () => {
|
439 | if (this._config.focus) {
|
440 | this._element.nativeElement.focus();
|
441 | }
|
442 | this.onShown.emit(this);
|
443 | };
|
444 | if (this._config.animated) {
|
445 | setTimeout(transitionComplete, TRANSITION_DURATION);
|
446 | }
|
447 | else {
|
448 | transitionComplete();
|
449 | }
|
450 | }
|
451 |
|
452 | hideModal() {
|
453 | this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'true');
|
454 | this._renderer.setStyle(this._element.nativeElement, 'display', 'none');
|
455 | this.showBackdrop(() => {
|
456 | if (!this.isNested) {
|
457 | if (document$1 && document$1.body) {
|
458 | this._renderer.removeClass(document$1.body, CLASS_NAME.OPEN);
|
459 | this._renderer.setStyle(document$1.body, 'overflow-y', '');
|
460 | }
|
461 | this.resetScrollbar();
|
462 | }
|
463 | this.resetAdjustments();
|
464 | this.focusOtherModal();
|
465 | this.onHidden.emit(this);
|
466 | });
|
467 | }
|
468 |
|
469 |
|
470 |
|
471 | showBackdrop(callback) {
|
472 | if (this._isShown &&
|
473 | this.config.backdrop &&
|
474 | (!this.backdrop || !this.backdrop.instance.isShown)) {
|
475 | this.removeBackdrop();
|
476 | this._backdrop
|
477 | .attach(ModalBackdropComponent)
|
478 | .to('body')
|
479 | .show({ isAnimated: this._config.animated });
|
480 | this.backdrop = this._backdrop._componentRef;
|
481 | if (!callback) {
|
482 | return;
|
483 | }
|
484 | if (!this._config.animated) {
|
485 | callback();
|
486 | return;
|
487 | }
|
488 | setTimeout(callback, BACKDROP_TRANSITION_DURATION);
|
489 | }
|
490 | else if (!this._isShown && this.backdrop) {
|
491 | this.backdrop.instance.isShown = false;
|
492 | const callbackRemove = () => {
|
493 | this.removeBackdrop();
|
494 | if (callback) {
|
495 | callback();
|
496 | }
|
497 | };
|
498 | if (this.backdrop.instance.isAnimated) {
|
499 | this.timerRmBackDrop = window$1.setTimeout(callbackRemove, BACKDROP_TRANSITION_DURATION);
|
500 | }
|
501 | else {
|
502 | callbackRemove();
|
503 | }
|
504 | }
|
505 | else if (callback) {
|
506 | callback();
|
507 | }
|
508 | }
|
509 |
|
510 | removeBackdrop() {
|
511 | this._backdrop.hide();
|
512 | }
|
513 |
|
514 |
|
515 |
|
516 |
|
517 |
|
518 |
|
519 |
|
520 |
|
521 |
|
522 |
|
523 |
|
524 |
|
525 |
|
526 |
|
527 |
|
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 |
|
535 | focusOtherModal() {
|
536 | if (this._element.nativeElement.parentElement == null) {
|
537 | return;
|
538 | }
|
539 | const otherOpenedModals = this._element.nativeElement.parentElement.querySelectorAll('.in[bsModal]');
|
540 | if (!otherOpenedModals.length) {
|
541 | return;
|
542 | }
|
543 | otherOpenedModals[otherOpenedModals.length - 1].focus();
|
544 | }
|
545 |
|
546 | resetAdjustments() {
|
547 | this._renderer.setStyle(this._element.nativeElement, 'paddingLeft', '');
|
548 | this._renderer.setStyle(this._element.nativeElement, 'paddingRight', '');
|
549 | }
|
550 |
|
551 |
|
552 | checkScrollbar() {
|
553 | this.isBodyOverflowing = document$1.body.clientWidth < window$1.innerWidth;
|
554 | this.scrollbarWidth = this.getScrollbarWidth();
|
555 | }
|
556 | setScrollbar() {
|
557 | if (!document$1) {
|
558 | return;
|
559 | }
|
560 | this.originalBodyPadding = parseInt(window$1
|
561 | .getComputedStyle(document$1.body)
|
562 | .getPropertyValue('padding-right') || 0, 10);
|
563 | if (this.isBodyOverflowing) {
|
564 | document$1.body.style.paddingRight = `${this.originalBodyPadding +
|
565 | this.scrollbarWidth}px`;
|
566 | }
|
567 | }
|
568 | resetScrollbar() {
|
569 | document$1.body.style.paddingRight = `${this.originalBodyPadding}px`;
|
570 | }
|
571 |
|
572 | getScrollbarWidth() {
|
573 | const scrollDiv = this._renderer.createElement('div');
|
574 | this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
|
575 | this._renderer.appendChild(document$1.body, scrollDiv);
|
576 | const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
577 | this._renderer.removeChild(document$1.body, scrollDiv);
|
578 | return scrollbarWidth;
|
579 | }
|
580 | }
|
581 | ModalDirective.decorators = [
|
582 | { type: Directive, args: [{
|
583 | selector: '[bsModal]',
|
584 | exportAs: 'bs-modal'
|
585 | },] }
|
586 | ];
|
587 | ModalDirective.ctorParameters = () => [
|
588 | { type: ElementRef },
|
589 | { type: ViewContainerRef },
|
590 | { type: Renderer2 },
|
591 | { type: ComponentLoaderFactory },
|
592 | { type: ModalOptions, decorators: [{ type: Optional }, { type: Inject, args: [MODAL_CONFIG_DEFAULT_OVERRIDE,] }] }
|
593 | ];
|
594 | ModalDirective.propDecorators = {
|
595 | config: [{ type: Input }],
|
596 | closeInterceptor: [{ type: Input }],
|
597 | onShow: [{ type: Output }],
|
598 | onShown: [{ type: Output }],
|
599 | onHide: [{ type: Output }],
|
600 | onHidden: [{ type: Output }],
|
601 | onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
|
602 | onClickStop: [{ type: HostListener, args: ['mouseup', ['$event'],] }],
|
603 | onEsc: [{ type: HostListener, args: ['keydown.esc', ['$event'],] }]
|
604 | };
|
605 |
|
606 | class BsModalService {
|
607 | constructor(rendererFactory, clf, modalDefaultOption) {
|
608 | this.clf = clf;
|
609 | this.modalDefaultOption = modalDefaultOption;
|
610 | this.onShow = new EventEmitter();
|
611 | this.onShown = new EventEmitter();
|
612 | this.onHide = new EventEmitter();
|
613 | this.onHidden = new EventEmitter();
|
614 | this.isBodyOverflowing = false;
|
615 | this.originalBodyPadding = 0;
|
616 | this.scrollbarWidth = 0;
|
617 | this.modalsCount = 0;
|
618 | this.loaders = [];
|
619 | this._backdropLoader = this.clf.createLoader();
|
620 | this._renderer = rendererFactory.createRenderer(null, null);
|
621 | this.config = modalDefaultOption ?
|
622 | (Object.assign({}, modalConfigDefaults, modalDefaultOption)) :
|
623 | modalConfigDefaults;
|
624 | }
|
625 |
|
626 | show(
|
627 |
|
628 | content, config) {
|
629 | this.modalsCount++;
|
630 | this._createLoaders();
|
631 |
|
632 | const id = (config === null || config === void 0 ? void 0 : config.id) || (new Date()).getUTCMilliseconds();
|
633 | this.config = this.modalDefaultOption ?
|
634 | Object.assign({}, modalConfigDefaults, this.modalDefaultOption, config) :
|
635 | Object.assign({}, modalConfigDefaults, config);
|
636 | this.config.id = id;
|
637 | this._showBackdrop();
|
638 | this.lastDismissReason = void 0;
|
639 | return this._showModal(content);
|
640 | }
|
641 | hide(id) {
|
642 | if (this.modalsCount === 1 || id == null) {
|
643 | this._hideBackdrop();
|
644 | this.resetScrollbar();
|
645 | }
|
646 | this.modalsCount = this.modalsCount >= 1 && id != null ? this.modalsCount - 1 : 0;
|
647 | setTimeout(() => {
|
648 | this._hideModal(id);
|
649 | this.removeLoaders(id);
|
650 | }, this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0);
|
651 | }
|
652 | _showBackdrop() {
|
653 | const isBackdropEnabled = this.config.backdrop === true || this.config.backdrop === 'static';
|
654 | const isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
|
655 | if (this.modalsCount === 1) {
|
656 | this.removeBackdrop();
|
657 | if (isBackdropEnabled && isBackdropInDOM) {
|
658 | this._backdropLoader
|
659 | .attach(ModalBackdropComponent)
|
660 | .to('body')
|
661 | .show({ isAnimated: this.config.animated });
|
662 | this.backdropRef = this._backdropLoader._componentRef;
|
663 | }
|
664 | }
|
665 | }
|
666 | _hideBackdrop() {
|
667 | if (!this.backdropRef) {
|
668 | return;
|
669 | }
|
670 | this.backdropRef.instance.isShown = false;
|
671 | const duration = this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0;
|
672 | setTimeout(() => this.removeBackdrop(), duration);
|
673 | }
|
674 |
|
675 | _showModal(content) {
|
676 | var _a;
|
677 | const modalLoader = this.loaders[this.loaders.length - 1];
|
678 | if (this.config && this.config.providers) {
|
679 | for (const provider of this.config.providers) {
|
680 | modalLoader.provide(provider);
|
681 | }
|
682 | }
|
683 |
|
684 | const bsModalRef = new BsModalRef();
|
685 | const modalContainerRef = modalLoader
|
686 | .provide({ provide: ModalOptions, useValue: this.config })
|
687 | .provide({ provide: BsModalRef, useValue: bsModalRef })
|
688 | .attach(ModalContainerComponent)
|
689 | .to('body');
|
690 | bsModalRef.hide = () => { var _a; return (_a = modalContainerRef.instance) === null || _a === void 0 ? void 0 : _a.hide(); };
|
691 | bsModalRef.setClass = (newClass) => {
|
692 | if (modalContainerRef.instance) {
|
693 | modalContainerRef.instance.config.class = newClass;
|
694 | }
|
695 | };
|
696 | bsModalRef.onHidden = new EventEmitter();
|
697 | bsModalRef.onHide = new EventEmitter();
|
698 | this.copyEvent(modalLoader.onBeforeHide, bsModalRef.onHide);
|
699 | this.copyEvent(modalLoader.onHidden, bsModalRef.onHidden);
|
700 |
|
701 |
|
702 | modalContainerRef.show({
|
703 | content,
|
704 | isAnimated: this.config.animated,
|
705 | initialState: this.config.initialState,
|
706 | bsModalService: this,
|
707 | id: this.config.id
|
708 | });
|
709 | if (modalContainerRef.instance) {
|
710 | modalContainerRef.instance.level = this.getModalsCount();
|
711 | bsModalRef.content = modalLoader.getInnerComponent();
|
712 | bsModalRef.id = (_a = modalContainerRef.instance.config) === null || _a === void 0 ? void 0 : _a.id;
|
713 | }
|
714 | return bsModalRef;
|
715 | }
|
716 | _hideModal(id) {
|
717 | if (id != null) {
|
718 | const indexToRemove = this.loaders.findIndex(loader => { var _a; return ((_a = loader.instance) === null || _a === void 0 ? void 0 : _a.config.id) === id; });
|
719 | const modalLoader = this.loaders[indexToRemove];
|
720 | if (modalLoader) {
|
721 | modalLoader.hide(id);
|
722 | }
|
723 | }
|
724 | else {
|
725 | this.loaders.forEach((loader) => {
|
726 | if (loader.instance) {
|
727 | loader.hide(loader.instance.config.id);
|
728 | }
|
729 | });
|
730 | }
|
731 | }
|
732 | getModalsCount() {
|
733 | return this.modalsCount;
|
734 | }
|
735 | setDismissReason(reason) {
|
736 | this.lastDismissReason = reason;
|
737 | }
|
738 | removeBackdrop() {
|
739 | this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
|
740 | this._renderer.setStyle(document.body, 'overflow-y', '');
|
741 | this._backdropLoader.hide();
|
742 | this.backdropRef = void 0;
|
743 | }
|
744 |
|
745 |
|
746 | checkScrollbar() {
|
747 | this.isBodyOverflowing = document.body.clientWidth < window.innerWidth;
|
748 | this.scrollbarWidth = this.getScrollbarWidth();
|
749 | }
|
750 | setScrollbar() {
|
751 | if (!document) {
|
752 | return;
|
753 | }
|
754 | this.originalBodyPadding = parseInt(window
|
755 | .getComputedStyle(document.body)
|
756 | .getPropertyValue('padding-right') || '0', 10);
|
757 | if (this.isBodyOverflowing) {
|
758 | document.body.style.paddingRight = `${this.originalBodyPadding +
|
759 | this.scrollbarWidth}px`;
|
760 | }
|
761 | }
|
762 | resetScrollbar() {
|
763 | document.body.style.paddingRight = `${this.originalBodyPadding}px`;
|
764 | }
|
765 |
|
766 | getScrollbarWidth() {
|
767 | const scrollDiv = this._renderer.createElement('div');
|
768 | this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
|
769 | this._renderer.appendChild(document.body, scrollDiv);
|
770 | const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
771 | this._renderer.removeChild(document.body, scrollDiv);
|
772 | return scrollbarWidth;
|
773 | }
|
774 | _createLoaders() {
|
775 | const loader = this.clf.createLoader();
|
776 | this.copyEvent(loader.onBeforeShow, this.onShow);
|
777 | this.copyEvent(loader.onShown, this.onShown);
|
778 | this.copyEvent(loader.onBeforeHide, this.onHide);
|
779 | this.copyEvent(loader.onHidden, this.onHidden);
|
780 | this.loaders.push(loader);
|
781 | }
|
782 | removeLoaders(id) {
|
783 | if (id != null) {
|
784 | const indexToRemove = this.loaders.findIndex(loader => { var _a; return ((_a = loader.instance) === null || _a === void 0 ? void 0 : _a.config.id) === id; });
|
785 | if (indexToRemove >= 0) {
|
786 | this.loaders.splice(indexToRemove, 1);
|
787 | this.loaders.forEach((loader, i) => {
|
788 | if (loader.instance) {
|
789 | loader.instance.level = i + 1;
|
790 | }
|
791 | });
|
792 | }
|
793 | }
|
794 | else {
|
795 | this.loaders.splice(0, this.loaders.length);
|
796 | }
|
797 | }
|
798 | copyEvent(from, to) {
|
799 | from.subscribe((data) => {
|
800 | to.emit(this.lastDismissReason || data);
|
801 | });
|
802 | }
|
803 | }
|
804 | BsModalService.decorators = [
|
805 | { type: Injectable }
|
806 | ];
|
807 | BsModalService.ctorParameters = () => [
|
808 | { type: RendererFactory2 },
|
809 | { type: ComponentLoaderFactory },
|
810 | { type: ModalOptions, decorators: [{ type: Optional }, { type: Inject, args: [MODAL_CONFIG_DEFAULT_OVERRIDE,] }] }
|
811 | ];
|
812 |
|
813 | const focusTrapModule = FocusTrapModule.forRoot();
|
814 | class ModalModule {
|
815 | static forRoot() {
|
816 | return {
|
817 | ngModule: ModalModule,
|
818 | providers: [BsModalService, ComponentLoaderFactory, PositioningService]
|
819 | };
|
820 | }
|
821 | static forChild() {
|
822 | return {
|
823 | ngModule: ModalModule,
|
824 | providers: [BsModalService, ComponentLoaderFactory, PositioningService]
|
825 | };
|
826 | }
|
827 | }
|
828 | ModalModule.decorators = [
|
829 | { type: NgModule, args: [{
|
830 | imports: [FocusTrapModule],
|
831 | declarations: [
|
832 | ModalBackdropComponent,
|
833 | ModalDirective,
|
834 | ModalContainerComponent
|
835 | ],
|
836 | exports: [ModalBackdropComponent, ModalDirective],
|
837 | entryComponents: [ModalBackdropComponent, ModalContainerComponent]
|
838 | },] }
|
839 | ];
|
840 |
|
841 |
|
842 |
|
843 |
|
844 |
|
845 | export { BsModalRef, BsModalService, MODAL_CONFIG_DEFAULT_OVERRIDE, ModalBackdropComponent, ModalBackdropOptions, ModalContainerComponent, ModalDirective, ModalModule, ModalOptions, CLASS_NAME as ɵa };
|
846 |
|