Skip to content

Commit

Permalink
feat(platform-browser): expose EventManagerPlugin in the public API.
Browse files Browse the repository at this point in the history
The exposed type of the `EVENT_MANAGER_PLUGINS` token should be in the public API.
  • Loading branch information
JeanMeche committed Apr 25, 2023
1 parent 92897b4 commit 09dd296
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 43 deletions.
Expand Up @@ -971,6 +971,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -1169,6 +1172,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down
Expand Up @@ -740,6 +740,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -917,6 +920,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down
Expand Up @@ -809,6 +809,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -980,6 +983,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down Expand Up @@ -1103,6 +1109,9 @@
{
"name": "ngZoneApplicationErrorHandlerFactory"
},
{
"name": "noSideEffects"
},
{
"name": "nonNull"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/core/test/bundling/router/bundle.golden_symbols.json
Expand Up @@ -2102,6 +2102,9 @@
{
"name": "ɵɵelementStart"
},
{
"name": "ɵɵgetInheritedFactory"
},
{
"name": "ɵɵinject"
},
Expand Down
Expand Up @@ -662,6 +662,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -809,6 +812,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down Expand Up @@ -902,6 +908,9 @@
{
"name": "ngZoneApplicationErrorHandlerFactory"
},
{
"name": "noSideEffects"
},
{
"name": "nonNull"
},
Expand Down
6 changes: 6 additions & 0 deletions packages/core/test/bundling/todo/bundle.golden_symbols.json
Expand Up @@ -878,6 +878,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -1103,6 +1106,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down
6 changes: 1 addition & 5 deletions packages/core/test/render3/imported_renderer2.ts
Expand Up @@ -17,10 +17,6 @@ import {EventManagerPlugin} from '@angular/platform-browser/src/dom/events/event
import {isTextNode} from '@angular/platform-browser/testing/src/browser_util';

export class SimpleDomEventsPlugin extends EventManagerPlugin {
constructor(doc: any) {
super(doc);
}

override supports(eventName: string): boolean {
return true;
}
Expand All @@ -38,7 +34,7 @@ export class SimpleDomEventsPlugin extends EventManagerPlugin {

export function getRendererFactory2(document: any): RendererFactory2 {
const fakeNgZone: NgZone = new NoopNgZone();
const eventManager = new EventManager([new SimpleDomEventsPlugin(document)], fakeNgZone);
const eventManager = new EventManager([new SimpleDomEventsPlugin()], fakeNgZone);
const appId = 'appid';
const rendererFactory = new ɵDomRendererFactory2(
eventManager, new ɵSharedStylesHost(document, appId), appId, true, document,
Expand Down
10 changes: 3 additions & 7 deletions packages/platform-browser/src/dom/events/dom_events.ts
Expand Up @@ -6,24 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/

import {DOCUMENT} from '@angular/common';
import {Inject, Injectable} from '@angular/core';
import {Injectable} from '@angular/core';

import {EventManagerPlugin} from './event_manager';

@Injectable()
export class DomEventsPlugin extends EventManagerPlugin {
constructor(@Inject(DOCUMENT) doc: any) {
super(doc);
}

// This plugin should come last in the list of plugins, because it accepts all
// events.
override supports(eventName: string): boolean {
return true;
}

override addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
override addEventListener(
element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void {
element.addEventListener(eventName, handler as EventListener, false);
return () => this.removeEventListener(element, eventName, handler as EventListener);
}
Expand Down
21 changes: 16 additions & 5 deletions packages/platform-browser/src/dom/events/event_manager.ts
Expand Up @@ -9,7 +9,7 @@
import {Inject, Injectable, InjectionToken, NgZone} from '@angular/core';

/**
* The injection token for the event-manager plug-in service.
* The injection token for plugins of the `EventManager` service.
*
* @publicApi
*/
Expand Down Expand Up @@ -48,7 +48,7 @@ export class EventManager {
*/
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
const plugin = this._findPluginFor(eventName);
return plugin.addEventListener(element, eventName, handler);
return plugin.addEventListener(element, eventName, handler as (event: Event) => void);
}

/**
Expand Down Expand Up @@ -77,13 +77,24 @@ export class EventManager {
}
}

/**
* The plugin definition for the `EventManager` class
*
* @publicApi
*/
@Injectable()
export abstract class EventManagerPlugin {
constructor(private _doc: any) {}

// 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;

abstract addEventListener(element: HTMLElement, eventName: string, handler: Function): Function;
/**
* Implement the behaviour for the supported events
*/
abstract addEventListener(
element: HTMLElement, eventName: string, handler: (event: Event) => void): Function;
}
5 changes: 2 additions & 3 deletions packages/platform-browser/src/dom/events/hammer_gestures.ts
Expand Up @@ -165,10 +165,9 @@ export class HammerGesturesPlugin extends EventManagerPlugin {
private _loaderPromise: Promise<void>|null = null;

constructor(
@Inject(DOCUMENT) doc: any,
@Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig, private console: Console,
@Optional() @Inject(HAMMER_LOADER) private loader?: HammerLoader|null) {
super(doc);
super();
}

override supports(eventName: string): boolean {
Expand Down Expand Up @@ -272,7 +271,7 @@ export class HammerGesturesPlugin extends EventManagerPlugin {
* HammerJS to detect gesture events.
*
* Note that applications still need to include the HammerJS script itself. This module
* simply sets up the coordination layer between HammerJS and Angular's EventManager.
* simply sets up the coordination layer between HammerJS and Angular's `EventManager`.
*
* @publicApi
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/platform-browser/src/dom/events/key_events.ts
Expand Up @@ -54,8 +54,9 @@ export class KeyEventsPlugin extends EventManagerPlugin {
* Initializes an instance of the browser plug-in.
* @param doc The document in which key events will be detected.
*/
// TODO: doc is unused and should be remove in the next major.
constructor(@Inject(DOCUMENT) doc: any) {
super(doc);
super();
}

/**
Expand Down Expand Up @@ -188,7 +189,6 @@ export class KeyEventsPlugin extends EventManagerPlugin {

/** @internal */
static _normalizeKey(keyName: string): string {
// TODO: switch to a Map if the mapping grows too much
switch (keyName) {
case 'esc':
return 'escape';
Expand Down
2 changes: 1 addition & 1 deletion packages/platform-browser/src/platform-browser.ts
Expand Up @@ -73,7 +73,7 @@ export {Title} from './browser/title';
export {disableDebugTools, enableDebugTools} from './browser/tools/tools';
export {By} from './dom/debug/by';
export {REMOVE_STYLES_ON_COMPONENT_DESTROY} from './dom/dom_renderer';
export {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
export {EVENT_MANAGER_PLUGINS, EventManager, EventManagerPlugin} from './dom/events/event_manager';
export {HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerLoader, HammerModule} from './dom/events/hammer_gestures';
export {DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl, SafeValue} from './security/dom_sanitization_service';
export {HydrationFeature, provideClientHydration, HydrationFeatureKind, withNoDomReuse, withNoHttpTransferCache} from './hydration';
Expand Down
22 changes: 11 additions & 11 deletions packages/platform-browser/test/dom/events/event_manager_spec.ts
Expand Up @@ -23,14 +23,14 @@ describe('EventManager', () => {
beforeEach(() => {
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
zone = new NgZone({});
domEventPlugin = new DomEventsPlugin(doc);
domEventPlugin = new DomEventsPlugin();
});

it('should delegate event bindings to plugins that are passed in from the most generic one to the most specific one',
() => {
const element = el('<div></div>');
const handler = (e: any /** TODO #9100 */) => e;
const plugin = new FakeEventManagerPlugin(doc, ['click']);
const plugin = new FakeEventManagerPlugin(['click']);
const manager = new EventManager([domEventPlugin, plugin], new FakeNgZone());
manager.addEventListener(element, 'click', handler);
expect(plugin.eventHandler['click']).toBe(handler);
Expand All @@ -40,8 +40,8 @@ describe('EventManager', () => {
const element = el('<div></div>');
const clickHandler = (e: any /** TODO #9100 */) => e;
const dblClickHandler = (e: any /** TODO #9100 */) => e;
const plugin1 = new FakeEventManagerPlugin(doc, ['dblclick']);
const plugin2 = new FakeEventManagerPlugin(doc, ['click', 'dblclick']);
const plugin1 = new FakeEventManagerPlugin(['dblclick']);
const plugin2 = new FakeEventManagerPlugin(['click', 'dblclick']);
const manager = new EventManager([plugin2, plugin1], new FakeNgZone());
manager.addEventListener(element, 'click', clickHandler);
manager.addEventListener(element, 'dblclick', dblClickHandler);
Expand All @@ -51,7 +51,7 @@ describe('EventManager', () => {

it('should throw when no plugin can handle the event', () => {
const element = el('<div></div>');
const plugin = new FakeEventManagerPlugin(doc, ['dblclick']);
const plugin = new FakeEventManagerPlugin(['dblclick']);
const manager = new EventManager([plugin], new FakeNgZone());
expect(() => manager.addEventListener(element, 'click', null!))
.toThrowError('No event manager plugin found for event click');
Expand Down Expand Up @@ -326,7 +326,7 @@ describe('EventManager', () => {
(done: DoneFn) => {
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
domEventPlugin = new DomEventsPlugin(doc);
domEventPlugin = new DomEventsPlugin();
const element = el('<div></div>');
const child = el('<div></div>');
element.appendChild(child);
Expand Down Expand Up @@ -363,7 +363,7 @@ describe('EventManager', () => {
(done: DoneFn) => {
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
domEventPlugin = new DomEventsPlugin(doc);
domEventPlugin = new DomEventsPlugin();
const element = el('<div></div>');
const child = el('<div></div>');
element.appendChild(child);
Expand Down Expand Up @@ -400,7 +400,7 @@ describe('EventManager', () => {
(done: DoneFn) => {
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
domEventPlugin = new DomEventsPlugin(doc);
domEventPlugin = new DomEventsPlugin();
const element = el('<div></div>');
const child = el('<div></div>');
doc.body.appendChild(element);
Expand Down Expand Up @@ -446,7 +446,7 @@ describe('EventManager', () => {
(done: DoneFn) => {
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
domEventPlugin = new DomEventsPlugin(doc);
domEventPlugin = new DomEventsPlugin();
const element = el('<div></div>');
const child = el('<div></div>');
doc.body.appendChild(element);
Expand Down Expand Up @@ -494,8 +494,8 @@ describe('EventManager', () => {
class FakeEventManagerPlugin extends EventManagerPlugin {
eventHandler: {[event: string]: Function} = {};

constructor(doc: any, public supportedEvents: string[]) {
super(doc);
constructor(public supportedEvents: string[]) {
super();
}

override supports(eventName: string): boolean {
Expand Down
Expand Up @@ -27,7 +27,7 @@ import {HammerGestureConfig, HammerGesturesPlugin,} from '@angular/platform-brow

describe('with no custom loader', () => {
beforeEach(() => {
plugin = new HammerGesturesPlugin(document, new HammerGestureConfig(), fakeConsole);
plugin = new HammerGesturesPlugin(new HammerGestureConfig(), fakeConsole);
});

it('should warn user and do nothing when Hammer.js not loaded', () => {
Expand Down Expand Up @@ -88,7 +88,7 @@ import {HammerGestureConfig, HammerGesturesPlugin,} from '@angular/platform-brow
const hammerConfig = new HammerGestureConfig();
spyOn(hammerConfig, 'buildHammer').and.returnValue(fakeHammerInstance);

plugin = new HammerGesturesPlugin(document, hammerConfig, fakeConsole, loader);
plugin = new HammerGesturesPlugin(hammerConfig, fakeConsole, loader);

// Use a fake EventManager that has access to the NgZone.
plugin.manager = {getZone: () => ngZone} as EventManager;
Expand Down

0 comments on commit 09dd296

Please sign in to comment.