feat(ivy): make Hammer support tree-shakable (#32203)

Currently, it's not possible to tree-shake away the
coordination layer between HammerJS and Angular's
EventManager. This means that you get the HammerJS
support code in your production bundle whether or
not you actually use the library.

This commit removes the Hammer providers from the
default platform_browser providers list and instead
provides them as part of a `HammerModule`. Apps on
Ivy just need to import the `HammerModule` at root
to turn on Hammer support. Otherwise all Hammer code
will tree-shake away. View Engine apps will require
no change.

BREAKING CHANGE

Previously, in Ivy applications, Hammer providers
were included by default. With this commit, apps
that want Hammer support must import `HammerModule`
in their root module.

PR Close #32203
This commit is contained in:
Kara Erickson
2019-08-19 20:00:26 -07:00
committed by Andrew Kushnir
parent 0287b234ea
commit de8ebbdfd0
6 changed files with 193 additions and 14 deletions

View File

@ -17,7 +17,7 @@ import {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
import {DomRendererFactory2} from './dom/dom_renderer';
import {DomEventsPlugin} from './dom/events/dom_events';
import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
import {HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerGesturesPlugin} from './dom/events/hammer_gestures';
import {HAMMER_PROVIDERS} from './dom/events/hammer_gestures';
import {KeyEventsPlugin} from './dom/events/key_events';
import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host';
import {DomSanitizer, DomSanitizerImpl} from './security/dom_sanitization_service';
@ -77,13 +77,7 @@ export const BROWSER_MODULE_PROVIDERS: StaticProvider[] = [
deps: [DOCUMENT, NgZone, PLATFORM_ID]
},
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true, deps: [DOCUMENT]},
{
provide: EVENT_MANAGER_PLUGINS,
useClass: HammerGesturesPlugin,
multi: true,
deps: [DOCUMENT, HAMMER_GESTURE_CONFIG, Console, [new Optional(), HAMMER_LOADER]]
},
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig, deps: []},
HAMMER_PROVIDERS,
{
provide: DomRendererFactory2,
useClass: DomRendererFactory2,

View File

@ -7,9 +7,11 @@
*/
import {DOCUMENT} from '@angular/common';
import {Inject, Injectable, InjectionToken, Optional, ɵConsole as Console} from '@angular/core';
import {Inject, Injectable, InjectionToken, NgModule, Optional, Provider, ɵConsole as Console} from '@angular/core';
import {EVENT_MANAGER_PLUGINS, EventManagerPlugin} from './event_manager';
import {EventManagerPlugin} from './event_manager';
/**
* Supported HammerJS recognizer event names.
@ -56,6 +58,7 @@ const EVENT_NAMES = {
* DI token for providing [HammerJS](http://hammerjs.github.io/) support to Angular.
* @see `HammerGestureConfig`
*
* @ngModule HammerModule
* @publicApi
*/
export const HAMMER_GESTURE_CONFIG = new InjectionToken<HammerGestureConfig>('HammerGestureConfig');
@ -149,6 +152,11 @@ export class HammerGestureConfig {
}
}
/**
* Event plugin that adds Hammer support to an application.
*
* @ngModule HammerModule
*/
@Injectable()
export class HammerGesturesPlugin extends EventManagerPlugin {
constructor(
@ -234,3 +242,40 @@ export class HammerGesturesPlugin extends EventManagerPlugin {
isCustomEvent(eventName: string): boolean { return this._config.events.indexOf(eventName) > -1; }
}
/**
* In Ivy, support for Hammer gestures is optional, so applications must
* import the `HammerModule` at root to turn on support. This means that
* Hammer-specific code can be tree-shaken away if not needed.
*/
export const HAMMER_PROVIDERS__POST_R3__ = [];
/**
* In View Engine, support for Hammer gestures is built-in by default.
*/
export const HAMMER_PROVIDERS__PRE_R3__: Provider[] = [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: HammerGesturesPlugin,
multi: true,
deps: [DOCUMENT, HAMMER_GESTURE_CONFIG, Console, [new Optional(), HAMMER_LOADER]]
},
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig, deps: []},
];
export const HAMMER_PROVIDERS = HAMMER_PROVIDERS__PRE_R3__;
/**
* Adds support for HammerJS.
*
* Import this module at the root of your application so that Angular can work with
* 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.
*
* @publicApi
*/
@NgModule({providers: HAMMER_PROVIDERS__PRE_R3__})
export class HammerModule {
}

View File

@ -13,7 +13,7 @@ export {disableDebugTools, enableDebugTools} from './browser/tools/tools';
export {BrowserTransferStateModule, StateKey, TransferState, makeStateKey} from './browser/transfer_state';
export {By} from './dom/debug/by';
export {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
export {HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerLoader} from './dom/events/hammer_gestures';
export {HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HAMMER_PROVIDERS__POST_R3__ as ɵHAMMER_PROVIDERS__POST_R3__, HammerGestureConfig, HammerLoader, HammerModule} from './dom/events/hammer_gestures';
export {DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl, SafeValue} from './security/dom_sanitization_service';
export * from './private_export';