@@ -10,13 +10,15 @@ import {
1010 Component ,
1111 DebugElement ,
1212 AnimationTransitionEvent ,
13+ ViewChild ,
1314 ChangeDetectionStrategy
1415} from '@angular/core' ;
1516import { By } from '@angular/platform-browser' ;
16- import { TooltipPosition , MdTooltip , MdTooltipModule } from './tooltip' ;
17+ import { TooltipPosition , MdTooltip , MdTooltipModule , SCROLL_THROTTLE_MS } from './tooltip' ;
1718import { OverlayContainer } from '../core' ;
1819import { Dir , LayoutDirection } from '../core/rtl/dir' ;
1920import { OverlayModule } from '../core/overlay/overlay-directives' ;
21+ import { Scrollable } from '../core/overlay/scroll/scrollable' ;
2022
2123const initialTooltipMessage = 'initial tooltip message' ;
2224
@@ -27,10 +29,11 @@ describe('MdTooltip', () => {
2729 beforeEach ( async ( ( ) => {
2830 TestBed . configureTestingModule ( {
2931 imports : [ MdTooltipModule . forRoot ( ) , OverlayModule ] ,
30- declarations : [ BasicTooltipDemo , OnPushTooltipDemo ] ,
32+ declarations : [ BasicTooltipDemo , ScrollableTooltipDemo , OnPushTooltipDemo ] ,
3133 providers : [
3234 { provide : OverlayContainer , useFactory : ( ) => {
3335 overlayContainerElement = document . createElement ( 'div' ) ;
36+ document . body . appendChild ( overlayContainerElement ) ;
3437 return { getContainerElement : ( ) => overlayContainerElement } ;
3538 } } ,
3639 { provide : Dir , useFactory : ( ) => {
@@ -312,6 +315,43 @@ describe('MdTooltip', () => {
312315 } ) ;
313316 } ) ;
314317
318+ describe ( 'scrollable usage' , ( ) => {
319+ let fixture : ComponentFixture < ScrollableTooltipDemo > ;
320+ let buttonDebugElement : DebugElement ;
321+ let buttonElement : HTMLButtonElement ;
322+ let tooltipDirective : MdTooltip ;
323+
324+ beforeEach ( ( ) => {
325+ fixture = TestBed . createComponent ( ScrollableTooltipDemo ) ;
326+ fixture . detectChanges ( ) ;
327+ buttonDebugElement = fixture . debugElement . query ( By . css ( 'button' ) ) ;
328+ buttonElement = < HTMLButtonElement > buttonDebugElement . nativeElement ;
329+ tooltipDirective = buttonDebugElement . injector . get ( MdTooltip ) ;
330+ } ) ;
331+
332+ it ( 'should hide tooltip if clipped after changing positions' , fakeAsync ( ( ) => {
333+ expect ( tooltipDirective . _tooltipInstance ) . toBeUndefined ( ) ;
334+
335+ // Show the tooltip and tick for the show delay (default is 0)
336+ tooltipDirective . show ( ) ;
337+ fixture . detectChanges ( ) ;
338+ tick ( 0 ) ;
339+
340+ // Expect that the tooltip is displayed
341+ expect ( tooltipDirective . _isTooltipVisible ( ) ) . toBe ( true ) ;
342+
343+ // Scroll the page but tick just before the default throttle should update.
344+ fixture . componentInstance . scrollDown ( ) ;
345+ tick ( SCROLL_THROTTLE_MS - 1 ) ;
346+ expect ( tooltipDirective . _isTooltipVisible ( ) ) . toBe ( true ) ;
347+
348+ // Finish ticking to the throttle's limit and check that the scroll event notified the
349+ // tooltip and it was hidden.
350+ tick ( 1 ) ;
351+ expect ( tooltipDirective . _isTooltipVisible ( ) ) . toBe ( false ) ;
352+ } ) ) ;
353+ } ) ;
354+
315355 describe ( 'with OnPush' , ( ) => {
316356 let fixture : ComponentFixture < OnPushTooltipDemo > ;
317357 let buttonDebugElement : DebugElement ;
@@ -374,6 +414,39 @@ class BasicTooltipDemo {
374414 message : string = initialTooltipMessage ;
375415 showButton : boolean = true ;
376416}
417+
418+ @Component ( {
419+ selector : 'app' ,
420+ template : `
421+ <div cdk-scrollable style="padding: 100px; margin: 300px;
422+ height: 200px; width: 200px; overflow: auto;">
423+ <button *ngIf="showButton" style="margin-bottom: 600px"
424+ [md-tooltip]="message"
425+ [tooltip-position]="position">
426+ Button
427+ </button>
428+ </div>`
429+ } )
430+ class ScrollableTooltipDemo {
431+ position : string = 'below' ;
432+ message : string = initialTooltipMessage ;
433+ showButton : boolean = true ;
434+
435+ @ViewChild ( Scrollable ) scrollingContainer : Scrollable ;
436+
437+ scrollDown ( ) {
438+ const scrollingContainerEl = this . scrollingContainer . getElementRef ( ) . nativeElement ;
439+ scrollingContainerEl . scrollTop = 250 ;
440+
441+ // Emit a scroll event from the scrolling element in our component.
442+ // This event should be picked up by the scrollable directive and notify.
443+ // The notification should be picked up by the service.
444+ const scrollEvent = document . createEvent ( 'UIEvents' ) ;
445+ scrollEvent . initUIEvent ( 'scroll' , true , true , window , 0 ) ;
446+ scrollingContainerEl . dispatchEvent ( scrollEvent ) ;
447+ }
448+ }
449+
377450@Component ( {
378451 selector : 'app' ,
379452 template : `
@@ -387,4 +460,3 @@ class OnPushTooltipDemo {
387460 position : string = 'below' ;
388461 message : string = initialTooltipMessage ;
389462}
390-
0 commit comments