diff --git a/src/display/editor/annotation_editor_layer.js b/src/display/editor/annotation_editor_layer.js index e2d13d65f..72f705d29 100644 --- a/src/display/editor/annotation_editor_layer.js +++ b/src/display/editor/annotation_editor_layer.js @@ -151,8 +151,9 @@ class AnnotationEditorLayer { case AnnotationEditorType.NONE: this.disableTextSelection(); this.togglePointerEvents(false); + this.toggleAnnotationLayerPointerEvents(true); this.disableClick(); - break; + return; case AnnotationEditorType.INK: // We always want to have an ink editor ready to draw in. this.addInkEditorIfNeeded(false); @@ -172,16 +173,15 @@ class AnnotationEditorLayer { this.enableClick(); } - if (mode !== AnnotationEditorType.NONE) { - const { classList } = this.div; - for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { - classList.toggle( - `${editorType._type}Editing`, - mode === editorType._editorType - ); - } - this.div.hidden = false; + this.toggleAnnotationLayerPointerEvents(false); + const { classList } = this.div; + for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { + classList.toggle( + `${editorType._type}Editing`, + mode === editorType._editorType + ); } + this.div.hidden = false; } addInkEditorIfNeeded(isCommitting) { @@ -228,6 +228,10 @@ class AnnotationEditorLayer { this.div.classList.toggle("disabled", !enabled); } + toggleAnnotationLayerPointerEvents(enabled = false) { + this.#annotationLayer?.div.classList.toggle("disabled", !enabled); + } + /** * Enable pointer events on the main div in order to enable * editor creation. @@ -306,6 +310,7 @@ class AnnotationEditorLayer { classList.remove(`${editorType._type}Editing`); } this.disableTextSelection(); + this.toggleAnnotationLayerPointerEvents(true); this.#isDisabling = false; } diff --git a/test/integration/highlight_editor_spec.mjs b/test/integration/highlight_editor_spec.mjs index 20730d5cf..522f37bbd 100644 --- a/test/integration/highlight_editor_spec.mjs +++ b/test/integration/highlight_editor_spec.mjs @@ -840,4 +840,107 @@ describe("Highlight Editor", () => { ); }); }); + + describe("Highlight links", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait( + "bug1868759.pdf", + ".annotationEditorLayer", + null, + null, + { highlightEditorColors: "red=#AB0000" } + ); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that it's possible to highlight a part of a link", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await page.click("#editorHighlight"); + await page.waitForSelector(".annotationEditorLayer.highlightEditing"); + + const rect = await getSpanRectFromText( + page, + 1, + "Questions courantes" + ); + const x = rect.x + 0.75 * rect.width; + const y = rect.y + rect.height / 2; + await page.mouse.click(x, y, { count: 2 }); + + await page.waitForSelector(`${getEditorSelector(0)}`); + const usedColor = await page.evaluate(() => { + const highlight = document.querySelector( + `.page[data-page-number = "1"] .canvasWrapper > svg.highlight` + ); + return highlight.getAttribute("fill"); + }); + + expect(usedColor).withContext(`In ${browserName}`).toEqual("#AB0000"); + }) + ); + }); + }); + + describe("Highlight forms", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait( + "issue12233.pdf", + ".annotationEditorLayer", + null, + null, + { highlightEditorColors: "red=#AB0000" } + ); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that it's possible to highlight a part of a form", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await page.click("#editorHighlight"); + await page.waitForSelector(".annotationEditorLayer.highlightEditing"); + + const rect1 = await page.$eval("#pdfjs_internal_id_5R", el => { + const { x, y, width, height } = el.getBoundingClientRect(); + return { x, y, width, height }; + }); + const rect2 = await page.$eval("#pdfjs_internal_id_16R", el => { + const { x, y, width, height } = el.getBoundingClientRect(); + return { x, y, width, height }; + }); + + const x1 = rect1.x + rect1.width / 2; + const y1 = rect1.y + rect1.height / 2; + const x2 = rect2.x + rect2.width / 2; + const y2 = rect2.y + rect2.height / 2; + const clickHandle = await waitForPointerUp(page); + await page.mouse.move(x1, y1); + await page.mouse.down(); + await page.mouse.move(x2, y2); + await page.mouse.up(); + await awaitPromise(clickHandle); + + await page.waitForSelector(getEditorSelector(0)); + const usedColor = await page.evaluate(() => { + const highlight = document.querySelector( + `.page[data-page-number = "1"] .canvasWrapper > svg.highlight` + ); + return highlight.getAttribute("fill"); + }); + + expect(usedColor).withContext(`In ${browserName}`).toEqual("#AB0000"); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 5fd7f0c1d..bed5dd704 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -631,3 +631,4 @@ !issue17540.pdf !bug1669097.pdf !issue17671.pdf +!bug1868759.pdf diff --git a/test/pdfs/bug1868759.pdf b/test/pdfs/bug1868759.pdf new file mode 100755 index 000000000..6c34f3547 Binary files /dev/null and b/test/pdfs/bug1868759.pdf differ diff --git a/web/annotation_layer_builder.css b/web/annotation_layer_builder.css index 4e5694c4a..74add91ca 100644 --- a/web/annotation_layer_builder.css +++ b/web/annotation_layer_builder.css @@ -88,6 +88,13 @@ transform: rotate(90deg) translateY(-100%); } + &.disabled { + section, + .popup { + pointer-events: none; + } + } + canvas { position: absolute; width: 100%;