fix(events): provide the ability to register global hammer.js events

closes #12797
This commit is contained in:
Dzmitry Shylovich 2016-11-11 01:46:23 +03:00 committed by Victor Berchet
parent 92f244aa26
commit 768cddbe62
6 changed files with 84 additions and 85 deletions

View File

@ -19,22 +19,4 @@ export class DomEventsPlugin extends EventManagerPlugin {
element.addEventListener(eventName, handler as any, false); element.addEventListener(eventName, handler as any, false);
return () => element.removeEventListener(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);
}
} }

View File

@ -51,17 +51,18 @@ export class EventManager {
} }
} }
export class EventManagerPlugin { export abstract class EventManagerPlugin {
manager: EventManager; manager: EventManager;
// That is equivalent to having supporting $event.target abstract supports(eventName: string): boolean;
supports(eventName: string): boolean { return false; }
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function { abstract addEventListener(element: HTMLElement, eventName: string, handler: Function): Function;
throw 'not implemented';
}
addGlobalEventListener(element: string, 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);
};
} }

View File

@ -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());
}
}

View File

@ -7,7 +7,45 @@
*/ */
import {Inject, Injectable, OpaqueToken} from '@angular/core'; 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 * 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() @Injectable()
export class HammerGesturesPlugin extends HammerGesturesPluginCommon { export class HammerGesturesPlugin extends EventManagerPlugin {
constructor(@Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig) { super(); } constructor(@Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig) { super(); }
supports(eventName: string): boolean { 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) { if (!(window as any).Hammer) {
throw new Error(`Hammer.js is not loaded, can not bind ${eventName} event`); throw new Error(`Hammer.js is not loaded, can not bind ${eventName} event`);

View File

@ -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();
});
});
}

View File

@ -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'; import {KeyEventsPlugin} from '@angular/platform-browser/src/dom/events/key_events';
export function main() { export function main() {
describe('KeyEvents', () => { describe('KeyEventsPlugin', () => {
it('should ignore unrecognized events', () => { it('should ignore unrecognized events', () => {
expect(KeyEventsPlugin.parseEventName('keydown')).toEqual(null); expect(KeyEventsPlugin.parseEventName('keydown')).toEqual(null);
@ -58,5 +58,14 @@ export function main() {
.toEqual(KeyEventsPlugin.parseEventName('keyup.control.escape')); .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();
});
}); });
} }