Skip to content

Commit

Permalink
fix(tooltip): check tooltip disposed on animation hidden
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewseguin committed Nov 10, 2016
1 parent 547a75d commit a8b778d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/lib/tooltip/tooltip.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="md-tooltip"
[style.transform-origin]="_transformOrigin"
[@state]="_visibility"
(@state.done)="this._afterVisibilityAnimation($event)">
(@state.done)="_afterVisibilityAnimation($event)">
{{message}}
</div>
34 changes: 32 additions & 2 deletions src/lib/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
async, ComponentFixture, TestBed, tick, fakeAsync,
flushMicrotasks
} from '@angular/core/testing';
import {Component, DebugElement} from '@angular/core';
import {Component, DebugElement, AnimationTransitionEvent} from '@angular/core';
import {By} from '@angular/platform-browser';
import {TooltipPosition, MdTooltip, TOOLTIP_HIDE_DELAY, MdTooltipModule} from './tooltip';
import {OverlayContainer} from '../core';
Expand Down Expand Up @@ -123,14 +123,44 @@ describe('MdTooltip', () => {
expect(overlayContainerElement.childNodes.length).toBe(0);
expect(overlayContainerElement.textContent).toBe('');
});

it('should not try to dispose the tooltip when destroyed and done hiding', fakeAsync(() => {
tooltipDirective.show();
fixture.detectChanges();
tick(150);

tooltipDirective.hide();
tick(TOOLTIP_HIDE_DELAY); // Change the tooltip state to hidden and trigger animation start

// Store the tooltip instance, which will be set to null after the button is hidden.
const tooltipInstance = tooltipDirective._tooltipInstance;
fixture.componentInstance.showButton = false;
fixture.detectChanges();

// At this point the animation should be able to complete itself and trigger the
// _afterVisibilityAnimation function, but for unknown reasons in the test infrastructure,
// this does not occur. Manually call this and verify that doing so does not
// throw an error.
tooltipInstance._afterVisibilityAnimation(new AnimationTransitionEvent({
fromState: 'visible',
toState: 'hidden',
totalTime: 150
}));
}));
});
});

@Component({
selector: 'app',
template: `<button [md-tooltip]="message" [tooltip-position]="position">Button</button>`
template: `
<button *ngIf="showButton"
[md-tooltip]="message"
[tooltip-position]="position">
Button
</button>`
})
class BasicTooltipDemo {
position: TooltipPosition = 'below';
message: string = initialTooltipMessage;
showButton: boolean = true;
}
6 changes: 4 additions & 2 deletions src/lib/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ export class MdTooltip {

// Dispose the overlay when finished the shown tooltip.
this._tooltipInstance.afterHidden().subscribe(() => {
this._disposeTooltip();
// Check first if the tooltip has already been removed through this components destroy.
if (this._tooltipInstance) {
this._disposeTooltip();
}
});
}

Expand Down Expand Up @@ -270,7 +273,6 @@ export class TooltipComponent {
_afterVisibilityAnimation(e: AnimationTransitionEvent): void {
if (e.toState === 'hidden' && !this.isVisible()) {
this._onHide.next();

}
}

Expand Down

0 comments on commit a8b778d

Please sign in to comment.