gutterpress 0.10.0-beta.1 → 0.10.0
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-85zn35v8.js → audit-cvarpa72.js} +4 -4
- package/dist/{build-1faqmp0y.js → build-6r502chw.js} +4 -4
- package/dist/{cli-7e79d7se.js → cli-149edp6b.js} +1 -1
- package/dist/{cli-v935c2ws.js → cli-cqtggsng.js} +1 -1
- package/dist/{cli-5tffrg48.js → cli-eq5naw4m.js} +136 -122
- package/dist/{cli-afm8pa0h.js → cli-zfcryxg8.js} +2 -2
- package/dist/cli.js +15 -15
- package/dist/{doctor-69v5c9wy.js → doctor-akvxbtjb.js} +2 -2
- package/dist/{engine-nbfdy0pp.js → engine-b159tbns.js} +2 -2
- package/dist/{engine-hrtn0b28.js → engine-ft4cr3ep.js} +1 -1
- package/dist/{gutterpress-viewer-fb6fhwsy.js → gutterpress-viewer-te8g5grx.js} +55 -21
- package/dist/{index-052x5fef.js → index-ge7q9xj3.js} +244 -230
- package/dist/{index-wsydvp08.js → index-wq3r5pj7.js} +1 -1
- package/dist/{index-c2b6gyeg.js → index-ycpvr0am.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/lib/build-staging.d.ts +51 -0
- package/dist/{lint-17404bsx.js → lint-p2sw53d9.js} +4 -4
- package/dist/{new-vsgpxzek.js → new-hvq0x91q.js} +4 -4
- package/dist/{plugin-s4yfpx6p.js → plugin-pssmk0dx.js} +4 -4
- package/dist/{preflight-1h3apvqh.js → preflight-4j00yd0g.js} +4 -4
- package/dist/{preview-cqf383g4.js → preview-d4s6gk6p.js} +4 -4
- package/dist/{preview-interface-hg5eqv88.js → preview-interface-0ssk8bmm.js} +4 -2
- package/dist/{publish-arvycera.js → publish-tkc26en7.js} +4 -4
- package/dist/{repair-vmwh2bhe.js → repair-2va4w12t.js} +4 -4
- package/dist/{validate-ztzq7p35.js → validate-w9vfefrw.js} +4 -4
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
strideOf: () => strideOf,
|
|
25
25
|
stabilizeFullHeightPageRoots: () => stabilizeFullHeightPageRoots,
|
|
26
26
|
spreadModeSupported: () => spreadModeSupported,
|
|
27
|
+
runPageBox: () => runPageBox,
|
|
27
28
|
rowStrideOf: () => rowStrideOf,
|
|
28
29
|
pageRangeOf: () => pageRangeOf,
|
|
29
30
|
pageOf: () => pageOf,
|
|
@@ -96,11 +97,23 @@
|
|
|
96
97
|
transform: translate(var(--gp-margin-left), var(--gp-margin-top));
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
/*
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
/* NOTE: there is deliberately no \`.gp-strip > * { break-inside: auto }\` here.
|
|
101
|
+
The original spike shipped one, under a comment about sheet transparency that
|
|
102
|
+
described no rule of its own, and it was never justified anywhere. Because
|
|
103
|
+
viewer chrome is injected after the author's stylesheet, it beat every
|
|
104
|
+
single-class author rule at equal specificity: a top-level block the author
|
|
105
|
+
declared atomic (\`.card\`, \`.section\`, a stat block) split on screen while the
|
|
106
|
+
PDF moved it whole and left a short page. Measured on
|
|
107
|
+
\`docs/fixtures/atomic-blocks\`: print 6pp, viewer 5pp with the rule, 6pp and
|
|
108
|
+
6pp without it; a longer probe of the same shape ran 25pp against 21pp.
|
|
109
|
+
Chromium honours \`break-inside: avoid\` in multicol as it does in paged media,
|
|
110
|
+
including relaxing it for a block too tall to fit an empty fragmentainer, so
|
|
111
|
+
nothing here needs to override the author.
|
|
112
|
+
|
|
113
|
+
Scope: \`>\` means this only ever reached the flow root's OWN children, so a
|
|
114
|
+
book whose atomic blocks sit inside \`@page\`/\`@section\` wrappers was never
|
|
115
|
+
affected — which is why removing it does not move the dc-op-manual field
|
|
116
|
+
guide's remaining 4-page divergence. That one is still open. */
|
|
104
117
|
|
|
105
118
|
/* View mode (\`applySpreadMode\` in fragment.ts): wraps this run's multicol
|
|
106
119
|
columns into \`--gp-wrap-cols\` ROWS instead of one long row — 2 for
|
|
@@ -1103,7 +1116,7 @@
|
|
|
1103
1116
|
continue;
|
|
1104
1117
|
const stripTop = strip.getBoundingClientRect().top;
|
|
1105
1118
|
const edge = prop === "break-after" ? rect.bottom : rect.top;
|
|
1106
|
-
const reserve = columnReserve(edge - stripTop, strip.clientHeight);
|
|
1119
|
+
const reserve = columnReserve((edge - stripTop) / cssZoomOf(strip), strip.clientHeight);
|
|
1107
1120
|
if (reserve === null)
|
|
1108
1121
|
continue;
|
|
1109
1122
|
const spacer = document.createElement("div");
|
|
@@ -1301,19 +1314,21 @@
|
|
|
1301
1314
|
const prevRect = prevRects.at(-1);
|
|
1302
1315
|
const stripRect = stripEl.getBoundingClientRect();
|
|
1303
1316
|
const { stride } = stripMetrics(stripEl);
|
|
1304
|
-
const
|
|
1317
|
+
const zoom = cssZoomOf(stripEl);
|
|
1318
|
+
const colOf = (r) => Math.floor(((r.left - stripRect.left) / zoom + 1) / stride);
|
|
1305
1319
|
const currentCol = colOf(rect);
|
|
1306
1320
|
if (currentCol !== colOf(prevRect) + 1)
|
|
1307
1321
|
continue;
|
|
1308
|
-
if (Math.abs(rect.top - stripRect.top) > 0.5)
|
|
1322
|
+
if (Math.abs(rect.top - stripRect.top) / zoom > 0.5)
|
|
1309
1323
|
continue;
|
|
1310
1324
|
const marginEnd = parseFloat(getComputedStyle(prev).marginBlockEnd) || 0;
|
|
1311
1325
|
if (marginEnd <= 0.5)
|
|
1312
1326
|
continue;
|
|
1313
|
-
const remaining = stripEl.clientHeight - (prevRect.bottom - stripRect.top);
|
|
1314
|
-
|
|
1327
|
+
const remaining = stripEl.clientHeight - (prevRect.bottom - stripRect.top) / zoom;
|
|
1328
|
+
const height = rect.height / zoom;
|
|
1329
|
+
if (height > remaining + 0.5)
|
|
1315
1330
|
continue;
|
|
1316
|
-
if (
|
|
1331
|
+
if (height + marginEnd <= remaining + 0.5)
|
|
1317
1332
|
continue;
|
|
1318
1333
|
prev.dataset.gpTrailingMargin = "compensated";
|
|
1319
1334
|
prev.dataset.gpTrailingMarginValue = prev.style.getPropertyValue("margin-block-end");
|
|
@@ -1346,6 +1361,20 @@
|
|
|
1346
1361
|
}
|
|
1347
1362
|
}
|
|
1348
1363
|
}
|
|
1364
|
+
function runPageBox(model, name, warnings = []) {
|
|
1365
|
+
const right = resolvePage(model, { name, pseudos: ["right"] }).geometry;
|
|
1366
|
+
const left = resolvePage(model, { name, pseudos: ["left"] }).geometry;
|
|
1367
|
+
const box = (g) => ({
|
|
1368
|
+
w: g.width - g.margin.left - g.margin.right,
|
|
1369
|
+
h: g.height - g.margin.top - g.margin.bottom
|
|
1370
|
+
});
|
|
1371
|
+
const r = box(right);
|
|
1372
|
+
const l = box(left);
|
|
1373
|
+
if (Math.abs(r.w - l.w) < 0.01 && Math.abs(r.h - l.h) < 0.01)
|
|
1374
|
+
return right;
|
|
1375
|
+
warnings.push(`@page :left and @page :right give ${name ? `the "${name}" page` : "this book"} ` + `different content areas (${l.w.toFixed(1)}×${l.h.toFixed(1)}pt vs ` + `${r.w.toFixed(1)}×${r.h.toFixed(1)}pt). Print alternates between them; the preview can ` + `only show one, so page breaks here may not match the PDF. Mirror the margins instead: ` + `swap which edge is wide and keep the total the same.`);
|
|
1376
|
+
return resolvePage(model, { name }).geometry;
|
|
1377
|
+
}
|
|
1349
1378
|
function buildStrips(model, opts = {}, warnings = []) {
|
|
1350
1379
|
const doc = document;
|
|
1351
1380
|
const root = opts.root ?? doc.querySelector("main") ?? doc.body;
|
|
@@ -1353,7 +1382,7 @@
|
|
|
1353
1382
|
const runs = explodeChildren(root, model);
|
|
1354
1383
|
const strips = [];
|
|
1355
1384
|
for (const run of runs) {
|
|
1356
|
-
const
|
|
1385
|
+
const geometry = runPageBox(model, run.page, warnings);
|
|
1357
1386
|
const strip = doc.createElement("div");
|
|
1358
1387
|
strip.className = "gp-strip";
|
|
1359
1388
|
if (run.page)
|
|
@@ -1406,14 +1435,15 @@
|
|
|
1406
1435
|
passes = Math.max(passes, pass + 1);
|
|
1407
1436
|
const stride = strideOf(strip.el);
|
|
1408
1437
|
const stripLeft = strip.el.getBoundingClientRect().left - strip.el.scrollLeft;
|
|
1409
|
-
const
|
|
1438
|
+
const zoom = cssZoomOf(strip.el);
|
|
1439
|
+
const colOf = (r) => Math.floor(((r.left - stripLeft) / zoom + 1) / stride);
|
|
1410
1440
|
const stripTop = strip.el.getBoundingClientRect().top;
|
|
1411
1441
|
const colBottom = strip.el.clientHeight;
|
|
1412
1442
|
const plans = [];
|
|
1413
1443
|
for (const table of tables) {
|
|
1414
1444
|
const head = table.tHead;
|
|
1415
1445
|
const headRect = head?.getClientRects()[0];
|
|
1416
|
-
const footHeight = table.tFoot?.getBoundingClientRect().height ?? 0;
|
|
1446
|
+
const footHeight = (table.tFoot?.getBoundingClientRect().height ?? 0) / zoom;
|
|
1417
1447
|
const rows = Array.from(table.querySelectorAll("tbody > tr")).filter((r) => !r.classList.contains("gp-thead-shim") && !r.classList.contains("gp-tfoot-shim"));
|
|
1418
1448
|
if (!rows.length)
|
|
1419
1449
|
continue;
|
|
@@ -1428,10 +1458,10 @@
|
|
|
1428
1458
|
const row = rows[i];
|
|
1429
1459
|
if (cols[i] === lastCol || claims.has(row))
|
|
1430
1460
|
continue;
|
|
1431
|
-
const bottom = rects[i].bottom - stripTop;
|
|
1461
|
+
const bottom = (rects[i].bottom - stripTop) / zoom;
|
|
1432
1462
|
if (bottom > colBottom - footHeight + 0.5) {
|
|
1433
1463
|
newClaim = row;
|
|
1434
|
-
claims.set(row, colBottom - (rects[i].top - stripTop));
|
|
1464
|
+
claims.set(row, colBottom - (rects[i].top - stripTop) / zoom);
|
|
1435
1465
|
break;
|
|
1436
1466
|
}
|
|
1437
1467
|
}
|
|
@@ -1439,7 +1469,7 @@
|
|
|
1439
1469
|
plans.push({
|
|
1440
1470
|
table,
|
|
1441
1471
|
push: headRect ? colOf(headRect) < cols[0] : false,
|
|
1442
|
-
headHeight: headRect?.height ?? 0,
|
|
1472
|
+
headHeight: (headRect?.height ?? 0) / zoom,
|
|
1443
1473
|
footHeight,
|
|
1444
1474
|
breakRows: headRect ? rows.filter((_, i) => i > 0 && cols[i] > cols[i - 1]) : [],
|
|
1445
1475
|
footRows: [...claims.entries()],
|
|
@@ -1563,6 +1593,9 @@
|
|
|
1563
1593
|
function strideOf(strip) {
|
|
1564
1594
|
return stripMetrics(strip).stride;
|
|
1565
1595
|
}
|
|
1596
|
+
function cssZoomOf(el) {
|
|
1597
|
+
return el.currentCSSZoom ?? 1;
|
|
1598
|
+
}
|
|
1566
1599
|
function stripMetrics(strip) {
|
|
1567
1600
|
const cs = getComputedStyle(strip);
|
|
1568
1601
|
const w = parseFloat(cs.getPropertyValue("--gp-content-w"));
|
|
@@ -1585,12 +1618,13 @@
|
|
|
1585
1618
|
function indexInStrip(left, top, strip) {
|
|
1586
1619
|
const { stride, rowStride } = stripMetrics(strip.el);
|
|
1587
1620
|
const stripBox = strip.el.getBoundingClientRect();
|
|
1588
|
-
const
|
|
1589
|
-
const
|
|
1621
|
+
const zoom = cssZoomOf(strip.el);
|
|
1622
|
+
const x = (left - stripBox.left) / zoom + strip.el.scrollLeft;
|
|
1623
|
+
const y = (top - stripBox.top) / zoom;
|
|
1590
1624
|
const { perRow, shift } = wrapGeometry(strip);
|
|
1591
|
-
const colVisual = Math.floor((
|
|
1625
|
+
const colVisual = Math.floor((x + 1) / stride);
|
|
1592
1626
|
const colClamped = Math.max(0, Math.min(perRow - 1, colVisual));
|
|
1593
|
-
const row = Math.max(0, Math.floor((
|
|
1627
|
+
const row = Math.max(0, Math.floor((y + 1) / rowStride));
|
|
1594
1628
|
const idx = row * perRow + colClamped - shift;
|
|
1595
1629
|
return Math.max(0, Math.min(strip.pages - 1, idx));
|
|
1596
1630
|
}
|