From 37ef0b4a86acafff1e004baaccd4b01a01bf44ff Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 8 Feb 2025 17:07:03 +0100 Subject: [PATCH] Ignore the URLs when checking if inferred links overlap existing LinkAnnotations (PR 19110 follow-up) *Note:* For the issue mentioned on Matrix it'll obviously still make sense to improve the regular expression to detect more URL edge-cases. However it occurred to me that even once that particular case is fixed there'll always be a risk that inferred links could overlap, and effectively block, the actual LinkAnnotations. Hence this patch removes the URL comparison to ensure that overlapping inferred links will always be ignored. --- test/integration/autolinker_spec.mjs | 33 +++++++++++++++++++++++++++ test/pdfs/.gitignore | 1 + test/pdfs/pr19449.pdf | Bin 0 -> 11528 bytes web/annotation_layer_builder.js | 2 +- web/app.js | 1 + 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/pdfs/pr19449.pdf diff --git a/test/integration/autolinker_spec.mjs b/test/integration/autolinker_spec.mjs index 455f106d6..4492fa556 100644 --- a/test/integration/autolinker_spec.mjs +++ b/test/integration/autolinker_spec.mjs @@ -88,4 +88,37 @@ describe("autolinker", function () { ); }); }); + + describe("pr19449.pdf", function () { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("pr19449.pdf", ".annotationLayer", null, null, { + docBaseUrl: "http://example.com", + enableAutoLinking: true, + }); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must not add links that overlap even if the URLs are different", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + const linkIds = await page.$$eval( + ".annotationLayer > .linkAnnotation > a", + annotations => + annotations.map(a => a.getAttribute("data-element-id")) + ); + expect(linkIds.length).withContext(`In ${browserName}`).toEqual(1); + linkIds.forEach(id => + expect(id) + .withContext(`In ${browserName}`) + .not.toContain("inferred_link_") + ); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 14660ecd3..83fa48a0b 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -276,6 +276,7 @@ !pr6531_1.pdf !pr6531_2.pdf !pr7352.pdf +!pr19449.pdf !bug900822.pdf !bug1392647.pdf !issue918.pdf diff --git a/test/pdfs/pr19449.pdf b/test/pdfs/pr19449.pdf new file mode 100644 index 0000000000000000000000000000000000000000..90c15d22a725015f3f1ad4c8db684335efbd76bf GIT binary patch literal 11528 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 literal 0 HcmV?d00001 diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index effe83bf6..24c4668c2 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -327,7 +327,7 @@ class AnnotationLayerBuilder { for (const annotation of this.#annotations) { if ( annotation.annotationType !== AnnotationType.LINK || - annotation.url !== link.url + !annotation.url ) { continue; } diff --git a/web/app.js b/web/app.js index 06b05cfb8..eebe8beaa 100644 --- a/web/app.js +++ b/web/app.js @@ -353,6 +353,7 @@ const PDFViewerApplication = { // Set some specific preferences for tests. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) { Object.assign(opts, { + docBaseUrl: x => x, enableAltText: x => x === "true", enableAutoLinking: x => x === "true", enableFakeMLManager: x => x === "true",