From 2d43ba2b67e8c687bfae2b37463d12f78a502b85 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 26 Mar 2026 16:49:44 +0100 Subject: [PATCH] Avoid to be blocked when searching after a page move (bug 2023150) --- test/integration/reorganize_pages_spec.mjs | 43 ++++++++++++++++++++++ web/pdf_find_controller.js | 15 +++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/test/integration/reorganize_pages_spec.mjs b/test/integration/reorganize_pages_spec.mjs index c50347c05..d4e0b0a65 100644 --- a/test/integration/reorganize_pages_spec.mjs +++ b/test/integration/reorganize_pages_spec.mjs @@ -450,6 +450,49 @@ describe("Reorganize Pages View", () => { ); }); + it("should check that find navigation is not blocked after moving pages (bug 2023150)", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await waitAndClick(page, "#viewFindButton"); + await page.waitForSelector("#findInput", { visible: true }); + await page.type("#findInput", "1"); + await page.keyboard.press("Enter"); + + // Wait for the first result to be selected and the search to settle. + await page.waitForSelector("#findInput[data-status='']"); + let resultEl = await page.waitForSelector("#findResultsCount"); + const firstResult = await resultEl.evaluate(el => el.textContent); + expect(firstResult) + .withContext(`In ${browserName}`) + .toEqual(`${FSI}1${PDI} of ${FSI}10${PDI} matches`); + + // Navigate to the next match. + await page.keyboard.press("Enter"); + await page.waitForSelector("#findInput[data-status='']"); + resultEl = await page.waitForSelector("#findResultsCount"); + const secondResult = await resultEl.evaluate(el => el.textContent); + expect(secondResult) + .withContext(`In ${browserName}`) + .toEqual(`${FSI}2${PDI} of ${FSI}10${PDI} matches`); + + // Move a page: this previously blocked subsequent find navigation. + await movePages(page, [3], 0); + + // Wait for the search to re-run after the page move. + await page.waitForSelector("#findInput[data-status='']"); + + // Navigate to the next match — must not be blocked. + await page.keyboard.press("Enter"); + await page.waitForSelector("#findInput[data-status='']"); + resultEl = await page.waitForSelector("#findResultsCount"); + const resultAfterMove = await resultEl.evaluate(el => el.textContent); + expect(resultAfterMove) + .withContext(`In ${browserName}`) + .not.toEqual(secondResult); + }) + ); + }); + it("should check if the search is working after copy and paste (bug 2023150)", async () => { await Promise.all( pages.map(async ([browserName, page]) => { diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index c1b8f1f31..0d8eb5a2a 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -1168,7 +1168,14 @@ class PDFFindController { return; } - this.#onFindBarClose(); + // Cancel any pending find timeout and clear a pending resume page index + // synchronously. Calling #onFindBarClose() here would schedule its cleanup + // asynchronously. + if (this._findTimeout) { + clearTimeout(this._findTimeout); + this._findTimeout = null; + } + this._resumePageIdx = null; this._dirtyMatch = true; const prevPromises = this._extractTextPromises; const prevContents = this._pageContents; @@ -1198,11 +1205,7 @@ class PDFFindController { hasDiacritics.push(prevDiacritics[prevPageNumber - 1] ?? false); } if (this.#state) { - this._eventBus.dispatch("find", { - source: this, - type: "", - ...this.#state, - }); + this.#nextMatch(); } }