import ngModule from '../../module'; import Component from '../../lib/component'; import template from './index.html'; import './style.scss'; /** * Base class for windows displayed over application content. */ export default class Popup extends Component { constructor($element, $scope, $transclude) { super($element, $scope); this.$transclude = $transclude; this._shown = false; this.displayMode = 'centered'; this.template = template; } $onDestroy() { this.hide(); } /** * @type {Boolean} Wether to show or hide the popup. */ get shown() { return this._shown; } set shown(value) { if (value) this.show(); else this.hide(); } /** * Displays the dialog to the user. */ show() { if (this.shown) return; this._shown = true; if (this.closeTimeout) { this.$timeout.cancel(this.closeTimeout); this.onClose(); } let linkFn = this.$compile(this.template); this.$contentScope = this.$.$new(); this.popup = linkFn(this.$contentScope, null, {parentBoundTranscludeFn: this.$transclude} )[0]; this.windowEl = this.popup.querySelector('.window'); let classList = this.popup.classList; classList.add(this.displayMode); classList.add(...this.constructor.$classNames); this.document.body.appendChild(this.popup); this.keyDownHandler = e => this.onkeyDown(e); this.document.addEventListener('keydown', this.keyDownHandler); this.deregisterCallback = this.$transitions.onStart({}, () => this.hide()); this.$timeout.cancel(this.showTimeout); this.showTimeout = this.$timeout(() => { this.showTimeout = null; classList.add('shown'); }, 10); this.emit('open'); } /** * Hides the dialog calling the response handler. */ hide() { if (!this.shown) return; this._shown = false; this.document.removeEventListener('keydown', this.keyDownHandler); this.keyDownHandler = null; this.deregisterCallback(); this.deregisterCallback = null; this.popup.classList.remove('shown'); this.closeTimeout = this.$timeout( () => this.onClose(), 200); this.lastEvent = null; this.emit('closeStart'); } onClose() { this.closeTimeout = null; this.popup.remove(); this.popup = null; this.$contentScope.$destroy(); this.$contentScope = null; this.windowEl = null; this.emit('close'); } onWindowMouseDown(event) { this.lastEvent = event; } onBgMouseDown(event) { if (!event.defaultPrevented && event != this.lastEvent) this.hide(); } onkeyDown(event) { if (!event.defaultPrevented && event.key == 'Escape') this.hide(); } } Popup.$inject = ['$element', '$scope', '$transclude']; ngModule.vnComponent('vnPopup', { controller: Popup, transclude: true, bindings: { shown: '=?' } });