-
Notifications
You must be signed in to change notification settings - Fork 24.7k
/
event_manager.ts
100 lines (89 loc) 路 2.84 KB
/
event_manager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* @license
* Copyright Google LLC 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 {Inject, Injectable, InjectionToken, NgZone} from '@angular/core';
/**
* The injection token for plugins of the `EventManager` service.
*
* @publicApi
*/
export const EVENT_MANAGER_PLUGINS =
new InjectionToken<EventManagerPlugin[]>('EventManagerPlugins');
/**
* An injectable service that provides event management for Angular
* through a browser plug-in.
*
* @publicApi
*/
@Injectable()
export class EventManager {
private _plugins: EventManagerPlugin[];
private _eventNameToPlugin = new Map<string, EventManagerPlugin>();
/**
* Initializes an instance of the event-manager service.
*/
constructor(@Inject(EVENT_MANAGER_PLUGINS) plugins: EventManagerPlugin[], private _zone: NgZone) {
plugins.forEach((plugin) => {
plugin.manager = this;
});
this._plugins = plugins.slice().reverse();
}
/**
* Registers a handler for a specific element and event.
*
* @param element The HTML element to receive event notifications.
* @param eventName The name of the event to listen for.
* @param handler A function to call when the notification occurs. Receives the
* event object as an argument.
* @returns A callback function that can be used to remove the handler.
*/
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
const plugin = this._findPluginFor(eventName);
return plugin.addEventListener(element, eventName, handler as (event: Event) => void);
}
/**
* Retrieves the compilation zone in which event listeners are registered.
*/
getZone(): NgZone {
return this._zone;
}
/** @internal */
_findPluginFor(eventName: string): EventManagerPlugin {
const plugin = this._eventNameToPlugin.get(eventName);
if (plugin) {
return plugin;
}
const plugins = this._plugins;
for (let i = 0; i < plugins.length; i++) {
const plugin = plugins[i];
if (plugin.supports(eventName)) {
this._eventNameToPlugin.set(eventName, plugin);
return plugin;
}
}
throw new Error(`No event manager plugin found for event ${eventName}`);
}
}
/**
* The plugin definition for the `EventManager` class
*
* @publicApi
*/
@Injectable()
export abstract class EventManagerPlugin {
// Using non-null assertion because it's set by EventManager's constructor
manager!: EventManager;
/**
* Should return `true` for every event name that should be supported by this plugin
*/
abstract supports(eventName: string): boolean;
/**
* Implement the behaviour for the supported events
*/
abstract addEventListener(
element: HTMLElement, eventName: string, handler: (event: Event) => void): Function;
}