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); 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; 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'; } 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; } } Popover.$inject = ['$document', '$compile']; module.service('vnPopover', Popover);