fix(events): provide the ability to register global hammer.js events
closes #12797
This commit is contained in:
parent
92f244aa26
commit
768cddbe62
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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`);
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue