@@ -11,6 +11,7 @@ import {Directionality} from '@angular/cdk/bidi';
1111import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
1212import { ESCAPE } from '@angular/cdk/keycodes' ;
1313import { BreakpointObserver , Breakpoints , BreakpointState } from '@angular/cdk/layout' ;
14+ import { HammerLoader , HAMMER_LOADER } from '@angular/platform-browser' ;
1415import {
1516 FlexibleConnectedPositionStrategy ,
1617 HorizontalConnectionPos ,
@@ -201,27 +202,34 @@ export class MatTooltip implements OnDestroy {
201202 private _scrollDispatcher : ScrollDispatcher ,
202203 private _viewContainerRef : ViewContainerRef ,
203204 private _ngZone : NgZone ,
204- private _platform : Platform ,
205+ platform : Platform ,
205206 private _ariaDescriber : AriaDescriber ,
206207 private _focusMonitor : FocusMonitor ,
207208 @Inject ( MAT_TOOLTIP_SCROLL_STRATEGY ) scrollStrategy : any ,
208209 @Optional ( ) private _dir : Directionality ,
209210 @Optional ( ) @Inject ( MAT_TOOLTIP_DEFAULT_OPTIONS )
210- private _defaultOptions : MatTooltipDefaultOptions ) {
211+ private _defaultOptions : MatTooltipDefaultOptions ,
212+ @Optional ( ) @Inject ( HAMMER_LOADER ) hammerLoader ?: HammerLoader ) {
211213
212214 this . _scrollStrategy = scrollStrategy ;
213215 const element : HTMLElement = _elementRef . nativeElement ;
214216 const elementStyle = element . style as CSSStyleDeclaration & { webkitUserDrag : string } ;
217+ const hasGestures = typeof window === 'undefined' || ( window as any ) . Hammer || hammerLoader ;
215218
216219 // The mouse events shouldn't be bound on mobile devices, because they can prevent the
217220 // 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 ) {
219222 this . _manualListeners
220223 . 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 ( ) ) ;
223229 }
224230
231+ this . _manualListeners . forEach ( ( listener , event ) => element . addEventListener ( event , listener ) ) ;
232+
225233 if ( element . nodeName === 'INPUT' || element . nodeName === 'TEXTAREA' ) {
226234 // When we bind a gesture event on an element (in this case `longpress`), HammerJS
227235 // will add some inline styles by default, including `user-select: none`. This is
@@ -258,12 +266,10 @@ export class MatTooltip implements OnDestroy {
258266 }
259267
260268 // 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 ( ) ;
267273
268274 this . _destroyed . next ( ) ;
269275 this . _destroyed . complete ( ) ;
0 commit comments