Skip to content

Commit

Permalink
fix: tap event should not be triggered on mouse right-click (#981)
Browse files Browse the repository at this point in the history
  • Loading branch information
wsuwt committed Oct 3, 2023
1 parent 0a825ad commit 6936c51
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 6 deletions.
94 changes: 90 additions & 4 deletions packages/core/__test__/events/TapEvent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const getIdentifier = (element) => {
return identifiers.get(element);
};

const createMouseEvent = (element, eventType) => {
const createMouseEvent = (element, eventType, button) => {
const position = element.getBoundingClientRect();

return new MouseEvent(eventType, {
Expand All @@ -26,7 +26,7 @@ const createMouseEvent = (element, eventType) => {
screenY: position.top + element.offsetTop + position.height / 2,
clientX: position.left + position.width / 2,
clientY: position.top + position.height / 2,
button: 0,
button: button,
buttons: 1,
isTrusted: true,
view: window
Expand Down Expand Up @@ -56,8 +56,8 @@ const createTouchEvent = (element, eventType) => {
});
};

const dispatchMouseEvent = (element, eventType) => {
element.dispatchEvent(createMouseEvent(element, eventType));
const dispatchMouseEvent = (element, eventType, button = 0) => {
element.dispatchEvent(createMouseEvent(element, eventType, button));
};

const dispatchTouchEvent = (element, eventType) => {
Expand All @@ -71,6 +71,20 @@ const click = async (element1, element2) => {
await nextFrame();
};

const auxiliaryClick = async (element1, element2) => {
dispatchMouseEvent(element1, 'mousedown', 1);
await nextFrame();
dispatchMouseEvent(element2, 'mouseup', 1);
await nextFrame();
};

const secondaryClick = async (element1, element2) => {
dispatchMouseEvent(element1, 'mousedown', 2);
await nextFrame();
dispatchMouseEvent(element2, 'mouseup', 2);
await nextFrame();
};

const touch = async (element1, element2) => {
dispatchTouchEvent(element1, 'touchstart');
await nextFrame();
Expand Down Expand Up @@ -248,6 +262,78 @@ describe('TestTapEvent', function () {
expect(tapCount).to.equal(1, 'tap event should be fired just once');
});

it('Should not fire tap event on right-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await secondaryClick(element, element);

expect(tapEvent).to.not.exist;
expect(tapEvent).to.not.instanceOf(Event);
expect(tapCount).to.equal(0, 'tap event should not be fired on right click');
});

it('Should not fire tapstart event on right-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await secondaryClick(element, element);

expect(tapStartEvent).to.not.exist;
expect(tapStartEvent).to.not.instanceOf(Event);
expect(tapStartCount).to.equal(0, 'tapstart event should not be fired on right click');
});

it('Should not fire tapend event on right-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await secondaryClick(element, element);

expect(tapEndEvent).to.not.exist;
expect(tapEndEvent).to.not.instanceOf(Event);
expect(tapEndCount).to.equal(0, 'tapend event should not be fired on right click');
});

it('Should not fire tap event on middle-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await auxiliaryClick(element, element);

expect(tapEvent).to.not.exist;
expect(tapEvent).to.not.instanceOf(Event);
expect(tapCount).to.equal(0, 'tap event should not be fired on right click');
});

it('Should not fire tapstart event on middle-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await auxiliaryClick(element, element);

expect(tapStartEvent).to.not.exist;
expect(tapStartEvent).to.not.instanceOf(Event);
expect(tapStartCount).to.equal(0, 'tapstart event should not be fired on right click');
});

it('Should not fire tapend event on middle-click', async function () {
const element = await fixture(
html`<div style="display: block; width: 100px; height: 100px; background-color: red"></div>`
);

await auxiliaryClick(element, element);

expect(tapEndEvent).to.not.exist;
expect(tapEndEvent).to.not.instanceOf(Event);
expect(tapEndCount).to.equal(0, 'tapend event should not be fired on right click');
});

it('Should support tap event on role=button when Enter is pressed', async function () {
const el = await fixture(html`<div role="button">Fake Button</div>`);
const keyDownEvent = keyboardEvent('keydown', { key: 'Enter' });
Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/events/TapEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ declare global {
let positions: Positions;
let metaKeys: MetaKeys | undefined;

const MAIN_BUTTON = 0;

/**
* Simulates consistent click/tap events across pointer/touch devices
*/
Expand Down Expand Up @@ -219,12 +221,16 @@ const applyEvent = (target: Global): void => {

/**
* Listen to `mousedown` events on the target.
* Use this to fire tap events, unless one
* Use this to fire tapstart events, unless one
* has already been triggered from a touch event.
*/
target.addEventListener(
'mousedown',
(event) => {
if (event.button !== MAIN_BUTTON) {
return;
}

if (!lastTapTarget && event.target && currentTouch === -1) {
mouseEventPath = [...event.composedPath()];

Expand All @@ -240,12 +246,16 @@ const applyEvent = (target: Global): void => {

/**
* Listen to `mouseup` events on the target.
* Use this to fire tap events, unless one
* Use this to fire tapend events, unless one
* has already been triggered from a touch event.
*/
target.addEventListener(
'mouseup',
(event) => {
if (event.button !== MAIN_BUTTON) {
return;
}

if (lastTapTarget) {
/**
* Tap events have been dispatched,
Expand Down

0 comments on commit 6936c51

Please sign in to comment.