Skip to content

Commit

Permalink
Merge pull request #19109 from calixteman/click_when_dragging
Browse files Browse the repository at this point in the history
[Editor] Disallow to have multiple pointers while dragging an editor
  • Loading branch information
calixteman authored Nov 27, 2024
2 parents 052b001 + e695d04 commit 22babd7
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 37 deletions.
6 changes: 6 additions & 0 deletions src/display/display_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ function noContextMenu(e) {
e.preventDefault();
}

function stopEvent(e) {
e.preventDefault();
e.stopPropagation();
}

// Deprecated API function -- display regardless of the `verbosity` setting.
function deprecated(details) {
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -657,5 +662,6 @@ export {
RenderingCancelledException,
setLayerDimensions,
StatTimer,
stopEvent,
SVG_NS,
};
88 changes: 55 additions & 33 deletions src/display/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import {
KeyboardManager,
} from "./tools.js";
import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
import { noContextMenu, stopEvent } from "../display_utils.js";
import { AltText } from "./alt_text.js";
import { EditorToolbar } from "./toolbar.js";
import { noContextMenu } from "../display_utils.js";

/**
* @typedef {Object} AnnotationEditorParameters
Expand All @@ -48,6 +48,10 @@ class AnnotationEditor {

#disabled = false;

#dragPointerId = null;

#dragPointerType = "";

#keepAspectRatio = false;

#resizersDiv = null;
Expand Down Expand Up @@ -751,10 +755,7 @@ class AnnotationEditor {
);
window.addEventListener(
"touchmove",
e => {
// Prevent the page from scrolling.
e.preventDefault();
},
stopEvent /* Prevent the page from scrolling */,
{ passive: false, signal }
);
window.addEventListener("contextmenu", noContextMenu, { signal });
Expand Down Expand Up @@ -1138,46 +1139,67 @@ class AnnotationEditor {

const ac = new AbortController();
const signal = this._uiManager.combinedSignal(ac);
const opts = { capture: true, passive: false, signal };
const cancelDrag = e => {
ac.abort();

this.#dragPointerId = null;
this.#hasBeenClicked = false;
if (!this._uiManager.endDragSession()) {
this.#selectOnPointerEvent(e);
}
};

if (isSelected) {
this.div.classList.add("moving");
this.#prevDragX = event.clientX;
this.#prevDragY = event.clientY;
const pointerMoveCallback = e => {
const { clientX: x, clientY: y } = e;
const [tx, ty] = this.screenToPageTranslation(
x - this.#prevDragX,
y - this.#prevDragY
);
this.#prevDragX = x;
this.#prevDragY = y;
this._uiManager.dragSelectedEditors(tx, ty);
};
window.addEventListener("pointermove", pointerMoveCallback, {
passive: true,
capture: true,
signal,
});
this.#dragPointerId = event.pointerId;
this.#dragPointerType = event.pointerType;
window.addEventListener(
"pointermove",
e => {
const { clientX: x, clientY: y, pointerId } = e;
if (pointerId !== this.#dragPointerId) {
stopEvent(e);
return;
}
const [tx, ty] = this.screenToPageTranslation(
x - this.#prevDragX,
y - this.#prevDragY
);
this.#prevDragX = x;
this.#prevDragY = y;
this._uiManager.dragSelectedEditors(tx, ty);
},
opts
);
window.addEventListener(
"touchmove",
stopEvent /* Prevent the page from scrolling */,
opts
);
window.addEventListener(
"pointerdown",
// If the user drags with one finger and then clicks with another.
e => {
// Prevent the page from scrolling.
e.preventDefault();
if (e.isPrimary && e.pointerType === this.#dragPointerType) {
// We cannot have two primaries at the same time.
// It's possible to be in this state with Firefox and Gnome when
// trying to drag with three fingers (see bug 1933716).
cancelDrag(e);
}
stopEvent(e);
},
{ passive: false, signal }
opts
);
}

const pointerUpCallback = () => {
ac.abort();
if (isSelected) {
this.div.classList.remove("moving");
}

this.#hasBeenClicked = false;
if (!this._uiManager.endDragSession()) {
this.#selectOnPointerEvent(event);
const pointerUpCallback = e => {
if (!this.#dragPointerId || this.#dragPointerId === e.pointerId) {
cancelDrag(e);
return;
}
stopEvent(e);
};
window.addEventListener("pointerup", pointerUpCallback, { signal });
// If the user is using alt+tab during the dragging session, the pointerup
Expand Down
38 changes: 38 additions & 0 deletions test/integration/stamp_editor_spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1492,4 +1492,42 @@ describe("Stamp Editor", () => {
);
});
});

describe("Drag a stamp annotation and click on a touchscreen", () => {
let pages;

beforeAll(async () => {
pages = await loadAndWait("empty.pdf", ".annotationEditorLayer");
});

afterAll(async () => {
await closePages(pages);
});

it("must check that the annotation isn't unselected when an other finger taps on the screen", async () => {
// Run sequentially to avoid clipboard issues.
for (const [browserName, page] of pages) {
if (browserName === "chrome") {
// TODO: remove this check when puppeteer supports multiple touch
// events (it works in v23.9.1).
return;
}
await switchToStamp(page);

await copyImage(page, "../images/firefox_logo.png", 0);
const editorSelector = getEditorSelector(0);
const stampRect = await getRect(page, editorSelector);

await page.touchscreen.tap(stampRect.x + 10, stampRect.y + 10);
await waitForSelectedEditor(page, editorSelector);

await page.touchscreen.touchStart(stampRect.x + 10, stampRect.y + 10);
await page.touchscreen.touchMove(stampRect.x + 20, stampRect.y + 20);
await page.touchscreen.tap(stampRect.x - 10, stampRect.y - 10);
await page.touchscreen.touchEnd();

await waitForSelectedEditor(page, editorSelector);
}
});
});
});
4 changes: 0 additions & 4 deletions web/annotation_editor_layer_builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,6 @@
cursor: move;
}

&.moving {
touch-action: none;
}

&.selectedEditor {
border: var(--focus-outline);
outline: var(--focus-outline-around);
Expand Down

0 comments on commit 22babd7

Please sign in to comment.