gutterpress 0.10.0-alpha.3 → 0.10.0-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 +2 -0
- package/dist/api/index.js +2 -2
- package/dist/{audit-xxegv0t0.js → audit-85zn35v8.js} +4 -4
- package/dist/{build-w0vb6mgq.js → build-1faqmp0y.js} +6 -4
- package/dist/{cli-5czby0dd.js → cli-5tffrg48.js} +90 -23
- package/dist/{cli-f4rcbt2t.js → cli-7e79d7se.js} +1 -1
- package/dist/{cli-yp3p0sf2.js → cli-afm8pa0h.js} +327 -24
- package/dist/{cli-gk3wsdpb.js → cli-v935c2ws.js} +1 -1
- package/dist/{cli-revgt4pr.js → cli-yzf38679.js} +1 -0
- package/dist/cli.js +16 -16
- package/dist/{doctor-ctgn1dnt.js → doctor-69v5c9wy.js} +2 -2
- package/dist/engine/compiler/build.d.ts +1 -1
- package/dist/engine/shared/flush.d.ts +59 -0
- package/dist/engine/shared/margin-box-support.d.ts +24 -0
- package/dist/{engine-eng4xh2q.js → engine-hrtn0b28.js} +1 -1
- package/dist/{engine-q5skhgms.js → engine-nbfdy0pp.js} +2 -2
- package/dist/{gutterpress-agent-1ctgfz92.js → gutterpress-agent-cazqstr1.js} +49 -1
- package/dist/{gutterpress-viewer-cem7dmr5.js → gutterpress-viewer-fb6fhwsy.js} +137 -51
- package/dist/{index-s416qpdv.js → index-052x5fef.js} +89 -22
- package/dist/{index-mvehxh0e.js → index-c2b6gyeg.js} +47 -4
- package/dist/{index-a4kr77td.js → index-wsydvp08.js} +287 -23
- package/dist/index.js +3 -3
- package/dist/lib/build-runner.d.ts +7 -0
- package/dist/lib/engine.d.ts +9 -0
- package/dist/lib/markdown/gutterpress-css.d.ts +9 -1
- package/dist/lib/markdown/markers.d.ts +51 -1
- package/dist/{lint-gsh6qwrq.js → lint-17404bsx.js} +4 -4
- package/dist/{new-nkhycqy4.js → new-vsgpxzek.js} +4 -4
- package/dist/{plugin-129wcs93.js → plugin-s4yfpx6p.js} +4 -4
- package/dist/{preflight-41hcejg9.js → preflight-1h3apvqh.js} +4 -4
- package/dist/{preview-pftsvr9z.js → preview-cqf383g4.js} +6 -5
- package/dist/{preview-interface-fnqb2y4v.js → preview-interface-hg5eqv88.js} +193 -4
- package/dist/{publish-dnjvb4jg.js → publish-arvycera.js} +4 -4
- package/dist/render.js +83 -7
- package/dist/{repair-a3enjttn.js → repair-vmwh2bhe.js} +4 -4
- package/dist/{validate-ph1xffqy.js → validate-ztzq7p35.js} +4 -4
- package/package.json +1 -1
|
@@ -10,3 +10,27 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const MARGIN_BOX_IGNORED_PROPERTIES: ReadonlySet<string>;
|
|
12
12
|
export declare function isIgnoredMarginBoxProperty(property: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Geometry of each of the 16 margin boxes, per CSS Paged Media §5.3, in pt
|
|
15
|
+
* SHEET coordinates (origin at the sheet's top-left). One implementation for
|
|
16
|
+
* both furniture painters: the viewer's `drawMarginBoxes` overlays and the
|
|
17
|
+
* compiler's `.gp-flush` furniture relocation must place a box at the same
|
|
18
|
+
* spot or preview and print disagree about where the folio sits.
|
|
19
|
+
*/
|
|
20
|
+
export declare function marginBoxRectPt(name: string, g: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
margin: {
|
|
24
|
+
top: number;
|
|
25
|
+
right: number;
|
|
26
|
+
bottom: number;
|
|
27
|
+
left: number;
|
|
28
|
+
};
|
|
29
|
+
}): {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
w: number;
|
|
33
|
+
h: number;
|
|
34
|
+
};
|
|
35
|
+
/** Horizontal alignment of a margin box's content within its slot. */
|
|
36
|
+
export declare function marginBoxAlign(name: string): "start" | "center" | "end";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
build
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-wsydvp08.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-c2b6gyeg.js";
|
|
11
11
|
import"./index-37x76zdn.js";
|
|
12
12
|
|
|
13
13
|
// src/lib/engine.ts
|
|
@@ -44,8 +44,10 @@
|
|
|
44
44
|
targetTexts: () => targetTexts,
|
|
45
45
|
stringSources: () => stringSources,
|
|
46
46
|
setGenerated: () => setGenerated,
|
|
47
|
+
setFlushFurniture: () => setFlushFurniture,
|
|
47
48
|
instrument: () => instrument,
|
|
48
49
|
forcedBreakSites: () => forcedBreakSites,
|
|
50
|
+
flushRoots: () => flushRoots,
|
|
49
51
|
fillLeaders: () => fillLeaders,
|
|
50
52
|
counterResetSites: () => counterResetSites,
|
|
51
53
|
collectCss: () => collectCss,
|
|
@@ -557,6 +559,50 @@
|
|
|
557
559
|
addCss("gp-generated-content", css);
|
|
558
560
|
return entries.length;
|
|
559
561
|
}
|
|
562
|
+
function flushRoots() {
|
|
563
|
+
const out = [];
|
|
564
|
+
for (const root of Array.from(document.querySelectorAll(".page, .spread"))) {
|
|
565
|
+
const edges = ["top", "right", "bottom", "left"].filter((edge) => root.querySelector(`.gp-pin.gp-flush.gp-${edge}`));
|
|
566
|
+
if (!edges.length)
|
|
567
|
+
continue;
|
|
568
|
+
const page = getComputedStyle(root).page;
|
|
569
|
+
const key = `${page === "auto" ? "" : page}|${edges.map((e) => e[0]).join("")}`;
|
|
570
|
+
root.dataset.gpFlush = key;
|
|
571
|
+
out.push({ id: ensureAnchor(root), page, edges, key });
|
|
572
|
+
}
|
|
573
|
+
return out;
|
|
574
|
+
}
|
|
575
|
+
function setFlushFurniture(items) {
|
|
576
|
+
let painted = 0;
|
|
577
|
+
for (const item of items) {
|
|
578
|
+
const host = anchorHost(item.id);
|
|
579
|
+
if (!host)
|
|
580
|
+
continue;
|
|
581
|
+
let layer = host.querySelector(":scope > .gp-flush-furniture");
|
|
582
|
+
if (!layer) {
|
|
583
|
+
layer = document.createElement("div");
|
|
584
|
+
layer.className = "gp-flush-furniture";
|
|
585
|
+
layer.setAttribute("aria-hidden", "true");
|
|
586
|
+
layer.setAttribute("style", "position:absolute;inset:0;pointer-events:none;z-index:10;");
|
|
587
|
+
host.appendChild(layer);
|
|
588
|
+
}
|
|
589
|
+
layer.textContent = "";
|
|
590
|
+
for (const b of item.boxes) {
|
|
591
|
+
const slot = document.createElement("div");
|
|
592
|
+
slot.dataset.box = b.box;
|
|
593
|
+
const justify = b.align === "center" ? "center" : b.align === "end" ? "flex-end" : "flex-start";
|
|
594
|
+
slot.setAttribute("style", `position:absolute;left:${b.x}px;top:${b.y}px;width:${b.w}px;height:${b.h}px;` + `display:flex;align-items:center;justify-content:${justify};overflow:hidden;white-space:pre;`);
|
|
595
|
+
const content = document.createElement("span");
|
|
596
|
+
content.textContent = b.text;
|
|
597
|
+
for (const [prop, value] of Object.entries(b.decls))
|
|
598
|
+
content.style.setProperty(prop, value);
|
|
599
|
+
slot.appendChild(content);
|
|
600
|
+
layer.appendChild(slot);
|
|
601
|
+
painted++;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return painted;
|
|
605
|
+
}
|
|
560
606
|
var api = {
|
|
561
607
|
auditContent,
|
|
562
608
|
collectCss,
|
|
@@ -569,7 +615,9 @@
|
|
|
569
615
|
fillLeaders,
|
|
570
616
|
instrument,
|
|
571
617
|
addCss,
|
|
572
|
-
setGenerated
|
|
618
|
+
setGenerated,
|
|
619
|
+
flushRoots,
|
|
620
|
+
setFlushFurniture
|
|
573
621
|
};
|
|
574
622
|
if (typeof window !== "undefined")
|
|
575
623
|
window.__gp = api;
|
|
@@ -33,9 +33,11 @@
|
|
|
33
33
|
injectBreakMapping: () => injectBreakMapping,
|
|
34
34
|
fragmentDocument: () => fragmentDocument,
|
|
35
35
|
forcedColumnBreaksSupported: () => forcedColumnBreaksSupported,
|
|
36
|
+
contentEdgeRect: () => contentEdgeRect,
|
|
36
37
|
compensateTrailingMarginsBeforeAvoids: () => compensateTrailingMarginsBeforeAvoids,
|
|
37
38
|
compensateRepeatedHeaders: () => compensateRepeatedHeaders,
|
|
38
39
|
compensateRectoBreaks: () => compensateRectoBreaks,
|
|
40
|
+
columnReserve: () => columnReserve,
|
|
39
41
|
collectCssText: () => collectCssText,
|
|
40
42
|
buildStrips: () => buildStrips,
|
|
41
43
|
blankPageIndices: () => blankPageIndices,
|
|
@@ -148,6 +150,23 @@
|
|
|
148
150
|
.gp-run {
|
|
149
151
|
position: relative;
|
|
150
152
|
margin: 0 0 var(--gp-sheet-gap);
|
|
153
|
+
/* Hit-transparent, like \`.gp-layer\` below: in wrap mode a recto-starting
|
|
154
|
+
run is pulled up over the previous run's last row (decorate.ts's
|
|
155
|
+
cross-run negative margin-top — the spread-composition overlap), and
|
|
156
|
+
its leading \`.gp-wrap-spacer\` slot is visually empty. The covered page
|
|
157
|
+
paints through, but the run's full-width box used to win
|
|
158
|
+
elementFromPoint there, so clicks, right-clicks, link hits, and text
|
|
159
|
+
selection were all dead on every covered page (measured: 60/60 dead
|
|
160
|
+
probe points in two-column view). Runs are viewer chrome — only author
|
|
161
|
+
content may capture hits. */
|
|
162
|
+
pointer-events: none;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* …and the author's content re-enables hit testing. Equal specificity with
|
|
166
|
+
\`.gp-run { pointer-events: none }\` above, so ORDER is load-bearing:
|
|
167
|
+
\`auto\` must come after \`none\`. */
|
|
168
|
+
.gp-strip > * {
|
|
169
|
+
pointer-events: auto;
|
|
151
170
|
}
|
|
152
171
|
|
|
153
172
|
.gp-layer {
|
|
@@ -957,6 +976,20 @@
|
|
|
957
976
|
`);
|
|
958
977
|
}
|
|
959
978
|
|
|
979
|
+
// src/engine/shared/flush.ts
|
|
980
|
+
var FLUSH_EDGES = ["top", "right", "bottom", "left"];
|
|
981
|
+
function flushEdgesIn(root) {
|
|
982
|
+
return FLUSH_EDGES.filter((edge) => root.querySelector(`.gp-pin.gp-flush.gp-${edge}`));
|
|
983
|
+
}
|
|
984
|
+
function flushMargins(margin, edges) {
|
|
985
|
+
return {
|
|
986
|
+
top: edges.includes("top") ? 0 : margin.top,
|
|
987
|
+
right: edges.includes("right") ? 0 : margin.right,
|
|
988
|
+
bottom: edges.includes("bottom") ? 0 : margin.bottom,
|
|
989
|
+
left: edges.includes("left") ? 0 : margin.left
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
|
|
960
993
|
// src/engine/viewer/fragment.ts
|
|
961
994
|
var PX_PER_PT = 96 / 72;
|
|
962
995
|
function injectViewerCss(doc = document) {
|
|
@@ -1005,6 +1038,21 @@
|
|
|
1005
1038
|
function forcedColumnBreaksSupported() {
|
|
1006
1039
|
return typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("break-before", "column") && CSS.supports("break-after", "column");
|
|
1007
1040
|
}
|
|
1041
|
+
var FRAGMENT_EPSILON_PX = 1;
|
|
1042
|
+
function contentEdgeRect(site, atEnd) {
|
|
1043
|
+
const rects = Array.from(site.getClientRects());
|
|
1044
|
+
const solid = rects.filter((r) => r.height >= FRAGMENT_EPSILON_PX);
|
|
1045
|
+
const pool = solid.length ? solid : rects;
|
|
1046
|
+
return atEnd ? pool.at(-1) : pool[0];
|
|
1047
|
+
}
|
|
1048
|
+
function columnReserve(offset, columnHeight) {
|
|
1049
|
+
const remaining = columnHeight - offset;
|
|
1050
|
+
if (remaining < FRAGMENT_EPSILON_PX)
|
|
1051
|
+
return null;
|
|
1052
|
+
if (remaining > columnHeight - FRAGMENT_EPSILON_PX)
|
|
1053
|
+
return null;
|
|
1054
|
+
return Math.ceil(remaining);
|
|
1055
|
+
}
|
|
1008
1056
|
function synthesizeColumnBreaks(model) {
|
|
1009
1057
|
const sites = [];
|
|
1010
1058
|
const seen = new WeakMap;
|
|
@@ -1041,23 +1089,22 @@
|
|
|
1041
1089
|
const strip = el.closest(".gp-strip");
|
|
1042
1090
|
if (!strip)
|
|
1043
1091
|
continue;
|
|
1044
|
-
|
|
1045
|
-
|
|
1092
|
+
let site = el;
|
|
1093
|
+
if (prop === "break-before") {
|
|
1094
|
+
const target = propagatedBreakTarget(el, strip);
|
|
1095
|
+
if (!target)
|
|
1096
|
+
continue;
|
|
1097
|
+
site = target;
|
|
1098
|
+
}
|
|
1046
1099
|
if (prop === "break-after" && !el.nextElementSibling)
|
|
1047
1100
|
continue;
|
|
1048
|
-
const
|
|
1049
|
-
const rect = prop === "break-after" ? rects.at(-1) : rects[0];
|
|
1101
|
+
const rect = contentEdgeRect(site, prop === "break-after");
|
|
1050
1102
|
if (!rect)
|
|
1051
1103
|
continue;
|
|
1052
1104
|
const stripTop = strip.getBoundingClientRect().top;
|
|
1053
1105
|
const edge = prop === "break-after" ? rect.bottom : rect.top;
|
|
1054
|
-
const
|
|
1055
|
-
if (
|
|
1056
|
-
continue;
|
|
1057
|
-
if (prop === "break-after" && strip.clientHeight - offset < 0.5)
|
|
1058
|
-
continue;
|
|
1059
|
-
const reserve = Math.ceil(strip.clientHeight - offset);
|
|
1060
|
-
if (reserve <= 0)
|
|
1106
|
+
const reserve = columnReserve(edge - stripTop, strip.clientHeight);
|
|
1107
|
+
if (reserve === null)
|
|
1061
1108
|
continue;
|
|
1062
1109
|
const spacer = document.createElement("div");
|
|
1063
1110
|
spacer.className = "gp-column-break-spacer";
|
|
@@ -1066,9 +1113,29 @@
|
|
|
1066
1113
|
if (prop === "break-after")
|
|
1067
1114
|
el.after(spacer);
|
|
1068
1115
|
else
|
|
1069
|
-
|
|
1116
|
+
site.before(spacer);
|
|
1070
1117
|
}
|
|
1071
1118
|
}
|
|
1119
|
+
function propagatedBreakTarget(el, strip) {
|
|
1120
|
+
let site = el;
|
|
1121
|
+
while (!site.previousElementSibling) {
|
|
1122
|
+
const parent = site.parentElement;
|
|
1123
|
+
if (!parent || parent === strip)
|
|
1124
|
+
return null;
|
|
1125
|
+
const cs = getComputedStyle(site);
|
|
1126
|
+
if (cs.position === "absolute" || cs.position === "fixed" || cs.float !== "none")
|
|
1127
|
+
return null;
|
|
1128
|
+
for (let node = site.previousSibling;node; node = node.previousSibling) {
|
|
1129
|
+
if (node.nodeType === 3 && (node.textContent ?? "").trim() !== "")
|
|
1130
|
+
return site;
|
|
1131
|
+
}
|
|
1132
|
+
const pcs = getComputedStyle(parent);
|
|
1133
|
+
if (!/^(block|flow-root)$/.test(pcs.display) || pcs.columnCount !== "auto")
|
|
1134
|
+
return null;
|
|
1135
|
+
site = parent;
|
|
1136
|
+
}
|
|
1137
|
+
return site;
|
|
1138
|
+
}
|
|
1072
1139
|
function directPageName(el, model) {
|
|
1073
1140
|
for (const a of model.pageAssignments) {
|
|
1074
1141
|
try {
|
|
@@ -1087,12 +1154,13 @@
|
|
|
1087
1154
|
}
|
|
1088
1155
|
return false;
|
|
1089
1156
|
}
|
|
1090
|
-
function pushRun(runs, page, nodes) {
|
|
1157
|
+
function pushRun(runs, page, nodes, flushEdges) {
|
|
1158
|
+
const key = (r) => `${r.page ?? ""}\x00${(r.flushEdges ?? []).join(",")}`;
|
|
1091
1159
|
const last = runs[runs.length - 1];
|
|
1092
|
-
if (last && last
|
|
1160
|
+
if (last && key(last) === key({ page, flushEdges }))
|
|
1093
1161
|
last.nodes.push(...nodes);
|
|
1094
1162
|
else
|
|
1095
|
-
runs.push({ page, nodes });
|
|
1163
|
+
runs.push({ page, nodes, flushEdges: flushEdges?.length ? flushEdges : undefined });
|
|
1096
1164
|
}
|
|
1097
1165
|
function explodeChildren(container, model) {
|
|
1098
1166
|
const runs = [];
|
|
@@ -1104,7 +1172,7 @@
|
|
|
1104
1172
|
pending = [];
|
|
1105
1173
|
const last = runs[runs.length - 1];
|
|
1106
1174
|
if (last) {
|
|
1107
|
-
pushRun(runs, last.page, held);
|
|
1175
|
+
pushRun(runs, last.page, held, last.flushEdges);
|
|
1108
1176
|
return [];
|
|
1109
1177
|
}
|
|
1110
1178
|
if (held.some((n) => (n.textContent ?? "").trim() !== "")) {
|
|
@@ -1121,13 +1189,14 @@
|
|
|
1121
1189
|
const kid = node;
|
|
1122
1190
|
if (kid.classList.contains("gp-layer"))
|
|
1123
1191
|
continue;
|
|
1192
|
+
const flush = flushEdgesIn(kid);
|
|
1124
1193
|
const own = directPageName(kid, model);
|
|
1125
1194
|
if (own !== undefined) {
|
|
1126
|
-
pushRun(runs, own, [...carry(), kid]);
|
|
1195
|
+
pushRun(runs, own, [...carry(), kid], flush);
|
|
1127
1196
|
continue;
|
|
1128
1197
|
}
|
|
1129
1198
|
if (!hasDescendantPageAssignment(kid, model)) {
|
|
1130
|
-
pushRun(runs, undefined, [...carry(), kid]);
|
|
1199
|
+
pushRun(runs, undefined, [...carry(), kid], flush);
|
|
1131
1200
|
continue;
|
|
1132
1201
|
}
|
|
1133
1202
|
const inner = explodeChildren(kid, model);
|
|
@@ -1141,7 +1210,7 @@
|
|
|
1141
1210
|
for (const n of r.nodes)
|
|
1142
1211
|
shell.appendChild(n);
|
|
1143
1212
|
kid.before(shell);
|
|
1144
|
-
pushRun(runs, r.page, [...lead, shell]);
|
|
1213
|
+
pushRun(runs, r.page, [...lead, shell], flushEdgesIn(shell));
|
|
1145
1214
|
lead = [];
|
|
1146
1215
|
}
|
|
1147
1216
|
kid.remove();
|
|
@@ -1289,21 +1358,29 @@
|
|
|
1289
1358
|
strip.className = "gp-strip";
|
|
1290
1359
|
if (run.page)
|
|
1291
1360
|
strip.dataset.page = run.page;
|
|
1292
|
-
const
|
|
1293
|
-
const
|
|
1361
|
+
const margin = run.flushEdges?.length ? flushMargins(geometry.margin, run.flushEdges) : geometry.margin;
|
|
1362
|
+
const w = pt(geometry.width - margin.left - margin.right);
|
|
1363
|
+
const h = pt(geometry.height - margin.top - margin.bottom);
|
|
1294
1364
|
strip.style.setProperty("--gp-content-w", `${w}px`);
|
|
1295
1365
|
strip.style.setProperty("--gp-content-h", `${h}px`);
|
|
1296
1366
|
strip.style.setProperty("--gp-sheet-gap", `${gap}px`);
|
|
1297
1367
|
strip.style.setProperty("--gp-page-w", `${pt(geometry.width)}px`);
|
|
1298
1368
|
strip.style.setProperty("--gp-page-h", `${pt(geometry.height)}px`);
|
|
1299
|
-
strip.style.setProperty("--gp-margin-top", `${pt(
|
|
1300
|
-
strip.style.setProperty("--gp-margin-right", `${pt(
|
|
1301
|
-
strip.style.setProperty("--gp-margin-bottom", `${pt(
|
|
1302
|
-
strip.style.setProperty("--gp-margin-left", `${pt(
|
|
1369
|
+
strip.style.setProperty("--gp-margin-top", `${pt(margin.top)}px`);
|
|
1370
|
+
strip.style.setProperty("--gp-margin-right", `${pt(margin.right)}px`);
|
|
1371
|
+
strip.style.setProperty("--gp-margin-bottom", `${pt(margin.bottom)}px`);
|
|
1372
|
+
strip.style.setProperty("--gp-margin-left", `${pt(margin.left)}px`);
|
|
1303
1373
|
run.nodes[0].before(strip);
|
|
1304
1374
|
for (const n of run.nodes)
|
|
1305
1375
|
strip.appendChild(n);
|
|
1306
|
-
strips.push({
|
|
1376
|
+
strips.push({
|
|
1377
|
+
el: strip,
|
|
1378
|
+
page: run.page,
|
|
1379
|
+
geometry,
|
|
1380
|
+
flushEdges: run.flushEdges,
|
|
1381
|
+
pages: 0,
|
|
1382
|
+
offset: 0
|
|
1383
|
+
});
|
|
1307
1384
|
}
|
|
1308
1385
|
for (const s of strips)
|
|
1309
1386
|
clearLeadingForcedBreaks(s.el);
|
|
@@ -1864,6 +1941,37 @@
|
|
|
1864
1941
|
function isIgnoredMarginBoxProperty(property) {
|
|
1865
1942
|
return MARGIN_BOX_IGNORED_PROPERTIES.has(property.toLowerCase());
|
|
1866
1943
|
}
|
|
1944
|
+
function marginBoxRectPt(name, g) {
|
|
1945
|
+
const { top, right, bottom, left } = g.margin;
|
|
1946
|
+
const cw = g.width - left - right;
|
|
1947
|
+
const ch = g.height - top - bottom;
|
|
1948
|
+
const third = (n) => n / 3;
|
|
1949
|
+
const T = {
|
|
1950
|
+
"top-left-corner": [0, 0, left, top],
|
|
1951
|
+
"top-left": [left, 0, third(cw), top],
|
|
1952
|
+
"top-center": [left + third(cw), 0, third(cw), top],
|
|
1953
|
+
"top-right": [left + 2 * third(cw), 0, third(cw), top],
|
|
1954
|
+
"top-right-corner": [g.width - right, 0, right, top],
|
|
1955
|
+
"bottom-left-corner": [0, g.height - bottom, left, bottom],
|
|
1956
|
+
"bottom-left": [left, g.height - bottom, third(cw), bottom],
|
|
1957
|
+
"bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
|
|
1958
|
+
"bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
|
|
1959
|
+
"bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
|
|
1960
|
+
"left-top": [0, top, left, third(ch)],
|
|
1961
|
+
"left-middle": [0, top + third(ch), left, third(ch)],
|
|
1962
|
+
"left-bottom": [0, top + 2 * third(ch), left, third(ch)],
|
|
1963
|
+
"right-top": [g.width - right, top, right, third(ch)],
|
|
1964
|
+
"right-middle": [g.width - right, top + third(ch), right, third(ch)],
|
|
1965
|
+
"right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
|
|
1966
|
+
};
|
|
1967
|
+
const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
|
|
1968
|
+
return { x, y, w, h };
|
|
1969
|
+
}
|
|
1970
|
+
function marginBoxAlign(name) {
|
|
1971
|
+
if (name.includes("center") || name.includes("middle"))
|
|
1972
|
+
return "center";
|
|
1973
|
+
return /right/.test(name) ? "end" : "start";
|
|
1974
|
+
}
|
|
1867
1975
|
|
|
1868
1976
|
// src/engine/viewer/decorate.ts
|
|
1869
1977
|
var px = (v) => `${v * PX_PER_PT}px`;
|
|
@@ -2120,7 +2228,7 @@
|
|
|
2120
2228
|
box.className = "gp-marginbox";
|
|
2121
2229
|
box.dataset.box = name;
|
|
2122
2230
|
Object.assign(box.style, rectFor(name, g));
|
|
2123
|
-
box.dataset.align =
|
|
2231
|
+
box.dataset.align = marginBoxAlign(name);
|
|
2124
2232
|
const content = document.createElement("span");
|
|
2125
2233
|
content.className = "gp-marginbox-content";
|
|
2126
2234
|
content.textContent = text;
|
|
@@ -2232,30 +2340,8 @@
|
|
|
2232
2340
|
return run;
|
|
2233
2341
|
}
|
|
2234
2342
|
function rectFor(name, g) {
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2237
|
-
const ch = g.height - top - bottom;
|
|
2238
|
-
const third = (n) => n / 3;
|
|
2239
|
-
const T = {
|
|
2240
|
-
"top-left-corner": [0, 0, left, top],
|
|
2241
|
-
"top-left": [left, 0, third(cw), top],
|
|
2242
|
-
"top-center": [left + third(cw), 0, third(cw), top],
|
|
2243
|
-
"top-right": [left + 2 * third(cw), 0, third(cw), top],
|
|
2244
|
-
"top-right-corner": [g.width - right, 0, right, top],
|
|
2245
|
-
"bottom-left-corner": [0, g.height - bottom, left, bottom],
|
|
2246
|
-
"bottom-left": [left, g.height - bottom, third(cw), bottom],
|
|
2247
|
-
"bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
|
|
2248
|
-
"bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
|
|
2249
|
-
"bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
|
|
2250
|
-
"left-top": [0, top, left, third(ch)],
|
|
2251
|
-
"left-middle": [0, top + third(ch), left, third(ch)],
|
|
2252
|
-
"left-bottom": [0, top + 2 * third(ch), left, third(ch)],
|
|
2253
|
-
"right-top": [g.width - right, top, right, third(ch)],
|
|
2254
|
-
"right-middle": [g.width - right, top + third(ch), right, third(ch)],
|
|
2255
|
-
"right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
|
|
2256
|
-
};
|
|
2257
|
-
const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
|
|
2258
|
-
return { left: px(x), top: px(y), width: px(w), height: px(h) };
|
|
2343
|
+
const r = marginBoxRectPt(name, g);
|
|
2344
|
+
return { left: px(r.x), top: px(r.y), width: px(r.w), height: px(r.h) };
|
|
2259
2345
|
}
|
|
2260
2346
|
|
|
2261
2347
|
// src/engine/viewer/index.ts
|