From e56e09555ebc844226ef5d8e97a5dbceda99e1c7 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 1 Sep 2018 14:32:01 +0200 Subject: [PATCH] fix(ripple): ripples not being cleared if touch sequence is canceled If the browser's touch sequence gets canceled by something, the `touchend` event won't fire which means that the ripples won't be cleared from the ripple container. These changes add an extra handler to make sure that they are. --- src/lib/core/ripple/ripple-renderer.ts | 14 ++++++++------ src/lib/core/ripple/ripple.spec.ts | 11 +++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/lib/core/ripple/ripple-renderer.ts b/src/lib/core/ripple/ripple-renderer.ts index f3a1dac39875..fcbc66846043 100644 --- a/src/lib/core/ripple/ripple-renderer.ts +++ b/src/lib/core/ripple/ripple-renderer.ts @@ -110,12 +110,14 @@ export class RippleRenderer { this._containerElement = elementRef.nativeElement; // Specify events which need to be registered on the trigger. - this._triggerEvents.set('mousedown', this.onMousedown); - this._triggerEvents.set('mouseup', this.onPointerUp); - this._triggerEvents.set('mouseleave', this.onPointerUp); - - this._triggerEvents.set('touchstart', this.onTouchStart); - this._triggerEvents.set('touchend', this.onPointerUp); + this._triggerEvents + .set('mousedown', this.onMousedown) + .set('mouseup', this.onPointerUp) + .set('mouseleave', this.onPointerUp) + + .set('touchstart', this.onTouchStart) + .set('touchend', this.onPointerUp) + .set('touchcancel', this.onPointerUp); } } diff --git a/src/lib/core/ripple/ripple.spec.ts b/src/lib/core/ripple/ripple.spec.ts index 2d7f919d39dc..85bc3fb884e5 100644 --- a/src/lib/core/ripple/ripple.spec.ts +++ b/src/lib/core/ripple/ripple.spec.ts @@ -127,6 +127,17 @@ describe('MatRipple', () => { expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0); })); + it('should clear ripples if the touch sequence is cancelled', fakeAsync(() => { + dispatchTouchEvent(rippleTarget, 'touchstart'); + tick(enterDuration); + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1); + + dispatchTouchEvent(rippleTarget, 'touchcancel'); + tick(exitDuration); + + expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0); + })); + it('should launch multiple ripples for multi-touch', fakeAsync(() => { const touchEvent = createTouchEvent('touchstart');