mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat: make hammerjs optional (#2280)
* feat: make hammerjs optional Makes HammerJS and logs a warning if it's missing, instead of crashing the app. * Rename the MdHammerEvent interface. * Replace the HammerJS annotations with stripped-down alternatives. * Remove "hammerjs" from the "types" config.
This commit is contained in:
committed by
Jeremy Elbourn
parent
d076bd319f
commit
28691ca780
+3
-1
@@ -32,11 +32,13 @@
|
||||
"@angular/http": "^2.2.0",
|
||||
"@angular/platform-browser": "^2.2.0",
|
||||
"core-js": "^2.4.1",
|
||||
"hammerjs": "^2.0.8",
|
||||
"rxjs": "5.0.0-beta.12",
|
||||
"systemjs": "0.19.38",
|
||||
"zone.js": "^0.6.23"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"hammerjs": "^2.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "^2.2.0",
|
||||
"@angular/platform-browser-dynamic": "^2.2.0",
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
"@angular/material": [
|
||||
"../../dist/@angular/material"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"hammerjs"
|
||||
]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"genDir": "../../dist",
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
"@angular/material": [
|
||||
"../../dist/@angular/material"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"hammerjs"
|
||||
]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"genDir": "../../dist",
|
||||
|
||||
@@ -50,6 +50,7 @@ export * from './overlay/position/connected-position';
|
||||
|
||||
// Gestures
|
||||
export {GestureConfig} from './gestures/gesture-config';
|
||||
export * from './gestures/gesture-annotations';
|
||||
|
||||
// Ripple
|
||||
export {MdRipple, MdRippleModule} from './ripple/ripple';
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Stripped-down HammerJS annotations to be used within Material, which are necessary,
|
||||
* because HammerJS is an optional dependency. For the full annotations see:
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/hammerjs
|
||||
*/
|
||||
|
||||
/** @docs-private */
|
||||
export interface HammerInput {
|
||||
preventDefault: () => {};
|
||||
deltaX: number;
|
||||
deltaY: number;
|
||||
center: { x: number; y: number; };
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface HammerStatic {
|
||||
new(element: HTMLElement | SVGElement, options?: any): HammerManager;
|
||||
|
||||
Pan: Recognizer;
|
||||
Swipe: Recognizer;
|
||||
Press: Recognizer;
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface Recognizer {
|
||||
new(options?: any): Recognizer;
|
||||
recognizeWith(otherRecognizer: Recognizer | string): Recognizer;
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface RecognizerStatic {
|
||||
new(options?: any): Recognizer;
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface HammerInstance {
|
||||
on(eventName: string, callback: Function): void;
|
||||
off(eventName: string, callback: Function): void;
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface HammerManager {
|
||||
add(recogniser: Recognizer | Recognizer[]): Recognizer;
|
||||
set(options: any): HammerManager;
|
||||
emit(event: string, data: any): void;
|
||||
off(events: string, handler?: Function): void;
|
||||
on(events: string, handler: Function): void;
|
||||
}
|
||||
@@ -1,19 +1,32 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Injectable, isDevMode} from '@angular/core';
|
||||
import {HammerGestureConfig} from '@angular/platform-browser';
|
||||
import {HammerStatic, HammerInstance, Recognizer, RecognizerStatic} from './gesture-annotations';
|
||||
|
||||
/* Adjusts configuration of our gesture library, Hammer. */
|
||||
@Injectable()
|
||||
export class GestureConfig extends HammerGestureConfig {
|
||||
private _hammer: HammerStatic = typeof window !== 'undefined' ? (window as any).Hammer : null;
|
||||
|
||||
/* List of new event names to add to the gesture support list */
|
||||
events: string[] = [
|
||||
events: string[] = this._hammer ? [
|
||||
'longpress',
|
||||
'slide',
|
||||
'slidestart',
|
||||
'slideend',
|
||||
'slideright',
|
||||
'slideleft'
|
||||
];
|
||||
] : [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (!this._hammer && isDevMode()) {
|
||||
console.warn(
|
||||
'Could not find HammerJS. Certain Angular Material ' +
|
||||
'components may not work correctly.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds Hammer instance manually to add custom recognizers that match the Material Design spec.
|
||||
@@ -28,12 +41,12 @@ export class GestureConfig extends HammerGestureConfig {
|
||||
* TODO: Confirm threshold numbers with Material Design UX Team
|
||||
* */
|
||||
buildHammer(element: HTMLElement) {
|
||||
const mc = new Hammer(element);
|
||||
const mc = new this._hammer(element);
|
||||
|
||||
// Default Hammer Recognizers.
|
||||
let pan = new Hammer.Pan();
|
||||
let swipe = new Hammer.Swipe();
|
||||
let press = new Hammer.Press();
|
||||
let pan = new this._hammer.Pan();
|
||||
let swipe = new this._hammer.Swipe();
|
||||
let press = new this._hammer.Press();
|
||||
|
||||
// Notice that a HammerJS recognizer can only depend on one other recognizer once.
|
||||
// Otherwise the previous `recognizeWith` will be dropped.
|
||||
@@ -46,12 +59,12 @@ export class GestureConfig extends HammerGestureConfig {
|
||||
// Add customized gestures to Hammer manager
|
||||
mc.add([swipe, press, pan, slide, longpress]);
|
||||
|
||||
return mc;
|
||||
return mc as HammerInstance;
|
||||
}
|
||||
|
||||
/** Creates a new recognizer, without affecting the default recognizers of HammerJS */
|
||||
private _createRecognizer(base: Recognizer, options: any, ...inheritances: Recognizer[]) {
|
||||
let recognizer = new (<RecognizerStatic> base.constructor)(options);
|
||||
let recognizer = new (base.constructor as RecognizerStatic)(options);
|
||||
|
||||
inheritances.push(base);
|
||||
inheritances.forEach(item => recognizer.recognizeWith(item));
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
applyCssTransform,
|
||||
coerceBooleanProperty,
|
||||
GestureConfig,
|
||||
HammerInput,
|
||||
DefaultStyleCompatibilityModeModule,
|
||||
} from '../core';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
|
||||
@@ -14,11 +14,11 @@ import {NG_VALUE_ACCESSOR, ControlValueAccessor, FormsModule} from '@angular/for
|
||||
import {HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
|
||||
import {
|
||||
GestureConfig,
|
||||
HammerInput,
|
||||
coerceBooleanProperty,
|
||||
coerceNumberProperty,
|
||||
DefaultStyleCompatibilityModeModule,
|
||||
} from '../core';
|
||||
import {Input as HammerInput} from 'hammerjs';
|
||||
import {Dir} from '../core/rtl/dir';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {
|
||||
@@ -32,7 +32,6 @@ import {
|
||||
DOWN_ARROW,
|
||||
} from '../core/keyboard/keycodes';
|
||||
|
||||
|
||||
/**
|
||||
* Visually, a 30px separation between tick marks looks best. This is very subjective but it is
|
||||
* the default separation we chose.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {GestureConfig} from '../core';
|
||||
import {GestureConfig, HammerManager} from '../core';
|
||||
|
||||
/**
|
||||
* An extension of GestureConfig that exposes the underlying HammerManager instances.
|
||||
@@ -17,7 +17,7 @@ export class TestGestureConfig extends GestureConfig {
|
||||
* Create a mapping of Hammer instances to element so that events can be emitted during testing.
|
||||
*/
|
||||
buildHammer(element: HTMLElement) {
|
||||
let mc = super.buildHammer(element);
|
||||
let mc = super.buildHammer(element) as HammerManager;
|
||||
|
||||
if (this.hammerInstances.get(element)) {
|
||||
this.hammerInstances.get(element).push(mc);
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
"stripInternal": false,
|
||||
"typeRoots": [
|
||||
"../../node_modules/@types"
|
||||
],
|
||||
"types": [
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
|
||||
Reference in New Issue
Block a user