Merge pull request #20932 from calixteman/bug2023150

Trigger the current find after a page has been moved (bug 2023150)
This commit is contained in:
calixteman 2026-03-20 18:07:24 +01:00 committed by GitHub
commit 5a240f7802
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 157 additions and 33 deletions

View File

@ -15,7 +15,6 @@
import {
awaitPromise,
clearInput,
closePages,
createPromise,
createPromiseWithArgs,
@ -404,14 +403,6 @@ describe("Reorganize Pages View", () => {
]);
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(
() => document.querySelectorAll("span.highlight").length === 10
);
@ -433,13 +424,6 @@ describe("Reorganize Pages View", () => {
]);
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(
() => document.querySelectorAll("span.highlight").length === 10
@ -463,6 +447,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", () => {

View File

@ -422,9 +422,9 @@ class PDFFindController {
#visitedPagesCount = 0;
#copiedExtractTextPromises = null;
#copiedPageData = null;
#savedExtractTextPromises = null;
#savedPageData = null;
/**
* @param {PDFFindControllerOptions} options
@ -613,7 +613,7 @@ class PDFFindController {
this._dirtyMatch = false;
clearTimeout(this._findTimeout);
this._findTimeout = null;
this.#copiedExtractTextPromises = null;
this.#copiedPageData = null;
this._firstPageCapability = Promise.withResolvers();
}
@ -1138,51 +1138,82 @@ class PDFFindController {
}
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) {
this.#copiedExtractTextPromises.set(
pageNum,
this._extractTextPromises[pageNum - 1]
);
promises.set(pageNum, this._extractTextPromises[pageNum - 1]);
contents.set(pageNum, this._pageContents[pageNum - 1]);
diffs.set(pageNum, this._pageDiffs[pageNum - 1]);
diacritics.set(pageNum, this._hasDiacritics[pageNum - 1]);
}
this.#copiedPageData = { promises, contents, diffs, diacritics };
return;
}
if (type === "cancelCopy") {
this.#copiedExtractTextPromises = null;
this.#copiedPageData = null;
return;
}
if (type === "delete") {
this.#savedExtractTextPromises = this._extractTextPromises;
this.#savedPageData = {
promises: this._extractTextPromises,
contents: this._pageContents,
diffs: this._pageDiffs,
diacritics: this._hasDiacritics,
};
}
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;
}
if (type === "cleanSavedData") {
this.#savedExtractTextPromises = null;
this.#savedPageData = null;
return;
}
this.#onFindBarClose();
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 = []);
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);
if (prevPageNumber < 0) {
const src = -prevPageNumber;
extractTextPromises.push(
this.#copiedExtractTextPromises?.get(-prevPageNumber) ||
Promise.resolve()
this.#copiedPageData?.promises.get(src) || 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;
}
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,
});
}
}