(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('mt-ngx-bootstrap/utils'), require('mt-ngx-bootstrap/positioning')) :
    typeof define === 'function' && define.amd ? define('ngx-bootstrap/component-loader', ['exports', '@angular/core', 'mt-ngx-bootstrap/utils', 'mt-ngx-bootstrap/positioning'], factory) :
    (global = global || self, factory((global['ngx-bootstrap'] = global['ngx-bootstrap'] || {}, global['ngx-bootstrap']['component-loader'] = {}), global.ng.core, global.utils, global.positioning));
}(this, (function (exports, core, utils, positioning) { 'use strict';

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @template T
     */
    var   /**
     * @template T
     */
    BsComponentRef = /** @class */ (function () {
        function BsComponentRef() {
        }
        return BsComponentRef;
    }());
    if (false) {
        /** @type {?} */
        BsComponentRef.prototype.templateRef;
        /** @type {?} */
        BsComponentRef.prototype.viewContainer;
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @copyright Valor Software
     * @copyright Angular ng-bootstrap team
     */
    var ContentRef = /** @class */ (function () {
        function ContentRef(
        /* tslint:disable-next-line: no-any */
        nodes, viewRef, 
        /* tslint:disable-next-line: no-any */
        componentRef) {
            this.nodes = nodes;
            this.viewRef = viewRef;
            this.componentRef = componentRef;
        }
        return ContentRef;
    }());
    if (false) {
        /** @type {?} */
        ContentRef.prototype.nodes;
        /** @type {?} */
        ContentRef.prototype.viewRef;
        /** @type {?} */
        ContentRef.prototype.componentRef;
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @template T
     */
    var   /**
     * @template T
     */
    ComponentLoader = /** @class */ (function () {
        /**
         * Do not use this directly, it should be instanced via
         * `ComponentLoadFactory.attach`
         * @internal
         */
        // tslint:disable-next-line
        function ComponentLoader(_viewContainerRef, _renderer, _elementRef, _injector, _componentFactoryResolver, _ngZone, _applicationRef, _posService) {
            this._viewContainerRef = _viewContainerRef;
            this._renderer = _renderer;
            this._elementRef = _elementRef;
            this._injector = _injector;
            this._componentFactoryResolver = _componentFactoryResolver;
            this._ngZone = _ngZone;
            this._applicationRef = _applicationRef;
            this._posService = _posService;
            this.onBeforeShow = new core.EventEmitter();
            /* tslint:disable-next-line: no-any*/
            this.onShown = new core.EventEmitter();
            /* tslint:disable-next-line: no-any*/
            this.onBeforeHide = new core.EventEmitter();
            this.onHidden = new core.EventEmitter();
            this._providers = [];
            this._isHiding = false;
            /**
             * A selector used if container element was not found
             */
            this.containerDefaultSelector = 'body';
            this._listenOpts = {};
            this._globalListener = Function.prototype;
        }
        Object.defineProperty(ComponentLoader.prototype, "isShown", {
            get: /**
             * @return {?}
             */
            function () {
                if (this._isHiding) {
                    return false;
                }
                return !!this._componentRef;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @param {?} compType
         * @return {?}
         */
        ComponentLoader.prototype.attach = /**
         * @param {?} compType
         * @return {?}
         */
        function (compType) {
            this._componentFactory = this._componentFactoryResolver
                .resolveComponentFactory(compType);
            return this;
        };
        // todo: add behaviour: to target element, `body`, custom element
        // todo: add behaviour: to target element, `body`, custom element
        /**
         * @param {?=} container
         * @return {?}
         */
        ComponentLoader.prototype.to = 
        // todo: add behaviour: to target element, `body`, custom element
        /**
         * @param {?=} container
         * @return {?}
         */
        function (container) {
            this.container = container || this.container;
            return this;
        };
        /**
         * @param {?=} opts
         * @return {?}
         */
        ComponentLoader.prototype.position = /**
         * @param {?=} opts
         * @return {?}
         */
        function (opts) {
            this.attachment = opts.attachment || this.attachment;
            /* tslint:disable-next-line: no-unnecessary-type-assertion */
            this._elementRef = ((/** @type {?} */ (opts.target))) || this._elementRef;
            return this;
        };
        /**
         * @param {?} provider
         * @return {?}
         */
        ComponentLoader.prototype.provide = /**
         * @param {?} provider
         * @return {?}
         */
        function (provider) {
            this._providers.push(provider);
            return this;
        };
        // todo: appendChild to element or document.querySelector(this.container)
        // todo: appendChild to element or document.querySelector(this.container)
        /**
         * @param {?=} opts
         * @return {?}
         */
        ComponentLoader.prototype.show = 
        // todo: appendChild to element or document.querySelector(this.container)
        /**
         * @param {?=} opts
         * @return {?}
         */
        function (opts) {
            if (opts === void 0) { opts = {}; }
            this._subscribePositioning();
            this._innerComponent = null;
            if (!this._componentRef) {
                this.onBeforeShow.emit();
                this._contentRef = this._getContentRef(opts.content, opts.context, opts.initialState);
                /** @type {?} */
                var injector = core.Injector.create({
                    providers: this._providers,
                    parent: this._injector
                });
                this._componentRef = this._componentFactory.create(injector, this._contentRef.nodes);
                this._applicationRef.attachView(this._componentRef.hostView);
                // this._componentRef = this._viewContainerRef
                //   .createComponent(this._componentFactory, 0, injector, this._contentRef.nodes);
                this.instance = this._componentRef.instance;
                Object.assign(this._componentRef.instance, opts);
                if (this.container instanceof core.ElementRef) {
                    this.container.nativeElement.appendChild(this._componentRef.location.nativeElement);
                }
                if (typeof this.container === 'string' && typeof document !== 'undefined') {
                    /** @type {?} */
                    var selectedElement = document.querySelector(this.container) ||
                        document.querySelector(this.containerDefaultSelector);
                    selectedElement.appendChild(this._componentRef.location.nativeElement);
                }
                if (!this.container &&
                    this._elementRef &&
                    this._elementRef.nativeElement.parentElement) {
                    this._elementRef.nativeElement.parentElement.appendChild(this._componentRef.location.nativeElement);
                }
                // we need to manually invoke change detection since events registered
                // via
                // Renderer::listen() are not picked up by change detection with the
                // OnPush strategy
                if (this._contentRef.componentRef) {
                    this._innerComponent = this._contentRef.componentRef.instance;
                    this._contentRef.componentRef.changeDetectorRef.markForCheck();
                    this._contentRef.componentRef.changeDetectorRef.detectChanges();
                }
                this._componentRef.changeDetectorRef.markForCheck();
                this._componentRef.changeDetectorRef.detectChanges();
                this.onShown.emit(this._componentRef.instance);
            }
            this._registerOutsideClick();
            return this._componentRef;
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype.hide = /**
         * @return {?}
         */
        function () {
            if (!this._componentRef) {
                return this;
            }
            this._posService.deletePositionElement(this._componentRef.location);
            this.onBeforeHide.emit(this._componentRef.instance);
            /** @type {?} */
            var componentEl = this._componentRef.location.nativeElement;
            componentEl.parentNode.removeChild(componentEl);
            if (this._contentRef.componentRef) {
                this._contentRef.componentRef.destroy();
            }
            this._componentRef.destroy();
            if (this._viewContainerRef && this._contentRef.viewRef) {
                this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._contentRef.viewRef));
            }
            if (this._contentRef.viewRef) {
                this._contentRef.viewRef.destroy();
            }
            this._contentRef = null;
            this._componentRef = null;
            this._removeGlobalListener();
            this.onHidden.emit();
            return this;
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype.toggle = /**
         * @return {?}
         */
        function () {
            if (this.isShown) {
                this.hide();
                return;
            }
            this.show();
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype.dispose = /**
         * @return {?}
         */
        function () {
            if (this.isShown) {
                this.hide();
            }
            this._unsubscribePositioning();
            if (this._unregisterListenersFn) {
                this._unregisterListenersFn();
            }
        };
        /**
         * @param {?} listenOpts
         * @return {?}
         */
        ComponentLoader.prototype.listen = /**
         * @param {?} listenOpts
         * @return {?}
         */
        function (listenOpts) {
            var _this = this;
            this.triggers = listenOpts.triggers || this.triggers;
            this._listenOpts.outsideClick = listenOpts.outsideClick;
            this._listenOpts.outsideEsc = listenOpts.outsideEsc;
            listenOpts.target = listenOpts.target || this._elementRef.nativeElement;
            /** @type {?} */
            var hide = (this._listenOpts.hide = (/**
             * @return {?}
             */
            function () {
                return listenOpts.hide ? listenOpts.hide() : void _this.hide();
            }));
            /** @type {?} */
            var show = (this._listenOpts.show = (/**
             * @param {?} registerHide
             * @return {?}
             */
            function (registerHide) {
                listenOpts.show ? listenOpts.show(registerHide) : _this.show(registerHide);
                registerHide();
            }));
            /** @type {?} */
            var toggle = (/**
             * @param {?} registerHide
             * @return {?}
             */
            function (registerHide) {
                _this.isShown ? hide() : show(registerHide);
            });
            this._unregisterListenersFn = utils.listenToTriggersV2(this._renderer, {
                target: listenOpts.target,
                triggers: listenOpts.triggers,
                show: show,
                hide: hide,
                toggle: toggle
            });
            return this;
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype._removeGlobalListener = /**
         * @return {?}
         */
        function () {
            if (this._globalListener) {
                this._globalListener();
                this._globalListener = null;
            }
        };
        /**
         * @param {?} vRef
         * @param {?} template
         * @return {?}
         */
        ComponentLoader.prototype.attachInline = /**
         * @param {?} vRef
         * @param {?} template
         * @return {?}
         */
        function (vRef, 
        /* tslint:disable-next-line: no-any*/
        template) {
            this._inlineViewRef = vRef.createEmbeddedView(template);
            return this;
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype._registerOutsideClick = /**
         * @return {?}
         */
        function () {
            var _this = this;
            if (!this._componentRef || !this._componentRef.location) {
                return;
            }
            // why: should run after first event bubble
            if (this._listenOpts.outsideClick) {
                /** @type {?} */
                var target_1 = this._componentRef.location.nativeElement;
                setTimeout((/**
                 * @return {?}
                 */
                function () {
                    _this._globalListener = utils.registerOutsideClick(_this._renderer, {
                        targets: [target_1, _this._elementRef.nativeElement],
                        outsideClick: _this._listenOpts.outsideClick,
                        hide: (/**
                         * @return {?}
                         */
                        function () { return _this._listenOpts.hide(); })
                    });
                }));
            }
            if (this._listenOpts.outsideEsc) {
                /** @type {?} */
                var target = this._componentRef.location.nativeElement;
                this._globalListener = utils.registerEscClick(this._renderer, {
                    targets: [target, this._elementRef.nativeElement],
                    outsideEsc: this._listenOpts.outsideEsc,
                    hide: (/**
                     * @return {?}
                     */
                    function () { return _this._listenOpts.hide(); })
                });
            }
        };
        /**
         * @return {?}
         */
        ComponentLoader.prototype.getInnerComponent = /**
         * @return {?}
         */
        function () {
            return this._innerComponent;
        };
        /**
         * @private
         * @return {?}
         */
        ComponentLoader.prototype._subscribePositioning = /**
         * @private
         * @return {?}
         */
        function () {
            var _this = this;
            if (this._zoneSubscription || !this.attachment) {
                return;
            }
            this.onShown.subscribe((/**
             * @return {?}
             */
            function () {
                _this._posService.position({
                    element: _this._componentRef.location,
                    target: _this._elementRef,
                    attachment: _this.attachment,
                    appendToBody: _this.container === 'body'
                });
            }));
            this._zoneSubscription = this._ngZone.onStable.subscribe((/**
             * @return {?}
             */
            function () {
                if (!_this._componentRef) {
                    return;
                }
                _this._posService.calcPosition();
            }));
        };
        /**
         * @private
         * @return {?}
         */
        ComponentLoader.prototype._unsubscribePositioning = /**
         * @private
         * @return {?}
         */
        function () {
            if (!this._zoneSubscription) {
                return;
            }
            this._zoneSubscription.unsubscribe();
            this._zoneSubscription = null;
        };
        /**
         * @private
         * @param {?} content
         * @param {?=} context
         * @param {?=} initialState
         * @return {?}
         */
        ComponentLoader.prototype._getContentRef = /**
         * @private
         * @param {?} content
         * @param {?=} context
         * @param {?=} initialState
         * @return {?}
         */
        function (
        /* tslint:disable-next-line: no-any*/
        content, 
        /* tslint:disable-next-line: no-any*/
        context, 
        /* tslint:disable-next-line: no-any*/
        initialState) {
            if (!content) {
                return new ContentRef([]);
            }
            if (content instanceof core.TemplateRef) {
                if (this._viewContainerRef) {
                    /** @type {?} */
                    var _viewRef = this._viewContainerRef
                        .createEmbeddedView(content, context);
                    _viewRef.markForCheck();
                    return new ContentRef([_viewRef.rootNodes], _viewRef);
                }
                /** @type {?} */
                var viewRef = content.createEmbeddedView({});
                this._applicationRef.attachView(viewRef);
                return new ContentRef([viewRef.rootNodes], viewRef);
            }
            if (typeof content === 'function') {
                /** @type {?} */
                var contentCmptFactory = this._componentFactoryResolver.resolveComponentFactory(content);
                /** @type {?} */
                var modalContentInjector = core.Injector.create({
                    providers: this._providers,
                    parent: this._injector
                });
                /** @type {?} */
                var componentRef = contentCmptFactory.create(modalContentInjector);
                Object.assign(componentRef.instance, initialState);
                this._applicationRef.attachView(componentRef.hostView);
                return new ContentRef([[componentRef.location.nativeElement]], componentRef.hostView, componentRef);
            }
            return new ContentRef([[this._renderer.createText("" + content)]]);
        };
        return ComponentLoader;
    }());
    if (false) {
        /** @type {?} */
        ComponentLoader.prototype.onBeforeShow;
        /** @type {?} */
        ComponentLoader.prototype.onShown;
        /** @type {?} */
        ComponentLoader.prototype.onBeforeHide;
        /** @type {?} */
        ComponentLoader.prototype.onHidden;
        /** @type {?} */
        ComponentLoader.prototype.instance;
        /** @type {?} */
        ComponentLoader.prototype._componentRef;
        /** @type {?} */
        ComponentLoader.prototype._inlineViewRef;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._providers;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._componentFactory;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._zoneSubscription;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._contentRef;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._innerComponent;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._unregisterListenersFn;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._isHiding;
        /**
         * Placement of a component. Accepts: "top", "bottom", "left", "right"
         * @type {?}
         * @private
         */
        ComponentLoader.prototype.attachment;
        /**
         * A selector specifying the element the popover should be appended to.
         * @type {?}
         * @private
         */
        ComponentLoader.prototype.container;
        /**
         * A selector used if container element was not found
         * @type {?}
         * @private
         */
        ComponentLoader.prototype.containerDefaultSelector;
        /**
         * Specifies events that should trigger. Supports a space separated list of
         * event names.
         * @type {?}
         * @private
         */
        ComponentLoader.prototype.triggers;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._listenOpts;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._globalListener;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._viewContainerRef;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._renderer;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._elementRef;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._injector;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._componentFactoryResolver;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._ngZone;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._applicationRef;
        /**
         * @type {?}
         * @private
         */
        ComponentLoader.prototype._posService;
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var ComponentLoaderFactory = /** @class */ (function () {
        function ComponentLoaderFactory(_componentFactoryResolver, _ngZone, _injector, _posService, _applicationRef) {
            this._componentFactoryResolver = _componentFactoryResolver;
            this._ngZone = _ngZone;
            this._injector = _injector;
            this._posService = _posService;
            this._applicationRef = _applicationRef;
        }
        /**
         *
         * @param _elementRef
         * @param _viewContainerRef
         * @param _renderer
         */
        /**
         *
         * @template T
         * @param {?} _elementRef
         * @param {?} _viewContainerRef
         * @param {?} _renderer
         * @return {?}
         */
        ComponentLoaderFactory.prototype.createLoader = /**
         *
         * @template T
         * @param {?} _elementRef
         * @param {?} _viewContainerRef
         * @param {?} _renderer
         * @return {?}
         */
        function (_elementRef, _viewContainerRef, _renderer) {
            return new ComponentLoader(_viewContainerRef, _renderer, _elementRef, this._injector, this._componentFactoryResolver, this._ngZone, this._applicationRef, this._posService);
        };
        ComponentLoaderFactory.decorators = [
            { type: core.Injectable }
        ];
        /** @nocollapse */
        ComponentLoaderFactory.ctorParameters = function () { return [
            { type: core.ComponentFactoryResolver },
            { type: core.NgZone },
            { type: core.Injector },
            { type: positioning.PositioningService },
            { type: core.ApplicationRef }
        ]; };
        return ComponentLoaderFactory;
    }());
    if (false) {
        /**
         * @type {?}
         * @private
         */
        ComponentLoaderFactory.prototype._componentFactoryResolver;
        /**
         * @type {?}
         * @private
         */
        ComponentLoaderFactory.prototype._ngZone;
        /**
         * @type {?}
         * @private
         */
        ComponentLoaderFactory.prototype._injector;
        /**
         * @type {?}
         * @private
         */
        ComponentLoaderFactory.prototype._posService;
        /**
         * @type {?}
         * @private
         */
        ComponentLoaderFactory.prototype._applicationRef;
    }

    exports.BsComponentRef = BsComponentRef;
    exports.ComponentLoader = ComponentLoader;
    exports.ComponentLoaderFactory = ComponentLoaderFactory;
    exports.ContentRef = ContentRef;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=ngx-bootstrap-component-loader.umd.js.map
