From e1f02be67098dadbb6cbcd03b92e0ff92a2cc683 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Fri, 20 Mar 2026 14:25:36 +0100 Subject: [PATCH] Pass the global signal the text layer builder in order to remove all the listeners defined here The goal of this patch is to remove the noice we've in the logs: ``` 0:09.36 INFO Console message: [JavaScript Warning: "Script terminated by timeout at: reset@resource://pdf.js/web/viewer.mjs:11773:7 EventListener.handleEvent*#enableGlobalSelectionListener@resource://pdf.js/web/viewer.mjs:11787:12 render@resource://pdf.js/web/viewer.mjs:11716:20 async*#renderTextLayer@resource://pdf.js/web/viewer.mjs:12108:28 draw/resultPromise<@resource://pdf.js/web/viewer.mjs:12575:53 promise callback*draw@resource://pdf.js/web/viewer.mjs:12570:8 renderView@resource://pdf.js/web/viewer.mjs:7872:14 forceRendering/<@resource://pdf.js/web/viewer.mjs:13963:29 " {file: "resource://pdf.js/web/viewer.mjs" line: 11773}] ``` --- web/pdf_page_view.js | 6 +++++ web/pdf_viewer.js | 4 +++ web/text_layer_builder.js | 51 +++++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 5cd05661c..653c2489e 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -108,6 +108,7 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js"; * text that look like URLs. The default value is `true`. * @property {CommentManager} [commentManager] - The comment manager instance. * to. + * @property {AbortSignal} [abortSignal] */ const DEFAULT_LAYER_PROPERTIES = @@ -135,6 +136,8 @@ const LAYERS_ORDER = new Map([ ]); class PDFPageView extends BasePDFPageView { + #abortSignal = null; + #annotationMode = AnnotationMode.ENABLE_FORMS; #canvasWrapper = null; @@ -181,6 +184,7 @@ class PDFPageView extends BasePDFPageView { this.renderingId = "page" + this.id; this.#layerProperties = options.layerProperties || DEFAULT_LAYER_PROPERTIES; + this.#abortSignal = options.abortSignal || null; this.pdfPage = null; this.pageLabel = null; @@ -285,6 +289,7 @@ class PDFPageView extends BasePDFPageView { defaultViewport: this.viewport, id, layerProperties: this.#layerProperties, + abortSignal: this.#abortSignal, scale: this.scale, optionalContentConfigPromise: this._optionalContentConfigPromise, textLayerMode: this.#textLayerMode, @@ -1056,6 +1061,7 @@ class PDFPageView extends BasePDFPageView { this.#addLayer(textLayerDiv, "textLayer"); this.l10n.resume(); }, + abortSignal: this.#abortSignal, }); } diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 5e271e962..b4e5aba26 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -253,6 +253,8 @@ class PDFViewer { #enableAutoLinking = true; + #abortSignal = null; + #eventAbortController = null; #minDurationToUpdateCanvas = 0; @@ -385,6 +387,7 @@ class PDFViewer { } const { abortSignal } = options; + this.#abortSignal = abortSignal || null; abortSignal?.addEventListener( "abort", () => { @@ -1068,6 +1071,7 @@ class PDFViewer { enableAutoLinking: this.#enableAutoLinking, minDurationToUpdateCanvas: this.#minDurationToUpdateCanvas, commentManager: this.#commentManager, + abortSignal: this.#abortSignal, }); this._pages.push(pageView); } diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index 56a273a68..4388589f2 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -33,6 +33,7 @@ import { removeNullCharacters } from "./ui_utils.js"; * @property {TextAccessibilityManager} [accessibilityManager] * @property {boolean} [enablePermissions] * @property {function} [onAppend] + * @property {AbortSignal} [abortSignal] */ /** @@ -48,6 +49,8 @@ import { removeNullCharacters } from "./ui_utils.js"; * contain text that matches the PDF text they are overlaying. */ class TextLayerBuilder { + #abortSignal = null; + #enablePermissions = false; #onAppend = null; @@ -69,12 +72,14 @@ class TextLayerBuilder { accessibilityManager = null, enablePermissions = false, onAppend = null, + abortSignal = null, }) { this.pdfPage = pdfPage; this.highlighter = highlighter; this.accessibilityManager = accessibilityManager; this.#enablePermissions = enablePermissions === true; this.#onAppend = onAppend; + this.#abortSignal = abortSignal; this.div = document.createElement("div"); this.div.tabIndex = 0; @@ -163,24 +168,33 @@ class TextLayerBuilder { */ #bindMouse(end) { const { div } = this; + const abortSignal = this.#abortSignal; - div.addEventListener("mousedown", () => { - div.classList.add("selecting"); - }); + div.addEventListener( + "mousedown", + () => { + div.classList.add("selecting"); + }, + { signal: abortSignal } + ); - div.addEventListener("copy", event => { - if (!this.#enablePermissions) { - const selection = document.getSelection(); - event.clipboardData.setData( - "text/plain", - removeNullCharacters(normalizeUnicode(selection.toString())) - ); - } - stopEvent(event); - }); + div.addEventListener( + "copy", + event => { + if (!this.#enablePermissions) { + const selection = document.getSelection(); + event.clipboardData.setData( + "text/plain", + removeNullCharacters(normalizeUnicode(selection.toString())) + ); + } + stopEvent(event); + }, + { signal: abortSignal } + ); TextLayerBuilder.#textLayers.set(div, end); - TextLayerBuilder.#enableGlobalSelectionListener(); + TextLayerBuilder.#enableGlobalSelectionListener(abortSignal); } static #removeGlobalSelectionListener(textLayerDiv) { @@ -192,13 +206,18 @@ class TextLayerBuilder { } } - static #enableGlobalSelectionListener() { + static #enableGlobalSelectionListener(globalAbortSignal) { if (this.#selectionChangeAbortController) { // document-level event listeners already installed return; } this.#selectionChangeAbortController = new AbortController(); - const { signal } = this.#selectionChangeAbortController; + const signal = globalAbortSignal + ? AbortSignal.any([ + this.#selectionChangeAbortController.signal, + globalAbortSignal, + ]) + : this.#selectionChangeAbortController.signal; const reset = (end, textLayer) => { if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {