1 import {Input, Output, EventEmitter, Directive} from '@angular/core';
2 import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
3 import {ContextMenuService, ContextMenu, ContextMenuEntry} from './context-menu.service';
6 /* Import all of this stuff so we can pass it to our parent
7 * class via its constructor */
8 /* eslint-disable no-duplicate-imports */
10 Inject, Injector, Renderer2, ElementRef, ViewContainerRef,
11 NgZone, ChangeDetectorRef, ApplicationRef
12 } from '@angular/core';
13 import {DOCUMENT} from '@angular/common';
14 import {NgbPopoverConfig} from '@ng-bootstrap/ng-bootstrap';
15 /* eslint-enable no-duplicate-imports */
19 selector: '[egContextMenu]',
20 exportAs: 'egContextMenu'
22 export class ContextMenuDirective extends NgbPopover {
24 // Only one active menu is allowed at a time.
25 static activeDirective: ContextMenuDirective;
28 triggers = 'contextmenu';
29 popoverClass = 'eg-context-menu';
31 menuEntries: ContextMenuEntry[] = [];
34 @Input() set egContextMenu(menuEntries: ContextMenuEntry[]) {
35 this.menuEntries = menuEntries;
38 @Output() menuItemSelected: EventEmitter<ContextMenuEntry>;
41 p1: ElementRef<HTMLElement>, p2: Renderer2, p3: Injector,
42 p5: ViewContainerRef, p6: NgbPopoverConfig,
43 p7: NgZone, @Inject(DOCUMENT) p8: any, p9: ChangeDetectorRef,
44 p10: ApplicationRef, private menuService: ContextMenuService) {
46 // relay injected services to parent
47 super(p1, p2, p3, p5, p6, p7, p8, p9, p10);
49 this.menuItemSelected = new EventEmitter<ContextMenuEntry>();
51 this.menuService.menuItemSelected.subscribe(
52 (entry: ContextMenuEntry) => {
54 // Only broadcast entry selection to my listeners if I'm
55 // hosting the menu where the selection occurred.
57 if (this.activeMenuIsMe()) {
58 this.menuItemSelected.emit(entry);
60 // Item selection via keyboard fails to close the menu.
67 activeMenuIsMe(): boolean {
70 this.menuService.activeMenu &&
71 this.menu.id === this.menuService.activeMenu.id
75 // Close the active menu
77 if (ContextMenuDirective.activeDirective) {
78 ContextMenuDirective.activeDirective.close();
79 ContextMenuDirective.activeDirective = null;
80 this.menuService.activeMenu = null;
86 // In certain scenarios (e.g. right-clicking on another context
87 // menu) an open popover will stay open. Force it closed here.
90 if (!this.menuEntries ||
91 this.menuEntries.length === 0) {
95 this.menu = new ContextMenu();
96 this.menu.id = ContextMenuDirective.menuId++;
97 this.menu.entries = this.menuEntries;
99 this.menuService.activeMenu = this.menu;
100 this.menuService.showMenuRequest.emit(this.menu);
101 this.ngbPopover = this.menuService.menuTemplate;
103 ContextMenuDirective.activeDirective = this;