pdf-viewer: various visual and usability changes

- fix page nav buttons, smaller default pages, violet bg

  - Build toolbar after renderAllPages so it queries existing canvases;
    query canvases fresh in the scroll handler so page tracking works
    after re-render (zoom in/out).
  - Default data-pdf-scale 0.85 (JS fallback 0.8) so pages are a bit
    smaller by default.
  - Add dark transparent violet background (accent-secondary 22%) to
    .pdf-expanded, behind the pages.

  - expand to fill column top-to-bottom via CSS flex

    Use a flex chain (.tfe-files flex:1, .tfe-file-item:has(.pdf-expanded)
    flex:1) so the expanded PDF wrapper fills the right column from under
    the header to the bottom of the viewport, instead of viewport-based
    clamp math that didn't account for the header height.

  - fill right column, center pages, freeze column on expand

  The expanded viewer now stays inside the right column instead of
  growing the page: the column switches to overflow:hidden while the
  PDF panel scrolls internally. Pages are centered horizontally via
  flexbox align-items: center.

  - fix toolbar not full-width, hide sibling file items

  The toolbar was constrained by the parent's align-items:center; fixed
  with align-self:stretch. Hiding sibling .tfe-file-item elements when
  a PDF is expanded prevents them from rendering above the overlay.

  - disable overscroll on expanded view

  - use overscroll-behavior-y on container, none on toolbar

  - disable body overscroll via .pdf-viewer-open class

  - mobile full-viewport, iframe matches pdf height

  - mobile overlay above everything via position:fixed

  - opaque dark-violet bg on mobile overlay

  - tfe: add 'Open in new tab' link above website iframes

  - trim column padding when expanded for more vertical space

  - 5% zoom increments, subtle padding on expanded column

  - prevent horizontal overflow/overscroll
This commit is contained in:
Pontoporeia
2026-07-08 22:41:52 +02:00
parent 82d8eff512
commit 20873f94af
4 changed files with 99 additions and 18 deletions
+12 -11
View File
@@ -116,6 +116,7 @@
async function expand(container, pdfDoc) {
container.classList.remove("pdf-collapsed");
container.classList.add("pdf-expanded");
document.body.classList.add("pdf-viewer-open");
container.addEventListener("contextmenu", (e) => e.preventDefault());
container.addEventListener("keydown", (e) => {
@@ -132,10 +133,10 @@
if (oldThumb) oldThumb.remove();
// Build toolbar
buildToolbar(container, pdfDoc);
// Render pages directly into the wrapper
// Render pages directly into the wrapper, then build the toolbar
// (toolbar queries canvases, so it must run after they exist).
await renderAllPages(container, pdfDoc);
buildToolbar(container, pdfDoc);
container.scrollIntoView({ behavior: "smooth", block: "nearest" });
}
@@ -143,6 +144,7 @@
function collapse(container) {
container.classList.remove("pdf-expanded");
container.classList.add("pdf-collapsed");
document.body.classList.remove("pdf-viewer-open");
const oldToolbar = container.querySelector(".pdf-toolbar");
if (oldToolbar) oldToolbar.remove();
@@ -178,7 +180,7 @@
const rendering = new Set();
const resolveScale = () => {
const userScale = parseFloat(container.dataset.pdfScale ?? "1");
const userScale = parseFloat(container.dataset.pdfScale ?? "0.8");
const containerWidth = container.clientWidth - 16;
if (containerWidth <= 0) return userScale;
return (containerWidth / firstViewport.width) * userScale;
@@ -236,7 +238,7 @@
toolbar.className = "pdf-toolbar";
let currentPage = 1;
let currentScale = parseFloat(container.dataset.pdfScale ?? "1");
let currentScale = parseFloat(container.dataset.pdfScale ?? "0.8");
const numPages = pdfDoc.numPages;
const updateUI = () => {
@@ -261,14 +263,14 @@
const pageLabel = mkLabel("");
const zoomOutBtn = mkBtn("", "Zoom arrière", () => {
currentScale = Math.max(0.5, currentScale - 0.2);
currentScale = Math.max(0.5, currentScale - 0.05);
container.dataset.pdfScale = String(currentScale);
reRender(container, pdfDoc);
updateUI();
});
const zoomInBtn = mkBtn("+", "Zoom avant", () => {
currentScale = Math.min(3.0, currentScale + 0.2);
currentScale = Math.min(3.0, currentScale + 0.05);
container.dataset.pdfScale = String(currentScale);
reRender(container, pdfDoc);
updateUI();
@@ -296,9 +298,8 @@
updateUI();
const canvases = container.querySelectorAll(".pdf-canvas");
const onScroll = () => {
const canvases = container.querySelectorAll(".pdf-canvas");
const mid = container.scrollTop + container.clientHeight * 0.4;
let best = 1;
let bestDist = Infinity;
@@ -352,14 +353,14 @@
function reRender(container, pdfDoc) {
if (container._onScroll) {
container.removeEventListener("scroll", container._onScroll);
container._onScroll = null;
}
container.querySelectorAll(".pdf-canvas").forEach((c) => {
c.remove();
});
const oldToolbar = container.querySelector(".pdf-toolbar");
if (oldToolbar) oldToolbar.remove();
buildToolbar(container, pdfDoc);
renderAllPages(container, pdfDoc);
renderAllPages(container, pdfDoc).then(() => buildToolbar(container, pdfDoc));
}
// ── Bootstrap ──────────────────────────────────────────────────