diff --git a/test/integration/reorganize_pages_spec.mjs b/test/integration/reorganize_pages_spec.mjs index c50347c05..dfb2d764e 100644 --- a/test/integration/reorganize_pages_spec.mjs +++ b/test/integration/reorganize_pages_spec.mjs @@ -2819,4 +2819,93 @@ describe("Reorganize Pages View", () => { ); }); }); + + describe("New badge (bug 2026564)", () => { + let pages; + + beforeEach(async () => { + pages = await loadAndWait( + "page_with_number.pdf", + "#viewsManagerToggleButton", + "page-fit", + null, + { enableSplitMerge: true, enableNewBadge: true } + ); + }); + + afterEach(async () => { + await closePages(pages); + }); + + it("should hide the new badge when a page is selected and show it again when deselected", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await waitForThumbnailVisible(page, 1); + + // The badge must be visible initially. + await page.waitForSelector(".newBadge", { visible: true }); + + // Select page 1 via its checkbox. + await waitAndClick( + page, + `.thumbnail:has(${getThumbnailSelector(1)}) input` + ); + + // The badge must be hidden after selection. + await page.waitForSelector(".newBadge", { hidden: true }); + + // Deselect page 1. + await waitAndClick( + page, + `.thumbnail:has(${getThumbnailSelector(1)}) input` + ); + + // The badge must be visible again after deselection. + await page.waitForSelector(".newBadge", { visible: true }); + }) + ); + }); + + it("should hide the new badge when dragging an unselected page and restore it after", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await waitForThumbnailVisible(page, 1); + + // The badge must be visible initially. + await page.waitForSelector(".newBadge", { visible: true }); + + // Watch for the badge being hidden during the drag. + const handleBadgeHidden = await createPromise(page, resolve => { + const observer = new MutationObserver(() => { + const badge = document.querySelector(".newBadge"); + if (badge?.classList.contains("hidden")) { + observer.disconnect(); + resolve(); + } + }); + observer.observe(document.querySelector(".newBadge"), { + attributes: true, + attributeFilter: ["class"], + }); + }); + + const rect1 = await getRect(page, getThumbnailSelector(1)); + const rect2 = await getRect(page, getThumbnailSelector(2)); + + await dragAndDrop( + page, + getThumbnailSelector(1), + [[0, rect2.y - rect1.y + rect2.height / 2]], + 10 + ); + + // The badge must have been hidden at some point during the drag. + await awaitPromise(handleBadgeHidden); + + // The badge must be visible again after the drag ends. + await page.waitForSelector(".newBadge", { visible: true }); + }) + ); + }); + }); }); diff --git a/web/app.js b/web/app.js index fae7725f8..ed78bd41e 100644 --- a/web/app.js +++ b/web/app.js @@ -373,6 +373,7 @@ const PDFViewerApplication = { enableComment: x => x === "true", enableFakeMLManager: x => x === "true", enableGuessAltText: x => x === "true", + enableNewBadge: x => x === "true", enablePermissions: x => x === "true", enableSplitMerge: x => x === "true", enableUpdatedAddImage: x => x === "true", diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index f0113e470..0c5f03b89 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -161,6 +161,8 @@ class PDFThumbnailViewer { #hasUndoBarVisible = false; + #newBadge = null; + /** * @param {PDFThumbnailViewerOptions} options */ @@ -216,6 +218,7 @@ class PDFThumbnailViewer { newSpan.setAttribute("data-l10n-id", "pdfjs-new-badge-content"); newSpan.classList.add("newBadge"); button.parentElement.before(newSpan); + this.#newBadge = newSpan; } this.eventBus.on( @@ -601,6 +604,7 @@ class PDFThumbnailViewer { this.#currentScrollTop + this.scrollableContainer.clientHeight; this.#dragAC = new AbortController(); this.container.classList.add("isDragging"); + this.#newBadge?.classList.add("hidden"); const startPageNumber = parseInt( draggedThumbnail.getAttribute("page-number"), 10 @@ -658,6 +662,7 @@ class PDFThumbnailViewer { this.#dragMarker = null; this.#dragAC.abort(); this.#dragAC = null; + this.#newBadge?.classList.remove("hidden"); this.container.classList.remove("isDragging"); for (const selected of this.#selectedPages) { @@ -976,12 +981,14 @@ class PDFThumbnailViewer { : "pdfjs-views-manager-pages-status-none-action-label" ); if (count) { + this.#newBadge?.classList.add("hidden"); this.#statusLabel.setAttribute( "data-l10n-args", JSON.stringify({ count }) ); this.#deselectButton.classList.toggle("hidden", false); } else { + this.#newBadge?.classList.remove("hidden"); this.#statusLabel.removeAttribute("data-l10n-args"); this.#deselectButton.classList.toggle("hidden", true); }