From cf5447740853a5fbb3b6af39add9f23879ef1dc3 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 10 Dec 2020 11:51:55 +0000 Subject: [PATCH] remove old context menu (#6424) --- .../app/components/files/files.component.html | 2 - .../context-menu-holder.component.spec.ts | 292 ------------------ .../context-menu-holder.component.ts | 175 ----------- .../context-menu-overlay.service.spec.ts | 2 +- .../context-menu/context-menu.directive.ts | 2 +- lib/core/context-menu/context-menu.module.ts | 3 - lib/core/context-menu/context-menu.service.ts | 26 -- lib/core/context-menu/public-api.ts | 2 - 8 files changed, 2 insertions(+), 502 deletions(-) delete mode 100644 lib/core/context-menu/context-menu-holder.component.spec.ts delete mode 100644 lib/core/context-menu/context-menu-holder.component.ts delete mode 100644 lib/core/context-menu/context-menu.service.ts diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index fed1687d65..8e9331edbc 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -497,8 +497,6 @@ - -
{ - let fixture: ComponentFixture; - let component: ContextMenuHolderComponent; - let contextMenuService: ContextMenuService; - const overlayContainer = { - getContainerElement: () => ({ - addEventListener: () => {}, - querySelector: (val) => ({ - name: val, - clientWidth: 0, - clientHeight: 0, - parentElement: { - style: { - left: 0, - top: 0 - } - } - }) - - }) - }; - - const getViewportRect = { - getViewportRect: () => ({ - left: 0, top: 0, width: 1014, height: 686, bottom: 0, right: 0 - }) - }; - - setupTestBed({ - imports: [ - TranslateModule.forRoot(), - CoreTestingModule, - ContextMenuModule - ], - providers: [ - { - provide: OverlayContainer, - useValue: overlayContainer - }, - { - provide: ViewportRuler, - useValue: getViewportRect - } - ] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(ContextMenuHolderComponent); - component = fixture.componentInstance; - contextMenuService = TestBed.inject(ContextMenuService); - - component.ngOnDestroy = () => {}; - fixture.detectChanges(); - }); - - beforeEach(() => { - spyOn(component.menuTrigger, 'openMenu'); - }); - - describe('Events', () => { - it('should show menu on service event', () => { - spyOn(component, 'showMenu'); - - contextMenuService.show.next( {}); - - expect(component.showMenu).toHaveBeenCalled(); - }); - - it('should set DOM element reference on menu open event', () => { - component.menuTrigger.onMenuOpen.next(); - - expect(component.mdMenuElement.name).toBe('.context-menu'); - }); - - it('should reset DOM element reference on menu close event', () => { - component.menuTrigger.onMenuClose.next(); - - expect(component.mdMenuElement).toBe(null); - }); - }); - - describe('onMenuItemClick()', () => { - - it('should emit when link is not disabled', () => { - const menuItem = { - model: { - disabled: false - }, - subject: { - next: (val) => val - } - }; - - spyOn(menuItem.subject, 'next'); - - const event = { - preventDefault: () => null, - stopImmediatePropagation: () => null - }; - - component.onMenuItemClick( event, menuItem); - - expect(menuItem.subject.next).toHaveBeenCalledWith(menuItem); - }); - - it('should not emit when link is disabled', () => { - const menuItem = { - model: { - disabled: false - }, - subject: { - next: (val) => val - } - }; - - spyOn(menuItem.subject, 'next'); - - const event = { - preventDefault: () => null, - stopImmediatePropagation: () => null - }; - - menuItem.model.disabled = true; - component.onMenuItemClick( event, menuItem); - - expect(menuItem.subject.next).not.toHaveBeenCalled(); - }); - }); - - describe('showMenu()', () => { - it('should open menu panel', () => { - component.showMenu( {}, [{}]); - - expect(component.menuTrigger.openMenu).toHaveBeenCalled(); - }); - }); - - describe('Menu position', () => { - beforeEach(() => { - component.menuTrigger.onMenuOpen.next(); - component.mdMenuElement.clientHeight = 160; - component.mdMenuElement.clientWidth = 200; - }); - - it('should set position to mouse position', fakeAsync(() => { - const contextMenuEvent = { - clientX: 100, - clientY: 210 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.mdMenuElement.parentElement.style).toEqual({ - left: '100px', - top: '210px' - }); - })); - - it('should adjust position relative to right margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 1000, - clientY: 210 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.mdMenuElement.parentElement.style).toEqual({ - left: '800px', - top: '210px' - }); - })); - - it('should adjust position relative to bottom margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 100, - clientY: 600 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.mdMenuElement.parentElement.style).toEqual({ - left: '100px', - top: '440px' - }); - })); - - it('should adjust position relative to bottom - right margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 900, - clientY: 610 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.mdMenuElement.parentElement.style).toEqual({ - left: '700px', - top: '450px' - }); - })); - }); - - describe('Menu direction', () => { - beforeEach(() => { - component.menuTrigger.onMenuOpen.next(); - component.mdMenuElement.clientHeight = 160; - component.mdMenuElement.clientWidth = 200; - }); - - it('should set default menu direction', fakeAsync(() => { - const contextMenuEvent = { - clientX: 100, - clientY: 210 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.menuTrigger.menu.xPosition).toBe('after'); - expect(component.menuTrigger.menu.yPosition).toBe('below'); - })); - - it('should adjust direction relative to right margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 1000, - clientY: 210 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.menuTrigger.menu.xPosition).toBe('before'); - expect(component.menuTrigger.menu.yPosition).toBe('below'); - })); - - it('should adjust direction relative to bottom margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 100, - clientY: 600 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.menuTrigger.menu.xPosition).toBe('after'); - expect(component.menuTrigger.menu.yPosition).toBe('above'); - })); - - it('should adjust position relative to bottom - right margin of the screen', fakeAsync(() => { - const contextMenuEvent = { - clientX: 900, - clientY: 610 - }; - - component.showMenu( contextMenuEvent, [{}]); - tick(); - - expect(component.menuTrigger.menu.xPosition).toBe('before'); - expect(component.menuTrigger.menu.yPosition).toBe('above'); - })); - }); -}); diff --git a/lib/core/context-menu/context-menu-holder.component.ts b/lib/core/context-menu/context-menu-holder.component.ts deleted file mode 100644 index 3574e497a5..0000000000 --- a/lib/core/context-menu/context-menu-holder.component.ts +++ /dev/null @@ -1,175 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OverlayContainer } from '@angular/cdk/overlay'; -import { ViewportRuler } from '@angular/cdk/scrolling'; -import { Component, HostListener, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core'; -import { MatMenuTrigger } from '@angular/material/menu'; -import { Subscription } from 'rxjs'; -import { ContextMenuService } from './context-menu.service'; - -@Component({ - selector: 'adf-context-menu-holder', - template: ` - - - - - - - ` -}) -export class ContextMenuHolderComponent implements OnInit, OnDestroy { - links = []; - - private mouseLocation: { left: number, top: number } = { left: 0, top: 0 }; - private menuElement = null; - private subscriptions: Subscription[] = []; - private contextMenuListenerFn: () => void; - - @Input() - showIcons: boolean = false; - - @ViewChild(MatMenuTrigger, { static: true }) - menuTrigger: MatMenuTrigger; - - @HostListener('contextmenu', ['$event']) - onShowContextMenu(event?: MouseEvent) { - if (event) { - event.preventDefault(); - } - } - - @HostListener('window:resize') - onResize() { - if (this.mdMenuElement) { - this.updatePosition(); - } - } - - constructor( - private viewport: ViewportRuler, - private overlayContainer: OverlayContainer, - private contextMenuService: ContextMenuService, - private renderer: Renderer2 - ) { - } - - ngOnInit() { - this.subscriptions.push( - this.contextMenuService.show.subscribe((mouseEvent) => this.showMenu(mouseEvent.event, mouseEvent.obj)), - - this.menuTrigger.menuOpened.subscribe(() => { - const container = this.overlayContainer.getContainerElement(); - if (container) { - this.contextMenuListenerFn = this.renderer.listen(container, 'contextmenu', (contextmenuEvent: Event) => { - contextmenuEvent.preventDefault(); - }); - } - this.menuElement = this.getContextMenuElement(); - }), - - this.menuTrigger.menuClosed.subscribe(() => { - this.menuElement = null; - if (this.contextMenuListenerFn) { - this.contextMenuListenerFn(); - } - }) - ); - } - - ngOnDestroy() { - if (this.contextMenuListenerFn) { - this.contextMenuListenerFn(); - } - - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - this.subscriptions = []; - - this.menuElement = null; - } - - onMenuItemClick(event: Event, menuItem: any): void { - if (menuItem && menuItem.model && menuItem.model.disabled) { - event.preventDefault(); - event.stopImmediatePropagation(); - return; - } - menuItem.subject.next(menuItem); - } - - showMenu(mouseEvent, links) { - this.links = links; - - if (mouseEvent) { - this.mouseLocation = { - left: mouseEvent.clientX, - top: mouseEvent.clientY - }; - } - - this.menuTrigger.openMenu(); - - if (this.mdMenuElement) { - this.updatePosition(); - } - } - - get mdMenuElement() { - return this.menuElement; - } - - private locationCss() { - return { - left: this.mouseLocation.left + 'px', - top: this.mouseLocation.top + 'px' - }; - } - - private updatePosition() { - setTimeout(() => { - if (this.mdMenuElement.parentElement) { - if (this.mdMenuElement.clientWidth + this.mouseLocation.left > this.viewport.getViewportRect().width) { - this.menuTrigger.menu.xPosition = 'before'; - this.mdMenuElement.parentElement.style.left = this.mouseLocation.left - this.mdMenuElement.clientWidth + 'px'; - } else { - this.menuTrigger.menu.xPosition = 'after'; - this.mdMenuElement.parentElement.style.left = this.locationCss().left; - } - - if (this.mdMenuElement.clientHeight + this.mouseLocation.top > this.viewport.getViewportRect().height) { - this.menuTrigger.menu.yPosition = 'above'; - this.mdMenuElement.parentElement.style.top = this.mouseLocation.top - this.mdMenuElement.clientHeight + 'px'; - } else { - this.menuTrigger.menu.yPosition = 'below'; - this.mdMenuElement.parentElement.style.top = this.locationCss().top; - } - } - }, 0); - } - - private getContextMenuElement() { - return this.overlayContainer.getContainerElement().querySelector('.context-menu'); - } -} diff --git a/lib/core/context-menu/context-menu-overlay.service.spec.ts b/lib/core/context-menu/context-menu-overlay.service.spec.ts index 103f1293bd..7d6f16eefb 100644 --- a/lib/core/context-menu/context-menu-overlay.service.spec.ts +++ b/lib/core/context-menu/context-menu-overlay.service.spec.ts @@ -23,7 +23,7 @@ import { setupTestBed } from '../testing/setup-test-bed'; import { TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; -describe('ContextMenuService', () => { +describe('ContextMenuOverlayService', () => { let contextMenuOverlayService: ContextMenuOverlayService; let overlay: Overlay; let injector: Injector; diff --git a/lib/core/context-menu/context-menu.directive.ts b/lib/core/context-menu/context-menu.directive.ts index 5151dc8d6b..623e7bb356 100644 --- a/lib/core/context-menu/context-menu.directive.ts +++ b/lib/core/context-menu/context-menu.directive.ts @@ -21,7 +21,7 @@ import { Directive, HostListener, Input } from '@angular/core'; import { ContextMenuOverlayService } from './context-menu-overlay.service'; @Directive({ - selector: '[adf-context-menu], [context-menu]' + selector: '[adf-context-menu]' }) export class ContextMenuDirective { /** Items for the menu. */ diff --git a/lib/core/context-menu/context-menu.module.ts b/lib/core/context-menu/context-menu.module.ts index 8335dab4b6..243cebb9e6 100644 --- a/lib/core/context-menu/context-menu.module.ts +++ b/lib/core/context-menu/context-menu.module.ts @@ -20,7 +20,6 @@ import { NgModule } from '@angular/core'; import { MaterialModule } from '../material.module'; import { TranslateModule } from '@ngx-translate/core'; -import { ContextMenuHolderComponent } from './context-menu-holder.component'; import { ContextMenuDirective } from './context-menu.directive'; import { ContextMenuListComponent } from './context-menu-list.component'; @@ -31,12 +30,10 @@ import { ContextMenuListComponent } from './context-menu-list.component'; TranslateModule ], declarations: [ - ContextMenuHolderComponent, ContextMenuDirective, ContextMenuListComponent ], exports: [ - ContextMenuHolderComponent, ContextMenuDirective ] }) diff --git a/lib/core/context-menu/context-menu.service.ts b/lib/core/context-menu/context-menu.service.ts deleted file mode 100644 index 1c65b2c277..0000000000 --- a/lib/core/context-menu/context-menu.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; - -@Injectable({ - providedIn: 'root' -}) -export class ContextMenuService { - public show: Subject<{event: MouseEvent, obj: any[]}> = new Subject<{event: MouseEvent, obj: any[]}>(); -} diff --git a/lib/core/context-menu/public-api.ts b/lib/core/context-menu/public-api.ts index fb9b1e4634..7fecc58fc1 100644 --- a/lib/core/context-menu/public-api.ts +++ b/lib/core/context-menu/public-api.ts @@ -15,9 +15,7 @@ * limitations under the License. */ -export * from './context-menu-holder.component'; export * from './context-menu.directive'; -export * from './context-menu.service'; export * from './context-menu-overlay.service'; export * from './context-menu.module';