gutterpress 0.10.0-beta.1 → 0.10.1-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/README.md +3 -16
- package/dist/api/index.d.ts +10 -19
- package/dist/api/index.js +8 -64
- package/dist/{audit-85zn35v8.js → audit-7a37g51p.js} +5 -5
- package/dist/{build-1faqmp0y.js → build-kdaet3pd.js} +5 -5
- package/dist/checks/source/index.d.ts +1 -0
- package/dist/checks/source/merge-markers.d.ts +3 -0
- package/dist/{cli-afm8pa0h.js → cli-ak1tagkr.js} +95 -58
- package/dist/{cli-5tffrg48.js → cli-df7gcyns.js} +510 -1375
- package/dist/{cli-7e79d7se.js → cli-dx6sxj2t.js} +1 -1
- package/dist/{cli-v935c2ws.js → cli-mcb484g3.js} +2 -47
- package/dist/{cli-k1065rkg.js → cli-w692g6dx.js} +75 -29
- package/dist/cli.js +14 -15
- package/dist/{doctor-69v5c9wy.js → doctor-vajd5h45.js} +2 -2
- package/dist/{engine-nbfdy0pp.js → engine-0nt35svz.js} +2 -2
- package/dist/{engine-hrtn0b28.js → engine-gkcqdye5.js} +1 -1
- package/dist/{gutterpress-viewer-fb6fhwsy.js → gutterpress-viewer-tma1qwz2.js} +111 -35
- package/dist/{index-052x5fef.js → index-6g72h2n1.js} +980 -1677
- package/dist/{index-c2b6gyeg.js → index-b2rqw41a.js} +2 -2
- package/dist/{index-mdefp0y5.js → index-dtrftayr.js} +75 -27
- package/dist/{index-wsydvp08.js → index-kvgq4q3q.js} +94 -57
- package/dist/index.js +9 -65
- package/dist/lib/build-staging.d.ts +51 -0
- package/dist/lib/git-fs.d.ts +43 -0
- package/dist/lib/host-policy.d.ts +14 -2
- package/dist/lib/remote-auth/clone.d.ts +0 -21
- package/dist/lib/remote-auth/converge-merge.d.ts +24 -7
- package/dist/lib/remote-auth/generic-auth.d.ts +0 -22
- package/dist/lib/remote-auth/git-http.d.ts +1 -1
- package/dist/lib/remote-auth/github-auth.d.ts +2 -22
- package/dist/lib/remote-auth/operation-log.d.ts +4 -9
- package/dist/lib/remote-auth/sync-messages.d.ts +35 -12
- package/dist/lib/remote-auth/sync-types.d.ts +30 -101
- package/dist/lib/remote-auth/sync.d.ts +19 -21
- package/dist/lib/remote-auth/token-store.d.ts +0 -10
- package/dist/lib/remote-auth/transport.d.ts +42 -40
- package/dist/lib/source-provider.d.ts +12 -0
- package/dist/{lint-17404bsx.js → lint-p6a4bkvh.js} +5 -5
- package/dist/{new-vsgpxzek.js → new-4cdzfbsj.js} +5 -5
- package/dist/{plugin-s4yfpx6p.js → plugin-a89tqspy.js} +5 -5
- package/dist/{preflight-1h3apvqh.js → preflight-r4y3f8f9.js} +5 -5
- package/dist/{preview-interface-hg5eqv88.js → preview-interface-0ssk8bmm.js} +4 -2
- package/dist/{preview-cqf383g4.js → preview-k8n2kew7.js} +5 -5
- package/dist/{publish-arvycera.js → publish-jnhjp2vd.js} +5 -5
- package/dist/{source-provider-3tcj6qg2.js → source-provider-2j5x2hyw.js} +1 -1
- package/dist/{source-provider-vanafrt9.js → source-provider-kn41jmbs.js} +1 -1
- package/dist/{validate-ztzq7p35.js → validate-prnybpkx.js} +5 -5
- package/package.json +1 -1
- package/dist/lib/app-heartbeat.d.ts +0 -102
- package/dist/lib/remote-auth/image-clash.d.ts +0 -17
- package/dist/lib/remote-auth/recovery/classify.d.ts +0 -97
- package/dist/lib/remote-auth/recovery/inspect.d.ts +0 -75
- package/dist/lib/remote-auth/recovery/locks.d.ts +0 -20
- package/dist/lib/remote-auth/recovery/repair.d.ts +0 -29
- package/dist/lib/remote-auth/recovery/types.d.ts +0 -39
- package/dist/repair-vmwh2bhe.js +0 -137
|
@@ -24,15 +24,16 @@
|
|
|
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,
|
|
30
31
|
measure: () => measure,
|
|
32
|
+
makeOverflowFragmentable: () => makeOverflowFragmentable,
|
|
31
33
|
loadStyleSources: () => loadStyleSources,
|
|
32
34
|
injectViewerCss: () => injectViewerCss,
|
|
33
35
|
injectBreakMapping: () => injectBreakMapping,
|
|
34
36
|
fragmentDocument: () => fragmentDocument,
|
|
35
|
-
forcedColumnBreaksSupported: () => forcedColumnBreaksSupported,
|
|
36
37
|
contentEdgeRect: () => contentEdgeRect,
|
|
37
38
|
compensateTrailingMarginsBeforeAvoids: () => compensateTrailingMarginsBeforeAvoids,
|
|
38
39
|
compensateRepeatedHeaders: () => compensateRepeatedHeaders,
|
|
@@ -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
|
|
@@ -1035,15 +1048,10 @@
|
|
|
1035
1048
|
doc.getElementById("gp-break-mapping")?.remove();
|
|
1036
1049
|
return "";
|
|
1037
1050
|
}
|
|
1038
|
-
function forcedColumnBreaksSupported() {
|
|
1039
|
-
return typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("break-before", "column") && CSS.supports("break-after", "column");
|
|
1040
|
-
}
|
|
1041
1051
|
var FRAGMENT_EPSILON_PX = 1;
|
|
1042
1052
|
function contentEdgeRect(site, atEnd) {
|
|
1043
1053
|
const rects = Array.from(site.getClientRects());
|
|
1044
|
-
|
|
1045
|
-
const pool = solid.length ? solid : rects;
|
|
1046
|
-
return atEnd ? pool.at(-1) : pool[0];
|
|
1054
|
+
return atEnd ? rects.at(-1) : rects[0];
|
|
1047
1055
|
}
|
|
1048
1056
|
function columnReserve(offset, columnHeight) {
|
|
1049
1057
|
const remaining = columnHeight - offset;
|
|
@@ -1103,13 +1111,12 @@
|
|
|
1103
1111
|
continue;
|
|
1104
1112
|
const stripTop = strip.getBoundingClientRect().top;
|
|
1105
1113
|
const edge = prop === "break-after" ? rect.bottom : rect.top;
|
|
1106
|
-
|
|
1107
|
-
if (reserve === null)
|
|
1114
|
+
if (columnReserve((edge - stripTop) / cssZoomOf(strip), strip.clientHeight) === null)
|
|
1108
1115
|
continue;
|
|
1109
1116
|
const spacer = document.createElement("div");
|
|
1110
1117
|
spacer.className = "gp-column-break-spacer";
|
|
1111
1118
|
spacer.setAttribute("aria-hidden", "true");
|
|
1112
|
-
spacer.style.cssText =
|
|
1119
|
+
spacer.style.cssText = `${prop}: column; height:0; margin:0; padding:0; border:0;`;
|
|
1113
1120
|
if (prop === "break-after")
|
|
1114
1121
|
el.after(spacer);
|
|
1115
1122
|
else
|
|
@@ -1267,6 +1274,47 @@
|
|
|
1267
1274
|
delete el.dataset.gpLeadingPageRootDisplayPriority;
|
|
1268
1275
|
}
|
|
1269
1276
|
}
|
|
1277
|
+
var SCROLLABLE = /^(auto|scroll|hidden)$/;
|
|
1278
|
+
function makeOverflowFragmentable(strips) {
|
|
1279
|
+
const todo = [];
|
|
1280
|
+
for (const strip of strips) {
|
|
1281
|
+
for (const el of Array.from(strip.el.querySelectorAll("*"))) {
|
|
1282
|
+
const cs = getComputedStyle(el);
|
|
1283
|
+
const x = SCROLLABLE.test(cs.overflowX);
|
|
1284
|
+
const y = SCROLLABLE.test(cs.overflowY);
|
|
1285
|
+
if (x || y)
|
|
1286
|
+
todo.push({ el, x, y });
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
for (const { el, x, y } of todo) {
|
|
1290
|
+
el.dataset.gpOverflow = "clipped";
|
|
1291
|
+
el.dataset.gpOverflowX = el.style.getPropertyValue("overflow-x");
|
|
1292
|
+
el.dataset.gpOverflowY = el.style.getPropertyValue("overflow-y");
|
|
1293
|
+
el.dataset.gpOverflowXPriority = el.style.getPropertyPriority("overflow-x");
|
|
1294
|
+
el.dataset.gpOverflowYPriority = el.style.getPropertyPriority("overflow-y");
|
|
1295
|
+
if (x)
|
|
1296
|
+
el.style.setProperty("overflow-x", "clip");
|
|
1297
|
+
if (y)
|
|
1298
|
+
el.style.setProperty("overflow-y", "clip");
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
function restoreScrollContainers(doc = document) {
|
|
1302
|
+
for (const el of Array.from(doc.querySelectorAll('[data-gp-overflow="clipped"]'))) {
|
|
1303
|
+
for (const axis of ["x", "y"]) {
|
|
1304
|
+
const value = axis === "x" ? el.dataset.gpOverflowX : el.dataset.gpOverflowY;
|
|
1305
|
+
const priority = axis === "x" ? el.dataset.gpOverflowXPriority : el.dataset.gpOverflowYPriority;
|
|
1306
|
+
if (value)
|
|
1307
|
+
el.style.setProperty(`overflow-${axis}`, value, priority || "");
|
|
1308
|
+
else
|
|
1309
|
+
el.style.removeProperty(`overflow-${axis}`);
|
|
1310
|
+
}
|
|
1311
|
+
delete el.dataset.gpOverflow;
|
|
1312
|
+
delete el.dataset.gpOverflowX;
|
|
1313
|
+
delete el.dataset.gpOverflowY;
|
|
1314
|
+
delete el.dataset.gpOverflowXPriority;
|
|
1315
|
+
delete el.dataset.gpOverflowYPriority;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1270
1318
|
function compensateTrailingMarginsBeforeAvoids(model, strips) {
|
|
1271
1319
|
const candidates = new Set;
|
|
1272
1320
|
for (const decl of model.breaks) {
|
|
@@ -1301,19 +1349,21 @@
|
|
|
1301
1349
|
const prevRect = prevRects.at(-1);
|
|
1302
1350
|
const stripRect = stripEl.getBoundingClientRect();
|
|
1303
1351
|
const { stride } = stripMetrics(stripEl);
|
|
1304
|
-
const
|
|
1352
|
+
const zoom = cssZoomOf(stripEl);
|
|
1353
|
+
const colOf = (r) => Math.floor(((r.left - stripRect.left) / zoom + 1) / stride);
|
|
1305
1354
|
const currentCol = colOf(rect);
|
|
1306
1355
|
if (currentCol !== colOf(prevRect) + 1)
|
|
1307
1356
|
continue;
|
|
1308
|
-
if (Math.abs(rect.top - stripRect.top) > 0.5)
|
|
1357
|
+
if (Math.abs(rect.top - stripRect.top) / zoom > 0.5)
|
|
1309
1358
|
continue;
|
|
1310
1359
|
const marginEnd = parseFloat(getComputedStyle(prev).marginBlockEnd) || 0;
|
|
1311
1360
|
if (marginEnd <= 0.5)
|
|
1312
1361
|
continue;
|
|
1313
|
-
const remaining = stripEl.clientHeight - (prevRect.bottom - stripRect.top);
|
|
1314
|
-
|
|
1362
|
+
const remaining = stripEl.clientHeight - (prevRect.bottom - stripRect.top) / zoom;
|
|
1363
|
+
const height = rect.height / zoom;
|
|
1364
|
+
if (height > remaining + 0.5)
|
|
1315
1365
|
continue;
|
|
1316
|
-
if (
|
|
1366
|
+
if (height + marginEnd <= remaining + 0.5)
|
|
1317
1367
|
continue;
|
|
1318
1368
|
prev.dataset.gpTrailingMargin = "compensated";
|
|
1319
1369
|
prev.dataset.gpTrailingMarginValue = prev.style.getPropertyValue("margin-block-end");
|
|
@@ -1346,6 +1396,20 @@
|
|
|
1346
1396
|
}
|
|
1347
1397
|
}
|
|
1348
1398
|
}
|
|
1399
|
+
function runPageBox(model, name, warnings = []) {
|
|
1400
|
+
const right = resolvePage(model, { name, pseudos: ["right"] }).geometry;
|
|
1401
|
+
const left = resolvePage(model, { name, pseudos: ["left"] }).geometry;
|
|
1402
|
+
const box = (g) => ({
|
|
1403
|
+
w: g.width - g.margin.left - g.margin.right,
|
|
1404
|
+
h: g.height - g.margin.top - g.margin.bottom
|
|
1405
|
+
});
|
|
1406
|
+
const r = box(right);
|
|
1407
|
+
const l = box(left);
|
|
1408
|
+
if (Math.abs(r.w - l.w) < 0.01 && Math.abs(r.h - l.h) < 0.01)
|
|
1409
|
+
return right;
|
|
1410
|
+
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.`);
|
|
1411
|
+
return resolvePage(model, { name }).geometry;
|
|
1412
|
+
}
|
|
1349
1413
|
function buildStrips(model, opts = {}, warnings = []) {
|
|
1350
1414
|
const doc = document;
|
|
1351
1415
|
const root = opts.root ?? doc.querySelector("main") ?? doc.body;
|
|
@@ -1353,7 +1417,7 @@
|
|
|
1353
1417
|
const runs = explodeChildren(root, model);
|
|
1354
1418
|
const strips = [];
|
|
1355
1419
|
for (const run of runs) {
|
|
1356
|
-
const
|
|
1420
|
+
const geometry = runPageBox(model, run.page, warnings);
|
|
1357
1421
|
const strip = doc.createElement("div");
|
|
1358
1422
|
strip.className = "gp-strip";
|
|
1359
1423
|
if (run.page)
|
|
@@ -1406,14 +1470,15 @@
|
|
|
1406
1470
|
passes = Math.max(passes, pass + 1);
|
|
1407
1471
|
const stride = strideOf(strip.el);
|
|
1408
1472
|
const stripLeft = strip.el.getBoundingClientRect().left - strip.el.scrollLeft;
|
|
1409
|
-
const
|
|
1473
|
+
const zoom = cssZoomOf(strip.el);
|
|
1474
|
+
const colOf = (r) => Math.floor(((r.left - stripLeft) / zoom + 1) / stride);
|
|
1410
1475
|
const stripTop = strip.el.getBoundingClientRect().top;
|
|
1411
1476
|
const colBottom = strip.el.clientHeight;
|
|
1412
1477
|
const plans = [];
|
|
1413
1478
|
for (const table of tables) {
|
|
1414
1479
|
const head = table.tHead;
|
|
1415
1480
|
const headRect = head?.getClientRects()[0];
|
|
1416
|
-
const footHeight = table.tFoot?.getBoundingClientRect().height ?? 0;
|
|
1481
|
+
const footHeight = (table.tFoot?.getBoundingClientRect().height ?? 0) / zoom;
|
|
1417
1482
|
const rows = Array.from(table.querySelectorAll("tbody > tr")).filter((r) => !r.classList.contains("gp-thead-shim") && !r.classList.contains("gp-tfoot-shim"));
|
|
1418
1483
|
if (!rows.length)
|
|
1419
1484
|
continue;
|
|
@@ -1428,10 +1493,10 @@
|
|
|
1428
1493
|
const row = rows[i];
|
|
1429
1494
|
if (cols[i] === lastCol || claims.has(row))
|
|
1430
1495
|
continue;
|
|
1431
|
-
const bottom = rects[i].bottom - stripTop;
|
|
1496
|
+
const bottom = (rects[i].bottom - stripTop) / zoom;
|
|
1432
1497
|
if (bottom > colBottom - footHeight + 0.5) {
|
|
1433
1498
|
newClaim = row;
|
|
1434
|
-
claims.set(row, colBottom - (rects[i].top - stripTop));
|
|
1499
|
+
claims.set(row, colBottom - (rects[i].top - stripTop) / zoom);
|
|
1435
1500
|
break;
|
|
1436
1501
|
}
|
|
1437
1502
|
}
|
|
@@ -1439,7 +1504,7 @@
|
|
|
1439
1504
|
plans.push({
|
|
1440
1505
|
table,
|
|
1441
1506
|
push: headRect ? colOf(headRect) < cols[0] : false,
|
|
1442
|
-
headHeight: headRect?.height ?? 0,
|
|
1507
|
+
headHeight: (headRect?.height ?? 0) / zoom,
|
|
1443
1508
|
footHeight,
|
|
1444
1509
|
breakRows: headRect ? rows.filter((_, i) => i > 0 && cols[i] > cols[i - 1]) : [],
|
|
1445
1510
|
footRows: [...claims.entries()],
|
|
@@ -1525,11 +1590,15 @@
|
|
|
1525
1590
|
for (const [i, site] of sites.entries()) {
|
|
1526
1591
|
if (!plan[i])
|
|
1527
1592
|
continue;
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1593
|
+
const leading = site.el.previousElementSibling;
|
|
1594
|
+
const need = leading?.classList.contains("gp-column-break-spacer") ? 1 : 2;
|
|
1595
|
+
for (let n = 0;n < need; n++) {
|
|
1596
|
+
const spacer = document.createElement("div");
|
|
1597
|
+
spacer.className = "gp-recto-spacer";
|
|
1598
|
+
spacer.setAttribute("aria-hidden", "true");
|
|
1599
|
+
spacer.style.cssText = "break-before: column; height: 0; margin: 0; padding: 0; border: 0;";
|
|
1600
|
+
site.el.before(spacer);
|
|
1601
|
+
}
|
|
1533
1602
|
inserted++;
|
|
1534
1603
|
}
|
|
1535
1604
|
return inserted;
|
|
@@ -1563,6 +1632,9 @@
|
|
|
1563
1632
|
function strideOf(strip) {
|
|
1564
1633
|
return stripMetrics(strip).stride;
|
|
1565
1634
|
}
|
|
1635
|
+
function cssZoomOf(el) {
|
|
1636
|
+
return el.currentCSSZoom ?? 1;
|
|
1637
|
+
}
|
|
1566
1638
|
function stripMetrics(strip) {
|
|
1567
1639
|
const cs = getComputedStyle(strip);
|
|
1568
1640
|
const w = parseFloat(cs.getPropertyValue("--gp-content-w"));
|
|
@@ -1585,12 +1657,13 @@
|
|
|
1585
1657
|
function indexInStrip(left, top, strip) {
|
|
1586
1658
|
const { stride, rowStride } = stripMetrics(strip.el);
|
|
1587
1659
|
const stripBox = strip.el.getBoundingClientRect();
|
|
1588
|
-
const
|
|
1589
|
-
const
|
|
1660
|
+
const zoom = cssZoomOf(strip.el);
|
|
1661
|
+
const x = (left - stripBox.left) / zoom + strip.el.scrollLeft;
|
|
1662
|
+
const y = (top - stripBox.top) / zoom;
|
|
1590
1663
|
const { perRow, shift } = wrapGeometry(strip);
|
|
1591
|
-
const colVisual = Math.floor((
|
|
1664
|
+
const colVisual = Math.floor((x + 1) / stride);
|
|
1592
1665
|
const colClamped = Math.max(0, Math.min(perRow - 1, colVisual));
|
|
1593
|
-
const row = Math.max(0, Math.floor((
|
|
1666
|
+
const row = Math.max(0, Math.floor((y + 1) / rowStride));
|
|
1594
1667
|
const idx = row * perRow + colClamped - shift;
|
|
1595
1668
|
return Math.max(0, Math.min(strip.pages - 1, idx));
|
|
1596
1669
|
}
|
|
@@ -1679,6 +1752,7 @@
|
|
|
1679
1752
|
const authoring = [];
|
|
1680
1753
|
const strips = buildStrips(model, opts, authoring);
|
|
1681
1754
|
await layoutReady;
|
|
1755
|
+
makeOverflowFragmentable(strips);
|
|
1682
1756
|
stabilizeFullHeightPageRoots(model, strips);
|
|
1683
1757
|
compensateTrailingMarginsBeforeAvoids(model, strips);
|
|
1684
1758
|
synthesizeColumnBreaks(model);
|
|
@@ -1701,12 +1775,14 @@
|
|
|
1701
1775
|
relayout: () => {
|
|
1702
1776
|
restoreFullHeightPageRoots();
|
|
1703
1777
|
restoreTrailingMargins();
|
|
1778
|
+
restoreScrollContainers();
|
|
1704
1779
|
unwrapStrips(strips);
|
|
1705
1780
|
for (const spacer of Array.from(document.querySelectorAll(".gp-recto-spacer")))
|
|
1706
1781
|
spacer.remove();
|
|
1707
1782
|
const rebuilt = buildStrips(model, opts, authoring);
|
|
1708
1783
|
strips.length = 0;
|
|
1709
1784
|
strips.push(...rebuilt);
|
|
1785
|
+
makeOverflowFragmentable(strips);
|
|
1710
1786
|
stabilizeFullHeightPageRoots(model, strips);
|
|
1711
1787
|
compensateTrailingMarginsBeforeAvoids(model, strips);
|
|
1712
1788
|
synthesizeColumnBreaks(model);
|