2017-01-31 13:13:06 +00:00
|
|
|
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);
|
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
export class Popover {
|
|
|
|
constructor($document, $compile) {
|
|
|
|
this.document = $document[0];
|
|
|
|
this.$compile = $compile;
|
|
|
|
}
|
|
|
|
show(childElement, parent) {
|
|
|
|
let popover = this.document.createElement('div');
|
|
|
|
popover.className = 'vn-popover';
|
|
|
|
popover.addEventListener('mousedown',
|
|
|
|
(event) => this.onPopoverMouseDown(event));
|
|
|
|
popover.appendChild(childElement);
|
|
|
|
this.popover = popover;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
let style = popover.style;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
let spacing = 0;
|
|
|
|
let screenMargin = 20;
|
|
|
|
let dblMargin = screenMargin * 2;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
let width = popover.offsetWidth;
|
|
|
|
let height = popover.offsetHeight;
|
|
|
|
let innerWidth = window.innerWidth;
|
|
|
|
let innerHeight = window.innerHeight;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
if(width + dblMargin > innerWidth) {
|
|
|
|
width = innerWidth - dblMargin;
|
|
|
|
style.width = width +'px';
|
|
|
|
}
|
|
|
|
if(height + dblMargin > innerHeight) {
|
|
|
|
height = innerHeight - dblMargin;
|
|
|
|
style.height = height +'px';
|
|
|
|
}
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
if(parent) {
|
|
|
|
let parentNode = parent;
|
|
|
|
let rect = parentNode.getBoundingClientRect();
|
|
|
|
let left = rect.left;
|
|
|
|
let top = rect.top + spacing + parentNode.offsetHeight;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
if(left + width > innerWidth)
|
|
|
|
left -= (left + width) - innerWidth + margin;
|
|
|
|
if(top + height > innerHeight)
|
|
|
|
top -= height + parentNode.offsetHeight + spacing * 2;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
if(left < 0)
|
|
|
|
left = screenMargin;
|
|
|
|
if(top < 0)
|
|
|
|
top = screenMargin;
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-01 09:05:15 +00:00
|
|
|
style.top = (top) +'px';
|
|
|
|
style.left = (left) +'px';
|
|
|
|
style.minWidth = (rect.width) +'px';
|
2017-01-31 13:13:06 +00:00
|
|
|
}
|
2017-02-01 09:05:15 +00:00
|
|
|
|
|
|
|
this.document.body.appendChild(popover);
|
|
|
|
this.docMouseDownHandler = (event) => this.onDocMouseDown(event);
|
|
|
|
this.document.addEventListener('mousedown', this.docMouseDownHandler);
|
|
|
|
}
|
|
|
|
showComponent(childComponent, $scope, parent) {
|
|
|
|
let childElement = this.document.createElement(childComponent);
|
|
|
|
this.$compile(childElement)($scope);
|
|
|
|
this.show(childElement, parent);
|
|
|
|
}
|
|
|
|
hide() {
|
|
|
|
if(!this.popover) return;
|
|
|
|
this.document.removeEventListener('mousedown', this.docMouseDownHandler);
|
|
|
|
this.document.body.removeChild(this.popover);
|
|
|
|
this.popover = null;
|
|
|
|
this.lastEvent = null;
|
|
|
|
this.docMouseDownHandler = null;
|
|
|
|
}
|
|
|
|
onDocMouseDown(event) {
|
|
|
|
if (event != this.lastEvent)
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
onPopoverMouseDown(event) {
|
|
|
|
this.lastEvent = event;
|
|
|
|
}
|
2017-01-31 13:13:06 +00:00
|
|
|
}
|
2017-02-01 09:05:15 +00:00
|
|
|
Popover.$inject = ['$document', '$compile'];
|
|
|
|
module.service('vnPopover', Popover);
|