From e01970613dbc9c75b7ab97603736484779c344f0 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Thu, 2 Mar 2017 20:32:41 +0100 Subject: [PATCH] fix(ripple): unable to remove programmatically if animations is ongoing This is something I ran into while working on #3102. For persistent ripples, the `fadeOutAll` method doesn't work if it is called before the enter animation is finished. The issue was that the set of active ripples doesn't get populated until the animation is done. Relates to #3102. --- src/lib/core/ripple/ripple-renderer.ts | 16 +++++++--------- src/lib/core/ripple/ripple.spec.ts | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/lib/core/ripple/ripple-renderer.ts b/src/lib/core/ripple/ripple-renderer.ts index 6b31dbd2473d..91d6b45d9a5b 100644 --- a/src/lib/core/ripple/ripple-renderer.ts +++ b/src/lib/core/ripple/ripple-renderer.ts @@ -101,15 +101,13 @@ export class RippleRenderer { // Exposed reference to the ripple that will be returned. let rippleRef = new RippleRef(this, ripple, config); - // Wait for the ripple element to be completely faded in. - // Once it's faded in, the ripple can be hidden immediately if the mouse is released. - this.runTimeoutOutsideZone(() => { - if (config.persistent || this._isMousedown) { - this._activeRipples.add(rippleRef); - } else { - rippleRef.fadeOut(); - } - }, duration); + if (config.persistent || this._isMousedown) { + this._activeRipples.add(rippleRef); + } else { + // Wait for the ripple element to be completely faded in. + // Once it's faded in, the ripple can be hidden immediately if the mouse is released. + this.runTimeoutOutsideZone(() => rippleRef.fadeOut(), duration); + } return rippleRef; } diff --git a/src/lib/core/ripple/ripple.spec.ts b/src/lib/core/ripple/ripple.spec.ts index 71531a9abbff..246c93c19433 100644 --- a/src/lib/core/ripple/ripple.spec.ts +++ b/src/lib/core/ripple/ripple.spec.ts @@ -270,6 +270,25 @@ describe('MdRipple', () => { expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0); })); + it('should be able to remove ripples that are not done animating in', fakeAsync(() => { + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples on init.'); + + rippleDirective.launch(0, 0, { persistent: true }); + + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length) + .toBe(1, 'Expected one ripple after launch.'); + + tick(RIPPLE_FADE_IN_DURATION / 2); + + rippleDirective.fadeOutAll(); + + tick(RIPPLE_FADE_OUT_DURATION); + + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples after fadeOutAll has been called.'); + })); + }); describe('configuring behavior', () => {