require('./style.scss'); var Component = require('vn/component'); /** * Class to handle popups. */ module.exports = new Class({ Extends: Component ,Tag: 'htk-popup' ,Properties: { /** * The popup child. */ child: { type: Component ,set(x) { this._child = x; this._setChildNode(x.node); } ,get() { return this._child; } } /** * The popup child Node. */ ,childNode: { type: Object ,set(x) { this._child = null; this._setChildNode(x); } ,get() { return this.node.firstChild; } } /** * Indicates how the dialog must be displayed. */ ,modal: { type: Boolean ,set(x) { this._modal = x; } ,get() { return this._modal; } } } ,_parent: null ,_modal: false ,_isOpen: false ,_child: null ,initialize(props) { this._bgMouseDownHandler = this._bgMouseDown.bind(this); Component.prototype.initialize.call(this, props); } ,render() { this.createRoot('div'); } ,_setChildNode(childNode) { Vn.Node.removeChilds(this.node); this.node.appendChild(childNode); } ,show(parent, event) { this._parent = parent; this._lastEvent = event; this.open(); } ,isModal() { return this._modal || Vn.isMobile(); } ,open() { if (this._isOpen) { this.reset(); return; } this.node.addEventListener('mousedown', this._onMouseDown.bind(this)); if (this.isModal()) { var bg = this._bg = this.createElement('div'); bg.className = 'htk-background'; bg.addEventListener('mousedown', this._bgMouseDownHandler); Htk.Toast.pushTop(bg); this.node.classList.add('modal'); bg.appendChild(this.node); this.doc.body.appendChild(bg); setTimeout(this._onOpacityTimeout.bind(this), 0); } else { this.doc.addEventListener('mousedown', this._bgMouseDownHandler); this.doc.body.appendChild(this.node); } this._isOpen = true; this.reset(); setTimeout(this._onResetTimeout.bind(this), 0); } ,_onOpacityTimeout() { if (this._bg) this._bg.style.opacity = 1; } ,_onResetTimeout() { this.reset(); } ,reset() { if (!this._isOpen) return; var node = this._node; var style = node.style; style.height = ''; style.width = ''; if (!this.isModal()) { var margin = 20; var dblMargin = margin * 2; var width = node.offsetWidth; var height = node.offsetHeight; var innerWidth = window.innerWidth; var innerHeight = window.innerHeight; if (width + dblMargin > innerWidth) { width = innerWidth - dblMargin; style.width = width +'px'; } if (height + dblMargin > innerHeight) { height = innerHeight - dblMargin; style.height = height +'px'; } var spacing = 4; var rect = this._parent.getBoundingClientRect(); var left = rect.left; var top = rect.top + spacing + this._parent.offsetHeight; if (left + width > innerWidth) left -= (left + width) - window.innerWidth + margin; if (top + height > innerHeight) top -= height + this._parent.offsetHeight + spacing * 2; if (left < 0) left = margin; if (top < 0) top = margin; style.top = (top) +'px'; style.left = (left) +'px'; } } ,hide() { if (!this._isOpen) return; if (this._bg) { Htk.Toast.popTop(); Vn.Node.remove(this._bg); Vn.Node.removeClass(this._node, 'modal'); this._bg = null; } else this.doc.removeEventListener('mousedown', this._bgMouseDownHandler); Vn.Node.remove(this._node); this._parent = null; this._isOpen = false; this.emit('closed'); } ,_bgMouseDown(e) { if (e !== this._lastEvent) this.hide(); this._lastEvent = null; } ,_onMouseDown(e) { this._lastEvent = e; } });