From 768cddbe62dcf8cc721db04b202344795545cbd0 Mon Sep 17 00:00:00 2001 From: Dzmitry Shylovich Date: Fri, 11 Nov 2016 01:46:23 +0300 Subject: [PATCH] fix(events): provide the ability to register global hammer.js events closes #12797 --- .../src/dom/events/dom_events.ts | 18 ------ .../src/dom/events/event_manager.ts | 17 +++--- .../src/dom/events/hammer_common.ts | 55 ------------------- .../src/dom/events/hammer_gestures.ts | 46 +++++++++++++++- .../test/dom/events/hammer_gestures_spec.ts | 22 ++++++++ .../test/dom/events/key_events_spec.ts | 11 +++- 6 files changed, 84 insertions(+), 85 deletions(-) delete mode 100644 modules/@angular/platform-browser/src/dom/events/hammer_common.ts create mode 100644 modules/@angular/platform-browser/test/dom/events/hammer_gestures_spec.ts diff --git a/modules/@angular/platform-browser/src/dom/events/dom_events.ts b/modules/@angular/platform-browser/src/dom/events/dom_events.ts index e42d694338..e1d48049ec 100644 --- a/modules/@angular/platform-browser/src/dom/events/dom_events.ts +++ b/modules/@angular/platform-browser/src/dom/events/dom_events.ts @@ -19,22 +19,4 @@ export class DomEventsPlugin extends EventManagerPlugin { element.addEventListener(eventName, handler as any, false); return () => element.removeEventListener(eventName, handler as any, false); } - - addGlobalEventListener(target: string, eventName: string, handler: Function): Function { - let element: any; - switch (target) { - case 'window': - element = window; - break; - case 'document': - element = document; - break; - case 'body': - element = document.body; - break; - default: - throw new Error(`Unsupported event target ${target} for event ${eventName}`); - } - return this.addEventListener(element, eventName, handler); - } } diff --git a/modules/@angular/platform-browser/src/dom/events/event_manager.ts b/modules/@angular/platform-browser/src/dom/events/event_manager.ts index fdad32f09b..349ea70b20 100644 --- a/modules/@angular/platform-browser/src/dom/events/event_manager.ts +++ b/modules/@angular/platform-browser/src/dom/events/event_manager.ts @@ -51,17 +51,18 @@ export class EventManager { } } -export class EventManagerPlugin { +export abstract class EventManagerPlugin { manager: EventManager; - // That is equivalent to having supporting $event.target - supports(eventName: string): boolean { return false; } + abstract supports(eventName: string): boolean; - addEventListener(element: HTMLElement, eventName: string, handler: Function): Function { - throw 'not implemented'; - } + abstract addEventListener(element: HTMLElement, eventName: string, handler: Function): Function; addGlobalEventListener(element: string, eventName: string, handler: Function): Function { - throw 'not implemented'; - } + const target: HTMLElement = getDOM().getGlobalEventTarget(element); + if (!target) { + throw new Error(`Unsupported event target ${target} for event ${eventName}`); + } + return this.addEventListener(target, eventName, handler); + }; } diff --git a/modules/@angular/platform-browser/src/dom/events/hammer_common.ts b/modules/@angular/platform-browser/src/dom/events/hammer_common.ts deleted file mode 100644 index 602edc4eee..0000000000 --- a/modules/@angular/platform-browser/src/dom/events/hammer_common.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {EventManagerPlugin} from './event_manager'; - -const EVENT_NAMES = { - // pan - 'pan': true, - 'panstart': true, - 'panmove': true, - 'panend': true, - 'pancancel': true, - 'panleft': true, - 'panright': true, - 'panup': true, - 'pandown': true, - // pinch - 'pinch': true, - 'pinchstart': true, - 'pinchmove': true, - 'pinchend': true, - 'pinchcancel': true, - 'pinchin': true, - 'pinchout': true, - // press - 'press': true, - 'pressup': true, - // rotate - 'rotate': true, - 'rotatestart': true, - 'rotatemove': true, - 'rotateend': true, - 'rotatecancel': true, - // swipe - 'swipe': true, - 'swipeleft': true, - 'swiperight': true, - 'swipeup': true, - 'swipedown': true, - // tap - 'tap': true, -}; - -export abstract class HammerGesturesPluginCommon extends EventManagerPlugin { - constructor() { super(); } - - supports(eventName: string): boolean { - return EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()); - } -} diff --git a/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts b/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts index c92d077e9f..e6710db080 100644 --- a/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts +++ b/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts @@ -7,7 +7,45 @@ */ import {Inject, Injectable, OpaqueToken} from '@angular/core'; -import {HammerGesturesPluginCommon} from './hammer_common'; +import {EventManagerPlugin} from './event_manager'; + +const EVENT_NAMES = { + // pan + 'pan': true, + 'panstart': true, + 'panmove': true, + 'panend': true, + 'pancancel': true, + 'panleft': true, + 'panright': true, + 'panup': true, + 'pandown': true, + // pinch + 'pinch': true, + 'pinchstart': true, + 'pinchmove': true, + 'pinchend': true, + 'pinchcancel': true, + 'pinchin': true, + 'pinchout': true, + // press + 'press': true, + 'pressup': true, + // rotate + 'rotate': true, + 'rotatestart': true, + 'rotatemove': true, + 'rotateend': true, + 'rotatecancel': true, + // swipe + 'swipe': true, + 'swipeleft': true, + 'swiperight': true, + 'swipeup': true, + 'swipedown': true, + // tap + 'tap': true, +}; /** * A DI token that you can use to provide{@link HammerGestureConfig} to Angular. Use it to configure @@ -46,11 +84,13 @@ export class HammerGestureConfig { } @Injectable() -export class HammerGesturesPlugin extends HammerGesturesPluginCommon { +export class HammerGesturesPlugin extends EventManagerPlugin { constructor(@Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig) { super(); } supports(eventName: string): boolean { - if (!super.supports(eventName) && !this.isCustomEvent(eventName)) return false; + if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) { + return false; + } if (!(window as any).Hammer) { throw new Error(`Hammer.js is not loaded, can not bind ${eventName} event`); diff --git a/modules/@angular/platform-browser/test/dom/events/hammer_gestures_spec.ts b/modules/@angular/platform-browser/test/dom/events/hammer_gestures_spec.ts new file mode 100644 index 0000000000..84d2a1adfb --- /dev/null +++ b/modules/@angular/platform-browser/test/dom/events/hammer_gestures_spec.ts @@ -0,0 +1,22 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import {describe, expect, it} from '@angular/core/testing/testing_internal'; +import {HammerGestureConfig, HammerGesturesPlugin} from '@angular/platform-browser/src/dom/events/hammer_gestures'; + +export function main() { + describe('HammerGesturesPlugin', () => { + + it('should implement addGlobalEventListener', () => { + const plugin = new HammerGesturesPlugin(new HammerGestureConfig()); + + spyOn(plugin, 'addEventListener').and.callFake(() => {}); + + expect(() => plugin.addGlobalEventListener('document', 'swipe', () => {})).not.toThrowError(); + }); + }); +} diff --git a/modules/@angular/platform-browser/test/dom/events/key_events_spec.ts b/modules/@angular/platform-browser/test/dom/events/key_events_spec.ts index d308a2c6ad..d8b4de8888 100644 --- a/modules/@angular/platform-browser/test/dom/events/key_events_spec.ts +++ b/modules/@angular/platform-browser/test/dom/events/key_events_spec.ts @@ -10,7 +10,7 @@ import {describe, expect, it} from '@angular/core/testing/testing_internal'; import {KeyEventsPlugin} from '@angular/platform-browser/src/dom/events/key_events'; export function main() { - describe('KeyEvents', () => { + describe('KeyEventsPlugin', () => { it('should ignore unrecognized events', () => { expect(KeyEventsPlugin.parseEventName('keydown')).toEqual(null); @@ -58,5 +58,14 @@ export function main() { .toEqual(KeyEventsPlugin.parseEventName('keyup.control.escape')); }); + it('should implement addGlobalEventListener', () => { + const plugin = new KeyEventsPlugin(); + + spyOn(plugin, 'addEventListener').and.callFake(() => {}); + + expect(() => plugin.addGlobalEventListener('window', 'keyup.control.esc', () => {})) + .not.toThrowError(); + }); + }); }