From 21ab3c7f3d8c545a3ad4d9c92682000628019b08 Mon Sep 17 00:00:00 2001 From: Joe Schafer Date: Sun, 17 Jul 2022 19:30:40 -0700 Subject: [PATCH] fix: check for event.cancelable in touch events (#634) Co-authored-by: Tony Brix --- src/signature_pad.ts | 13 +++++-- tests/signature_pad.test.ts | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/signature_pad.ts b/src/signature_pad.ts index 473196f7..5b608ad4 100644 --- a/src/signature_pad.ts +++ b/src/signature_pad.ts @@ -236,7 +236,9 @@ export default class SignaturePad extends SignatureEventTarget { private _handleTouchStart = (event: TouchEvent): void => { // Prevent scrolling. - event.preventDefault(); + if (event.cancelable) { + event.preventDefault(); + } if (event.targetTouches.length === 1) { const touch = event.changedTouches[0]; @@ -246,7 +248,9 @@ export default class SignaturePad extends SignatureEventTarget { private _handleTouchMove = (event: TouchEvent): void => { // Prevent scrolling. - event.preventDefault(); + if (event.cancelable) { + event.preventDefault(); + } const touch = event.targetTouches[0]; this._strokeMoveUpdate(touch); @@ -255,8 +259,9 @@ export default class SignaturePad extends SignatureEventTarget { private _handleTouchEnd = (event: TouchEvent): void => { const wasCanvasTouched = event.target === this.canvas; if (wasCanvasTouched) { - event.preventDefault(); - + if (event.cancelable) { + event.preventDefault(); + } const touch = event.changedTouches[0]; this._strokeEnd(touch); } diff --git a/tests/signature_pad.test.ts b/tests/signature_pad.test.ts index 6f2e07d1..c1a2938e 100644 --- a/tests/signature_pad.test.ts +++ b/tests/signature_pad.test.ts @@ -167,6 +167,83 @@ describe('user interactions', () => { }); }); +describe(`touch events.`, () => { + let signpad: SignaturePad; + + function createTouchEvents(cancelable: boolean) { + const touchStartEvent = new TouchEvent('touchstart', { + cancelable, + targetTouches: [{} as Touch], + changedTouches: [ + { + clientX: 50, + clientY: 30, + force: 1, + } as Touch, + ], + }); + const touchMoveEvent = new TouchEvent('touchmove', { + cancelable, + targetTouches: [ + { + clientX: 55, + clientY: 35, + force: 1, + } as Touch, + ], + }); + const touchEndEvent = new TouchEvent('touchend', { + cancelable, + changedTouches: [ + { + clientX: 55, + clientY: 35, + force: 1, + } as Touch, + ], + }); + jest.spyOn(touchStartEvent, 'preventDefault'); + jest.spyOn(touchMoveEvent, 'preventDefault'); + jest.spyOn(touchEndEvent, 'preventDefault'); + + return { + touchStartEvent, + touchMoveEvent, + touchEndEvent, + }; + } + + beforeEach(() => { + signpad = new SignaturePad(canvas); + signpad.off(); + signpad['_handleTouchEvents'](); + }); + + it('the event should not be prevented.', () => { + const { touchStartEvent, touchMoveEvent, touchEndEvent } = + createTouchEvents(false); + canvas.dispatchEvent(touchStartEvent); + canvas.dispatchEvent(touchMoveEvent); + canvas.dispatchEvent(touchEndEvent); + + expect(touchStartEvent.preventDefault).not.toHaveBeenCalled(); + expect(touchMoveEvent.preventDefault).not.toHaveBeenCalled(); + expect(touchEndEvent.preventDefault).not.toHaveBeenCalled(); + }); + + it('the event should be prevented.', () => { + const { touchStartEvent, touchMoveEvent, touchEndEvent } = + createTouchEvents(true); + canvas.dispatchEvent(touchStartEvent); + canvas.dispatchEvent(touchMoveEvent); + canvas.dispatchEvent(touchEndEvent); + + expect(touchStartEvent.preventDefault).toHaveBeenCalled(); + expect(touchMoveEvent.preventDefault).toHaveBeenCalled(); + expect(touchEndEvent.preventDefault).toHaveBeenCalled(); + }); +}); + describe('Signature events.', () => { let signpad: SignaturePad; let eventDispatched: Event | undefined;