var Widget = require ('./widget'); /** * Class to handle popups. **/ module.exports = new Class ({ Extends: Widget ,Tag: 'htk-popup' ,Properties: { /** * The popup child. **/ child: { type: Widget ,set: function (x) { this._child = x; this._setChildNode (x.node); } ,get: function () { return this._child; } } /** * The popup child Node. **/ ,childNode: { type: Object ,set: function (x) { this._child = null; this._setChildNode (x); } ,get: function () { return this.node.firstChild; } } /** * Indicates how the dialog must be displayed. **/ ,modal: { type: Boolean ,set: function (x) { this._modal = x; } ,get: function () { return this._modal; } } } ,_parent: null ,_modal: false ,_isOpen: false ,_child: null ,initialize: function (props) { this._bgMouseDownHandler = this._bgMouseDown.bind (this); this.parent (props); } ,render: function () { var div = this.createRoot ('div'); div.className = 'htk-popup'; } ,_setChildNode: function (childNode) { Vn.Node.removeChilds (this.node); this.node.appendChild (childNode); } ,show: function (parent) { this._parent = parent; this.open (); } ,isModal: function () { return this._modal || Vn.isMobile (); } ,open: function () { 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); Vn.Node.addClass (this.node, '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: function () { if (this._bg) this._bg.style.opacity = 1; } ,_onResetTimeout: function () { this.reset (); } ,reset: function () { if (!this._isOpen) return; var style = this.node.style; style.height = ''; style.width = ''; var margin = 20; var dblMargin = margin * 2; var width = this.node.offsetWidth; var height = this.node.offsetHeight; var innerWidth = Vn.Browser.getInnerWidth (); var innerHeight = Vn.Browser.getInnerHeight (); if (width + dblMargin > innerWidth) { width = innerWidth - dblMargin; style.width = width +'px'; } if (height + dblMargin > innerHeight) { height = innerHeight - dblMargin; style.height = height +'px'; } if (this.isModal ()) { style.top = '50%'; style.left = '50%'; style.marginLeft = (-this.node.offsetWidth / 2) +'px'; style.marginTop = (-this.node.offsetHeight / 2) +'px'; } else { 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) - Vn.Browser.getInnerWidth () + 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: function () { if (!this._isOpen) return; if (this._bg) { 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.signalEmit ('closed'); } ,_bgMouseDown: function (e) { if (e !== this._lastEvent) this.hide (); this._lastEvent = null; } ,_onMouseDown: function (e) { this._lastEvent = e; } });