Skip to content

Commit

Permalink
fix: prevent non-primary for pointer events (#796)
Browse files Browse the repository at this point in the history
  • Loading branch information
UziTech authored Oct 17, 2024
1 parent 6191456 commit 956450c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/js/signature_pad.umd.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/js/signature_pad.umd.min.js.map

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions src/signature_pad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ export default class SignaturePad extends SignatureEventTarget {
};

private _handlePointerDown = (event: PointerEvent): void => {
if (!this._isLeftButtonPressed(event) || this._drawingStroke) {
if (!event.isPrimary || !this._isLeftButtonPressed(event) || this._drawingStroke) {
return;
}

Expand All @@ -386,6 +386,9 @@ export default class SignaturePad extends SignatureEventTarget {
};

private _handlePointerMove = (event: PointerEvent): void => {
if (!event.isPrimary) {
return;
}
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) {
// Stop when primary button not pressed or multiple buttons pressed
this._strokeEnd(this._pointerEventToSignatureEvent(event), false);
Expand All @@ -397,7 +400,7 @@ export default class SignaturePad extends SignatureEventTarget {
};

private _handlePointerUp = (event: PointerEvent): void => {
if (this._isLeftButtonPressed(event)) {
if (!event.isPrimary || this._isLeftButtonPressed(event)) {
return;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/__snapshots__/signature_pad.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ exports[`#toSVG returns SVG image with backgroundColor 1`] = `"<svg xmlns="http:
exports[`#toSVG returns SVG image with high DPI 1`] = `"<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 300 150" width="300" height="150"><circle r="1.5" cx="125" cy="54" fill="black"></circle><circle r="1.5" cx="175" cy="54" fill="black"></circle><path d="M 83.000,57.000 C 83.174,60.510 84.000,60.000 85.000,63.000" stroke-width="5.508" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 85.000,63.000 C 89.060,68.048 88.674,68.010 94.000,72.000" stroke-width="4.407" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 94.000,72.000 C 99.488,75.519 99.060,76.048 105.000,79.000" stroke-width="3.402" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 105.000,79.000 C 108.700,82.157 108.988,81.519 113.000,84.000" stroke-width="3.497" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 113.000,84.000 C 119.500,86.000 119.200,86.657 126.000,88.000" stroke-width="3.228" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 126.000,88.000 C 132.402,90.416 132.500,90.000 139.000,92.000" stroke-width="3.211" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 139.000,92.000 C 144.961,93.475 144.902,93.416 151.000,94.000" stroke-width="3.258" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 151.000,94.000 C 156.569,94.652 156.461,94.475 162.000,94.000" stroke-width="3.366" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 162.000,94.000 C 168.992,92.460 169.069,93.152 176.000,91.000" stroke-width="3.078" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 176.000,91.000 C 181.072,90.285 180.992,89.960 186.000,89.000" stroke-width="3.372" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 186.000,89.000 C 192.582,87.232 192.572,87.285 199.000,85.000" stroke-width="3.133" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 199.000,85.000 C 204.297,83.565 204.082,83.232 209.000,81.000" stroke-width="3.290" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 209.000,81.000 C 215.334,77.407 215.297,77.565 221.000,73.000" stroke-width="3.113" stroke="black" fill="none" stroke-linecap="round"></path><path d="M 221.000,73.000 C 224.115,70.107 224.334,70.407 227.000,67.000" stroke-width="3.535" stroke="black" fill="none" stroke-linecap="round"></path></svg>"`;

exports[`user interactions allows user to paint on the pad 1`] = `"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAwIDE1MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIxNTAiPjxjaXJjbGUgcj0iMS41IiBjeD0iNTAiIGN5PSIzMCIgZmlsbD0iYmxhY2siPjwvY2lyY2xlPjxjaXJjbGUgcj0iMS41IiBjeD0iMjQwIiBjeT0iMzAiIGZpbGw9ImJsYWNrIj48L2NpcmNsZT48Y2lyY2xlIHI9IjEuNSIgY3g9IjE1MCIgY3k9IjEyMCIgZmlsbD0iYmxhY2siPjwvY2lyY2xlPjwvc3ZnPg=="`;

exports[`user interactions non-primary pointer events are ignored 1`] = `"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAwIDE1MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIxNTAiPjxjaXJjbGUgcj0iMS41IiBjeD0iNTAiIGN5PSIzMCIgZmlsbD0iYmxhY2siPjwvY2lyY2xlPjwvc3ZnPg=="`;
57 changes: 57 additions & 0 deletions tests/signature_pad.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ describe('user interactions', () => {
const pad = new SignaturePad(canvas);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand All @@ -275,13 +276,15 @@ describe('user interactions', () => {
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
}),
);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 240,
clientY: 30,
pressure: 1,
Expand All @@ -290,13 +293,15 @@ describe('user interactions', () => {
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 240,
clientY: 30,
pressure: 1,
}),
);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 150,
clientY: 120,
pressure: 1,
Expand All @@ -305,6 +310,7 @@ describe('user interactions', () => {
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 150,
clientY: 120,
pressure: 1,
Expand All @@ -313,12 +319,52 @@ describe('user interactions', () => {
expect(pad.toDataURL('image/svg+xml')).toMatchSnapshot();
});

it('non-primary pointer events are ignored', () => {
const pad = new SignaturePad(canvas);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
buttons: 1,
}),
);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: false,
clientX: 240,
clientY: 30,
pressure: 1,
buttons: 1,
}),
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: false,
clientX: 240,
clientY: 30,
pressure: 1,
}),
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
}),
);
expect(pad.toDataURL('image/svg+xml')).toMatchSnapshot();
});

