gutterpress 0.10.2 → 0.10.4-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.js +2 -2
- package/dist/{audit-7ttrs98p.js → audit-8eaaemfk.js} +4 -4
- package/dist/{build-b10s6ht6.js → build-j6ygk7fv.js} +4 -4
- package/dist/{cli-3dehjhtb.js → cli-00gqsfce.js} +1 -1
- package/dist/{cli-v5c0s1vp.js → cli-2y07zn1g.js} +1 -1
- package/dist/{cli-2h1s42gy.js → cli-7hay1r0h.js} +103 -15
- package/dist/{cli-jkxgt9w9.js → cli-avsnd8r3.js} +6 -7
- package/dist/cli.js +14 -14
- package/dist/{doctor-91ewrfbn.js → doctor-wtpgvfnr.js} +2 -2
- package/dist/{engine-a8qa7wr5.js → engine-dzrzyyew.js} +1 -1
- package/dist/{engine-gf90g9vk.js → engine-pta3yeyt.js} +2 -2
- package/dist/{gutterpress-viewer-h031snh8.js → gutterpress-viewer-k0xrt5hw.js} +28 -89
- package/dist/{index-s69b3t18.js → index-cm4dywtk.js} +102 -14
- package/dist/{index-mmv2rc82.js → index-g0vvds4s.js} +5 -6
- package/dist/{index-d1es8g3a.js → index-p4yq14qw.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{lint-xq54b626.js → lint-7ngwa1mj.js} +4 -4
- package/dist/{new-amjrjd8p.js → new-ca7931w9.js} +4 -4
- package/dist/{plugin-svrqwjj4.js → plugin-52qk3h7k.js} +4 -4
- package/dist/{preflight-0txk2k9q.js → preflight-nht6dqvw.js} +4 -4
- package/dist/{preview-02zpmta4.js → preview-k56acsvd.js} +4 -4
- package/dist/{publish-01e1e84m.js → publish-yyc10rj3.js} +4 -4
- package/dist/{validate-yat2eh2p.js → validate-bv3tknh5.js} +4 -4
- package/package.json +1 -1
package/dist/api/index.js
CHANGED
|
@@ -95,12 +95,12 @@ import {
|
|
|
95
95
|
syncProject,
|
|
96
96
|
testRemoteAccess,
|
|
97
97
|
validateProjectPlugins
|
|
98
|
-
} from "../index-
|
|
98
|
+
} from "../index-g0vvds4s.js";
|
|
99
99
|
import {
|
|
100
100
|
BuildError,
|
|
101
101
|
DEFAULT_PRINT_OPTS,
|
|
102
102
|
readyProbeExpr
|
|
103
|
-
} from "../index-
|
|
103
|
+
} from "../index-p4yq14qw.js";
|
|
104
104
|
import {
|
|
105
105
|
AUTO_SNAPSHOT_MESSAGE,
|
|
106
106
|
HISTORY_PAGE_LIMIT,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeAndReport
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-avsnd8r3.js";
|
|
4
4
|
import {
|
|
5
5
|
log
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-2y07zn1g.js";
|
|
7
7
|
import {
|
|
8
8
|
UsageError,
|
|
9
9
|
rejectExtraPositionals,
|
|
10
10
|
rejectUnknownFlags
|
|
11
|
-
} from "./cli-
|
|
12
|
-
import"./cli-
|
|
11
|
+
} from "./cli-00gqsfce.js";
|
|
12
|
+
import"./cli-7hay1r0h.js";
|
|
13
13
|
import"./cli-c41yr7he.js";
|
|
14
14
|
import {
|
|
15
15
|
EXIT_CODES
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
splitOutPath
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-avsnd8r3.js";
|
|
5
5
|
import {
|
|
6
6
|
log
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-2y07zn1g.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError,
|
|
10
10
|
parseEngine,
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
parsePdfxFlavor,
|
|
13
13
|
rejectExtraPositionals,
|
|
14
14
|
rejectUnknownFlags
|
|
15
|
-
} from "./cli-
|
|
16
|
-
import"./cli-
|
|
15
|
+
} from "./cli-00gqsfce.js";
|
|
16
|
+
import"./cli-7hay1r0h.js";
|
|
17
17
|
import"./cli-c41yr7he.js";
|
|
18
18
|
import {
|
|
19
19
|
BuildError
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "gutterpress",
|
|
7
|
-
version: "0.10.
|
|
7
|
+
version: "0.10.4-beta.1",
|
|
8
8
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
9
9
|
author: "itlackey",
|
|
10
10
|
license: "MPL-2.0",
|
|
@@ -171,7 +171,7 @@ function readDevToolsUrl(proc) {
|
|
|
171
171
|
return new Promise((resolve, reject) => {
|
|
172
172
|
let buf = "";
|
|
173
173
|
const timer = setTimeout(() => reject(new Error(`Chromium did not report a DevTools URL:
|
|
174
|
-
${buf}`)),
|
|
174
|
+
${buf}`)), 60000);
|
|
175
175
|
proc.stderr.on("data", (d) => {
|
|
176
176
|
buf += String(d);
|
|
177
177
|
const m = /ws:\/\/[^\s]+/.exec(buf);
|
|
@@ -1445,7 +1445,7 @@ var preview_shell_default = "./preview-shell-gqnc5xxe.js";
|
|
|
1445
1445
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
1446
1446
|
|
|
1447
1447
|
// src/assets/engine/gutterpress-viewer.js
|
|
1448
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
1448
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-k0xrt5hw.js";
|
|
1449
1449
|
|
|
1450
1450
|
// src/assets/engine/gutterpress-agent.js
|
|
1451
1451
|
var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
|
|
@@ -2006,7 +2006,8 @@ ${flushCss}`);
|
|
|
2006
2006
|
const widthOffenders = await findWidthOffenders(page, model, 2 * (tier2.geometry.bleed + tier2.geometry.slug), sheetViewport);
|
|
2007
2007
|
const describe = (list) => list.map((o) => {
|
|
2008
2008
|
const fix = o.left !== undefined && o.left < -1 ? "keep it inside the page content box" : "give it an explicit width";
|
|
2009
|
-
|
|
2009
|
+
const lim = o.limit ?? widthOffenders.limitPx;
|
|
2010
|
+
return ` ${o.desc} — ${Math.round(o.px)}px > ${Math.round(lim)}px content box (${fix})`;
|
|
2010
2011
|
}).join(`
|
|
2011
2012
|
`);
|
|
2012
2013
|
if (widthOffenders.boxes.length) {
|
|
@@ -2528,20 +2529,42 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2528
2529
|
resolvePage(model),
|
|
2529
2530
|
...model.pageNames.filter((n) => !n.startsWith("gp-") || n.startsWith("gp--flush-")).map((n) => resolvePage(model, { name: n }))
|
|
2530
2531
|
];
|
|
2531
|
-
const
|
|
2532
|
-
const
|
|
2532
|
+
const contentPxOf = (c) => (c.geometry.width - c.geometry.margin.left - c.geometry.margin.right + bleedSlugExtensionPt) * 96 / 72;
|
|
2533
|
+
const defaultLimitPx = contentPxOf(contexts[0]);
|
|
2534
|
+
const namedLimits = {};
|
|
2535
|
+
model.pageNames.filter((n) => !n.startsWith("gp-") || n.startsWith("gp--flush-")).forEach((n) => {
|
|
2536
|
+
namedLimits[n] = contentPxOf(resolvePage(model, { name: n }));
|
|
2537
|
+
});
|
|
2538
|
+
const widths = [...new Set([defaultLimitPx, ...Object.values(namedLimits)])].sort((a, b) => a - b);
|
|
2539
|
+
const limitPx = Math.max(...widths);
|
|
2533
2540
|
await page.evaluate(`Promise.allSettled(
|
|
2534
2541
|
[...document.images].map((i) => i.decode().catch(() => {}))
|
|
2535
2542
|
)`);
|
|
2536
2543
|
try {
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2544
|
+
const boxes = [];
|
|
2545
|
+
for (const widthPx of widths) {
|
|
2546
|
+
await page.send("Emulation.setDeviceMetricsOverride", {
|
|
2547
|
+
width: Math.ceil(widthPx),
|
|
2548
|
+
height: 1080,
|
|
2549
|
+
deviceScaleFactor: 1,
|
|
2550
|
+
mobile: false
|
|
2551
|
+
});
|
|
2552
|
+
boxes.push(...JSON.parse(await page.evaluate(`(() => {
|
|
2553
|
+
const LIMIT = ${widthPx} + 1;
|
|
2554
|
+
const NAMED = ${JSON.stringify(namedLimits)};
|
|
2555
|
+
const DEFAULT_LIMIT = ${defaultLimitPx};
|
|
2556
|
+
// The page an element lands on: the nearest ancestor with a non-auto
|
|
2557
|
+
// page property, else the default page. Chromium reports the computed
|
|
2558
|
+
// value on the assigned element only -- descendants read "auto" -- so
|
|
2559
|
+
// this walk is what turns it into the USED value.
|
|
2560
|
+
const limitOf = (el) => {
|
|
2561
|
+
for (let e = el; e; e = e.parentElement) {
|
|
2562
|
+
const n = getComputedStyle(e).page;
|
|
2563
|
+
if (n && n !== "auto") return NAMED[n] ?? DEFAULT_LIMIT;
|
|
2564
|
+
}
|
|
2565
|
+
return DEFAULT_LIMIT;
|
|
2566
|
+
};
|
|
2567
|
+
const mine = (el) => Math.abs(limitOf(el) - ${widthPx}) < 0.5;
|
|
2545
2568
|
const desc = ${DESC_JS};
|
|
2546
2569
|
// Shrink-to-fit only reacts to overflow that ESCAPES: a clipping or
|
|
2547
2570
|
// scrolling ancestor contains its subtree's overflow, so the
|
|
@@ -2558,7 +2581,9 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2558
2581
|
// response.
|
|
2559
2582
|
const clipEdges = ${CLIP_EDGES_JS};
|
|
2560
2583
|
const out = [];
|
|
2584
|
+
const boxEls = [];
|
|
2561
2585
|
for (const el of document.querySelectorAll("*")) {
|
|
2586
|
+
if (!mine(el)) continue;
|
|
2562
2587
|
const r = el.getBoundingClientRect();
|
|
2563
2588
|
const right = Math.max(r.right, r.left + r.width);
|
|
2564
2589
|
// Flag right-edge overflow (fixed-width blocks, negative-margin
|
|
@@ -2574,11 +2599,74 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2574
2599
|
if (c.getBoundingClientRect().width >= r.width - 1) { deepest = false; break; }
|
|
2575
2600
|
}
|
|
2576
2601
|
if (!deepest) continue;
|
|
2577
|
-
out.push({ desc: desc(el), px: Math.max(r.width, right), left: r.left });
|
|
2602
|
+
out.push({ desc: desc(el), px: Math.max(r.width, right), left: r.left, limit: limitOf(el) });
|
|
2603
|
+
boxEls.push(el);
|
|
2578
2604
|
if (out.length >= 20) break;
|
|
2579
2605
|
}
|
|
2606
|
+
|
|
2607
|
+
// pass 1b -- SCROLLABLE overflow, which the border-box walk above
|
|
2608
|
+
// cannot see. querySelectorAll("*") returns elements and
|
|
2609
|
+
// getBoundingClientRect() measures their border boxes, so a
|
|
2610
|
+
// ::before / ::after that sticks out is invisible to it -- while its
|
|
2611
|
+
// overflow still reaches the document and still shrinks the book.
|
|
2612
|
+
// scrollWidth DOES account for pseudo-elements, so it is the one
|
|
2613
|
+
// cheap read that closes the gap.
|
|
2614
|
+
//
|
|
2615
|
+
// MEASURED, the field guide: .dc-spray::before is a decorative skewed
|
|
2616
|
+
// tab at right:-8px, width:14px. It escaped its shell (scrollWidth 394
|
|
2617
|
+
// vs clientWidth 384), Chromium's print widened the layout 696 -> 697
|
|
2618
|
+
// CSS px, that one pixel re-broke a line, and the book printed TWO
|
|
2619
|
+
// PAGES shorter than the preview -- with this audit silent throughout.
|
|
2620
|
+
// page-templates.css had already recorded the gap: "this book still
|
|
2621
|
+
// has one the audit does not catch".
|
|
2622
|
+
//
|
|
2623
|
+
// Same escape rule as above: overflow a clipping ancestor contains
|
|
2624
|
+
// never reaches the document, so it is not a trigger. The element
|
|
2625
|
+
// CARRYING the pseudo is what gets named -- an author cannot select a
|
|
2626
|
+
// pseudo-element to fix it.
|
|
2627
|
+
const scrollCands = [];
|
|
2628
|
+
for (const el of document.querySelectorAll("*")) {
|
|
2629
|
+
if (!mine(el)) continue;
|
|
2630
|
+
const over = el.scrollWidth - el.clientWidth;
|
|
2631
|
+
// clientWidth is 0 on inline/replaced boxes, where scrollWidth
|
|
2632
|
+
// carries no overflow information -- skip rather than guess.
|
|
2633
|
+
if (el.clientWidth <= 0 || over <= 1) continue;
|
|
2634
|
+
// A descendant assigned to a DIFFERENT page is not overflowing this
|
|
2635
|
+
// element's page -- it is laid out against its own, wider one. The
|
|
2636
|
+
// full-bleed art plate is the standard case: it is legitimately
|
|
2637
|
+
// sheet-wide on its own zero-margin page, and its wrapper on the
|
|
2638
|
+
// ordinary page must not be blamed for containing it.
|
|
2639
|
+
if ([...el.querySelectorAll("*")].some((d) => {
|
|
2640
|
+
const n = getComputedStyle(d).page;
|
|
2641
|
+
return n && n !== "auto" && Math.abs((NAMED[n] ?? DEFAULT_LIMIT) - limitOf(el)) >= 0.5;
|
|
2642
|
+
})) continue;
|
|
2643
|
+
// An element that clips its OWN horizontal overflow contains it, so
|
|
2644
|
+
// nothing reaches the document. Read the computed value, not the
|
|
2645
|
+
// declaration: per CSS Overflow 3 an axis set to visible beside a
|
|
2646
|
+
// non-visible one computes to auto, and that really does clip --
|
|
2647
|
+
// while overflow-y: clip leaves x genuinely visible.
|
|
2648
|
+
if (getComputedStyle(el).overflowX !== "visible") continue;
|
|
2649
|
+
const r = el.getBoundingClientRect();
|
|
2650
|
+
const right = r.left + el.scrollWidth;
|
|
2651
|
+
if (right <= LIMIT) continue;
|
|
2652
|
+
if (Math.min(right, clipEdges(el).edges.right) <= LIMIT) continue;
|
|
2653
|
+
scrollCands.push({ el, right, left: r.left });
|
|
2654
|
+
}
|
|
2655
|
+
// Scroll overflow propagates UP: an offender's ancestors all report it
|
|
2656
|
+
// too (html, body, the page wrapper...). Name only the innermost box
|
|
2657
|
+
// of each chain -- the one the author can actually act on.
|
|
2658
|
+
for (const c of scrollCands) {
|
|
2659
|
+
if (out.length >= 20) break;
|
|
2660
|
+
if (scrollCands.some((o) => o !== c && c.el.contains(o.el))) continue;
|
|
2661
|
+
// The border-box pass already named a descendant, so this element's
|
|
2662
|
+
// scroll overflow is that box's, reported one level too high.
|
|
2663
|
+
if (boxEls.some((b) => c.el.contains(b))) continue;
|
|
2664
|
+
if (out.some((o) => o.desc === desc(c.el))) continue;
|
|
2665
|
+
out.push({ desc: desc(c.el), px: c.right, left: c.left, limit: limitOf(c.el) });
|
|
2666
|
+
}
|
|
2580
2667
|
return JSON.stringify(out);
|
|
2581
|
-
})()`));
|
|
2668
|
+
})()`)));
|
|
2669
|
+
}
|
|
2582
2670
|
const replaced = JSON.parse(await page.evaluate(`(() => {
|
|
2583
2671
|
const LIMIT = ${limitPx} + 1;
|
|
2584
2672
|
const desc = ${DESC_JS};
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
stampCreator,
|
|
14
14
|
stripAnnotations,
|
|
15
15
|
warn
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-2y07zn1g.js";
|
|
17
17
|
import {
|
|
18
18
|
DEBOUNCE,
|
|
19
19
|
UsageError,
|
|
20
20
|
resolvePort
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-00gqsfce.js";
|
|
22
22
|
import {
|
|
23
23
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
24
24
|
RENDER_TIMEOUT_MS,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
getAssetPath,
|
|
28
28
|
getBrowser,
|
|
29
29
|
prewarmBrowser
|
|
30
|
-
} from "./cli-
|
|
30
|
+
} from "./cli-7hay1r0h.js";
|
|
31
31
|
import {
|
|
32
32
|
INSTALL_HINTS,
|
|
33
33
|
execCapture,
|
|
@@ -1100,7 +1100,6 @@ var riskyProperties = new Set([
|
|
|
1100
1100
|
"backdrop-filter",
|
|
1101
1101
|
"mix-blend-mode",
|
|
1102
1102
|
"background-blend-mode",
|
|
1103
|
-
"isolation",
|
|
1104
1103
|
"animation",
|
|
1105
1104
|
"animation-name",
|
|
1106
1105
|
"transition",
|
|
@@ -1381,12 +1380,12 @@ async function runLint(opts = {}) {
|
|
|
1381
1380
|
const { manifest, manifestDir } = await loadManifestWithPath(opts.manifest, {
|
|
1382
1381
|
explicit: opts.manifest !== undefined
|
|
1383
1382
|
});
|
|
1384
|
-
resolveConfig({}, manifest);
|
|
1383
|
+
const resolved = resolveConfig({}, manifest);
|
|
1385
1384
|
let files;
|
|
1386
1385
|
if (opts.files) {
|
|
1387
1386
|
files = await glob([opts.files], { nodir: true, ignore: ["**/*.min.css"] });
|
|
1388
1387
|
} else {
|
|
1389
|
-
const relStyles = await resolveActiveStyles(manifestDir,
|
|
1388
|
+
const relStyles = await resolveActiveStyles(manifestDir, resolved.styles);
|
|
1390
1389
|
files = relStyles.map((rel) => resolve2(manifestDir, rel)).filter((f) => !f.endsWith(".min.css"));
|
|
1391
1390
|
}
|
|
1392
1391
|
if (files.length === 0) {
|
|
@@ -7538,7 +7537,7 @@ class PdfOutput {
|
|
|
7538
7537
|
const rawPdf = pdfxMode ? path8.join(stage, "raw.pdf") : path8.resolve(pdfFile);
|
|
7539
7538
|
await fsp2.mkdir(path8.dirname(path8.resolve(pdfFile)), { recursive: true });
|
|
7540
7539
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
7541
|
-
const { buildNativePdf } = await import("./engine-
|
|
7540
|
+
const { buildNativePdf } = await import("./engine-dzrzyyew.js");
|
|
7542
7541
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
7543
7542
|
title: config.title,
|
|
7544
7543
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
UsageError,
|
|
7
7
|
package_default,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-00gqsfce.js";
|
|
10
10
|
import {
|
|
11
11
|
EXIT_CODES
|
|
12
12
|
} from "./cli-46ycxe6r.js";
|
|
@@ -18,16 +18,16 @@ import {
|
|
|
18
18
|
import { defineCommand, parseArgs, runMain } from "citty";
|
|
19
19
|
import { statSync } from "node:fs";
|
|
20
20
|
var SUBCOMMANDS = {
|
|
21
|
-
new: () => import("./new-
|
|
22
|
-
preview: () => import("./preview-
|
|
23
|
-
build: () => import("./build-
|
|
24
|
-
publish: () => import("./publish-
|
|
25
|
-
lint: () => import("./lint-
|
|
26
|
-
validate: () => import("./validate-
|
|
27
|
-
audit: () => import("./audit-
|
|
28
|
-
preflight: () => import("./preflight-
|
|
29
|
-
doctor: () => import("./doctor-
|
|
30
|
-
plugin: () => import("./plugin-
|
|
21
|
+
new: () => import("./new-ca7931w9.js").then((m) => m.default),
|
|
22
|
+
preview: () => import("./preview-k56acsvd.js").then((m) => m.default),
|
|
23
|
+
build: () => import("./build-j6ygk7fv.js").then((m) => m.default),
|
|
24
|
+
publish: () => import("./publish-yyc10rj3.js").then((m) => m.default),
|
|
25
|
+
lint: () => import("./lint-7ngwa1mj.js").then((m) => m.default),
|
|
26
|
+
validate: () => import("./validate-bv3tknh5.js").then((m) => m.default),
|
|
27
|
+
audit: () => import("./audit-8eaaemfk.js").then((m) => m.default),
|
|
28
|
+
preflight: () => import("./preflight-nht6dqvw.js").then((m) => m.default),
|
|
29
|
+
doctor: () => import("./doctor-wtpgvfnr.js").then((m) => m.default),
|
|
30
|
+
plugin: () => import("./plugin-52qk3h7k.js").then((m) => m.default)
|
|
31
31
|
};
|
|
32
32
|
var VERSION = package_default.version;
|
|
33
33
|
var main = defineCommand({
|
|
@@ -52,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
52
52
|
const [command, ...commandArgs] = rawArgs;
|
|
53
53
|
try {
|
|
54
54
|
if (command === "new") {
|
|
55
|
-
const { newArgs } = await import("./new-
|
|
55
|
+
const { newArgs } = await import("./new-ca7931w9.js");
|
|
56
56
|
rejectUnknownFlags(commandArgs, newArgs, "new");
|
|
57
57
|
const parsed2 = parseArgs(commandArgs, {
|
|
58
58
|
...newArgs,
|
|
@@ -64,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
if (command === "preflight") {
|
|
67
|
-
const { preflightArgs } = await import("./preflight-
|
|
67
|
+
const { preflightArgs } = await import("./preflight-nht6dqvw.js");
|
|
68
68
|
rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
|
|
69
69
|
const parsed2 = parseArgs(commandArgs, {
|
|
70
70
|
...preflightArgs,
|
|
@@ -88,7 +88,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
88
88
|
if (subcommand !== "add") {
|
|
89
89
|
throw new UsageError(`gutterpress plugin: unknown command "${subcommand}"`);
|
|
90
90
|
}
|
|
91
|
-
const { pluginAddArgs } = await import("./plugin-
|
|
91
|
+
const { pluginAddArgs } = await import("./plugin-52qk3h7k.js");
|
|
92
92
|
rejectUnknownFlags(subcommandArgs, pluginAddArgs, "plugin add");
|
|
93
93
|
const parsed = parseArgs(subcommandArgs, {
|
|
94
94
|
...pluginAddArgs,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getSystemDiagnostics,
|
|
3
3
|
log
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-2y07zn1g.js";
|
|
5
5
|
import {
|
|
6
6
|
UsageError,
|
|
7
7
|
rejectExtraPositionals,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-00gqsfce.js";
|
|
10
10
|
import"./cli-c41yr7he.js";
|
|
11
11
|
import"./cli-46ycxe6r.js";
|
|
12
12
|
import"./cli-37x76zdn.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
build
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-cm4dywtk.js";
|
|
4
4
|
import {
|
|
5
5
|
BuildError,
|
|
6
6
|
RENDER_TIMEOUT_MS,
|
|
7
7
|
assertMilestone,
|
|
8
8
|
connectChromium,
|
|
9
9
|
getBrowser
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-p4yq14qw.js";
|
|
11
11
|
import"./index-37x76zdn.js";
|
|
12
12
|
|
|
13
13
|
// src/lib/engine.ts
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
injectBreakMapping: () => injectBreakMapping,
|
|
36
36
|
fragmentDocument: () => fragmentDocument,
|
|
37
37
|
contentEdgeRect: () => contentEdgeRect,
|
|
38
|
-
compensateTrailingMarginsBeforeAvoids: () => compensateTrailingMarginsBeforeAvoids,
|
|
39
38
|
compensateRepeatedHeaders: () => compensateRepeatedHeaders,
|
|
40
39
|
compensateRectoBreaks: () => compensateRectoBreaks,
|
|
41
40
|
columnReserve: () => columnReserve,
|
|
@@ -112,8 +111,22 @@
|
|
|
112
111
|
|
|
113
112
|
Scope: \`>\` means this only ever reached the flow root's OWN children, so a
|
|
114
113
|
book whose atomic blocks sit inside \`@page\`/\`@section\` wrappers was never
|
|
115
|
-
affected — which is why removing it
|
|
116
|
-
guide's
|
|
114
|
+
affected — which is why removing it did not move the dc-op-manual field
|
|
115
|
+
guide's divergence.
|
|
116
|
+
|
|
117
|
+
That separate divergence is now PARTLY closed. Its cause was
|
|
118
|
+
\`compensateTrailingMarginsBeforeAvoids\`, a viewer shim built on the false
|
|
119
|
+
premise that print discards a trailing margin at a fragmentainer edge.
|
|
120
|
+
Measured with printToPDF on the shim's own fixture: print keeps the margin
|
|
121
|
+
and defers the avoid block (8 print pages; the viewer reported 6). Removing
|
|
122
|
+
it took the field guide from viewer 294 / PDF 295 to 295 / 295.
|
|
123
|
+
|
|
124
|
+
STILL OPEN, and NOT what that shim caused: an interior +1 then -1 pair,
|
|
125
|
+
opening after PDF p108 (inside Gutterdruid) and closing before p176
|
|
126
|
+
(Wirephreak), so roughly p109-p153 is one page out of register while the
|
|
127
|
+
totals still agree. Anchor it with image identity, not text — that PDF has
|
|
128
|
+
no extractable body text; \`rabbit-walking.png\` (1379x2530, unique) sits on
|
|
129
|
+
PDF p134 vs viewer folio 135. */
|
|
117
130
|
|
|
118
131
|
/* View mode (\`applySpreadMode\` in fragment.ts): wraps this run's multicol
|
|
119
132
|
columns into \`--gp-wrap-cols\` ROWS instead of one long row — 2 for
|
|
@@ -1092,6 +1105,8 @@
|
|
|
1092
1105
|
}
|
|
1093
1106
|
sites.sort((a, b) => a.el.compareDocumentPosition(b.el) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
1094
1107
|
for (const { el, prop } of sites) {
|
|
1108
|
+
if (prop === "break-before" && el.style.breakBefore === "auto")
|
|
1109
|
+
continue;
|
|
1095
1110
|
const strip = el.closest(".gp-strip");
|
|
1096
1111
|
if (!strip)
|
|
1097
1112
|
continue;
|
|
@@ -1225,6 +1240,14 @@
|
|
|
1225
1240
|
pushRun(runs, undefined, trailing);
|
|
1226
1241
|
return runs;
|
|
1227
1242
|
}
|
|
1243
|
+
var FORCED_BREAK = /^(column|page|left|right|recto|verso|always)$/;
|
|
1244
|
+
function clearLeadingForcedBreaks(strip) {
|
|
1245
|
+
for (let el = strip.firstElementChild;el; el = el.firstElementChild) {
|
|
1246
|
+
const cs = getComputedStyle(el);
|
|
1247
|
+
if (FORCED_BREAK.test(cs.breakBefore))
|
|
1248
|
+
el.style.breakBefore = "auto";
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1228
1251
|
function stabilizeFullHeightPageRoots(model, strips) {
|
|
1229
1252
|
let stabilized = 0;
|
|
1230
1253
|
for (const strip of strips) {
|
|
@@ -1305,87 +1328,6 @@
|
|
|
1305
1328
|
delete el.dataset.gpOverflowYPriority;
|
|
1306
1329
|
}
|
|
1307
1330
|
}
|
|
1308
|
-
function compensateTrailingMarginsBeforeAvoids(model, strips) {
|
|
1309
|
-
const candidates = new Set;
|
|
1310
|
-
for (const decl of model.breaks) {
|
|
1311
|
-
if (decl.prop !== "break-inside" || !/^avoid(?:-|$)/.test(decl.value.trim()))
|
|
1312
|
-
continue;
|
|
1313
|
-
let els;
|
|
1314
|
-
try {
|
|
1315
|
-
els = Array.from(document.querySelectorAll(decl.selector));
|
|
1316
|
-
} catch {
|
|
1317
|
-
continue;
|
|
1318
|
-
}
|
|
1319
|
-
for (const el of els) {
|
|
1320
|
-
if (el instanceof HTMLElement && el.closest(".gp-strip"))
|
|
1321
|
-
candidates.add(el);
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
let compensated = 0;
|
|
1325
|
-
const orderedCandidates = Array.from(candidates).sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
1326
|
-
for (const el of orderedCandidates) {
|
|
1327
|
-
if (!/^avoid(?:-|$)/.test(getComputedStyle(el).breakInside))
|
|
1328
|
-
continue;
|
|
1329
|
-
const prev = el.previousElementSibling;
|
|
1330
|
-
const stripEl = el.closest(".gp-strip");
|
|
1331
|
-
const strip = strips.find((item) => item.el === stripEl);
|
|
1332
|
-
if (!prev || !stripEl || !strip)
|
|
1333
|
-
continue;
|
|
1334
|
-
const rects = Array.from(el.getClientRects());
|
|
1335
|
-
const prevRects = Array.from(prev.getClientRects());
|
|
1336
|
-
if (rects.length !== 1 || !prevRects.length)
|
|
1337
|
-
continue;
|
|
1338
|
-
const rect = rects[0];
|
|
1339
|
-
const prevRect = prevRects.at(-1);
|
|
1340
|
-
const stripRect = stripEl.getBoundingClientRect();
|
|
1341
|
-
const { stride } = stripMetrics(stripEl);
|
|
1342
|
-
const zoom = cssZoomOf(stripEl);
|
|
1343
|
-
const colOf = (r) => Math.floor(((r.left - stripRect.left) / zoom + 1) / stride);
|
|
1344
|
-
const currentCol = colOf(rect);
|
|
1345
|
-
if (currentCol !== colOf(prevRect) + 1)
|
|
1346
|
-
continue;
|
|
1347
|
-
if (Math.abs(rect.top - stripRect.top) / zoom > 0.5)
|
|
1348
|
-
continue;
|
|
1349
|
-
const marginEnd = parseFloat(getComputedStyle(prev).marginBlockEnd) || 0;
|
|
1350
|
-
if (marginEnd <= 0.5)
|
|
1351
|
-
continue;
|
|
1352
|
-
const remaining = stripEl.clientHeight - (prevRect.bottom - stripRect.top) / zoom;
|
|
1353
|
-
const height = rect.height / zoom;
|
|
1354
|
-
if (height > remaining + 0.5)
|
|
1355
|
-
continue;
|
|
1356
|
-
if (height + marginEnd <= remaining + 0.5)
|
|
1357
|
-
continue;
|
|
1358
|
-
prev.dataset.gpTrailingMargin = "compensated";
|
|
1359
|
-
prev.dataset.gpTrailingMarginValue = prev.style.getPropertyValue("margin-block-end");
|
|
1360
|
-
prev.dataset.gpTrailingMarginPriority = prev.style.getPropertyPriority("margin-block-end");
|
|
1361
|
-
prev.style.setProperty("margin-block-end", "0px");
|
|
1362
|
-
compensated++;
|
|
1363
|
-
}
|
|
1364
|
-
return compensated;
|
|
1365
|
-
}
|
|
1366
|
-
function restoreTrailingMargins(doc = document) {
|
|
1367
|
-
for (const el of Array.from(doc.querySelectorAll('[data-gp-trailing-margin="compensated"]')))
|
|
1368
|
-
restoreTrailingMargin(el);
|
|
1369
|
-
}
|
|
1370
|
-
function restoreTrailingMargin(el) {
|
|
1371
|
-
const value = el.dataset.gpTrailingMarginValue ?? "";
|
|
1372
|
-
const priority = el.dataset.gpTrailingMarginPriority ?? "";
|
|
1373
|
-
if (value)
|
|
1374
|
-
el.style.setProperty("margin-block-end", value, priority);
|
|
1375
|
-
else
|
|
1376
|
-
el.style.removeProperty("margin-block-end");
|
|
1377
|
-
delete el.dataset.gpTrailingMargin;
|
|
1378
|
-
delete el.dataset.gpTrailingMarginValue;
|
|
1379
|
-
delete el.dataset.gpTrailingMarginPriority;
|
|
1380
|
-
}
|
|
1381
|
-
function restoreIneffectiveTrailingMargins(strips) {
|
|
1382
|
-
for (const prev of Array.from(document.querySelectorAll('[data-gp-trailing-margin="compensated"]'))) {
|
|
1383
|
-
const target = prev.nextElementSibling;
|
|
1384
|
-
if (!target || pageOf(target, strips) !== pageRangeOf(prev, strips)[1]) {
|
|
1385
|
-
restoreTrailingMargin(prev);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
1331
|
function runPageBox(model, name, warnings = []) {
|
|
1390
1332
|
const right = resolvePage(model, { name, pseudos: ["right"] }).geometry;
|
|
1391
1333
|
const left = resolvePage(model, { name, pseudos: ["left"] }).geometry;
|
|
@@ -1436,6 +1378,8 @@
|
|
|
1436
1378
|
offset: 0
|
|
1437
1379
|
});
|
|
1438
1380
|
}
|
|
1381
|
+
for (const s of strips)
|
|
1382
|
+
clearLeadingForcedBreaks(s.el);
|
|
1439
1383
|
return strips;
|
|
1440
1384
|
}
|
|
1441
1385
|
function compensateRepeatedHeaders(strips, maxPasses = 24) {
|
|
@@ -1742,14 +1686,12 @@
|
|
|
1742
1686
|
await layoutReady;
|
|
1743
1687
|
makeOverflowFragmentable(strips);
|
|
1744
1688
|
stabilizeFullHeightPageRoots(model, strips);
|
|
1745
|
-
compensateTrailingMarginsBeforeAvoids(model, strips);
|
|
1746
1689
|
synthesizeColumnBreaks(model);
|
|
1747
1690
|
measure(strips);
|
|
1748
1691
|
const blanks = compensateRectoBreaks(model, strips);
|
|
1749
1692
|
if (blanks)
|
|
1750
1693
|
measure(strips);
|
|
1751
1694
|
const headers = opts.compensateHeaders === false ? { tables: 0, passes: 0, warnings: [] } : compensateRepeatedHeaders(strips);
|
|
1752
|
-
restoreIneffectiveTrailingMargins(strips);
|
|
1753
1695
|
const { totalPages } = measure(strips);
|
|
1754
1696
|
const api = {
|
|
1755
1697
|
model,
|
|
@@ -1762,7 +1704,6 @@
|
|
|
1762
1704
|
pageRangeOf: (sel) => pageRangeOf(typeof sel === "string" ? document.querySelector(sel) : sel, strips),
|
|
1763
1705
|
relayout: () => {
|
|
1764
1706
|
restoreFullHeightPageRoots();
|
|
1765
|
-
restoreTrailingMargins();
|
|
1766
1707
|
restoreScrollContainers();
|
|
1767
1708
|
unwrapStrips(strips);
|
|
1768
1709
|
for (const spacer of Array.from(document.querySelectorAll(".gp-recto-spacer")))
|
|
@@ -1772,7 +1713,6 @@
|
|
|
1772
1713
|
strips.push(...rebuilt);
|
|
1773
1714
|
makeOverflowFragmentable(strips);
|
|
1774
1715
|
stabilizeFullHeightPageRoots(model, strips);
|
|
1775
|
-
compensateTrailingMarginsBeforeAvoids(model, strips);
|
|
1776
1716
|
synthesizeColumnBreaks(model);
|
|
1777
1717
|
measure(strips);
|
|
1778
1718
|
api.blankPages = compensateRectoBreaks(model, strips);
|
|
@@ -1780,7 +1720,6 @@
|
|
|
1780
1720
|
api.warnings = [
|
|
1781
1721
|
...new Set([...authoring, ...compensateRepeatedHeaders(strips).warnings])
|
|
1782
1722
|
];
|
|
1783
|
-
restoreIneffectiveTrailingMargins(strips);
|
|
1784
1723
|
const r = measure(strips);
|
|
1785
1724
|
api.totalPages = r.totalPages;
|
|
1786
1725
|
api.blankPageIndices = blankPageIndices(strips);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
launchChromium,
|
|
5
5
|
marginBoxAlign,
|
|
6
6
|
marginBoxRectPt
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-p4yq14qw.js";
|
|
8
8
|
|
|
9
9
|
// src/engine/compiler/build.ts
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
@@ -1521,7 +1521,8 @@ ${flushCss}`);
|
|
|
1521
1521
|
const widthOffenders = await findWidthOffenders(page, model, 2 * (tier2.geometry.bleed + tier2.geometry.slug), sheetViewport);
|
|
1522
1522
|
const describe = (list) => list.map((o) => {
|
|
1523
1523
|
const fix = o.left !== undefined && o.left < -1 ? "keep it inside the page content box" : "give it an explicit width";
|
|
1524
|
-
|
|
1524
|
+
const lim = o.limit ?? widthOffenders.limitPx;
|
|
1525
|
+
return ` ${o.desc} — ${Math.round(o.px)}px > ${Math.round(lim)}px content box (${fix})`;
|
|
1525
1526
|
}).join(`
|
|
1526
1527
|
`);
|
|
1527
1528
|
if (widthOffenders.boxes.length) {
|
|
@@ -2043,20 +2044,42 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2043
2044
|
resolvePage(model),
|
|
2044
2045
|
...model.pageNames.filter((n) => !n.startsWith("gp-") || n.startsWith("gp--flush-")).map((n) => resolvePage(model, { name: n }))
|
|
2045
2046
|
];
|
|
2046
|
-
const
|
|
2047
|
-
const
|
|
2047
|
+
const contentPxOf = (c) => (c.geometry.width - c.geometry.margin.left - c.geometry.margin.right + bleedSlugExtensionPt) * 96 / 72;
|
|
2048
|
+
const defaultLimitPx = contentPxOf(contexts[0]);
|
|
2049
|
+
const namedLimits = {};
|
|
2050
|
+
model.pageNames.filter((n) => !n.startsWith("gp-") || n.startsWith("gp--flush-")).forEach((n) => {
|
|
2051
|
+
namedLimits[n] = contentPxOf(resolvePage(model, { name: n }));
|
|
2052
|
+
});
|
|
2053
|
+
const widths = [...new Set([defaultLimitPx, ...Object.values(namedLimits)])].sort((a, b) => a - b);
|
|
2054
|
+
const limitPx = Math.max(...widths);
|
|
2048
2055
|
await page.evaluate(`Promise.allSettled(
|
|
2049
2056
|
[...document.images].map((i) => i.decode().catch(() => {}))
|
|
2050
2057
|
)`);
|
|
2051
2058
|
try {
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2059
|
+
const boxes = [];
|
|
2060
|
+
for (const widthPx of widths) {
|
|
2061
|
+
await page.send("Emulation.setDeviceMetricsOverride", {
|
|
2062
|
+
width: Math.ceil(widthPx),
|
|
2063
|
+
height: 1080,
|
|
2064
|
+
deviceScaleFactor: 1,
|
|
2065
|
+
mobile: false
|
|
2066
|
+
});
|
|
2067
|
+
boxes.push(...JSON.parse(await page.evaluate(`(() => {
|
|
2068
|
+
const LIMIT = ${widthPx} + 1;
|
|
2069
|
+
const NAMED = ${JSON.stringify(namedLimits)};
|
|
2070
|
+
const DEFAULT_LIMIT = ${defaultLimitPx};
|
|
2071
|
+
// The page an element lands on: the nearest ancestor with a non-auto
|
|
2072
|
+
// page property, else the default page. Chromium reports the computed
|
|
2073
|
+
// value on the assigned element only -- descendants read "auto" -- so
|
|
2074
|
+
// this walk is what turns it into the USED value.
|
|
2075
|
+
const limitOf = (el) => {
|
|
2076
|
+
for (let e = el; e; e = e.parentElement) {
|
|
2077
|
+
const n = getComputedStyle(e).page;
|
|
2078
|
+
if (n && n !== "auto") return NAMED[n] ?? DEFAULT_LIMIT;
|
|
2079
|
+
}
|
|
2080
|
+
return DEFAULT_LIMIT;
|
|
2081
|
+
};
|
|
2082
|
+
const mine = (el) => Math.abs(limitOf(el) - ${widthPx}) < 0.5;
|
|
2060
2083
|
const desc = ${DESC_JS};
|
|
2061
2084
|
// Shrink-to-fit only reacts to overflow that ESCAPES: a clipping or
|
|
2062
2085
|
// scrolling ancestor contains its subtree's overflow, so the
|
|
@@ -2073,7 +2096,9 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2073
2096
|
// response.
|
|
2074
2097
|
const clipEdges = ${CLIP_EDGES_JS};
|
|
2075
2098
|
const out = [];
|
|
2099
|
+
const boxEls = [];
|
|
2076
2100
|
for (const el of document.querySelectorAll("*")) {
|
|
2101
|
+
if (!mine(el)) continue;
|
|
2077
2102
|
const r = el.getBoundingClientRect();
|
|
2078
2103
|
const right = Math.max(r.right, r.left + r.width);
|
|
2079
2104
|
// Flag right-edge overflow (fixed-width blocks, negative-margin
|
|
@@ -2089,11 +2114,74 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2089
2114
|
if (c.getBoundingClientRect().width >= r.width - 1) { deepest = false; break; }
|
|
2090
2115
|
}
|
|
2091
2116
|
if (!deepest) continue;
|
|
2092
|
-
out.push({ desc: desc(el), px: Math.max(r.width, right), left: r.left });
|
|
2117
|
+
out.push({ desc: desc(el), px: Math.max(r.width, right), left: r.left, limit: limitOf(el) });
|
|
2118
|
+
boxEls.push(el);
|
|
2093
2119
|
if (out.length >= 20) break;
|
|
2094
2120
|
}
|
|
2121
|
+
|
|
2122
|
+
// pass 1b -- SCROLLABLE overflow, which the border-box walk above
|
|
2123
|
+
// cannot see. querySelectorAll("*") returns elements and
|
|
2124
|
+
// getBoundingClientRect() measures their border boxes, so a
|
|
2125
|
+
// ::before / ::after that sticks out is invisible to it -- while its
|
|
2126
|
+
// overflow still reaches the document and still shrinks the book.
|
|
2127
|
+
// scrollWidth DOES account for pseudo-elements, so it is the one
|
|
2128
|
+
// cheap read that closes the gap.
|
|
2129
|
+
//
|
|
2130
|
+
// MEASURED, the field guide: .dc-spray::before is a decorative skewed
|
|
2131
|
+
// tab at right:-8px, width:14px. It escaped its shell (scrollWidth 394
|
|
2132
|
+
// vs clientWidth 384), Chromium's print widened the layout 696 -> 697
|
|
2133
|
+
// CSS px, that one pixel re-broke a line, and the book printed TWO
|
|
2134
|
+
// PAGES shorter than the preview -- with this audit silent throughout.
|
|
2135
|
+
// page-templates.css had already recorded the gap: "this book still
|
|
2136
|
+
// has one the audit does not catch".
|
|
2137
|
+
//
|
|
2138
|
+
// Same escape rule as above: overflow a clipping ancestor contains
|
|
2139
|
+
// never reaches the document, so it is not a trigger. The element
|
|
2140
|
+
// CARRYING the pseudo is what gets named -- an author cannot select a
|
|
2141
|
+
// pseudo-element to fix it.
|
|
2142
|
+
const scrollCands = [];
|
|
2143
|
+
for (const el of document.querySelectorAll("*")) {
|
|
2144
|
+
if (!mine(el)) continue;
|
|
2145
|
+
const over = el.scrollWidth - el.clientWidth;
|
|
2146
|
+
// clientWidth is 0 on inline/replaced boxes, where scrollWidth
|
|
2147
|
+
// carries no overflow information -- skip rather than guess.
|
|
2148
|
+
if (el.clientWidth <= 0 || over <= 1) continue;
|
|
2149
|
+
// A descendant assigned to a DIFFERENT page is not overflowing this
|
|
2150
|
+
// element's page -- it is laid out against its own, wider one. The
|
|
2151
|
+
// full-bleed art plate is the standard case: it is legitimately
|
|
2152
|
+
// sheet-wide on its own zero-margin page, and its wrapper on the
|
|
2153
|
+
// ordinary page must not be blamed for containing it.
|
|
2154
|
+
if ([...el.querySelectorAll("*")].some((d) => {
|
|
2155
|
+
const n = getComputedStyle(d).page;
|
|
2156
|
+
return n && n !== "auto" && Math.abs((NAMED[n] ?? DEFAULT_LIMIT) - limitOf(el)) >= 0.5;
|
|
2157
|
+
})) continue;
|
|
2158
|
+
// An element that clips its OWN horizontal overflow contains it, so
|
|
2159
|
+
// nothing reaches the document. Read the computed value, not the
|
|
2160
|
+
// declaration: per CSS Overflow 3 an axis set to visible beside a
|
|
2161
|
+
// non-visible one computes to auto, and that really does clip --
|
|
2162
|
+
// while overflow-y: clip leaves x genuinely visible.
|
|
2163
|
+
if (getComputedStyle(el).overflowX !== "visible") continue;
|
|
2164
|
+
const r = el.getBoundingClientRect();
|
|
2165
|
+
const right = r.left + el.scrollWidth;
|
|
2166
|
+
if (right <= LIMIT) continue;
|
|
2167
|
+
if (Math.min(right, clipEdges(el).edges.right) <= LIMIT) continue;
|
|
2168
|
+
scrollCands.push({ el, right, left: r.left });
|
|
2169
|
+
}
|
|
2170
|
+
// Scroll overflow propagates UP: an offender's ancestors all report it
|
|
2171
|
+
// too (html, body, the page wrapper...). Name only the innermost box
|
|
2172
|
+
// of each chain -- the one the author can actually act on.
|
|
2173
|
+
for (const c of scrollCands) {
|
|
2174
|
+
if (out.length >= 20) break;
|
|
2175
|
+
if (scrollCands.some((o) => o !== c && c.el.contains(o.el))) continue;
|
|
2176
|
+
// The border-box pass already named a descendant, so this element's
|
|
2177
|
+
// scroll overflow is that box's, reported one level too high.
|
|
2178
|
+
if (boxEls.some((b) => c.el.contains(b))) continue;
|
|
2179
|
+
if (out.some((o) => o.desc === desc(c.el))) continue;
|
|
2180
|
+
out.push({ desc: desc(c.el), px: c.right, left: c.left, limit: limitOf(c.el) });
|
|
2181
|
+
}
|
|
2095
2182
|
return JSON.stringify(out);
|
|
2096
|
-
})()`));
|
|
2183
|
+
})()`)));
|
|
2184
|
+
}
|
|
2097
2185
|
const replaced = JSON.parse(await page.evaluate(`(() => {
|
|
2098
2186
|
const LIMIT = ${limitPx} + 1;
|
|
2099
2187
|
const desc = ${DESC_JS};
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
resolveChromiumExecutable,
|
|
18
18
|
run,
|
|
19
19
|
spawnCapture
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-p4yq14qw.js";
|
|
21
21
|
import {
|
|
22
22
|
gitFs,
|
|
23
23
|
gitScopeFor,
|
|
@@ -3978,7 +3978,7 @@ import git from "isomorphic-git";
|
|
|
3978
3978
|
// package.json
|
|
3979
3979
|
var package_default = {
|
|
3980
3980
|
name: "gutterpress",
|
|
3981
|
-
version: "0.10.
|
|
3981
|
+
version: "0.10.4-beta.1",
|
|
3982
3982
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
3983
3983
|
author: "itlackey",
|
|
3984
3984
|
license: "MPL-2.0",
|
|
@@ -4274,7 +4274,6 @@ var riskyProperties = new Set([
|
|
|
4274
4274
|
"backdrop-filter",
|
|
4275
4275
|
"mix-blend-mode",
|
|
4276
4276
|
"background-blend-mode",
|
|
4277
|
-
"isolation",
|
|
4278
4277
|
"animation",
|
|
4279
4278
|
"animation-name",
|
|
4280
4279
|
"transition",
|
|
@@ -4484,12 +4483,12 @@ async function runLint(opts = {}) {
|
|
|
4484
4483
|
const { manifest, manifestDir } = await loadManifestWithPath(opts.manifest, {
|
|
4485
4484
|
explicit: opts.manifest !== undefined
|
|
4486
4485
|
});
|
|
4487
|
-
resolveConfig({}, manifest);
|
|
4486
|
+
const resolved = resolveConfig({}, manifest);
|
|
4488
4487
|
let files;
|
|
4489
4488
|
if (opts.files) {
|
|
4490
4489
|
files = await glob([opts.files], { nodir: true, ignore: ["**/*.min.css"] });
|
|
4491
4490
|
} else {
|
|
4492
|
-
const relStyles = await resolveActiveStyles(manifestDir,
|
|
4491
|
+
const relStyles = await resolveActiveStyles(manifestDir, resolved.styles);
|
|
4493
4492
|
files = relStyles.map((rel) => resolve4(manifestDir, rel)).filter((f) => !f.endsWith(".min.css"));
|
|
4494
4493
|
}
|
|
4495
4494
|
if (files.length === 0) {
|
|
@@ -8033,7 +8032,7 @@ class PdfOutput {
|
|
|
8033
8032
|
const rawPdf = pdfxMode ? path8.join(stage, "raw.pdf") : path8.resolve(pdfFile);
|
|
8034
8033
|
await fsp2.mkdir(path8.dirname(path8.resolve(pdfFile)), { recursive: true });
|
|
8035
8034
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
8036
|
-
const { buildNativePdf } = await import("./engine-
|
|
8035
|
+
const { buildNativePdf } = await import("./engine-pta3yeyt.js");
|
|
8037
8036
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
8038
8037
|
title: config.title,
|
|
8039
8038
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -427,7 +427,7 @@ function readDevToolsUrl(proc) {
|
|
|
427
427
|
return new Promise((resolve, reject) => {
|
|
428
428
|
let buf = "";
|
|
429
429
|
const timer = setTimeout(() => reject(new Error(`Chromium did not report a DevTools URL:
|
|
430
|
-
${buf}`)),
|
|
430
|
+
${buf}`)), 60000);
|
|
431
431
|
proc.stderr.on("data", (d) => {
|
|
432
432
|
buf += String(d);
|
|
433
433
|
const m = /ws:\/\/[^\s]+/.exec(buf);
|
|
@@ -608,7 +608,7 @@ var preview_shell_default = "./preview-shell-gqnc5xxe.js";
|
|
|
608
608
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
609
609
|
|
|
610
610
|
// src/assets/engine/gutterpress-viewer.js
|
|
611
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
611
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-k0xrt5hw.js";
|
|
612
612
|
|
|
613
613
|
// src/assets/engine/gutterpress-agent.js
|
|
614
614
|
var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
|
package/dist/index.js
CHANGED
|
@@ -113,15 +113,15 @@ import {
|
|
|
113
113
|
syncProject,
|
|
114
114
|
testRemoteAccess,
|
|
115
115
|
validateProjectPlugins
|
|
116
|
-
} from "./index-
|
|
116
|
+
} from "./index-g0vvds4s.js";
|
|
117
117
|
import {
|
|
118
118
|
BUILD_DIAGNOSTIC_CODES
|
|
119
|
-
} from "./index-
|
|
119
|
+
} from "./index-cm4dywtk.js";
|
|
120
120
|
import {
|
|
121
121
|
BuildError,
|
|
122
122
|
DEFAULT_PRINT_OPTS,
|
|
123
123
|
readyProbeExpr
|
|
124
|
-
} from "./index-
|
|
124
|
+
} from "./index-p4yq14qw.js";
|
|
125
125
|
import {
|
|
126
126
|
AUTO_SNAPSHOT_MESSAGE,
|
|
127
127
|
HISTORY_PAGE_LIMIT,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MANIFEST_FILENAMES,
|
|
3
3
|
runLint
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-avsnd8r3.js";
|
|
5
5
|
import {
|
|
6
6
|
log
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-2y07zn1g.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError,
|
|
10
10
|
rejectExtraPositionals,
|
|
11
11
|
rejectUnknownFlags
|
|
12
|
-
} from "./cli-
|
|
13
|
-
import"./cli-
|
|
12
|
+
} from "./cli-00gqsfce.js";
|
|
13
|
+
import"./cli-7hay1r0h.js";
|
|
14
14
|
import"./cli-c41yr7he.js";
|
|
15
15
|
import {
|
|
16
16
|
EXIT_CODES
|
|
@@ -5,16 +5,16 @@ import {
|
|
|
5
5
|
TARGETS,
|
|
6
6
|
TARGET_IDS,
|
|
7
7
|
scaffoldProject
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-avsnd8r3.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveGhostscript
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-2y07zn1g.js";
|
|
12
12
|
import {
|
|
13
13
|
UsageError,
|
|
14
14
|
rejectExtraPositionals,
|
|
15
15
|
rejectUnknownFlags
|
|
16
|
-
} from "./cli-
|
|
17
|
-
import"./cli-
|
|
16
|
+
} from "./cli-00gqsfce.js";
|
|
17
|
+
import"./cli-7hay1r0h.js";
|
|
18
18
|
import {
|
|
19
19
|
isToolAvailable
|
|
20
20
|
} from "./cli-c41yr7he.js";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addNpmPlugin,
|
|
3
3
|
parseNpmPluginSpec
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
4
|
+
} from "./cli-avsnd8r3.js";
|
|
5
|
+
import"./cli-2y07zn1g.js";
|
|
6
6
|
import {
|
|
7
7
|
UsageError,
|
|
8
8
|
rejectExtraPositionals,
|
|
9
9
|
rejectUnknownFlags
|
|
10
|
-
} from "./cli-
|
|
11
|
-
import"./cli-
|
|
10
|
+
} from "./cli-00gqsfce.js";
|
|
11
|
+
import"./cli-7hay1r0h.js";
|
|
12
12
|
import"./cli-c41yr7he.js";
|
|
13
13
|
import {
|
|
14
14
|
EXIT_CODES
|
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
executeValidation,
|
|
3
3
|
publishTargetFor,
|
|
4
4
|
reportMissingTools
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-avsnd8r3.js";
|
|
6
6
|
import {
|
|
7
7
|
log
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-2y07zn1g.js";
|
|
9
9
|
import {
|
|
10
10
|
UsageError,
|
|
11
11
|
rejectExtraPositionals,
|
|
12
12
|
rejectUnknownFlags
|
|
13
|
-
} from "./cli-
|
|
14
|
-
import"./cli-
|
|
13
|
+
} from "./cli-00gqsfce.js";
|
|
14
|
+
import"./cli-7hay1r0h.js";
|
|
15
15
|
import"./cli-c41yr7he.js";
|
|
16
16
|
import {
|
|
17
17
|
EXIT_CODES
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
runBuild,
|
|
7
7
|
splitOutPath,
|
|
8
8
|
startPreviewServer
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-avsnd8r3.js";
|
|
10
10
|
import {
|
|
11
11
|
log
|
|
12
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-2y07zn1g.js";
|
|
13
13
|
import {
|
|
14
14
|
UsageError,
|
|
15
15
|
parseEngine,
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
rejectExtraPositionals,
|
|
19
19
|
rejectUnknownFlags,
|
|
20
20
|
resolvePort
|
|
21
|
-
} from "./cli-
|
|
22
|
-
import"./cli-
|
|
21
|
+
} from "./cli-00gqsfce.js";
|
|
22
|
+
import"./cli-7hay1r0h.js";
|
|
23
23
|
import"./cli-c41yr7he.js";
|
|
24
24
|
import {
|
|
25
25
|
BuildError
|
|
@@ -7,17 +7,17 @@ import {
|
|
|
7
7
|
publishCredentialKey,
|
|
8
8
|
publishProviderFor,
|
|
9
9
|
runPublish
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-avsnd8r3.js";
|
|
11
11
|
import {
|
|
12
12
|
FileTokenStore,
|
|
13
13
|
log
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-2y07zn1g.js";
|
|
15
15
|
import {
|
|
16
16
|
UsageError,
|
|
17
17
|
rejectExtraPositionals,
|
|
18
18
|
rejectUnknownFlags
|
|
19
|
-
} from "./cli-
|
|
20
|
-
import"./cli-
|
|
19
|
+
} from "./cli-00gqsfce.js";
|
|
20
|
+
import"./cli-7hay1r0h.js";
|
|
21
21
|
import"./cli-c41yr7he.js";
|
|
22
22
|
import {
|
|
23
23
|
EXIT_CODES
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeAndReport
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-avsnd8r3.js";
|
|
4
4
|
import {
|
|
5
5
|
log
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-2y07zn1g.js";
|
|
7
7
|
import {
|
|
8
8
|
UsageError,
|
|
9
9
|
rejectExtraPositionals,
|
|
10
10
|
rejectUnknownFlags
|
|
11
|
-
} from "./cli-
|
|
12
|
-
import"./cli-
|
|
11
|
+
} from "./cli-00gqsfce.js";
|
|
12
|
+
import"./cli-7hay1r0h.js";
|
|
13
13
|
import"./cli-c41yr7he.js";
|
|
14
14
|
import {
|
|
15
15
|
EXIT_CODES
|
package/package.json
CHANGED