diff --git a/packages/platform-browser/src/dom/events/hammer_gestures.ts b/packages/platform-browser/src/dom/events/hammer_gestures.ts index 015feeaf6a..11f9a70f3c 100644 --- a/packages/platform-browser/src/dom/events/hammer_gestures.ts +++ b/packages/platform-browser/src/dom/events/hammer_gestures.ts @@ -162,6 +162,8 @@ export class HammerGestureConfig { */ @Injectable() export class HammerGesturesPlugin extends EventManagerPlugin { + private _loaderPromise: Promise|null = null; + constructor( @Inject(DOCUMENT) doc: any, @Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig, private console: Console, @@ -175,9 +177,11 @@ export class HammerGesturesPlugin extends EventManagerPlugin { } if (!(window as any).Hammer && !this.loader) { - this.console.warn( - `The "${eventName}" event cannot be bound because Hammer.JS is not ` + - `loaded and no custom loader has been specified.`); + if (typeof ngDevMode === 'undefined' || ngDevMode) { + this.console.warn( + `The "${eventName}" event cannot be bound because Hammer.JS is not ` + + `loaded and no custom loader has been specified.`); + } return false; } @@ -191,6 +195,7 @@ export class HammerGesturesPlugin extends EventManagerPlugin { // If Hammer is not present but a loader is specified, we defer adding the event listener // until Hammer is loaded. if (!(window as any).Hammer && this.loader) { + this._loaderPromise = this._loaderPromise || this.loader(); // This `addEventListener` method returns a function to remove the added listener. // Until Hammer is loaded, the returned function needs to *cancel* the registration rather // than remove anything. @@ -199,12 +204,14 @@ export class HammerGesturesPlugin extends EventManagerPlugin { cancelRegistration = true; }; - this.loader() + this._loaderPromise .then(() => { // If Hammer isn't actually loaded when the custom loader resolves, give up. if (!(window as any).Hammer) { - this.console.warn( - `The custom HAMMER_LOADER completed, but Hammer.JS is not present.`); + if (typeof ngDevMode === 'undefined' || ngDevMode) { + this.console.warn( + `The custom HAMMER_LOADER completed, but Hammer.JS is not present.`); + } deregister = () => {}; return; } @@ -216,9 +223,11 @@ export class HammerGesturesPlugin extends EventManagerPlugin { } }) .catch(() => { - this.console.warn( - `The "${eventName}" event cannot be bound because the custom ` + - `Hammer.JS loader failed.`); + if (typeof ngDevMode === 'undefined' || ngDevMode) { + this.console.warn( + `The "${eventName}" event cannot be bound because the custom ` + + `Hammer.JS loader failed.`); + } deregister = () => {}; }); diff --git a/packages/platform-browser/test/dom/events/hammer_gestures_spec.ts b/packages/platform-browser/test/dom/events/hammer_gestures_spec.ts index db730fe7bb..715cc5b482 100644 --- a/packages/platform-browser/test/dom/events/hammer_gestures_spec.ts +++ b/packages/platform-browser/test/dom/events/hammer_gestures_spec.ts @@ -67,6 +67,8 @@ import {HammerGestureConfig, HammerGesturesPlugin,} from '@angular/platform-brow ngZone = z; })); + let loaderCalled = 0; + beforeEach(() => { originalHammerGlobal = (window as any).Hammer; (window as any).Hammer = undefined; @@ -76,10 +78,13 @@ import {HammerGestureConfig, HammerGesturesPlugin,} from '@angular/platform-brow off: jasmine.createSpy('mc.off'), }; - loader = () => new Promise((resolve, reject) => { - resolveLoader = resolve; - failLoader = reject; - }); + loader = () => { + loaderCalled++; + return new Promise((resolve, reject) => { + resolveLoader = resolve; + failLoader = reject; + }); + }; // Make the hammer config return a fake hammer instance const hammerConfig = new HammerGestureConfig(); @@ -95,9 +100,19 @@ import {HammerGestureConfig, HammerGesturesPlugin,} from '@angular/platform-brow }); afterEach(() => { + loaderCalled = 0; (window as any).Hammer = originalHammerGlobal; }); + it('should call the loader provider only once', () => { + plugin.addEventListener(someElement, 'swipe', () => {}); + plugin.addEventListener(someElement, 'panleft', () => {}); + plugin.addEventListener(someElement, 'panright', () => {}); + // Ensure that the loader is called only once, because previouly + // it was called the same number of times as `addEventListener` was called. + expect(loaderCalled).toEqual(1); + }); + it('should not log a warning when HammerJS is not loaded', () => { plugin.addEventListener(someElement, 'swipe', () => {}); expect(fakeConsole.warn).not.toHaveBeenCalled();