|
|
|
@ -5,7 +5,7 @@ |
|
|
|
* Copyright (c) Sebastian Stehle. All rights reserved |
|
|
|
*/ |
|
|
|
|
|
|
|
import { Directive, EmbeddedViewRef, Input, OnChanges, OnDestroy, OnInit, Renderer, TemplateRef, ViewContainerRef } from '@angular/core'; |
|
|
|
import { Directive, EmbeddedViewRef, Input, OnChanges, OnDestroy, Renderer, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core'; |
|
|
|
import { Subscription } from 'rxjs'; |
|
|
|
|
|
|
|
import { ModalView } from './../utils/modal-view'; |
|
|
|
@ -15,9 +15,8 @@ import { RootViewService } from './../services/root-view.service'; |
|
|
|
@Directive({ |
|
|
|
selector: '[sqxModalView]' |
|
|
|
}) |
|
|
|
export class ModalViewDirective implements OnChanges, OnInit, OnDestroy { |
|
|
|
export class ModalViewDirective implements OnChanges, OnDestroy { |
|
|
|
private subscription: Subscription | null; |
|
|
|
private isEnabled = true; |
|
|
|
private clickHandler: Function | null; |
|
|
|
private renderedView: EmbeddedViewRef<any> | null = null; |
|
|
|
|
|
|
|
@ -35,39 +34,15 @@ export class ModalViewDirective implements OnChanges, OnInit, OnDestroy { |
|
|
|
) { |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnInit() { |
|
|
|
this.clickHandler = |
|
|
|
this.renderer.listenGlobal('document', 'click', (event: MouseEvent) => { |
|
|
|
if (!event.target || this.renderedView === null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (this.renderedView.rootNodes.length === 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (this.isEnabled) { |
|
|
|
if (this.modalView.closeAlways) { |
|
|
|
this.modalView.hide(); |
|
|
|
} else { |
|
|
|
const clickedInside = this.renderedView.rootNodes[0].contains(event.target); |
|
|
|
|
|
|
|
if (!clickedInside && this.modalView) { |
|
|
|
this.modalView.hide(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
public ngOnDestroy() { |
|
|
|
this.stopListening(); |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnDestroy() { |
|
|
|
if (this.clickHandler) { |
|
|
|
this.clickHandler(); |
|
|
|
this.clickHandler = null; |
|
|
|
public ngOnChanges(changes: SimpleChanges) { |
|
|
|
if (!changes['modalView']) { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnChanges() { |
|
|
|
if (this.subscription) { |
|
|
|
this.subscription.unsubscribe(); |
|
|
|
this.subscription = null; |
|
|
|
@ -75,19 +50,22 @@ export class ModalViewDirective implements OnChanges, OnInit, OnDestroy { |
|
|
|
|
|
|
|
if (this.modalView) { |
|
|
|
this.subscription = this.modalView.isOpen.subscribe(isOpen => { |
|
|
|
if (this.isEnabled) { |
|
|
|
if (isOpen === (this.renderedView !== null)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (isOpen) { |
|
|
|
if (isOpen && !this.renderedView) { |
|
|
|
if (this.placeOnRoot) { |
|
|
|
this.renderedView = this.rootContainer.createEmbeddedView(this.templateRef); |
|
|
|
} else { |
|
|
|
this.renderedView = this.viewContainer.createEmbeddedView(this.templateRef); |
|
|
|
} |
|
|
|
this.renderer.setElementStyle(this.renderedView.rootNodes[0], 'display', 'block'); |
|
|
|
} else { |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
this.startListening(); |
|
|
|
}); |
|
|
|
} else if (!isOpen && this.renderedView) { |
|
|
|
this.renderedView = null; |
|
|
|
|
|
|
|
if (this.placeOnRoot) { |
|
|
|
@ -95,19 +73,45 @@ export class ModalViewDirective implements OnChanges, OnInit, OnDestroy { |
|
|
|
} else { |
|
|
|
this.viewContainer.clear(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.updateEnabled(); |
|
|
|
} |
|
|
|
this.stopListening(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private updateEnabled() { |
|
|
|
this.isEnabled = false; |
|
|
|
private startListening() { |
|
|
|
this.clickHandler = |
|
|
|
this.renderer.listenGlobal('document', 'click', (event: MouseEvent) => { |
|
|
|
if (!event.target || this.renderedView === null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (this.renderedView.rootNodes.length === 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (this.modalView.closeAlways) { |
|
|
|
this.modalView.hide(); |
|
|
|
} else { |
|
|
|
const rootNode = this.renderedView.rootNodes[0]; |
|
|
|
const rootBounds = rootNode.getBoundingClientRect(); |
|
|
|
|
|
|
|
if (rootBounds.width > 0 && rootBounds.height > 0) { |
|
|
|
const clickedInside = rootNode.contains(event.target); |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
this.isEnabled = true; |
|
|
|
}, 500); |
|
|
|
if (!clickedInside && this.modalView) { |
|
|
|
this.modalView.hide(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private stopListening() { |
|
|
|
if (this.clickHandler) { |
|
|
|
this.clickHandler(); |
|
|
|
this.clickHandler = null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |