From 948e563ed9d9f88377fab61b3631277122df519e Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 11 Sep 2018 19:58:50 +0200 Subject: [PATCH] fix(ripple): ripples not being cleared if touch sequence is canceled (#12936) 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 | 12 +++++++----- src/lib/core/ripple/ripple.spec.ts | 11 +++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/lib/core/ripple/ripple-renderer.ts b/src/lib/core/ripple/ripple-renderer.ts index f3a1dac3987..fcbc6684604 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('mousedown', this.onMousedown) + .set('mouseup', this.onPointerUp) + .set('mouseleave', this.onPointerUp) - this._triggerEvents.set('touchstart', this.onTouchStart); - this._triggerEvents.set('touchend', 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 2d7f919d39d..85bc3fb884e 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');