/** * Custom HammerJS configuration forked from Angular Material. With Angular v9, * Angular Material dropped HammerJS as a dependency. This configuration was added * automatically to this application because ng-update detected that this application * directly used custom HammerJS gestures defined by Angular Material. * * Read more in the dedicated guide: https://git.io/ng-material-v9-hammer-migration */ import {Injectable, Inject, Optional, Type} from '@angular/core'; import {HammerGestureConfig} from '@angular/platform-browser'; import {MAT_HAMMER_OPTIONS} from '@angular/material/core'; /** * Noop hammer instance that is used when an instance is requested, but * Hammer has not been loaded on the page yet. */ const noopHammerInstance = { on: () => {}, off: () => {}, }; /** * Gesture config that provides custom Hammer gestures on top of the default Hammer * gestures. These gestures will be available as events in component templates. */ @Injectable() export class GestureConfig extends HammerGestureConfig { /** List of event names to add to the Hammer gesture plugin list */ events = [ 'longpress', 'slide', 'slidestart', 'slideend', 'slideright', 'slideleft' ]; constructor(@Optional() @Inject(MAT_HAMMER_OPTIONS) private hammerOptions?: any) { super(); } /** * Builds Hammer instance manually to add custom recognizers that match the * Material Design specification. Gesture names originate from the Material Design * gestures: https://material.io/design/#gestures-touch-mechanics * * More information on default recognizers can be found in the Hammer docs: * http://hammerjs.github.io/recognizer-pan/ * http://hammerjs.github.io/recognizer-press/ * @param element Element to which to assign the new HammerJS gestures. * @returns Newly-created HammerJS instance. */ buildHammer(element: HTMLElement): any { const hammer: any = typeof window !== 'undefined' ? (window as any).Hammer : null; if (!hammer) { return noopHammerInstance; } const mc = new hammer(element, this.hammerOptions || undefined); // Default Hammer Recognizers. const pan = new hammer.Pan(); const swipe = new hammer.Swipe(); const press = new hammer.Press(); // Notice that a HammerJS recognizer can only depend on one other recognizer once. // Otherwise the previous `recognizeWith` will be dropped. const slide = this._createRecognizer(pan, {event: 'slide', threshold: 0}, swipe); const longpress = this._createRecognizer(press, {event: 'longpress', time: 500}); // Overwrite the default `pan` event to use the swipe event. pan.recognizeWith(swipe); // Since the slide event threshold is set to zero, the slide recognizer can fire and // accidentally reset the longpress recognizer. In order to make sure that the two // recognizers can run simultaneously but don't affect each other, we allow the slide // recognizer to recognize while a longpress is being processed. // See: https://github.com/hammerjs/hammer.js/blob/master/src/manager.js#L123-L124 longpress.recognizeWith(slide); // Add customized gestures to Hammer manager mc.add([swipe, press, pan, slide, longpress]); return mc; } /** Creates a new recognizer, without affecting the default recognizers of HammerJS */ private _createRecognizer(base: object, options: any, ...inheritances: object[]) { const recognizer = new (base.constructor as Type)(options); inheritances.push(base); inheritances.forEach(item => recognizer.recognizeWith(item)); return recognizer; } }