salix/client/core/src/popover/index.js

97 lines
3.3 KiB
JavaScript
Raw Normal View History

import {module} from '../module';
require('./style.css');
directive.$inject = ['vnPopover'];
export function directive(popover) {
return {
restrict: 'A',
link: function($scope, $element, $attrs, $ctrl) {
$element.on('click', function(event) {
popover.showComponent($attrs.vnDialog, $scope, $element);
event.preventDefault();
});
}
}
}
module.directive('vnPopover', directive);
factory.$inject = ['$document', '$compile'];
function factory($document, $compile) {
return {
show: function(childElement, parent) {
let popover = $document[0].createElement('div');
popover.className = 'vn-popover';
popover.addEventListener('mousedown',
this.onPopoverMouseDown.bind(this));
popover.appendChild (childElement);
this.popover = popover;
let style = popover.style;
let spacing = 0;
let screenMargin = 20;
let dblMargin = screenMargin * 2;
let width = popover.offsetWidth;
let height = popover.offsetHeight;
let innerWidth = window.innerWidth;
let 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(parent) {
let parentNode = parent;
let rect = parentNode.getBoundingClientRect();
let left = rect.left;
let top = rect.top + spacing + parentNode.offsetHeight;
if(left + width > innerWidth)
left -= (left + width) - innerWidth + margin;
if(top + height > innerHeight)
top -= height + parentNode.offsetHeight + spacing * 2;
if(left < 0)
left = screenMargin;
if(top < 0)
top = screenMargin;
style.top = (top) +'px';
style.left = (left) +'px';
style.minWidth = (rect.width) +'px';
}
$document[0].body.appendChild (popover);
this.docMouseDownHandler = this.onDocMouseDown.bind(this);
$document.on('mousedown', this.docMouseDownHandler);
},
showComponent: function(childComponent, $scope, parent) {
let childElement = $document[0].createElement(childComponent);
$compile(childElement)($scope);
this.show(childElement, parent);
},
hide: function() {
if(!this.popover) return;
$document.off('mousedown', this.docMouseDownHandler);
$document[0].body.removeChild (this.popover);
this.popover = null;
this.lastEvent = null;
this.docMouseDownHandler = null;
},
onDocMouseDown: function(event) {
if (event != this.lastEvent)
this.hide();
},
onPopoverMouseDown: function(event) {
this.lastEvent = event;
}
};
}
module.factory('vnPopover', factory);