fix: viewer PDF (TOC, largeur) et plein ecran assistant (BUG-061 a BUG-063)
CI / lint (push) Successful in 1m36s
CI / security (push) Successful in 1m11s
CI / test (push) Successful in 3m33s
CI / build (push) Successful in 1m2s
CI / e2e (push) Successful in 11m23s

This commit is contained in:
2026-09-17 20:45:38 -04:00
parent 2e2a33cef3
commit f7e068baed
16 changed files with 309 additions and 21 deletions
+30 -5
View File
@@ -39,12 +39,12 @@ test("viewer.js — PDF branch renders the stream in an <iframe class=pdf-iframe
assert.ok(block, "PDF render block not found");
assert.match(
block[1],
/<iframe src="\$\{pdfUrl\}" class="pdf-iframe"/,
/<iframe src="\$\{pdfUrl\}" data-pdf-url="\$\{pdfUrl\}" class="pdf-iframe"/,
"PDF must use <iframe>, not <embed>/<object> (CSP object-src 'none' otherwise blocks it)",
);
assert.match(
block[1],
/\.pdf-iframe[\s\S]*?src="\$\{pdfUrl\}"/,
/<iframe src="\$\{pdfUrl\}"/,
"iframe src must come from the /pdf/stream URL",
);
});
@@ -54,12 +54,37 @@ test("viewer.js — no <embed>/<object> left in the source", () => {
assert.doesNotMatch(viewer, /<object\b/i, "<object> is blocked by CSP object-src 'none'");
});
test("viewer.js — TOC still targets the pdf-iframe via contentWindow", () => {
test("viewer.js — TOC links carry a data-page and never poke contentWindow", () => {
assert.match(
viewer,
/document\.querySelector\('\.pdf-iframe'\)\.contentWindow\.location\.hash='page=\$\{item\.page\}'/,
"TOC links must keep navigating the iframe",
/<a href="#" data-page="\$\{item\.page\}">/,
"TOC links must expose the target page via data-page",
);
assert.doesNotMatch(
viewer,
/contentWindow\.location\.hash\s*=/,
"contentWindow is about:blank in the native PDF viewer: hash navigation never reaches the document",
);
});
test("viewer.js — navigatePdfToPage reloads the iframe with the #page fragment", () => {
const fn = viewer.match(/export function navigatePdfToPage\(area, page\) \{([\s\S]*?)\n\}/);
assert.ok(fn, "navigatePdfToPage helper not found");
assert.match(fn[1], /data-pdf-url/, "the base URL must be preserved without the fragment");
assert.match(fn[1], /iframe\.src = `\$\{base\}#page=\$\{page\}`/, "the iframe must be reloaded with #page=N");
});
test("style.css — full-bleed viewers ignore the centered reading width", () => {
assert.match(
css,
/\.sidebar\.hidden ~ \.content-wrapper \.content-area:has\(\.pdf-viewer-container\)/,
"PDF viewer must fill the width when the navigation sidebar is hidden",
);
const rule = css.match(
/\.content-area:has\(\.pdf-viewer-container\)[\s\S]*?\{([^}]*)\}/,
);
assert.ok(rule, "full-bleed rule not found");
assert.match(rule[1], /max-width:\s*none/, "the 1200px reading cap must be lifted");
});
// ── backend : la CSP autorise le cadre same-origin ─────────────────────────