it('call endStroke on pointerup outside canvas', () => {
const pad = new SignaturePad(canvas);
const endStroke = jest.fn();
pad.addEventListener('endStroke', endStroke);
canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand All @@ -327,6 +373,7 @@ describe('user interactions', () => {
);
window.dispatchEvent(
new PointerEvent('pointermove', {
isPrimary: true,
clientX: 240,
clientY: 30,
pressure: 1,
Expand All @@ -335,6 +382,7 @@ describe('user interactions', () => {
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 150,
clientY: 120,
pressure: 1,
Expand All @@ -359,6 +407,7 @@ describe('user interactions', () => {

externalCanvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand All @@ -367,6 +416,7 @@ describe('user interactions', () => {
);
externalCanvas.dispatchEvent(
new PointerEvent('pointermove', {
isPrimary: true,
clientX: 240,
clientY: 30,
pressure: 1,
Expand All @@ -376,6 +426,7 @@ describe('user interactions', () => {
// check that original document is not affected
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 150,
clientY: 120,
pressure: 1,
Expand All @@ -385,6 +436,7 @@ describe('user interactions', () => {
// check that external document emits
externalDocument.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 150,
clientY: 120,
pressure: 1,
Expand Down Expand Up @@ -505,6 +557,7 @@ describe('Signature events.', () => {
describe(`${param.eventName}.`, () => {
function createPointerEvent(dispatchedEventName: string) {
return new PointerEvent(dispatchedEventName, {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand Down Expand Up @@ -554,6 +607,7 @@ describe('Signature events.', () => {

it('the event should be dispatched.', () => {
const eventInitObj = <PointerEventInit>{
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand Down Expand Up @@ -581,6 +635,7 @@ describe('Signature events.', () => {

canvas.dispatchEvent(
new PointerEvent('pointerdown', {
isPrimary: true,
clientX: 50,
clientY: 30,
pressure: 1,
Expand All @@ -589,6 +644,7 @@ describe('Signature events.', () => {
);
canvas.dispatchEvent(
new PointerEvent('pointermove', {
isPrimary: true,
clientX: 50,
clientY: 40,
pressure: 1,
Expand All @@ -597,6 +653,7 @@ describe('Signature events.', () => {
);
window.dispatchEvent(
new PointerEvent('pointerup', {
isPrimary: true,
clientX: 50,
clientY: 40,
pressure: 1,
Expand Down

0 comments on commit 956450c

Please sign in to comment.