@avdbrink/ngx-contextmenu
Version:
An Angular component to show a context menu on an arbitrary component
2 lines • 15.7 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("rxjs"),require("@angular/cdk/a11y"),require("@angular/cdk/overlay"),require("@angular/cdk/portal"),require("rxjs/operators"),require("@angular/common")):"function"==typeof define&&define.amd?define("ngx-contextmenu",["exports","@angular/core","rxjs","@angular/cdk/a11y","@angular/cdk/overlay","@angular/cdk/portal","rxjs/operators","@angular/common"],t):t(e["ngx-contextmenu"]={},e.ng.core,e.rxjs,e.ng.cdk.a11y,e.ng.cdk.overlay,e.ng.cdk.portal,e.rxjs.operators,e.ng.common)}(this,function(e,a,c,t,n,l,s,o){"use strict";var p=Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},i=new a.InjectionToken("CONTEXT_MENU_OPTIONS"),h=function(){function e(e,t,n,o){this.changeDetector=e,this.elementRef=t,this.options=n,this.renderer=o,this.menuItems=[],this.isLeaf=!1,this.execute=new a.EventEmitter,this.openSubMenu=new a.EventEmitter,this.closeLeafMenu=new a.EventEmitter,this.closeAllMenus=new a.EventEmitter,this.autoFocus=!1,this.useBootstrap4=!1,this.highlightParentItems=!1,this.subscription=new c.Subscription,n&&(this.autoFocus=n.autoFocus,this.useBootstrap4=n.useBootstrap4,this.highlightParentItems=n.highlightParentItems)}return e.prototype.ngOnInit=function(){var n=this;this.menuItems.forEach(function(t){t.currentItem=n.item,n.subscription.add(t.execute.subscribe(function(e){return n.execute.emit(p({},e,{menuItem:t}))}))});var e=new a.QueryList;e.reset(this.menuItems),this._keyManager=new t.ActiveDescendantKeyManager(e).withWrap()},e.prototype.ngAfterViewInit=function(){var e=this;this.autoFocus&&setTimeout(function(){return e.focus()}),this.overlay.updatePosition()},e.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},e.prototype.focus=function(){this.autoFocus&&this.menuElement.nativeElement.focus()},e.prototype.stopEvent=function(e){e.stopPropagation()},e.prototype.isMenuItemEnabled=function(e){return this.evaluateIfFunction(e&&e.enabled)},e.prototype.isMenuItemVisible=function(e){return this.evaluateIfFunction(e&&e.visible)},e.prototype.evaluateIfFunction=function(e){return e instanceof Function?e(this.item):e},e.prototype.isDisabled=function(e){return e.enabled&&!e.enabled(this.item)},e.prototype.onKeyEvent=function(e){this.isLeaf&&this._keyManager.onKeydown(e)},e.prototype.keyboardOpenSubMenu=function(e){if(this.isLeaf){this.cancelEvent(e);var t=this.menuItems[this._keyManager.activeItemIndex];t&&this.onOpenSubMenu(t)}},e.prototype.keyboardMenuItemSelect=function(e){if(this.isLeaf){this.cancelEvent(e);var t=this.menuItems[this._keyManager.activeItemIndex];t&&this.onMenuItemSelect(t,e)}},e.prototype.onCloseLeafMenu=function(e){this.isLeaf&&(this.cancelEvent(e),this.closeLeafMenu.emit({exceptRootMenu:37===e.keyCode,event:e}))},e.prototype.closeMenu=function(e){"click"===e.type&&2===e.button||this.closeAllMenus.emit({event:e})},e.prototype.onOpenSubMenu=function(t,e){var n=this.menuItemElements.toArray()[this._keyManager.activeItemIndex],o=n&&n.nativeElement;this.highlightParentItems&&this.menuItems.forEach(function(e){return e.isActiveParent=e===t&&t.subMenu}),this.openSubMenu.emit({anchorElement:o,contextMenu:t.subMenu,event:e,item:this.item,parentContextMenu:this})},e.prototype.onMenuItemSelect=function(e,t){t.preventDefault(),t.stopPropagation(),this.onOpenSubMenu(e,t),e.subMenu||e.triggerExecute(this.item,t)},e.prototype.cancelEvent=function(e){if(e){var t=e.target;-1<["INPUT","TEXTAREA","SELECT"].indexOf(t.tagName)||t.isContentEditable||(e.preventDefault(),e.stopPropagation())}},e.decorators=[{type:a.Component,args:[{selector:"context-menu-content",styles:['.passive {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n white-space: nowrap;\n }\n .hasSubMenu:before {\n content: "▶";\n float: right;\n }\n .activeParent {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n }'],template:'<div class="dropdown open show ngx-contextmenu" [ngClass]="menuClass" tabindex="0">\n <ul #menu class="dropdown-menu show" style="position: static; float: none;" tabindex="0">\n <li #li *ngFor="let menuItem of menuItems; let i = index" [class.disabled]="!isMenuItemEnabled(menuItem)"\n [class.divider]="menuItem.divider" [class.dropdown-divider]="useBootstrap4 && menuItem.divider"\n [class.active]="menuItem.isActive && isMenuItemEnabled(menuItem)"\n [attr.role]="menuItem.divider ? \'separator\' : undefined">\n <a *ngIf="!menuItem.divider && !menuItem.passive" href [class.dropdown-item]="useBootstrap4"\n [class.active]="menuItem.isActive && isMenuItemEnabled(menuItem)"\n [class.activeParent]="highlightParentItems && menuItem.isActiveParent && isMenuItemEnabled(menuItem)"\n [class.disabled]="useBootstrap4 && !isMenuItemEnabled(menuItem)" [class.hasSubMenu]="!!menuItem.subMenu"\n (click)="onMenuItemSelect(menuItem, $event)" (mouseenter)="onOpenSubMenu(menuItem, $event)">\n <ng-template [ngTemplateOutlet]="menuItem.template" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template>\n </a>\n\n <span (click)="stopEvent($event)" (contextmenu)="stopEvent($event)" class="passive"\n *ngIf="!menuItem.divider && menuItem.passive" [class.dropdown-item]="useBootstrap4"\n [class.disabled]="useBootstrap4 && !isMenuItemEnabled(menuItem)">\n <ng-template [ngTemplateOutlet]="menuItem.template" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template>\n </span>\n </li>\n </ul>\n </div>\n '}]}],e.ctorParameters=function(){return[{type:a.ChangeDetectorRef},{type:a.ElementRef},{type:undefined,decorators:[{type:a.Optional},{type:a.Inject,args:[i]}]},{type:a.Renderer}]},e.propDecorators={menuItems:[{type:a.Input}],item:[{type:a.Input}],event:[{type:a.Input}],parentContextMenu:[{type:a.Input}],menuClass:[{type:a.Input}],overlay:[{type:a.Input}],isLeaf:[{type:a.Input}],execute:[{type:a.Output}],openSubMenu:[{type:a.Output}],closeLeafMenu:[{type:a.Output}],closeAllMenus:[{type:a.Output}],menuElement:[{type:a.ViewChild,args:["menu"]}],menuItemElements:[{type:a.ViewChildren,args:["li"]}],onKeyEvent:[{type:a.HostListener,args:["window:keydown.ArrowDown",["$event"]]},{type:a.HostListener,args:["window:keydown.ArrowUp",["$event"]]}],keyboardOpenSubMenu:[{type:a.HostListener,args:["window:keydown.ArrowRight",["$event"]]}],keyboardMenuItemSelect:[{type:a.HostListener,args:["window:keydown.Enter",["$event"]]},{type:a.HostListener,args:["window:keydown.Space",["$event"]]}],onCloseLeafMenu:[{type:a.HostListener,args:["window:keydown.Escape",["$event"]]},{type:a.HostListener,args:["window:keydown.ArrowLeft",["$event"]]}],closeMenu:[{type:a.HostListener,args:["document:click",["$event"]]},{type:a.HostListener,args:["document:contextmenu",["$event"]]}]},e}(),r=function(){function e(e,t){this.overlay=e,this.scrollStrategy=t,this.isDestroyingLeafMenu=!1,this.show=new c.Subject,this.triggerClose=new c.Subject,this.close=new c.Subject,this.overlays=[],this.fakeElement={getBoundingClientRect:function(){return{bottom:0,height:0,left:0,right:0,top:0,width:0}}}}return e.prototype.openContextMenu=function(e){var t=e.anchorElement,n=e.event,o=e.parentContextMenu;if(o){r=this.overlay.position().connectedTo(new a.ElementRef(n?n.target:t),{originX:"end",originY:"top"},{overlayX:"start",overlayY:"top"}).withFallbackPosition({originX:"start",originY:"top"},{overlayX:"end",overlayY:"top"}).withFallbackPosition({originX:"end",originY:"bottom"},{overlayX:"start",overlayY:"bottom"}).withFallbackPosition({originX:"start",originY:"bottom"},{overlayX:"end",overlayY:"bottom"});var i=this.overlay.create({positionStrategy:r,panelClass:"ngx-contextmenu",scrollStrategy:this.scrollStrategy.close()});this.destroySubMenus(o),this.overlays=this.overlays.concat(i),this.attachContextMenu(i,e)}else{var s=n;this.fakeElement.getBoundingClientRect=function(){return{bottom:s.clientY,height:0,left:s.clientX,right:s.clientX,top:s.clientY,width:0}},this.closeAllContextMenus({eventType:"cancel",event:n});var r=this.overlay.position().connectedTo(new a.ElementRef(t||this.fakeElement),{originX:"start",originY:"bottom"},{overlayX:"start",overlayY:"top"}).withFallbackPosition({originX:"start",originY:"top"},{overlayX:"start",overlayY:"bottom"}).withFallbackPosition({originX:"end",originY:"top"},{overlayX:"start",overlayY:"top"}).withFallbackPosition({originX:"start",originY:"top"},{overlayX:"end",overlayY:"top"}).withFallbackPosition({originX:"end",originY:"center"},{overlayX:"start",overlayY:"center"}).withFallbackPosition({originX:"start",originY:"center"},{overlayX:"end",overlayY:"center"});this.overlays=[this.overlay.create({positionStrategy:r,panelClass:"ngx-contextmenu",scrollStrategy:this.scrollStrategy.close()})],this.attachContextMenu(this.overlays[0],e)}},e.prototype.attachContextMenu=function(e,t){var n=this,o=t.event,i=t.item,s=t.menuItems,r=t.menuClass,a=e.attach(new l.ComponentPortal(h));a.instance.event=o,a.instance.item=i,a.instance.menuItems=s,a.instance.overlay=e,a.instance.isLeaf=!0,a.instance.menuClass=r,e.contextMenu=a.instance;var u=new c.Subscription;u.add(a.instance.execute.asObservable().subscribe(function(e){return n.closeAllContextMenus(p({eventType:"execute"},e))})),u.add(a.instance.closeAllMenus.asObservable().subscribe(function(e){return n.closeAllContextMenus(p({eventType:"cancel"},e))})),u.add(a.instance.closeLeafMenu.asObservable().subscribe(function(e){return n.destroyLeafMenu(e)})),u.add(a.instance.openSubMenu.asObservable().subscribe(function(e){n.destroySubMenus(a.instance),e.contextMenu?(a.instance.isLeaf=!1,n.show.next(e)):a.instance.isLeaf=!0})),a.onDestroy(function(){s.forEach(function(e){return e.isActive=!1}),u.unsubscribe()}),a.changeDetectorRef.detectChanges()},e.prototype.closeAllContextMenus=function(e){this.overlays&&(this.close.next(e),this.overlays.forEach(function(e,t){e.detach(),e.dispose()})),this.overlays=[]},e.prototype.getLastAttachedOverlay=function(){for(var e=this.overlays[this.overlays.length-1];1<this.overlays.length&&e&&!e.hasAttached();)e.detach(),e.dispose(),this.overlays=this.overlays.slice(0,-1),e=this.overlays[this.overlays.length-1];return e},e.prototype.destroyLeafMenu=function(e){var n=this,t=void 0===e?{}:e,o=t.exceptRootMenu,i=t.event;this.isDestroyingLeafMenu||(this.isDestroyingLeafMenu=!0,setTimeout(function(){var e=n.getLastAttachedOverlay();1<n.overlays.length&&e&&(e.detach(),e.dispose()),!o&&0<n.overlays.length&&e&&(n.close.next({eventType:"cancel",event:i}),e.detach(),e.dispose());var t=n.getLastAttachedOverlay();t&&(t.contextMenu.isLeaf=!0),n.isDestroyingLeafMenu=!1}))},e.prototype.destroySubMenus=function(e){var t=e.overlay,n=this.overlays.indexOf(t);this.overlays.slice(n+1).forEach(function(e){e.detach(),e.dispose()})},e.prototype.isLeafMenu=function(e){var t=this.getLastAttachedOverlay();return e.overlay===t},e.decorators=[{type:a.Injectable}],e.ctorParameters=function(){return[{type:n.Overlay},{type:n.ScrollStrategyOptions}]},e}(),u=function(){function e(e){this.contextMenuService=e}return e.prototype.onContextMenu=function(e){this.contextMenu.disabled||(this.contextMenuService.show.next({contextMenu:this.contextMenu,event:e,item:this.contextMenuSubject}),e.preventDefault(),e.stopPropagation())},e.decorators=[{type:a.Directive,args:[{selector:"[contextMenu]"}]}],e.ctorParameters=function(){return[{type:r}]},e.propDecorators={contextMenuSubject:[{type:a.Input}],contextMenu:[{type:a.Input}],onContextMenu:[{type:a.HostListener,args:["contextmenu",["$event"]]}]},e}(),m=function(){function e(e,t){this.template=e,this.elementRef=t,this.divider=!1,this.enabled=!0,this.passive=!1,this.visible=!0,this.execute=new a.EventEmitter,this.isActive=!1,this.isActiveParent=!1}return Object.defineProperty(e.prototype,"disabled",{get:function(){return this.passive||this.divider||!this.evaluateIfFunction(this.enabled,this.currentItem)},enumerable:!0,configurable:!0}),e.prototype.evaluateIfFunction=function(e,t){return e instanceof Function?e(t):e},e.prototype.setActiveStyles=function(){this.isActive=!0},e.prototype.setInactiveStyles=function(){this.isActive=!1},e.prototype.setActiveParentStyles=function(){this.isActiveParent=!0},e.prototype.setInActiveParentStyles=function(){this.isActiveParent=!1},e.prototype.triggerExecute=function(e,t){this.evaluateIfFunction(this.enabled,e)&&this.execute.emit({event:t,item:e})},e.decorators=[{type:a.Directive,args:[{selector:"[contextMenuItem]"}]}],e.ctorParameters=function(){return[{type:a.TemplateRef},{type:a.ElementRef}]},e.propDecorators={subMenu:[{type:a.Input}],divider:[{type:a.Input}],enabled:[{type:a.Input}],passive:[{type:a.Input}],visible:[{type:a.Input}],execute:[{type:a.Output}]},e}(),y=function(){function e(e,t,n,o){var i=this;this._contextMenuService=e,this.changeDetector=t,this.elementRef=n,this.options=o,this.menuClass="",this.autoFocus=!1,this.useBootstrap4=!1,this.highlightParentItems=!1,this.disabled=!1,this.close=new a.EventEmitter,this.open=new a.EventEmitter,this.visibleMenuItems=[],this.links=[],this.subscription=new c.Subscription,o&&(this.autoFocus=o.autoFocus,this.useBootstrap4=o.useBootstrap4,this.highlightParentItems=o.highlightParentItems),this.subscription.add(e.show.subscribe(function(e){i.onMenuEvent(e)}))}return e.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},e.prototype.onMenuEvent=function(e){var t=this;if(!this.disabled){var n=e.contextMenu,o=e.event,i=e.item;n&&n!==this||(this.event=o,this.item=i,this.setVisibleMenuItems(),this._contextMenuService.openContextMenu(p({},e,{menuItems:this.visibleMenuItems,menuClass:this.menuClass})),this._contextMenuService.close.asObservable().pipe(s.first()).subscribe(function(e){return t.close.emit(e)}),this.open.next(e))}},e.prototype.isMenuItemVisible=function(e){return this.evaluateIfFunction(e.visible)},e.prototype.setVisibleMenuItems=function(){var t=this;this.visibleMenuItems=this.menuItems.filter(function(e){return t.isMenuItemVisible(e)})},e.prototype.evaluateIfFunction=function(e){return e instanceof Function?e(this.item):e},e.decorators=[{type:a.Component,args:[{encapsulation:a.ViewEncapsulation.None,selector:"context-menu",styles:["\n .cdk-overlay-container {\n position: fixed;\n z-index: 1000;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n .ngx-contextmenu.cdk-overlay-pane {\n position: absolute;\n pointer-events: auto;\n box-sizing: border-box;\n }\n"],template:" "}]}],e.ctorParameters=function(){return[{type:r},{type:a.ChangeDetectorRef},{type:a.ElementRef},{type:undefined,decorators:[{type:a.Optional},{type:a.Inject,args:[i]}]}]},e.propDecorators={menuClass:[{type:a.Input}],autoFocus:[{type:a.Input}],useBootstrap4:[{type:a.Input}],highlightParentItems:[{type:a.Input}],disabled:[{type:a.Input}],close:[{type:a.Output}],open:[{type:a.Output}],menuItems:[{type:a.ContentChildren,args:[m]}],menuElement:[{type:a.ViewChild,args:["menu"]}]},e}(),v=function(){function t(){}return t.forRoot=function(e){return{ngModule:t,providers:[r,{provide:i,useValue:e}]}},t.decorators=[{type:a.NgModule,args:[{declarations:[u,y,h,m],entryComponents:[h],exports:[u,y,m],imports:[o.CommonModule,n.OverlayModule]}]}],t}();e.ContextMenuModule=v,e.ContextMenuComponent=y,e.ContextMenuService=r,e.ɵa=u,e.ɵb=m,e.ɵc=i,e.ɵd=h,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=ngx-contextmenu.umd.min.js.map