ngx-bootstrap-fix-datepicker
Version:
Native Angular Bootstrap Components
1,381 lines (1,369 loc) • 38.5 kB
JavaScript
import { Injectable, Component, ElementRef, Renderer2, HostListener, EventEmitter, Directive, ViewContainerRef, Input, Output, RendererFactory2, NgModule } from '@angular/core';
import { isBs3, Utils, document as document$1, window as window$1 } from 'ngx-bootstrap/utils';
import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
import { PositioningService } from 'ngx-bootstrap/positioning';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class BsModalRef {
constructor() {
/**
* Hides the modal
*/
this.hide = Function;
/**
* Sets new class to modal window
*/
this.setClass = Function;
}
}
BsModalRef.decorators = [
{ type: Injectable }
];
if (false) {
/**
* Reference to a component inside the modal. Null if modal's been created with TemplateRef
* @type {?}
*/
BsModalRef.prototype.content;
/**
* Hides the modal
* @type {?}
*/
BsModalRef.prototype.hide;
/**
* Sets new class to modal window
* @type {?}
*/
BsModalRef.prototype.setClass;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ModalBackdropOptions {
/**
* @param {?} options
*/
constructor(options) {
this.animate = true;
Object.assign(this, options);
}
}
if (false) {
/** @type {?} */
ModalBackdropOptions.prototype.animate;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ModalOptions {
}
ModalOptions.decorators = [
{ type: Injectable }
];
if (false) {
/**
* Includes a modal-backdrop element. Alternatively,
* specify static for a backdrop which doesn't close the modal on click.
* @type {?}
*/
ModalOptions.prototype.backdrop;
/**
* Closes the modal when escape key is pressed.
* @type {?}
*/
ModalOptions.prototype.keyboard;
/** @type {?} */
ModalOptions.prototype.focus;
/**
* Shows the modal when initialized.
* @type {?}
*/
ModalOptions.prototype.show;
/**
* Ignore the backdrop click
* @type {?}
*/
ModalOptions.prototype.ignoreBackdropClick;
/**
* Css class for opened modal
* @type {?}
*/
ModalOptions.prototype.class;
/**
* Toggle animation
* @type {?}
*/
ModalOptions.prototype.animated;
/**
* Modal data
* @type {?}
*/
ModalOptions.prototype.initialState;
/**
* Modal providers
* @type {?}
*/
ModalOptions.prototype.providers;
/**
* aria-labelledby attribute value to set on the modal window
* @type {?}
*/
ModalOptions.prototype.ariaLabelledBy;
/**
* aria-describedby attribute value to set on the modal window
* @type {?}
*/
ModalOptions.prototype.ariaDescribedby;
}
/** @type {?} */
const modalConfigDefaults = {
backdrop: true,
keyboard: true,
focus: true,
show: false,
ignoreBackdropClick: false,
class: '',
animated: true,
initialState: {}
};
/** @type {?} */
const CLASS_NAME = {
SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
BACKDROP: 'modal-backdrop',
OPEN: 'modal-open',
FADE: 'fade',
IN: 'in',
// bs3
SHOW: 'show' // bs4
};
/** @type {?} */
const SELECTOR = {
DIALOG: '.modal-dialog',
DATA_TOGGLE: '[data-toggle="modal"]',
DATA_DISMISS: '[data-dismiss="modal"]',
FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
};
/** @type {?} */
const TRANSITION_DURATIONS = {
MODAL: 300,
BACKDROP: 150
};
/** @type {?} */
const DISMISS_REASONS = {
BACKRDOP: 'backdrop-click',
ESC: 'esc'
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ModalContainerComponent {
/**
* @param {?} options
* @param {?} _element
* @param {?} _renderer
*/
constructor(options, _element, _renderer) {
this._element = _element;
this._renderer = _renderer;
this.isShown = false;
this.isModalHiding = false;
this.clickStartedInContent = false;
this.config = Object.assign({}, options);
}
/**
* @return {?}
*/
ngOnInit() {
if (this.isAnimated) {
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.FADE);
}
this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
setTimeout((/**
* @return {?}
*/
() => {
this.isShown = true;
this._renderer.addClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
}), this.isAnimated ? TRANSITION_DURATIONS.BACKDROP : 0);
if (document && document.body) {
if (this.bsModalService.getModalsCount() === 1) {
this.bsModalService.checkScrollbar();
this.bsModalService.setScrollbar();
}
this._renderer.addClass(document.body, CLASS_NAME.OPEN);
}
if (this._element.nativeElement) {
this._element.nativeElement.focus();
}
}
/**
* @param {?} event
* @return {?}
*/
onClickStarted(event) {
this.clickStartedInContent = event.target !== this._element.nativeElement;
}
/**
* @param {?} event
* @return {?}
*/
onClickStop(event) {
/** @type {?} */
const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
if (this.config.ignoreBackdropClick ||
this.config.backdrop === 'static' ||
!clickedInBackdrop) {
this.clickStartedInContent = false;
return;
}
this.bsModalService.setDismissReason(DISMISS_REASONS.BACKRDOP);
this.hide();
}
/**
* @param {?} event
* @return {?}
*/
onEsc(event) {
if (!this.isShown) {
return;
}
// tslint:disable-next-line:deprecation
if (event.keyCode === 27 || event.key === 'Escape') {
event.preventDefault();
}
if (this.config.keyboard &&
this.level === this.bsModalService.getModalsCount()) {
this.bsModalService.setDismissReason(DISMISS_REASONS.ESC);
this.hide();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.isShown) {
this.hide();
}
}
/**
* @return {?}
*/
hide() {
if (this.isModalHiding || !this.isShown) {
return;
}
this.isModalHiding = true;
this._renderer.removeClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
setTimeout((/**
* @return {?}
*/
() => {
this.isShown = false;
if (document &&
document.body &&
this.bsModalService.getModalsCount() === 1) {
this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
}
this.bsModalService.hide(this.level);
this.isModalHiding = false;
}), this.isAnimated ? TRANSITION_DURATIONS.MODAL : 0);
}
}
ModalContainerComponent.decorators = [
{ type: Component, args: [{
selector: 'modal-container',
template: `
<div [class]="'modal-dialog' + (config.class ? ' ' + config.class : '')" role="document">
<div class="modal-content">
<ng-content></ng-content>
</div>
</div>
`,
host: {
class: 'modal',
role: 'dialog',
tabindex: '-1',
'[attr.aria-modal]': 'true',
'[attr.aria-labelledby]': 'config.ariaLabelledBy',
'[attr.aria-describedby]': 'config.ariaDescribedby'
}
}] }
];
/** @nocollapse */
ModalContainerComponent.ctorParameters = () => [
{ type: ModalOptions },
{ type: ElementRef },
{ type: Renderer2 }
];
ModalContainerComponent.propDecorators = {
onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
onClickStop: [{ type: HostListener, args: ['mouseup', ['$event'],] }],
onEsc: [{ type: HostListener, args: ['window:keydown.esc', ['$event'],] }]
};
if (false) {
/** @type {?} */
ModalContainerComponent.prototype.config;
/** @type {?} */
ModalContainerComponent.prototype.isShown;
/** @type {?} */
ModalContainerComponent.prototype.level;
/** @type {?} */
ModalContainerComponent.prototype.isAnimated;
/** @type {?} */
ModalContainerComponent.prototype.bsModalService;
/**
* @type {?}
* @private
*/
ModalContainerComponent.prototype.isModalHiding;
/**
* @type {?}
* @private
*/
ModalContainerComponent.prototype.clickStartedInContent;
/**
* @type {?}
* @protected
*/
ModalContainerComponent.prototype._element;
/**
* @type {?}
* @private
*/
ModalContainerComponent.prototype._renderer;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* This component will be added as background layout for modals if enabled
*/
class ModalBackdropComponent {
/**
* @param {?} element
* @param {?} renderer
*/
constructor(element, renderer) {
this._isShown = false;
this.element = element;
this.renderer = renderer;
}
/**
* @return {?}
*/
get isAnimated() {
return this._isAnimated;
}
/**
* @param {?} value
* @return {?}
*/
set isAnimated(value) {
this._isAnimated = value;
// this.renderer.setElementClass(this.element.nativeElement, `${ClassName.FADE}`, value);
}
/**
* @return {?}
*/
get isShown() {
return this._isShown;
}
/**
* @param {?} value
* @return {?}
*/
set isShown(value) {
this._isShown = value;
if (value) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
}
else {
this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
}
if (!isBs3()) {
if (value) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
}
else {
this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
}
}
}
/**
* @return {?}
*/
ngOnInit() {
if (this.isAnimated) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.FADE}`);
Utils.reflow(this.element.nativeElement);
}
this.isShown = true;
}
}
ModalBackdropComponent.decorators = [
{ type: Component, args: [{
selector: 'bs-modal-backdrop',
template: ' ',
host: { class: CLASS_NAME.BACKDROP }
}] }
];
/** @nocollapse */
ModalBackdropComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 }
];
if (false) {
/** @type {?} */
ModalBackdropComponent.prototype.element;
/** @type {?} */
ModalBackdropComponent.prototype.renderer;
/**
* @type {?}
* @protected
*/
ModalBackdropComponent.prototype._isAnimated;
/**
* @type {?}
* @protected
*/
ModalBackdropComponent.prototype._isShown;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const TRANSITION_DURATION = 300;
/** @type {?} */
const BACKDROP_TRANSITION_DURATION = 150;
/**
* Mark any code with directive to show it's content in modal
*/
class ModalDirective {
/**
* @param {?} _element
* @param {?} _viewContainerRef
* @param {?} _renderer
* @param {?} clf
*/
constructor(_element, _viewContainerRef, _renderer, clf) {
this._element = _element;
this._renderer = _renderer;
/**
* This event fires immediately when the `show` instance method is called.
*/
this.onShow = new EventEmitter();
/**
* This event is fired when the modal has been made visible to the user
* (will wait for CSS transitions to complete)
*/
this.onShown = new EventEmitter();
/**
* This event is fired immediately when
* the hide instance method has been called.
*/
this.onHide = new EventEmitter();
/**
* This event is fired when the modal has finished being
* hidden from the user (will wait for CSS transitions to complete).
*/
this.onHidden = new EventEmitter();
this._isShown = false;
this.isBodyOverflowing = false;
this.originalBodyPadding = 0;
this.scrollbarWidth = 0;
this.timerHideModal = 0;
this.timerRmBackDrop = 0;
this.isNested = false;
this.clickStartedInContent = false;
this._backdrop = clf.createLoader(_element, _viewContainerRef, _renderer);
}
/**
* allows to set modal configuration via element property
* @param {?} conf
* @return {?}
*/
set config(conf) {
this._config = this.getConfig(conf);
}
/**
* @return {?}
*/
get config() {
return this._config;
}
/**
* @return {?}
*/
get isShown() {
return this._isShown;
}
/**
* @param {?} event
* @return {?}
*/
onClickStarted(event) {
this.clickStartedInContent = event.target !== this._element.nativeElement;
}
/**
* @param {?} event
* @return {?}
*/
onClickStop(event) {
/** @type {?} */
const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
if (this.config.ignoreBackdropClick ||
this.config.backdrop === 'static' ||
!clickedInBackdrop) {
this.clickStartedInContent = false;
return;
}
this.dismissReason = DISMISS_REASONS.BACKRDOP;
this.hide(event);
}
// todo: consider preventing default and stopping propagation
/**
* @param {?} event
* @return {?}
*/
onEsc(event) {
if (!this._isShown) {
return;
}
// tslint:disable-next-line:deprecation
if (event.keyCode === 27 || event.key === 'Escape') {
event.preventDefault();
}
if (this.config.keyboard) {
this.dismissReason = DISMISS_REASONS.ESC;
this.hide();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this.config = void 0;
if (this._isShown) {
this._isShown = false;
this.hideModal();
this._backdrop.dispose();
}
}
/**
* @return {?}
*/
ngOnInit() {
this._config = this._config || this.getConfig();
setTimeout((/**
* @return {?}
*/
() => {
if (this._config.show) {
this.show();
}
}), 0);
}
/* Public methods */
/**
* Allows to manually toggle modal visibility
* @return {?}
*/
toggle() {
return this._isShown ? this.hide() : this.show();
}
/**
* Allows to manually open modal
* @return {?}
*/
show() {
this.dismissReason = null;
this.onShow.emit(this);
if (this._isShown) {
return;
}
clearTimeout(this.timerHideModal);
clearTimeout(this.timerRmBackDrop);
this._isShown = true;
this.checkScrollbar();
this.setScrollbar();
if (document$1 && document$1.body) {
if (document$1.body.classList.contains(CLASS_NAME.OPEN)) {
this.isNested = true;
}
else {
this._renderer.addClass(document$1.body, CLASS_NAME.OPEN);
}
}
this.showBackdrop((/**
* @return {?}
*/
() => {
this.showElement();
}));
}
/**
* Allows to manually close modal
* @param {?=} event
* @return {?}
*/
hide(event) {
if (event) {
event.preventDefault();
}
this.onHide.emit(this);
// todo: add an option to prevent hiding
if (!this._isShown) {
return;
}
window$1.clearTimeout(this.timerHideModal);
window$1.clearTimeout(this.timerRmBackDrop);
this._isShown = false;
this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.IN);
if (!isBs3()) {
this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.SHOW);
}
// this._addClassIn = false;
if (this._config.animated) {
this.timerHideModal = window$1.setTimeout((/**
* @return {?}
*/
() => this.hideModal()), TRANSITION_DURATION);
}
else {
this.hideModal();
}
}
/**
* Private methods \@internal
* @protected
* @param {?=} config
* @return {?}
*/
getConfig(config) {
return Object.assign({}, modalConfigDefaults, config);
}
/**
* Show dialog
* \@internal
* @protected
* @return {?}
*/
showElement() {
// todo: replace this with component loader usage
if (!this._element.nativeElement.parentNode ||
this._element.nativeElement.parentNode.nodeType !== Node.ELEMENT_NODE) {
// don't move modals dom position
if (document$1 && document$1.body) {
document$1.body.appendChild(this._element.nativeElement);
}
}
this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'false');
this._renderer.setAttribute(this._element.nativeElement, 'aria-modal', 'true');
this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
this._renderer.setProperty(this._element.nativeElement, 'scrollTop', 0);
if (this._config.animated) {
Utils.reflow(this._element.nativeElement);
}
// this._addClassIn = true;
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.IN);
if (!isBs3()) {
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.SHOW);
}
/** @type {?} */
const transitionComplete = (/**
* @return {?}
*/
() => {
if (this._config.focus) {
this._element.nativeElement.focus();
}
this.onShown.emit(this);
});
if (this._config.animated) {
setTimeout(transitionComplete, TRANSITION_DURATION);
}
else {
transitionComplete();
}
}
/**
* \@internal
* @protected
* @return {?}
*/
hideModal() {
this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'true');
this._renderer.setStyle(this._element.nativeElement, 'display', 'none');
this.showBackdrop((/**
* @return {?}
*/
() => {
if (!this.isNested) {
if (document$1 && document$1.body) {
this._renderer.removeClass(document$1.body, CLASS_NAME.OPEN);
}
this.resetScrollbar();
}
this.resetAdjustments();
this.focusOtherModal();
this.onHidden.emit(this);
}));
}
// todo: original show was calling a callback when done, but we can use
// promise
/**
* \@internal
* @protected
* @param {?=} callback
* @return {?}
*/
showBackdrop(callback) {
if (this._isShown &&
this.config.backdrop &&
(!this.backdrop || !this.backdrop.instance.isShown)) {
this.removeBackdrop();
this._backdrop
.attach(ModalBackdropComponent)
.to('body')
.show({ isAnimated: this._config.animated });
this.backdrop = this._backdrop._componentRef;
if (!callback) {
return;
}
if (!this._config.animated) {
callback();
return;
}
setTimeout(callback, BACKDROP_TRANSITION_DURATION);
}
else if (!this._isShown && this.backdrop) {
this.backdrop.instance.isShown = false;
/** @type {?} */
const callbackRemove = (/**
* @return {?}
*/
() => {
this.removeBackdrop();
if (callback) {
callback();
}
});
if (this.backdrop.instance.isAnimated) {
this.timerRmBackDrop = window$1.setTimeout(callbackRemove, BACKDROP_TRANSITION_DURATION);
}
else {
callbackRemove();
}
}
else if (callback) {
callback();
}
}
/**
* \@internal
* @protected
* @return {?}
*/
removeBackdrop() {
this._backdrop.hide();
}
/**
* Events tricks
* @protected
* @return {?}
*/
// no need for it
// protected setEscapeEvent():void {
// if (this._isShown && this._config.keyboard) {
// $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
// if (event.which === 27) {
// this.hide()
// }
// })
//
// } else if (!this._isShown) {
// $(this._element).off(Event.KEYDOWN_DISMISS)
// }
// }
// protected setResizeEvent():void {
// console.log(this.renderer.listenGlobal('', Event.RESIZE));
// if (this._isShown) {
// $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
// } else {
// $(window).off(Event.RESIZE)
// }
// }
focusOtherModal() {
if (this._element.nativeElement.parentElement == null) {
return;
}
/** @type {?} */
const otherOpenedModals = this._element.nativeElement.parentElement.querySelectorAll('.in[bsModal]');
if (!otherOpenedModals.length) {
return;
}
otherOpenedModals[otherOpenedModals.length - 1].focus();
}
/**
* \@internal
* @protected
* @return {?}
*/
resetAdjustments() {
this._renderer.setStyle(this._element.nativeElement, 'paddingLeft', '');
this._renderer.setStyle(this._element.nativeElement, 'paddingRight', '');
}
/** Scroll bar tricks */
/**
* \@internal
* @protected
* @return {?}
*/
checkScrollbar() {
this.isBodyOverflowing = document$1.body.clientWidth < window$1.innerWidth;
this.scrollbarWidth = this.getScrollbarWidth();
}
/**
* @protected
* @return {?}
*/
setScrollbar() {
if (!document$1) {
return;
}
this.originalBodyPadding = parseInt(window$1
.getComputedStyle(document$1.body)
.getPropertyValue('padding-right') || 0, 10);
if (this.isBodyOverflowing) {
document$1.body.style.paddingRight = `${this.originalBodyPadding +
this.scrollbarWidth}px`;
}
}
/**
* @protected
* @return {?}
*/
resetScrollbar() {
document$1.body.style.paddingRight = `${this.originalBodyPadding}px`;
}
// thx d.walsh
/**
* @protected
* @return {?}
*/
getScrollbarWidth() {
/** @type {?} */
const scrollDiv = this._renderer.createElement('div');
this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
this._renderer.appendChild(document$1.body, scrollDiv);
/** @type {?} */
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
this._renderer.removeChild(document$1.body, scrollDiv);
return scrollbarWidth;
}
}
ModalDirective.decorators = [
{ type: Directive, args: [{
selector: '[bsModal]',
exportAs: 'bs-modal'
},] }
];
/** @nocollapse */
ModalDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ViewContainerRef },
{ type: Renderer2 },
{ type: ComponentLoaderFactory }
];
ModalDirective.propDecorators = {
config: [{ type: Input }],
onShow: [{ type: Output }],
onShown: [{ type: Output }],
onHide: [{ type: Output }],
onHidden: [{ type: Output }],
onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
onClickStop: [{ type: HostListener, args: ['mouseup', ['$event'],] }],
onEsc: [{ type: HostListener, args: ['keydown.esc', ['$event'],] }]
};
if (false) {
/**
* This event fires immediately when the `show` instance method is called.
* @type {?}
*/
ModalDirective.prototype.onShow;
/**
* This event is fired when the modal has been made visible to the user
* (will wait for CSS transitions to complete)
* @type {?}
*/
ModalDirective.prototype.onShown;
/**
* This event is fired immediately when
* the hide instance method has been called.
* @type {?}
*/
ModalDirective.prototype.onHide;
/**
* This event is fired when the modal has finished being
* hidden from the user (will wait for CSS transitions to complete).
* @type {?}
*/
ModalDirective.prototype.onHidden;
/**
* This field contains last dismiss reason.
* Possible values: `backdrop-click`, `esc` and `null`
* (if modal was closed by direct call of `.hide()`).
* @type {?}
*/
ModalDirective.prototype.dismissReason;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype._config;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype._isShown;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.isBodyOverflowing;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.originalBodyPadding;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.scrollbarWidth;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.timerHideModal;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.timerRmBackDrop;
/**
* @type {?}
* @protected
*/
ModalDirective.prototype.backdrop;
/**
* @type {?}
* @private
*/
ModalDirective.prototype._backdrop;
/**
* @type {?}
* @private
*/
ModalDirective.prototype.isNested;
/**
* @type {?}
* @private
*/
ModalDirective.prototype.clickStartedInContent;
/**
* @type {?}
* @private
*/
ModalDirective.prototype._element;
/**
* @type {?}
* @private
*/
ModalDirective.prototype._renderer;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class BsModalService {
/**
* @param {?} rendererFactory
* @param {?} clf
*/
constructor(rendererFactory, clf) {
this.clf = clf;
// constructor props
this.config = modalConfigDefaults;
// tslint:disable-next-line:no-any
this.onShow = new EventEmitter();
// tslint:disable-next-line:no-any
this.onShown = new EventEmitter();
// tslint:disable-next-line:no-any
this.onHide = new EventEmitter();
// tslint:disable-next-line:no-any
this.onHidden = new EventEmitter();
this.isBodyOverflowing = false;
this.originalBodyPadding = 0;
this.scrollbarWidth = 0;
this.modalsCount = 0;
this.lastDismissReason = '';
this.loaders = [];
this._backdropLoader = this.clf.createLoader(null, null, null);
this._renderer = rendererFactory.createRenderer(null, null);
}
/**
* Shows a modal
* @param {?} content
* @param {?=} config
* @return {?}
*/
// tslint:disable-next-line:no-any
show(content, config) {
this.modalsCount++;
this._createLoaders();
this.config = Object.assign({}, modalConfigDefaults, config);
this._showBackdrop();
this.lastDismissReason = null;
return this._showModal(content);
}
/**
* @param {?} level
* @return {?}
*/
hide(level) {
if (this.modalsCount === 1) {
this._hideBackdrop();
this.resetScrollbar();
}
this.modalsCount = this.modalsCount >= 1 ? this.modalsCount - 1 : 0;
setTimeout((/**
* @return {?}
*/
() => {
this._hideModal(level);
this.removeLoaders(level);
}), this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0);
}
/**
* @return {?}
*/
_showBackdrop() {
/** @type {?} */
const isBackdropEnabled = this.config.backdrop || this.config.backdrop === 'static';
/** @type {?} */
const isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
if (this.modalsCount === 1) {
this.removeBackdrop();
if (isBackdropEnabled && isBackdropInDOM) {
this._backdropLoader
.attach(ModalBackdropComponent)
.to('body')
.show({ isAnimated: this.config.animated });
this.backdropRef = this._backdropLoader._componentRef;
}
}
}
/**
* @return {?}
*/
_hideBackdrop() {
if (!this.backdropRef) {
return;
}
this.backdropRef.instance.isShown = false;
/** @type {?} */
const duration = this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0;
setTimeout((/**
* @return {?}
*/
() => this.removeBackdrop()), duration);
}
// tslint:disable-next-line:no-any
/**
* @param {?} content
* @return {?}
*/
_showModal(content) {
/** @type {?} */
const modalLoader = this.loaders[this.loaders.length - 1];
if (this.config && this.config.providers) {
for (const provider of this.config.providers) {
modalLoader.provide(provider);
}
}
/** @type {?} */
const bsModalRef = new BsModalRef();
/** @type {?} */
const modalContainerRef = modalLoader
.provide({ provide: ModalOptions, useValue: this.config })
.provide({ provide: BsModalRef, useValue: bsModalRef })
.attach(ModalContainerComponent)
.to('body')
.show({ content, isAnimated: this.config.animated, initialState: this.config.initialState, bsModalService: this });
modalContainerRef.instance.level = this.getModalsCount();
bsModalRef.hide = (/**
* @return {?}
*/
() => {
/** @type {?} */
const duration = this.config.animated ? TRANSITION_DURATIONS.MODAL : 0;
setTimeout((/**
* @return {?}
*/
() => modalContainerRef.instance.hide()), duration);
});
bsModalRef.content = modalLoader.getInnerComponent() || null;
bsModalRef.setClass = (/**
* @param {?} newClass
* @return {?}
*/
(newClass) => {
modalContainerRef.instance.config.class = newClass;
});
return bsModalRef;
}
/**
* @param {?} level
* @return {?}
*/
_hideModal(level) {
/** @type {?} */
const modalLoader = this.loaders[level - 1];
if (modalLoader) {
modalLoader.hide();
}
}
/**
* @return {?}
*/
getModalsCount() {
return this.modalsCount;
}
/**
* @param {?} reason
* @return {?}
*/
setDismissReason(reason) {
this.lastDismissReason = reason;
}
/**
* @return {?}
*/
removeBackdrop() {
this._backdropLoader.hide();
this.backdropRef = null;
}
/** Checks if the body is overflowing and sets scrollbar width */
/**
* \@internal
* @return {?}
*/
checkScrollbar() {
this.isBodyOverflowing = document.body.clientWidth < window.innerWidth;
this.scrollbarWidth = this.getScrollbarWidth();
}
/**
* @return {?}
*/
setScrollbar() {
if (!document) {
return;
}
this.originalBodyPadding = parseInt(window
.getComputedStyle(document.body)
.getPropertyValue('padding-right') || '0', 10);
if (this.isBodyOverflowing) {
document.body.style.paddingRight = `${this.originalBodyPadding +
this.scrollbarWidth}px`;
}
}
/**
* @private
* @return {?}
*/
resetScrollbar() {
document.body.style.paddingRight = `${this.originalBodyPadding}px`;
}
// thx d.walsh
/**
* @private
* @return {?}
*/
getScrollbarWidth() {
/** @type {?} */
const scrollDiv = this._renderer.createElement('div');
this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
this._renderer.appendChild(document.body, scrollDiv);
/** @type {?} */
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
this._renderer.removeChild(document.body, scrollDiv);
return scrollbarWidth;
}
/**
* @private
* @return {?}
*/
_createLoaders() {
/** @type {?} */
const loader = this.clf.createLoader(null, null, null);
this.copyEvent(loader.onBeforeShow, this.onShow);
this.copyEvent(loader.onShown, this.onShown);
this.copyEvent(loader.onBeforeHide, this.onHide);
this.copyEvent(loader.onHidden, this.onHidden);
this.loaders.push(loader);
}
/**
* @private
* @param {?} level
* @return {?}
*/
removeLoaders(level) {
this.loaders.splice(level - 1, 1);
this.loaders.forEach((/**
* @param {?} loader
* @param {?} i
* @return {?}
*/
(loader, i) => {
loader.instance.level = i + 1;
}));
}
// tslint:disable-next-line:no-any
/**
* @private
* @param {?} from
* @param {?} to
* @return {?}
*/
copyEvent(from, to) {
from.subscribe((/**
* @return {?}
*/
() => {
to.emit(this.lastDismissReason);
}));
}
}
BsModalService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
BsModalService.ctorParameters = () => [
{ type: RendererFactory2 },
{ type: ComponentLoaderFactory }
];
if (false) {
/** @type {?} */
BsModalService.prototype.config;
/** @type {?} */
BsModalService.prototype.onShow;
/** @type {?} */
BsModalService.prototype.onShown;
/** @type {?} */
BsModalService.prototype.onHide;
/** @type {?} */
BsModalService.prototype.onHidden;
/**
* @type {?}
* @protected
*/
BsModalService.prototype.isBodyOverflowing;
/**
* @type {?}
* @protected
*/
BsModalService.prototype.originalBodyPadding;
/**
* @type {?}
* @protected
*/
BsModalService.prototype.scrollbarWidth;
/**
* @type {?}
* @protected
*/
BsModalService.prototype.backdropRef;
/**
* @type {?}
* @private
*/
BsModalService.prototype._backdropLoader;
/**
* @type {?}
* @private
*/
BsModalService.prototype.modalsCount;
/**
* @type {?}
* @private
*/
BsModalService.prototype.lastDismissReason;
/**
* @type {?}
* @private
*/
BsModalService.prototype.loaders;
/**
* @type {?}
* @private
*/
BsModalService.prototype._renderer;
/**
* @type {?}
* @private
*/
BsModalService.prototype.clf;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ModalModule {
/**
* @return {?}
*/
static forRoot() {
return {
ngModule: ModalModule,
providers: [BsModalService, ComponentLoaderFactory, PositioningService]
};
}
/**
* @return {?}
*/
static forChild() {
return {
ngModule: ModalModule,
providers: [BsModalService, ComponentLoaderFactory, PositioningService]
};
}
}
ModalModule.decorators = [
{ type: NgModule, args: [{
declarations: [
ModalBackdropComponent,
ModalDirective,
ModalContainerComponent
],
exports: [ModalBackdropComponent, ModalDirective],
entryComponents: [ModalBackdropComponent, ModalContainerComponent]
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { BsModalRef, BsModalService, ModalBackdropComponent, ModalBackdropOptions, ModalContainerComponent, ModalDirective, ModalModule, ModalOptions, CLASS_NAME as ɵa };
//# sourceMappingURL=ngx-bootstrap-modal.js.map