From bd5875d066da2bc6754c99a96872c3dff7e01f07 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Tue, 5 Mar 2024 15:28:32 +0100 Subject: [PATCH] [Editor] Let a free highlight be clipped when its bounding box exceeds the page limits (bug 1883632) --- src/display/editor/editor.js | 44 +++++++++++++--------- src/display/editor/highlight.js | 5 +++ test/integration/highlight_editor_spec.mjs | 43 +++++++++++++++++++++ 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js index 0c8e61cd4..cece94eeb 100644 --- a/src/display/editor/editor.js +++ b/src/display/editor/editor.js @@ -512,6 +512,14 @@ class AnnotationEditor { } } + /** + * @returns {boolean} true if position must be fixed (i.e. make the x and y + * living in the page). + */ + get _mustFixPosition() { + return true; + } + /** * Fix the position of the editor in order to keep it inside its parent page. * @param {number} [rotation] - the rotation of the page. @@ -524,23 +532,25 @@ class AnnotationEditor { x *= pageWidth; y *= pageHeight; - switch (rotation) { - case 0: - x = Math.max(0, Math.min(pageWidth - width, x)); - y = Math.max(0, Math.min(pageHeight - height, y)); - break; - case 90: - x = Math.max(0, Math.min(pageWidth - height, x)); - y = Math.min(pageHeight, Math.max(width, y)); - break; - case 180: - x = Math.min(pageWidth, Math.max(width, x)); - y = Math.min(pageHeight, Math.max(height, y)); - break; - case 270: - x = Math.min(pageWidth, Math.max(height, x)); - y = Math.max(0, Math.min(pageHeight - width, y)); - break; + if (this._mustFixPosition) { + switch (rotation) { + case 0: + x = Math.max(0, Math.min(pageWidth - width, x)); + y = Math.max(0, Math.min(pageHeight - height, y)); + break; + case 90: + x = Math.max(0, Math.min(pageWidth - height, x)); + y = Math.min(pageHeight, Math.max(width, y)); + break; + case 180: + x = Math.min(pageWidth, Math.max(width, x)); + y = Math.min(pageHeight, Math.max(height, y)); + break; + case 270: + x = Math.min(pageWidth, Math.max(height, x)); + y = Math.max(0, Math.min(pageHeight - width, y)); + break; + } } this.x = x /= pageWidth; diff --git a/src/display/editor/highlight.js b/src/display/editor/highlight.js index 0a0ccf5b2..a73df5b35 100644 --- a/src/display/editor/highlight.js +++ b/src/display/editor/highlight.js @@ -629,6 +629,11 @@ class HighlightEditor extends AnnotationEditor { } } + /** @inheritdoc */ + get _mustFixPosition() { + return !this.#isFreeHighlight; + } + #getRotation() { // Highlight annotations are always drawn horizontally but if // a free highlight annotation can be rotated. diff --git a/test/integration/highlight_editor_spec.mjs b/test/integration/highlight_editor_spec.mjs index 3196d4e4b..59a8b19a7 100644 --- a/test/integration/highlight_editor_spec.mjs +++ b/test/integration/highlight_editor_spec.mjs @@ -1398,4 +1398,47 @@ describe("Highlight Editor", () => { ); }); }); + + describe("Highlight editor mustn't be moved when close to the page limits", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("empty.pdf", ".annotationEditorLayer"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check the editor coordinates", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await page.click("#editorHighlight"); + await page.waitForSelector(".annotationEditorLayer.highlightEditing"); + + const rect = await page.$eval(".annotationEditorLayer", el => { + const { x, y } = el.getBoundingClientRect(); + return { x, y }; + }); + + const clickHandle = await waitForPointerUp(page); + await page.mouse.move(rect.x + 1, rect.y + 50); + await page.mouse.down(); + await page.mouse.move(rect.x + 1, rect.y + 100); + await page.mouse.up(); + await awaitPromise(clickHandle); + + await page.waitForSelector(getEditorSelector(0)); + const editorX = await page.$eval( + getEditorSelector(0), + el => el.getBoundingClientRect().x + ); + + expect(editorX < rect.x) + .withContext(`In ${browserName}`) + .toBeTrue(); + }) + ); + }); + }); });