forked from verdnatura/hedera-web
199 lines
3.9 KiB
JavaScript
199 lines
3.9 KiB
JavaScript
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: 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, event) {
|
|
this._parent = parent;
|
|
this._lastEvent = event;
|
|
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);
|
|
Htk.Toast.pushTop(bg);
|
|
|
|
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 node = this._node;
|
|
|
|
var style = node.style;
|
|
style.height = '';
|
|
style.width = '';
|
|
|
|
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';
|
|
}
|
|
|
|
if (this.isModal()) {
|
|
style.marginLeft = (-node.offsetWidth / 2) +'px';
|
|
style.marginTop = (-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) - 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: function() {
|
|
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: function(e) {
|
|
if (e !== this._lastEvent)
|
|
this.hide();
|
|
|
|
this._lastEvent = null;
|
|
}
|
|
|
|
,_onMouseDown: function(e) {
|
|
this._lastEvent = e;
|
|
}
|
|
});
|
|
|