From f7fec8c6d763b29b2bded2ef7871f65950fa8d84 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Tue, 5 Dec 2023 22:01:49 +0100 Subject: [PATCH] [Editor] Don't remove elements from the draw layer after it has been destroyed Fixes issue #17379. --- src/display/draw_layer.js | 3 + test/integration-boot.mjs | 1 + test/integration/highlight_editor_spec.mjs | 79 ++++++++++++++++++++++ web/app_options.js | 2 +- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 test/integration/highlight_editor_spec.mjs diff --git a/src/display/draw_layer.js b/src/display/draw_layer.js index ed024ff2e..1f43e2857 100644 --- a/src/display/draw_layer.js +++ b/src/display/draw_layer.js @@ -185,6 +185,9 @@ class DrawLayer { } remove(id) { + if (this.#parent === null) { + return; + } this.#mapping.get(id).remove(); this.#mapping.delete(id); } diff --git a/test/integration-boot.mjs b/test/integration-boot.mjs index 45827f628..6d7dad4a5 100644 --- a/test/integration-boot.mjs +++ b/test/integration-boot.mjs @@ -29,6 +29,7 @@ async function runTests(results) { "copy_paste_spec.mjs", "find_spec.mjs", "freetext_editor_spec.mjs", + "highlight_editor_spec.mjs", "ink_editor_spec.mjs", "scripting_spec.mjs", "stamp_editor_spec.mjs", diff --git a/test/integration/highlight_editor_spec.mjs b/test/integration/highlight_editor_spec.mjs new file mode 100644 index 000000000..7627d9dbe --- /dev/null +++ b/test/integration/highlight_editor_spec.mjs @@ -0,0 +1,79 @@ +/* Copyright 2022 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + closePages, + getEditorSelector, + loadAndWait, + scrollIntoView, +} from "./test_utils.mjs"; + +describe("Highlight Editor", () => { + describe("Editor must be removed without exception", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must scroll and check that the draw layer is there", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await page.click("#editorHighlight"); + await page.waitForSelector(".annotationEditorLayer.highlightEditing"); + + const rect = await page.evaluate(() => { + for (const el of document.querySelectorAll( + `.page[data-page-number="1"] > .textLayer > span` + )) { + if (el.textContent === "Abstract") { + const { x, y, width, height } = el.getBoundingClientRect(); + return { x, y, width, height }; + } + } + return null; + }); + + const x = rect.x + rect.width / 2; + const y = rect.y + rect.height / 2; + await page.mouse.click(x, y, { count: 2 }); + + await page.waitForSelector(`${getEditorSelector(0)}`); + + const oneToOne = Array.from(new Array(13).keys(), n => n + 2).concat( + Array.from(new Array(13).keys(), n => 13 - n) + ); + for (const pageNumber of oneToOne) { + await scrollIntoView( + page, + `.page[data-page-number = "${pageNumber}"]` + ); + } + + await page.waitForSelector( + `.page[data-page-number = "1"] svg.highlight`, + { + visible: true, + } + ); + }) + ); + }); + }); +}); diff --git a/web/app_options.js b/web/app_options.js index caf4dcd76..d4ec5ce95 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -130,7 +130,7 @@ const defaultOptions = { // in Firefox release, but it has to be temporary. // TODO: remove it when unnecessary. /** @type {boolean} */ - value: typeof PDFJSDev === "undefined", + value: typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING"), kind: OptionKind.VIEWER + OptionKind.PREFERENCE, }, enablePermissions: {