diff --git a/gulpfile.mjs b/gulpfile.mjs index 1b9481152..cebe49e5c 100644 --- a/gulpfile.mjs +++ b/gulpfile.mjs @@ -1209,6 +1209,10 @@ function discardCommentsCSS() { } function preprocessHTML(source, defines) { + defines = { + ...defines, + TESTING: defines.TESTING ?? process.env.TESTING === "true", + }; const outName = getTempFile("~preprocess", ".html"); preprocess(source, outName, defines); const out = fs.readFileSync(outName).toString(); diff --git a/test/integration/viewer_spec.mjs b/test/integration/viewer_spec.mjs index deb059ef1..1309029a9 100644 --- a/test/integration/viewer_spec.mjs +++ b/test/integration/viewer_spec.mjs @@ -26,8 +26,11 @@ import { waitForPageChanging, waitForPageRendered, } from "./test_utils.mjs"; +import path from "path"; import { PNG } from "pngjs"; +const __dirname = import.meta.dirname; + describe("PDF viewer", () => { describe("Zoom origin", () => { let pages; @@ -1892,5 +1895,108 @@ describe("PDF viewer", () => { ); }); }); + + describe("@page size stylesheet under CSP", () => { + let pages; + + beforeEach(async () => { + pages = await loadAndWait( + "basicapi.pdf", + ".textLayer .endOfContent", + null, + { + earlySetup: () => { + // Capture state while window.print() runs — the print service's + // destroy() removes the @page stylesheet right after, on the + // afterprint event. + window._pageRuleApplied = null; + window.print = () => { + window._pageRuleApplied = [ + ...document.querySelectorAll("style"), + ].some( + s => + s.sheet?.cssRules.length > 0 && + [...s.sheet.cssRules].some(r => r.cssText.includes("@page")) + ); + }; + }, + appSetup: app => { + app._testPrintResolver = Promise.withResolvers(); + }, + eventBusSetup: eventBus => { + eventBus.on( + "afterprint", + () => { + window.PDFViewerApplication._testPrintResolver.resolve(); + }, + { once: true } + ); + }, + } + ); + }); + + afterEach(async () => { + await closePages(pages); + }); + + // The print service injects an inline + // to match the PDF's page + // dimensions. If the CSP `style-src-elem` directive blocks inline + // + at print time (web/pdf_print_service.js, web/firefox_print_service.js) + to match the PDF's page dimensions. Since the size varies per PDF the + content can't be pre-hashed, so style-src-elem allows 'unsafe-inline'. + Inline style="…" attributes stay blocked via style-src (no fallback). + --> + + + + diff --git a/web/viewer-snippet-chrome-overlays.html b/web/viewer-snippet-chrome-overlays.html index fff0eb2f3..357b85107 100644 --- a/web/viewer-snippet-chrome-overlays.html +++ b/web/viewer-snippet-chrome-overlays.html @@ -4,19 +4,7 @@ users with recognizing which checkbox they have to click when they visit chrome://extensions. --> -

+

Click on "Allow access to file URLs" at chrome://extensions
diff --git a/web/viewer.css b/web/viewer.css index 832439af4..4defccd10 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -713,6 +713,25 @@ dialog :link { margin-top: 10px; } +/*#if !MOZCENTRAL*/ +#printServiceDialog { + min-width: 200px; +} +/*#endif*/ + +/*#if CHROME*/ +#chrome-pdfjs-logo-bg { + display: block; + padding-left: 60px; + min-height: 48px; + background-size: 48px; + background-repeat: no-repeat; + font-size: 14px; + line-height: 1.8em; + word-break: break-all; +} +/*#endif*/ + .grab-to-pan-grab { cursor: grab !important; } diff --git a/web/viewer.html b/web/viewer.html index 0d5d90c7d..e4d24d7e4 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -29,6 +29,35 @@ See https://github.com/adobe-type-tools/cmap-resources PDF.js viewer + + + + + + + + + + + @@ -1237,7 +1266,7 @@ See https://github.com/adobe-type-tools/cmap-resources -

+