@@ -11,6 +11,7 @@ import {Directionality} from '@angular/cdk/bidi';
11
11
import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
12
12
import { ESCAPE } from '@angular/cdk/keycodes' ;
13
13
import { BreakpointObserver , Breakpoints , BreakpointState } from '@angular/cdk/layout' ;
14
+ import { HammerLoader , HAMMER_LOADER } from '@angular/platform-browser' ;
14
15
import {
15
16
FlexibleConnectedPositionStrategy ,
16
17
HorizontalConnectionPos ,
@@ -201,27 +202,34 @@ export class MatTooltip implements OnDestroy {
201
202
private _scrollDispatcher : ScrollDispatcher ,
202
203
private _viewContainerRef : ViewContainerRef ,
203
204
private _ngZone : NgZone ,
204
- private _platform : Platform ,
205
+ platform : Platform ,
205
206
private _ariaDescriber : AriaDescriber ,
206
207
private _focusMonitor : FocusMonitor ,
207
208
@Inject ( MAT_TOOLTIP_SCROLL_STRATEGY ) scrollStrategy : any ,
208
209
@Optional ( ) private _dir : Directionality ,
209
210
@Optional ( ) @Inject ( MAT_TOOLTIP_DEFAULT_OPTIONS )
210
- private _defaultOptions : MatTooltipDefaultOptions ) {
211
+ private _defaultOptions : MatTooltipDefaultOptions ,
212
+ @Optional ( ) @Inject ( HAMMER_LOADER ) hammerLoader ?: HammerLoader ) {
211
213
212
214
this . _scrollStrategy = scrollStrategy ;
213
215
const element : HTMLElement = _elementRef . nativeElement ;
214
216
const elementStyle = element . style as CSSStyleDeclaration & { webkitUserDrag : string } ;
217
+ const hasGestures = typeof window === 'undefined' || ( window as any ) . Hammer || hammerLoader ;
215
218
216
219
// The mouse events shouldn't be bound on mobile devices, because they can prevent the
217
220
// first tap from firing its click event or can cause the tooltip to open for clicks.
218
- if ( ! _platform . IOS && ! _platform . ANDROID ) {
221
+ if ( ! platform . IOS && ! platform . ANDROID ) {
219
222
this . _manualListeners
220
223
. set ( 'mouseenter' , ( ) => this . show ( ) )
221
- . set ( 'mouseleave' , ( ) => this . hide ( ) )
222
- . forEach ( ( listener , event ) => element . addEventListener ( event , listener ) ) ;
224
+ . set ( 'mouseleave' , ( ) => this . hide ( ) ) ;
225
+ } else if ( ! hasGestures ) {
226
+ // If Hammerjs isn't loaded, fall back to showing on `touchstart`, otherwise
227
+ // there's no way for the user to trigger the tooltip on a touch device.
228
+ this . _manualListeners . set ( 'touchstart' , ( ) => this . show ( ) ) ;
223
229
}
224
230
231
+ this . _manualListeners . forEach ( ( listener , event ) => element . addEventListener ( event , listener ) ) ;
232
+
225
233
if ( element . nodeName === 'INPUT' || element . nodeName === 'TEXTAREA' ) {
226
234
// When we bind a gesture event on an element (in this case `longpress`), HammerJS
227
235
// will add some inline styles by default, including `user-select: none`. This is
@@ -258,12 +266,10 @@ export class MatTooltip implements OnDestroy {
258
266
}
259
267
260
268
// Clean up the event listeners set in the constructor
261
- if ( ! this . _platform . IOS ) {
262
- this . _manualListeners . forEach ( ( listener , event ) =>
263
- this . _elementRef . nativeElement . removeEventListener ( event , listener ) ) ;
264
-
265
- this . _manualListeners . clear ( ) ;
266
- }
269
+ this . _manualListeners . forEach ( ( listener , event ) => {
270
+ this . _elementRef . nativeElement . removeEventListener ( event , listener ) ;
271
+ } ) ;
272
+ this . _manualListeners . clear ( ) ;
267
273
268
274
this . _destroyed . next ( ) ;
269
275
this . _destroyed . complete ( ) ;
0 commit comments