Trigger the current find after a page has been moved (bug 2023150)

This commit is contained in:
Calixte Denizet 2026-03-20 16:21:20 +01:00
parent ff1af5a058
commit 118228480b
2 changed files with 157 additions and 33 deletions

View File

@ -15,7 +15,6 @@
import { import {
awaitPromise, awaitPromise,
clearInput,
closePages, closePages,
createPromise, createPromise,
createPromiseWithArgs, createPromiseWithArgs,
@ -400,14 +399,6 @@ describe("Reorganize Pages View", () => {
]); ]);
await movePages(page, [11, 2], 3); await movePages(page, [11, 2], 3);
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 0
);
await clearInput(page, "#findInput", true);
await page.type("#findInput", "1");
await page.keyboard.press("Enter");
await page.waitForFunction( await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 10 () => document.querySelectorAll("span.highlight").length === 10
); );
@ -429,13 +420,6 @@ describe("Reorganize Pages View", () => {
]); ]);
await movePages(page, [13], 0); await movePages(page, [13], 0);
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 0
);
await clearInput(page, "#findInput", true);
await page.type("#findInput", "1");
await page.keyboard.press("Enter");
await page.waitForFunction( await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 10 () => document.querySelectorAll("span.highlight").length === 10
@ -459,6 +443,115 @@ describe("Reorganize Pages View", () => {
}) })
); );
}); });
it("should check if the search is working after copy and paste (bug 2023150)", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await waitForThumbnailVisible(page, 1);
await page.waitForSelector("#viewsManagerStatusActionButton", {
visible: true,
});
await waitAndClick(page, "#viewFindButton");
await waitAndClick(page, ":has(> #findHighlightAll)");
await page.waitForSelector("#findInput", { visible: true });
await page.type("#findInput", "1");
await page.keyboard.press("Enter");
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 10
);
// Select page 1 and copy it.
await waitAndClick(
page,
`.thumbnail:has(${getThumbnailSelector(1)}) input`
);
let handlePagesEdited = await waitForPagesEdited(page, "copy");
await waitAndClick(page, "#viewsManagerStatusActionButton");
await waitAndClick(page, "#viewsManagerStatusActionCopy");
await awaitPromise(handlePagesEdited);
// Paste after page 3.
handlePagesEdited = await waitForPagesEdited(page);
await waitAndClick(page, `${getThumbnailSelector(3)}+button`);
await awaitPromise(handlePagesEdited);
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 11
);
const results = await getSearchResults(page);
expect(results)
.withContext(`In ${browserName}`)
.toEqual([
// Page number, [matches]; copy of page 1 inserted at position 4
[1, ["1"]],
[4, ["1"]],
[11, ["1"]],
[12, ["1", "1"]],
[13, ["1"]],
[14, ["1"]],
[15, ["1"]],
[16, ["1"]],
[17, ["1"]],
[18, ["1"]],
]);
})
);
});
it("should check if the search is working after deleting pages (bug 2023150)", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await waitForThumbnailVisible(page, 1);
await page.waitForSelector("#viewsManagerStatusActionButton", {
visible: true,
});
await waitAndClick(page, "#viewFindButton");
await waitAndClick(page, ":has(> #findHighlightAll)");
await page.waitForSelector("#findInput", { visible: true });
await page.type("#findInput", "1");
await page.keyboard.press("Enter");
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 10
);
// Select page 1 and delete it.
await waitAndClick(
page,
`.thumbnail:has(${getThumbnailSelector(1)}) input`
);
const handlePagesEdited = await waitForPagesEdited(page);
await waitAndClick(page, "#viewsManagerStatusActionButton");
await waitAndClick(page, "#viewsManagerStatusActionDelete");
await awaitPromise(handlePagesEdited);
await page.waitForFunction(
() => document.querySelectorAll("span.highlight").length === 9
);
const results = await getSearchResults(page);
expect(results)
.withContext(`In ${browserName}`)
.toEqual([
// Page number, [matches]; page 1 removed, all positions shifted
[9, ["1"]],
[10, ["1", "1"]],
[11, ["1"]],
[12, ["1"]],
[13, ["1"]],
[14, ["1"]],
[15, ["1"]],
[16, ["1"]],
]);
})
);
});
}); });
describe("Links and outlines", () => { describe("Links and outlines", () => {

View File

@ -422,9 +422,9 @@ class PDFFindController {
#visitedPagesCount = 0; #visitedPagesCount = 0;
#copiedExtractTextPromises = null; #copiedPageData = null;
#savedExtractTextPromises = null; #savedPageData = null;
/** /**
* @param {PDFFindControllerOptions} options * @param {PDFFindControllerOptions} options
@ -613,7 +613,7 @@ class PDFFindController {
this._dirtyMatch = false; this._dirtyMatch = false;
clearTimeout(this._findTimeout); clearTimeout(this._findTimeout);
this._findTimeout = null; this._findTimeout = null;
this.#copiedExtractTextPromises = null; this.#copiedPageData = null;
this._firstPageCapability = Promise.withResolvers(); this._firstPageCapability = Promise.withResolvers();
} }
@ -1138,51 +1138,82 @@ class PDFFindController {
} }
if (type === "copy") { if (type === "copy") {
this.#copiedExtractTextPromises = new Map(); const promises = new Map();
const contents = new Map();
const diffs = new Map();
const diacritics = new Map();
for (const pageNum of pageNumbers) { for (const pageNum of pageNumbers) {
this.#copiedExtractTextPromises.set( promises.set(pageNum, this._extractTextPromises[pageNum - 1]);
pageNum, contents.set(pageNum, this._pageContents[pageNum - 1]);
this._extractTextPromises[pageNum - 1] diffs.set(pageNum, this._pageDiffs[pageNum - 1]);
); diacritics.set(pageNum, this._hasDiacritics[pageNum - 1]);
} }
this.#copiedPageData = { promises, contents, diffs, diacritics };
return; return;
} }
if (type === "cancelCopy") { if (type === "cancelCopy") {
this.#copiedExtractTextPromises = null; this.#copiedPageData = null;
return; return;
} }
if (type === "delete") { if (type === "delete") {
this.#savedExtractTextPromises = this._extractTextPromises; this.#savedPageData = {
promises: this._extractTextPromises,
contents: this._pageContents,
diffs: this._pageDiffs,
diacritics: this._hasDiacritics,
};
} }
if (type === "cancelDelete") { if (type === "cancelDelete") {
this._extractTextPromises = this.#savedExtractTextPromises; this._extractTextPromises = this.#savedPageData.promises;
this._pageContents = this.#savedPageData.contents;
this._pageDiffs = this.#savedPageData.diffs;
this._hasDiacritics = this.#savedPageData.diacritics;
return; return;
} }
if (type === "cleanSavedData") { if (type === "cleanSavedData") {
this.#savedExtractTextPromises = null; this.#savedPageData = null;
return; return;
} }
this.#onFindBarClose(); this.#onFindBarClose();
this._dirtyMatch = true; this._dirtyMatch = true;
const prevTextPromises = this._extractTextPromises; const prevPromises = this._extractTextPromises;
const prevContents = this._pageContents;
const prevDiffs = this._pageDiffs;
const prevDiacritics = this._hasDiacritics;
const extractTextPromises = (this._extractTextPromises = []); const extractTextPromises = (this._extractTextPromises = []);
for (let i = 1, ii = pagesMapper.length; i <= ii; i++) { const pageContents = (this._pageContents = []);
const pageDiffs = (this._pageDiffs = []);
const hasDiacritics = (this._hasDiacritics = []);
for (let i = 1, ii = pagesMapper.pagesNumber; i <= ii; i++) {
const prevPageNumber = pagesMapper.getPrevPageNumber(i); const prevPageNumber = pagesMapper.getPrevPageNumber(i);
if (prevPageNumber < 0) { if (prevPageNumber < 0) {
const src = -prevPageNumber;
extractTextPromises.push( extractTextPromises.push(
this.#copiedExtractTextPromises?.get(-prevPageNumber) || this.#copiedPageData?.promises.get(src) || Promise.resolve()
Promise.resolve()
); );
pageContents.push(this.#copiedPageData?.contents.get(src) ?? "");
pageDiffs.push(this.#copiedPageData?.diffs.get(src) ?? null);
hasDiacritics.push(this.#copiedPageData?.diacritics.get(src) ?? false);
continue; continue;
} }
extractTextPromises.push( extractTextPromises.push(
prevTextPromises[prevPageNumber - 1] || Promise.resolve() prevPromises[prevPageNumber - 1] || Promise.resolve()
); );
pageContents.push(prevContents[prevPageNumber - 1] ?? "");
pageDiffs.push(prevDiffs[prevPageNumber - 1] ?? null);
hasDiacritics.push(prevDiacritics[prevPageNumber - 1] ?? false);
}
if (this.#state) {
this._eventBus.dispatch("find", {
source: this,
type: "",
...this.#state,
});
} }
} }