@forevka/wordcanvas 0.8.1 → 0.9.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-lib/assets/{worker-BFAbWoje.js → worker-VdvO3cMW.js} +1198 -1182
- package/dist-lib/builder.js +5 -5
- package/dist-lib/{editorApp-CQn18PAu.js → editorApp-BGyP48-P.js} +37 -36
- package/dist-lib/{recalcToc-Dzz8cQho.js → engine-Chvebzwr.js} +525 -548
- package/dist-lib/export.js +8 -7
- package/dist-lib/generate-toc.js +7 -6
- package/dist-lib/import.js +2 -2
- package/dist-lib/{lists-DpmgbDyt.js → lists-BVCy5dMa.js} +2 -2
- package/dist-lib/{parse-CIuWi88O.js → parse-PD2rg4oO.js} +28 -28
- package/dist-lib/{pipeline-DQil8qUX.js → pipeline-r7GVSMFb.js} +60 -60
- package/dist-lib/query.js +977 -0
- package/dist-lib/recalc-docx.js +22 -21
- package/dist-lib/recalcToc-CAeOzLr3.js +37 -0
- package/dist-lib/{stylesheet-BeM16Mvj.js → stylesheet-IH4Hyc8o.js} +3 -3
- package/dist-lib/{toc-C-JErW1U.js → toc-B-TzD-Mr.js} +102 -86
- package/dist-lib/{webmcp-B9Q6w0Vl.js → webmcp-CDpzmTtU.js} +2 -2
- package/dist-lib/{wordcanvas-Cla5Ys8Y.js → wordcanvas-CIqBAV2w.js} +3 -3
- package/dist-lib/wordcanvas.js +1 -1
- package/dist-node/{chunk-JVSPB6WM.js → chunk-A53KB3BE.js} +2 -2
- package/dist-node/{chunk-HMBQQDXD.js → chunk-TLGEFCLV.js} +64 -1
- package/dist-node/chunk-TLGEFCLV.js.map +7 -0
- package/dist-node/{chunk-KZHUXFDE.js → chunk-VNDCELYX.js} +5 -45
- package/dist-node/chunk-VNDCELYX.js.map +7 -0
- package/dist-node/{engine-46GL2RKU.js → engine-QKH45ZHY.js} +5 -4
- package/dist-node/export.js +3 -3
- package/dist-node/generate-toc.js +3 -3
- package/dist-node/import.js +2 -2
- package/dist-node/recalc-docx.js +2 -2
- package/package.json +6 -2
- package/types/builder.d.ts +47 -2
- package/types/model.d.ts +34 -0
- package/types/query.d.ts +416 -0
- package/dist-node/chunk-HMBQQDXD.js.map +0 -7
- package/dist-node/chunk-KZHUXFDE.js.map +0 -7
- /package/dist-node/{chunk-JVSPB6WM.js.map → chunk-A53KB3BE.js.map} +0 -0
- /package/dist-node/{engine-46GL2RKU.js.map → engine-QKH45ZHY.js.map} +0 -0
|
@@ -0,0 +1,977 @@
|
|
|
1
|
+
import { t as C, B as v, f as Q, a as X, D as Z, c as O, n as tt, e as dt, h as z, j as ft, k as ut, l as F, r as et } from "./toc-B-TzD-Mr.js";
|
|
2
|
+
import { r as nt, c as ht } from "./engine-Chvebzwr.js";
|
|
3
|
+
import { c as pt } from "./lists-BVCy5dMa.js";
|
|
4
|
+
import { r as mt } from "./stylesheet-IH4Hyc8o.js";
|
|
5
|
+
function _(o, t, e, n, s = []) {
|
|
6
|
+
for (const r of o)
|
|
7
|
+
if (n(r, t), e.cells && r.kind === "table")
|
|
8
|
+
for (let i = 0; i < r.rows.length; i++) {
|
|
9
|
+
const c = r.rows[i].cells;
|
|
10
|
+
for (let l = 0; l < c.length; l++) {
|
|
11
|
+
const d = { tableId: r.id, row: i, col: l }, a = [...s, d], f = { ...t, cell: d };
|
|
12
|
+
a.length >= 2 && (f.cellPath = a), _(c[l].blocks, f, e, n, a);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function k(o, t, e = {}) {
|
|
17
|
+
const n = { bands: !0, notes: !0, cells: !0, ...e };
|
|
18
|
+
if (_(o.blocks, { container: "body" }, n, t), n.bands) {
|
|
19
|
+
for (const s of v) {
|
|
20
|
+
const r = o.section[s];
|
|
21
|
+
r && _(r, { container: s }, n, t);
|
|
22
|
+
}
|
|
23
|
+
for (const s of o.blocks)
|
|
24
|
+
if (!(s.kind !== "paragraph" || !s.style.sectionBreak))
|
|
25
|
+
for (const r of v) {
|
|
26
|
+
const i = s.style.sectionBreak.props[r];
|
|
27
|
+
i && _(i, { container: r }, n, t);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (n.notes) {
|
|
31
|
+
for (const [s, r] of Object.entries(o.footnotes ?? {}))
|
|
32
|
+
_(r, { container: "body", note: { kind: "footnote", id: s } }, n, t);
|
|
33
|
+
for (const [s, r] of Object.entries(o.endnotes ?? {}))
|
|
34
|
+
_(r, { container: "body", note: { kind: "endnote", id: s } }, n, t);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function ot(o) {
|
|
38
|
+
return o.blocks.map(V).filter((t) => t.length > 0).join(`
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
function Vt(o, t, e) {
|
|
42
|
+
k(o, (n, s) => {
|
|
43
|
+
n.kind === "paragraph" && n.runs.forEach((r, i) => {
|
|
44
|
+
t(r, { ...s, block: n, runIndex: i, sdtChain: Q(n, r.style) });
|
|
45
|
+
});
|
|
46
|
+
}, e);
|
|
47
|
+
}
|
|
48
|
+
function V(o) {
|
|
49
|
+
switch (o.kind) {
|
|
50
|
+
case "paragraph":
|
|
51
|
+
return C(o.runs);
|
|
52
|
+
case "table":
|
|
53
|
+
return o.rows.map((t) => t.cells.map(ot).join(" ")).join(`
|
|
54
|
+
`);
|
|
55
|
+
default:
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function Kt(o, t) {
|
|
60
|
+
const e = [];
|
|
61
|
+
return k(o, (n) => {
|
|
62
|
+
n.kind === "paragraph" && e.push(n);
|
|
63
|
+
}, t), e;
|
|
64
|
+
}
|
|
65
|
+
function Yt(o, t) {
|
|
66
|
+
const e = [];
|
|
67
|
+
return k(o, (n) => {
|
|
68
|
+
n.kind === "table" && e.push(n);
|
|
69
|
+
}, t), e;
|
|
70
|
+
}
|
|
71
|
+
function qt(o, t) {
|
|
72
|
+
const e = [];
|
|
73
|
+
return k(o, (n) => {
|
|
74
|
+
n.kind === "image" && e.push(n);
|
|
75
|
+
}, t), e;
|
|
76
|
+
}
|
|
77
|
+
function yt(o, t, e) {
|
|
78
|
+
const n = typeof t == "string" ? (r) => r.includes(t) : (r) => (t.lastIndex = 0, t.test(r)), s = [];
|
|
79
|
+
return k(o, (r, i) => {
|
|
80
|
+
if (r.kind !== "paragraph") return;
|
|
81
|
+
const c = C(r.runs);
|
|
82
|
+
n(c) && s.push({ paragraph: r, text: c, context: i });
|
|
83
|
+
}, e), s;
|
|
84
|
+
}
|
|
85
|
+
function R(o, t, e) {
|
|
86
|
+
let n;
|
|
87
|
+
return k(o, (s) => {
|
|
88
|
+
n === void 0 && s.id === t && (n = s);
|
|
89
|
+
}, e), n;
|
|
90
|
+
}
|
|
91
|
+
function L(o, t, e) {
|
|
92
|
+
const n = R(o, t, e);
|
|
93
|
+
return n?.kind === "paragraph" ? n : void 0;
|
|
94
|
+
}
|
|
95
|
+
function G(o, t, e) {
|
|
96
|
+
const n = R(o, t, e);
|
|
97
|
+
return n?.kind === "table" ? n : void 0;
|
|
98
|
+
}
|
|
99
|
+
function Wt(o, t, e) {
|
|
100
|
+
const n = R(o, t, e);
|
|
101
|
+
return n?.kind === "image" ? n : void 0;
|
|
102
|
+
}
|
|
103
|
+
function zt(o) {
|
|
104
|
+
return nt(o);
|
|
105
|
+
}
|
|
106
|
+
function x(o, t) {
|
|
107
|
+
return o.sdts?.[t];
|
|
108
|
+
}
|
|
109
|
+
function st(o) {
|
|
110
|
+
return Object.entries(o.sdts ?? {}).map(([t, e]) => ({ id: t, props: e }));
|
|
111
|
+
}
|
|
112
|
+
function Gt(o, t) {
|
|
113
|
+
return st(o).filter((e) => e.props.tag === t);
|
|
114
|
+
}
|
|
115
|
+
function Jt(o, t) {
|
|
116
|
+
return st(o).filter((e) => e.props.alias === t);
|
|
117
|
+
}
|
|
118
|
+
function gt(o) {
|
|
119
|
+
const t = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set(), s = (r) => {
|
|
120
|
+
if (!(!r || r.length < 2))
|
|
121
|
+
for (let i = 1; i < r.length; i++) {
|
|
122
|
+
const c = r[i - 1], l = r[i];
|
|
123
|
+
t.has(l) || t.set(l, c);
|
|
124
|
+
const d = `${c}\0${l}`;
|
|
125
|
+
if (n.has(d)) continue;
|
|
126
|
+
n.add(d);
|
|
127
|
+
const a = e.get(c) ?? [];
|
|
128
|
+
a.push(l), e.set(c, a);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
return k(o, (r) => {
|
|
132
|
+
if (s(r.sdtPath), r.kind === "paragraph")
|
|
133
|
+
for (const i of r.runs) s(Q(r, i.style));
|
|
134
|
+
}), { parentOf: t, childrenOf: e };
|
|
135
|
+
}
|
|
136
|
+
function N(o) {
|
|
137
|
+
const t = o.sdts ?? {}, e = (c) => Object.prototype.hasOwnProperty.call(t, c), { parentOf: n, childrenOf: s } = gt(o), r = (c) => {
|
|
138
|
+
const l = [c], d = /* @__PURE__ */ new Set([c]);
|
|
139
|
+
for (let a = n.get(c); a !== void 0 && e(a) && !d.has(a); a = n.get(a))
|
|
140
|
+
l.unshift(a), d.add(a);
|
|
141
|
+
return l;
|
|
142
|
+
}, i = /* @__PURE__ */ new Map();
|
|
143
|
+
for (const [c, l] of Object.entries(t)) {
|
|
144
|
+
const d = n.get(c), a = d !== void 0 && e(d) ? d : void 0, f = (s.get(c) ?? []).filter(e), u = r(c);
|
|
145
|
+
i.set(c, {
|
|
146
|
+
id: c,
|
|
147
|
+
props: l,
|
|
148
|
+
...a !== void 0 ? { parentId: a } : {},
|
|
149
|
+
childIds: f,
|
|
150
|
+
path: u,
|
|
151
|
+
depth: u.length - 1
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return i;
|
|
155
|
+
}
|
|
156
|
+
function kt(o) {
|
|
157
|
+
return [...N(o).values()];
|
|
158
|
+
}
|
|
159
|
+
function Qt(o) {
|
|
160
|
+
return kt(o).filter((t) => t.parentId === void 0);
|
|
161
|
+
}
|
|
162
|
+
function Xt(o, t) {
|
|
163
|
+
const e = N(o), n = e.get(t);
|
|
164
|
+
return n ? n.childIds.map((s) => e.get(s)).filter((s) => s !== void 0) : [];
|
|
165
|
+
}
|
|
166
|
+
function Zt(o, t) {
|
|
167
|
+
const e = N(o), n = e.get(t);
|
|
168
|
+
return n ? n.path.slice(0, -1).map((s) => e.get(s)).filter((s) => s !== void 0) : [];
|
|
169
|
+
}
|
|
170
|
+
function te(o, t) {
|
|
171
|
+
const e = N(o), n = [], s = (r) => {
|
|
172
|
+
for (const i of e.get(r)?.childIds ?? []) {
|
|
173
|
+
const c = e.get(i);
|
|
174
|
+
c && (n.push(c), s(i));
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
return e.has(t) && s(t), n;
|
|
178
|
+
}
|
|
179
|
+
function bt(o, t, e) {
|
|
180
|
+
const n = [];
|
|
181
|
+
return k(o, (s) => {
|
|
182
|
+
s.sdtPath?.includes(t) && n.push(s);
|
|
183
|
+
}, e), n;
|
|
184
|
+
}
|
|
185
|
+
function wt(o, t, e) {
|
|
186
|
+
const n = [];
|
|
187
|
+
return k(o, (s) => {
|
|
188
|
+
if (s.sdtPath?.includes(t)) {
|
|
189
|
+
const r = V(s);
|
|
190
|
+
r.length > 0 && n.push(r);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (s.kind === "paragraph") {
|
|
194
|
+
const r = s.runs.filter((i) => i.style.sdtPath?.includes(t));
|
|
195
|
+
r.length > 0 && n.push(C(r));
|
|
196
|
+
}
|
|
197
|
+
}, e), n.join(`
|
|
198
|
+
`);
|
|
199
|
+
}
|
|
200
|
+
function ee(o, t) {
|
|
201
|
+
const e = o.sdts?.[t];
|
|
202
|
+
if (!e) return;
|
|
203
|
+
const n = { type: e.type, text: wt(o, t) };
|
|
204
|
+
if (e.type === "checkbox" && (n.checked = e.checked ?? !1), e.type === "dropDown" || e.type === "comboBox") {
|
|
205
|
+
const s = e.listItems?.find((r) => r.display === n.text);
|
|
206
|
+
s ? n.selected = s.value : e.type === "comboBox" && (n.selected = n.text);
|
|
207
|
+
}
|
|
208
|
+
return n;
|
|
209
|
+
}
|
|
210
|
+
function ne(o, t) {
|
|
211
|
+
return o.fields?.[t];
|
|
212
|
+
}
|
|
213
|
+
function St(o) {
|
|
214
|
+
return Object.values(o.fields ?? {});
|
|
215
|
+
}
|
|
216
|
+
function oe(o, t) {
|
|
217
|
+
const e = t.toUpperCase();
|
|
218
|
+
return St(o).filter((n) => n.name.toUpperCase() === e);
|
|
219
|
+
}
|
|
220
|
+
function se(o, t, e) {
|
|
221
|
+
const n = [];
|
|
222
|
+
return k(o, (s) => {
|
|
223
|
+
s.fieldId === t && n.push(s);
|
|
224
|
+
}, e), n;
|
|
225
|
+
}
|
|
226
|
+
function re(o, t) {
|
|
227
|
+
return o.bookmarks?.[t];
|
|
228
|
+
}
|
|
229
|
+
function ie(o) {
|
|
230
|
+
return Object.entries(o.bookmarks ?? {}).map(([t, e]) => ({ name: t, range: e }));
|
|
231
|
+
}
|
|
232
|
+
function ce(o) {
|
|
233
|
+
return Object.entries(o.footnotes ?? {}).map(([t, e]) => ({ id: t, paragraphs: e }));
|
|
234
|
+
}
|
|
235
|
+
function ae(o) {
|
|
236
|
+
return Object.entries(o.endnotes ?? {}).map(([t, e]) => ({ id: t, paragraphs: e }));
|
|
237
|
+
}
|
|
238
|
+
function le(o, t) {
|
|
239
|
+
const e = o.lists?.[t], n = [], s = [];
|
|
240
|
+
return k(o, (r, i) => {
|
|
241
|
+
if (r.kind !== "paragraph") return;
|
|
242
|
+
const c = r.style.list;
|
|
243
|
+
if (!c || c.listId !== t) return;
|
|
244
|
+
const l = e?.levels[Math.min(c.level, e.levels.length - 1)];
|
|
245
|
+
n[c.level] = (n[c.level] ?? (l?.start ?? 1) - 1) + 1, n.length = c.level + 1;
|
|
246
|
+
const d = e ? pt(e, c.level, n) : "";
|
|
247
|
+
s.push({ paragraph: r, level: c.level, marker: d, context: i });
|
|
248
|
+
}, { bands: !1, notes: !1 }), s;
|
|
249
|
+
}
|
|
250
|
+
function de(o) {
|
|
251
|
+
return o.stylesheet?.styles ?? [];
|
|
252
|
+
}
|
|
253
|
+
function fe(o, t) {
|
|
254
|
+
return o.stylesheet?.styles.find((e) => e.id === t);
|
|
255
|
+
}
|
|
256
|
+
function ue(o, t, e) {
|
|
257
|
+
let n;
|
|
258
|
+
return k(o, (s, r) => {
|
|
259
|
+
n === void 0 && s.id === t && (n = r);
|
|
260
|
+
}, e), n;
|
|
261
|
+
}
|
|
262
|
+
function J(o) {
|
|
263
|
+
return o.kind === "paragraph" ? C(o.runs) : V(o);
|
|
264
|
+
}
|
|
265
|
+
function he(o, t) {
|
|
266
|
+
const { anchor: e, focus: n } = t;
|
|
267
|
+
if (e.blockId === n.blockId) {
|
|
268
|
+
const u = R(o, e.blockId);
|
|
269
|
+
if (!u) return "";
|
|
270
|
+
const p = Math.min(e.offset, n.offset), P = Math.max(e.offset, n.offset);
|
|
271
|
+
return J(u).slice(p, P);
|
|
272
|
+
}
|
|
273
|
+
const s = new Map(o.blocks.map((u, p) => [u.id, p])), r = s.get(e.blockId), i = s.get(n.blockId);
|
|
274
|
+
if (r === void 0 || i === void 0) return "";
|
|
275
|
+
const [c, l, d, a] = r <= i ? [e, n, r, i] : [n, e, i, r], f = [];
|
|
276
|
+
for (let u = d; u <= a; u++) {
|
|
277
|
+
const p = J(o.blocks[u]);
|
|
278
|
+
u === d ? f.push(p.slice(c.offset)) : u === a ? f.push(p.slice(0, l.offset)) : f.push(p);
|
|
279
|
+
}
|
|
280
|
+
return f.join(`
|
|
281
|
+
`);
|
|
282
|
+
}
|
|
283
|
+
function pe(o, t, e) {
|
|
284
|
+
let n;
|
|
285
|
+
return k(o, (s) => {
|
|
286
|
+
if (n !== void 0 || s.kind !== "paragraph") return;
|
|
287
|
+
const r = C(s.runs).indexOf(t);
|
|
288
|
+
r >= 0 && (n = { blockId: s.id, offset: r });
|
|
289
|
+
}, e), n;
|
|
290
|
+
}
|
|
291
|
+
function K(o, t) {
|
|
292
|
+
if (!t.has(o)) return o;
|
|
293
|
+
let e = 2;
|
|
294
|
+
for (; t.has(`${o}__${e}`); ) e++;
|
|
295
|
+
return `${o}__${e}`;
|
|
296
|
+
}
|
|
297
|
+
const g = (o, t) => o.get(t) ?? t;
|
|
298
|
+
function E(o, t) {
|
|
299
|
+
for (const e of o)
|
|
300
|
+
if (t.set(e.id, O()), e.kind === "table")
|
|
301
|
+
for (const n of e.rows) for (const s of n.cells) E(s.blocks, t);
|
|
302
|
+
else if (e.kind === "paragraph" && e.style.sectionBreak)
|
|
303
|
+
for (const n of v) {
|
|
304
|
+
const s = e.style.sectionBreak.props[n];
|
|
305
|
+
s && E(s, t);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function Pt(o, t) {
|
|
309
|
+
const e = { ...o };
|
|
310
|
+
return e.sdtPath && (e.sdtPath = tt(e.sdtPath.map((n) => g(t.sdts, n)))), e.fieldId && (e.fieldId = g(t.fields, e.fieldId)), e.footnoteRef && (e.footnoteRef = g(t.footnotes, e.footnoteRef)), e.endnoteRef && (e.endnoteRef = g(t.endnotes, e.endnoteRef)), e.charStyleId && (e.charStyleId = g(t.styles, e.charStyleId)), e;
|
|
311
|
+
}
|
|
312
|
+
function U(o, t) {
|
|
313
|
+
return { text: o.text, style: Pt(o.style, t) };
|
|
314
|
+
}
|
|
315
|
+
function It(o, t) {
|
|
316
|
+
const e = { ...o };
|
|
317
|
+
return e.namedStyle && (e.namedStyle = g(t.styles, e.namedStyle)), e.list && (e.list = { ...e.list, listId: g(t.lists, e.list.listId) }), e.tocEntry && (e.tocEntry = { ...e.tocEntry, targetId: g(t.blocks, e.tocEntry.targetId) }), e.sectionBreak && (e.sectionBreak = { type: e.sectionBreak.type, props: Bt(e.sectionBreak.props, t) }), e;
|
|
318
|
+
}
|
|
319
|
+
function Bt(o, t) {
|
|
320
|
+
const e = { ...o };
|
|
321
|
+
for (const n of v) {
|
|
322
|
+
const s = e[n];
|
|
323
|
+
s && (e[n] = s.map((r) => $(r, t)));
|
|
324
|
+
}
|
|
325
|
+
return e;
|
|
326
|
+
}
|
|
327
|
+
function D(o, t) {
|
|
328
|
+
return o ? tt(o.map((e) => g(t, e))) : void 0;
|
|
329
|
+
}
|
|
330
|
+
function vt(o, t) {
|
|
331
|
+
return { ...o, id: O(), blocks: o.blocks.map((e) => $(e, t)) };
|
|
332
|
+
}
|
|
333
|
+
function xt(o, t) {
|
|
334
|
+
return { ...o, cells: o.cells.map((e) => vt(e, t)) };
|
|
335
|
+
}
|
|
336
|
+
function $(o, t) {
|
|
337
|
+
const e = g(t.blocks, o.id);
|
|
338
|
+
switch (o.kind) {
|
|
339
|
+
case "paragraph": {
|
|
340
|
+
const n = { ...o, id: e, runs: o.runs.map((s) => U(s, t)), style: It(o.style, t) };
|
|
341
|
+
return n.fieldId && (n.fieldId = g(t.fields, n.fieldId)), n.sdtPath = D(o.sdtPath, t.sdts), n;
|
|
342
|
+
}
|
|
343
|
+
case "image": {
|
|
344
|
+
const n = { ...o, id: e };
|
|
345
|
+
return n.fieldId && (n.fieldId = g(t.fields, n.fieldId)), n.sdtPath = D(o.sdtPath, t.sdts), n;
|
|
346
|
+
}
|
|
347
|
+
case "table": {
|
|
348
|
+
const n = { ...o, id: e, rows: o.rows.map((s) => xt(s, t)) };
|
|
349
|
+
return n.styleId && (n.styleId = g(t.tableStyles, n.styleId)), n.fieldId && (n.fieldId = g(t.fields, n.fieldId)), n.sdtPath = D(o.sdtPath, t.sdts), n;
|
|
350
|
+
}
|
|
351
|
+
case "equation": {
|
|
352
|
+
const n = { ...o, id: e };
|
|
353
|
+
return n.fieldId && (n.fieldId = g(t.fields, n.fieldId)), n.sdtPath = D(o.sdtPath, t.sdts), n;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function _t(o, t, e) {
|
|
358
|
+
const n = { ...o, id: t };
|
|
359
|
+
return n.spec?.type === "IF" && (n.spec = {
|
|
360
|
+
...n.spec,
|
|
361
|
+
trueRuns: n.spec.trueRuns.map((s) => U(s, e)),
|
|
362
|
+
falseRuns: n.spec.falseRuns.map((s) => U(s, e))
|
|
363
|
+
}), n;
|
|
364
|
+
}
|
|
365
|
+
function Et(o, t) {
|
|
366
|
+
const e = { ...o };
|
|
367
|
+
for (const n of v) {
|
|
368
|
+
const s = e[n];
|
|
369
|
+
s && (e[n] = s.map((r) => $(r, t)));
|
|
370
|
+
}
|
|
371
|
+
return e;
|
|
372
|
+
}
|
|
373
|
+
function Ot(o) {
|
|
374
|
+
const t = {
|
|
375
|
+
pageWidthPx: o.pageWidthPx,
|
|
376
|
+
pageHeightPx: o.pageHeightPx,
|
|
377
|
+
marginPx: o.marginPx,
|
|
378
|
+
columns: o.columns ?? null
|
|
379
|
+
};
|
|
380
|
+
o.pageNumberStart !== void 0 && (t.pageNumberStart = o.pageNumberStart), o.pageColorHex !== void 0 && (t.pageColorHex = o.pageColorHex), o.pageBorders !== void 0 && (t.pageBorders = o.pageBorders), o.headerDistancePx !== void 0 && (t.headerDistancePx = o.headerDistancePx), o.footerDistancePx !== void 0 && (t.footerDistancePx = o.footerDistancePx), o.lineNumbering !== void 0 && (t.lineNumbering = o.lineNumbering);
|
|
381
|
+
for (const e of v) t[e] = o[e] ?? [];
|
|
382
|
+
return t;
|
|
383
|
+
}
|
|
384
|
+
function $t(o, t) {
|
|
385
|
+
return {
|
|
386
|
+
kind: "paragraph",
|
|
387
|
+
id: O(),
|
|
388
|
+
revision: 0,
|
|
389
|
+
runs: [{ text: "", style: { ...Z } }],
|
|
390
|
+
style: { ...X, sectionBreak: { type: t, props: Ot(o) } }
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function rt(o, t, e, n, s, r) {
|
|
394
|
+
const i = o.map((a) => ({ ...a })), c = new Set(i.map((a) => a.id)), l = new Map(i.map((a) => [a.name, a.id])), d = [];
|
|
395
|
+
for (const a of t) {
|
|
396
|
+
if (e === "useDestination") {
|
|
397
|
+
const u = l.get(a.name);
|
|
398
|
+
if (u !== void 0) {
|
|
399
|
+
n.set(a.id, u);
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
let f = a.id;
|
|
404
|
+
c.has(f) && (f = K(a.id, c), s.push({ code: r, detail: `${a.id} → ${f}` })), c.add(f), n.set(a.id, f), d.push({ ...a, id: f });
|
|
405
|
+
}
|
|
406
|
+
for (const a of d) a.basedOn !== void 0 && (a.basedOn = g(n, a.basedOn));
|
|
407
|
+
return i.push(...d), i;
|
|
408
|
+
}
|
|
409
|
+
function Mt(o, t, e, n, s) {
|
|
410
|
+
return t ? { styles: rt(o?.styles ?? [], t.styles, e, n, s, "style-id-renamed"), defaultStyleId: o?.defaultStyleId ?? t.defaultStyleId } : o;
|
|
411
|
+
}
|
|
412
|
+
function Tt(o, t, e, n, s) {
|
|
413
|
+
const r = rt(Object.values(o ?? {}), Object.values(t ?? {}), e, n, s, "table-style-id-renamed"), i = {};
|
|
414
|
+
for (const c of r) i[c.id] = c;
|
|
415
|
+
return i;
|
|
416
|
+
}
|
|
417
|
+
function T(o, t, e) {
|
|
418
|
+
const n = { ...o ?? {} }, s = new Set(Object.keys(n));
|
|
419
|
+
for (const r of Object.keys(t ?? {})) {
|
|
420
|
+
let i = r;
|
|
421
|
+
s.has(i) && (i = K(r, s)), s.add(i), e.set(r, i);
|
|
422
|
+
}
|
|
423
|
+
return n;
|
|
424
|
+
}
|
|
425
|
+
function it() {
|
|
426
|
+
return { blocks: {}, styles: {}, lists: {}, tableStyles: {}, sdts: {}, fields: {}, footnotes: {}, endnotes: {}, bookmarks: {} };
|
|
427
|
+
}
|
|
428
|
+
function ct(o, t, e = {}) {
|
|
429
|
+
const n = e.styles ?? "useDestination", s = e.renameBookmarksOnCollision ?? !0, r = [], i = /* @__PURE__ */ new Map();
|
|
430
|
+
E(t.blocks, i);
|
|
431
|
+
for (const h of v) {
|
|
432
|
+
const y = t.section[h];
|
|
433
|
+
y && E(y, i);
|
|
434
|
+
}
|
|
435
|
+
for (const h of Object.values(t.footnotes ?? {})) E(h, i);
|
|
436
|
+
for (const h of Object.values(t.endnotes ?? {})) E(h, i);
|
|
437
|
+
const c = /* @__PURE__ */ new Map(), l = Mt(o.stylesheet, t.stylesheet, n, c, r), d = /* @__PURE__ */ new Map(), a = T(o.lists, t.lists, d);
|
|
438
|
+
for (const [h, y] of d) a[y] = { ...t.lists[h], id: y };
|
|
439
|
+
const f = /* @__PURE__ */ new Map(), u = Tt(o.tableStyles, t.tableStyles, n, f, r), p = /* @__PURE__ */ new Map(), P = T(o.sdts, t.sdts, p);
|
|
440
|
+
for (const [h, y] of p) P[y] = { ...t.sdts[h] };
|
|
441
|
+
const I = /* @__PURE__ */ new Map();
|
|
442
|
+
T(o.fields, t.fields, I);
|
|
443
|
+
const B = /* @__PURE__ */ new Map(), m = { ...o.footnotes ?? {} };
|
|
444
|
+
T(o.footnotes, t.footnotes, B);
|
|
445
|
+
const b = /* @__PURE__ */ new Map(), j = { ...o.endnotes ?? {} };
|
|
446
|
+
T(o.endnotes, t.endnotes, b);
|
|
447
|
+
const M = {
|
|
448
|
+
blocks: i,
|
|
449
|
+
styles: c,
|
|
450
|
+
lists: d,
|
|
451
|
+
tableStyles: f,
|
|
452
|
+
sdts: p,
|
|
453
|
+
fields: I,
|
|
454
|
+
footnotes: B,
|
|
455
|
+
endnotes: b
|
|
456
|
+
}, Y = { ...o.fields ?? {} };
|
|
457
|
+
for (const [h, y] of I) Y[y] = _t(t.fields[h], y, M);
|
|
458
|
+
for (const [h, y] of B) m[y] = t.footnotes[h].map((w) => $(w, M));
|
|
459
|
+
for (const [h, y] of b) j[y] = t.endnotes[h].map((w) => $(w, M));
|
|
460
|
+
const q = (h) => ({ blockId: g(i, h.blockId), offset: h.offset }), W = /* @__PURE__ */ new Map(), A = { ...o.bookmarks ?? {} }, H = new Set(Object.keys(A));
|
|
461
|
+
for (const [h, y] of Object.entries(t.bookmarks ?? {})) {
|
|
462
|
+
let w = h;
|
|
463
|
+
if (H.has(w)) {
|
|
464
|
+
if (!s) {
|
|
465
|
+
r.push({ code: "bookmark-dropped", detail: h });
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
w = K(h, H), r.push({ code: "bookmark-renamed", detail: `${h} → ${w}` });
|
|
469
|
+
}
|
|
470
|
+
H.add(w), W.set(h, w), A[w] = { start: q(y.start), end: q(y.end) };
|
|
471
|
+
}
|
|
472
|
+
const S = (h) => Object.fromEntries(h);
|
|
473
|
+
return {
|
|
474
|
+
stylesheet: l,
|
|
475
|
+
lists: a,
|
|
476
|
+
tableStyles: u,
|
|
477
|
+
sdts: P,
|
|
478
|
+
fields: Y,
|
|
479
|
+
footnotes: m,
|
|
480
|
+
endnotes: j,
|
|
481
|
+
bookmarks: A,
|
|
482
|
+
sourceBlocks: t.blocks.map((h) => $(h, M)),
|
|
483
|
+
sourceSection: Et(t.section, M),
|
|
484
|
+
idMap: {
|
|
485
|
+
blocks: S(i),
|
|
486
|
+
styles: S(c),
|
|
487
|
+
lists: S(d),
|
|
488
|
+
tableStyles: S(f),
|
|
489
|
+
sdts: S(p),
|
|
490
|
+
fields: S(I),
|
|
491
|
+
footnotes: S(B),
|
|
492
|
+
endnotes: S(b),
|
|
493
|
+
bookmarks: S(W)
|
|
494
|
+
},
|
|
495
|
+
warnings: r
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function at(o, t, e, n) {
|
|
499
|
+
const s = { section: e, blocks: n };
|
|
500
|
+
return t.stylesheet && (s.stylesheet = t.stylesheet), Object.keys(t.lists).length && (s.lists = t.lists), Object.keys(t.tableStyles).length && (s.tableStyles = t.tableStyles), Object.keys(t.footnotes).length && (s.footnotes = t.footnotes), Object.keys(t.endnotes).length && (s.endnotes = t.endnotes), Object.keys(t.sdts).length && (s.sdts = t.sdts), Object.keys(t.bookmarks).length && (s.bookmarks = t.bookmarks), Object.keys(t.fields).length && (s.fields = t.fields), o.tocInstruction !== void 0 && (s.tocInstruction = o.tocInstruction), o.tocAnchorBlockId !== void 0 && (s.tocAnchorBlockId = o.tocAnchorBlockId), o.defaultTabStopPx !== void 0 && (s.defaultTabStopPx = o.defaultTabStopPx), o.compatSettings && (s.compatSettings = o.compatSettings), s;
|
|
501
|
+
}
|
|
502
|
+
function lt(o, t, e = {}) {
|
|
503
|
+
const n = e.sectionBreak ?? "nextPage";
|
|
504
|
+
if (t.blocks.length === 0)
|
|
505
|
+
return { doc: { ...o }, idMap: it(), warnings: [{ code: "empty-source" }] };
|
|
506
|
+
const s = ct(o, t, e);
|
|
507
|
+
let r, i;
|
|
508
|
+
return o.blocks.length === 0 ? (r = s.sourceBlocks, i = s.sourceSection) : n === "continuous" || n === "none" ? (r = [...o.blocks, ...s.sourceBlocks], i = o.section, s.warnings.push({ code: "source-section-dropped", detail: n })) : (r = [...o.blocks, $t(o.section, n), ...s.sourceBlocks], i = s.sourceSection), { doc: at(o, s, i, r), idMap: s.idMap, warnings: s.warnings };
|
|
509
|
+
}
|
|
510
|
+
function me(o, t = {}) {
|
|
511
|
+
if (o.length === 0) throw new Error("mergeAll requires at least one document");
|
|
512
|
+
let e = o[0], n = it();
|
|
513
|
+
const s = [];
|
|
514
|
+
for (let r = 1; r < o.length; r++) {
|
|
515
|
+
const i = lt(e, o[r], t);
|
|
516
|
+
e = i.doc, n = i.idMap, s.push(...i.warnings);
|
|
517
|
+
}
|
|
518
|
+
return { doc: e, idMap: n, warnings: s };
|
|
519
|
+
}
|
|
520
|
+
const Ct = ["sectionBreak", "pageBreakBefore", "columnBreakBefore", "tocEntry"];
|
|
521
|
+
class ye {
|
|
522
|
+
_doc;
|
|
523
|
+
undoStack = [];
|
|
524
|
+
redoStack = [];
|
|
525
|
+
constructor(t) {
|
|
526
|
+
this._doc = t;
|
|
527
|
+
}
|
|
528
|
+
/** The current document. Every edit swaps this for a new immutable value
|
|
529
|
+
* (structural sharing), so a captured reference is a stable snapshot. */
|
|
530
|
+
get doc() {
|
|
531
|
+
return this._doc;
|
|
532
|
+
}
|
|
533
|
+
get canUndo() {
|
|
534
|
+
return this.undoStack.length > 0;
|
|
535
|
+
}
|
|
536
|
+
get canRedo() {
|
|
537
|
+
return this.redoStack.length > 0;
|
|
538
|
+
}
|
|
539
|
+
// --- editing ----------------------------------------------------------------
|
|
540
|
+
/** Replace all runs of a paragraph with a single run of `text`. `style`
|
|
541
|
+
* defaults to the paragraph's current first-run style. */
|
|
542
|
+
setParagraphText(t, e, n) {
|
|
543
|
+
const s = this.mustParagraph(t), r = [];
|
|
544
|
+
if (e.length > 0) {
|
|
545
|
+
const i = n ?? s.runs[0]?.style;
|
|
546
|
+
if (!i) throw new Error(`setParagraphText: paragraph ${t} is empty; pass a style`);
|
|
547
|
+
r.push({ text: e, style: i });
|
|
548
|
+
}
|
|
549
|
+
return this.commit([{ type: "setRuns", blockId: t, runs: r }]);
|
|
550
|
+
}
|
|
551
|
+
/** Insert `text` at a UTF-16 offset within a paragraph. */
|
|
552
|
+
insertText(t, e, n, s) {
|
|
553
|
+
return this.commit([{ type: "insertText", at: { blockId: t, offset: e }, text: n, ...s ? { style: s } : {} }]);
|
|
554
|
+
}
|
|
555
|
+
/** Delete the UTF-16 range [start, end) within a paragraph. */
|
|
556
|
+
deleteText(t, e, n) {
|
|
557
|
+
return this.commit([{ type: "deleteRange", blockId: t, start: e, end: n }]);
|
|
558
|
+
}
|
|
559
|
+
/** Replace the UTF-16 range [start, end) within a paragraph with `text`
|
|
560
|
+
* (delete + insert as one undoable step). */
|
|
561
|
+
replaceText(t, e, n, s, r) {
|
|
562
|
+
const i = [{ type: "deleteRange", blockId: t, start: e, end: n }];
|
|
563
|
+
return s.length > 0 && i.push({ type: "insertText", at: { blockId: t, offset: e }, text: s, ...r ? { style: r } : {} }), this.commit(i);
|
|
564
|
+
}
|
|
565
|
+
/** Patch a paragraph's style (alignment, indents, spacing, list, borders…). */
|
|
566
|
+
setParagraphStyle(t, e) {
|
|
567
|
+
return this.commit([{ type: "setParaStyle", blockId: t, patch: e }]);
|
|
568
|
+
}
|
|
569
|
+
/** Remove a top-level block (paragraph, table, image…) by id. */
|
|
570
|
+
removeBlock(t) {
|
|
571
|
+
return this.commit([{ type: "removeBlock", blockId: t }]);
|
|
572
|
+
}
|
|
573
|
+
/** Insert a new paragraph before/after a top-level reference block. Returns the
|
|
574
|
+
* new paragraph's id via `lastInsertedId`. */
|
|
575
|
+
insertParagraph(t, e, n = {}) {
|
|
576
|
+
const s = dt(this._doc, t);
|
|
577
|
+
if (!s) throw new Error(`insertParagraph: ${t} is not a top-level block`);
|
|
578
|
+
const r = R(this._doc, t), i = r?.kind === "paragraph" ? r : void 0, c = n.style ?? (i ? Rt(i.style) : void 0);
|
|
579
|
+
if (!c) throw new Error(`insertParagraph: reference ${t} is not a paragraph; pass options.style`);
|
|
580
|
+
const l = n.runStyle ?? i?.runs[0]?.style;
|
|
581
|
+
if (e.length > 0 && !l) throw new Error("insertParagraph: no run style available; pass options.runStyle");
|
|
582
|
+
const d = O(), a = {
|
|
583
|
+
kind: "paragraph",
|
|
584
|
+
id: d,
|
|
585
|
+
revision: 0,
|
|
586
|
+
runs: e.length > 0 ? [{ text: e, style: l }] : [],
|
|
587
|
+
style: c
|
|
588
|
+
}, f = n.position === "before" ? s.index : s.index + 1;
|
|
589
|
+
return this._lastInsertedId = d, this.commit([{ type: "insertBlock", index: f, block: a, where: s.where }]);
|
|
590
|
+
}
|
|
591
|
+
_lastInsertedId = null;
|
|
592
|
+
/** The id minted by the most recent `insertParagraph`, or null. */
|
|
593
|
+
get lastInsertedId() {
|
|
594
|
+
return this._lastInsertedId;
|
|
595
|
+
}
|
|
596
|
+
// --- content controls (SDTs) — the primary templating surface ---------------
|
|
597
|
+
/** Merge a patch onto a content control's properties (alias, tag, checked,
|
|
598
|
+
* listItems, date format, locks…). The control must already exist. The control
|
|
599
|
+
* `type` is the discriminant for how it round-trips and paints, so it is NOT
|
|
600
|
+
* patchable here — it is always preserved (excluded from the patch shape and
|
|
601
|
+
* re-forced on the merge, even against an untyped runtime caller). */
|
|
602
|
+
setSdtProps(t, e) {
|
|
603
|
+
const n = x(this._doc, t);
|
|
604
|
+
if (!n) throw new Error(`setSdtProps: content control ${t} not found`);
|
|
605
|
+
const s = { ...n, ...e, type: n.type };
|
|
606
|
+
return this.commit([{ type: "setSdtProps", id: t, props: s }]);
|
|
607
|
+
}
|
|
608
|
+
/** Set a checkbox content control's state (☒/☐). Throws if `id` is not a
|
|
609
|
+
* checkbox control. */
|
|
610
|
+
setCheckbox(t, e) {
|
|
611
|
+
const n = x(this._doc, t);
|
|
612
|
+
if (!n) throw new Error(`setCheckbox: content control ${t} not found`);
|
|
613
|
+
if (n.type !== "checkbox")
|
|
614
|
+
throw new Error(`setCheckbox: ${t} is a "${n.type}" control, not a checkbox`);
|
|
615
|
+
return this.setSdtProps(t, { checked: e });
|
|
616
|
+
}
|
|
617
|
+
/** Replace the text of a content control that occupies a SINGLE paragraph —
|
|
618
|
+
* either an inline control (runs tagged with `id`) or a block-level control
|
|
619
|
+
* wrapping one paragraph. The killer templating primitive: "fill this field".
|
|
620
|
+
* Preserves the control's ancestry (so nesting survives) and clears any
|
|
621
|
+
* placeholder flag. Throws for controls spanning multiple blocks (edit those by
|
|
622
|
+
* block id) or not found. */
|
|
623
|
+
setSdtText(t, e) {
|
|
624
|
+
const n = x(this._doc, t);
|
|
625
|
+
if (!n) throw new Error(`setSdtText: content control ${t} not found`);
|
|
626
|
+
const s = bt(this._doc, t);
|
|
627
|
+
if (s.length > 0) {
|
|
628
|
+
if (s.length > 1 || s[0].kind !== "paragraph")
|
|
629
|
+
throw new Error(`setSdtText: ${t} spans ${s.length} block(s); edit multi-block controls by block id`);
|
|
630
|
+
const u = s[0], p = u.runs[0]?.style;
|
|
631
|
+
if (e.length > 0 && !p)
|
|
632
|
+
throw new Error(`setSdtText: block control ${t} is empty; cannot infer a run style`);
|
|
633
|
+
const P = e.length > 0 ? [{ text: e, style: p }] : [];
|
|
634
|
+
return this.commit(this.withPlaceholderCleared(t, n, [{ type: "setRuns", blockId: u.id, runs: P }]));
|
|
635
|
+
}
|
|
636
|
+
const r = this.locateInlineSdt(t);
|
|
637
|
+
if (!r) throw new Error(`setSdtText: content control ${t} has no editable text region`);
|
|
638
|
+
const { para: i, from: c, to: l, baseStyle: d } = r, a = { ...d, sdtPath: z(d.sdtPath, t) ?? [t] }, f = [
|
|
639
|
+
...i.runs.slice(0, c),
|
|
640
|
+
...e.length > 0 ? [{ text: e, style: a }] : [],
|
|
641
|
+
...i.runs.slice(l)
|
|
642
|
+
];
|
|
643
|
+
return this.commit(this.withPlaceholderCleared(t, n, [{ type: "setRuns", blockId: i.id, runs: f }]));
|
|
644
|
+
}
|
|
645
|
+
/** Select a value on a dropDown/comboBox content control — the "choose an
|
|
646
|
+
* option" primitive. `value` matches a listItem by its VALUE first, then by its
|
|
647
|
+
* display; the control's text becomes that item's display. A comboBox accepts
|
|
648
|
+
* free text (no match ⇒ `value` is used verbatim); a dropDown requires a listed
|
|
649
|
+
* option (throws otherwise). For other control kinds use `setSdtText`/`setCheckbox`. */
|
|
650
|
+
setSdtValue(t, e) {
|
|
651
|
+
const n = x(this._doc, t);
|
|
652
|
+
if (!n) throw new Error(`setSdtValue: content control ${t} not found`);
|
|
653
|
+
if (n.type !== "dropDown" && n.type !== "comboBox")
|
|
654
|
+
throw new Error(`setSdtValue: ${t} is a "${n.type}" control; use setSdtText or setCheckbox`);
|
|
655
|
+
const s = n.listItems ?? [], r = s.find((i) => i.value === e) ?? s.find((i) => i.display === e);
|
|
656
|
+
if (!r && n.type === "dropDown")
|
|
657
|
+
throw new Error(`setSdtValue: "${e}" is not an option of dropdown ${t}`);
|
|
658
|
+
return this.setSdtText(t, r ? r.display : e);
|
|
659
|
+
}
|
|
660
|
+
/** Remove a content control, UNWRAPPING it: strip its id from every member run
|
|
661
|
+
* (inline) and body block (block-level) path — so NESTED controls survive — and
|
|
662
|
+
* delete its properties, keeping the "every path id has a props entry" invariant.
|
|
663
|
+
* With `deleteContents: true` the wrapped content is deleted too. Inline controls
|
|
664
|
+
* are handled in any story (body, cells, bands, notes); block-level controls are
|
|
665
|
+
* handled at the TOP LEVEL of the body — a block-level control nested in a table
|
|
666
|
+
* cell, band, or note throws (remove it by block id). */
|
|
667
|
+
removeSdt(t, e = {}) {
|
|
668
|
+
if (!x(this._doc, t)) throw new Error(`removeSdt: content control ${t} not found`);
|
|
669
|
+
const s = e.deleteContents ?? !1, r = new Map(this._doc.blocks.map((a, f) => [a.id, f])), i = [], c = [];
|
|
670
|
+
let l;
|
|
671
|
+
if (k(this._doc, (a, f) => {
|
|
672
|
+
a.sdtPath?.includes(t) ? f.container === "body" && !f.cell && !f.note && r.has(a.id) ? c.push(a) : l ??= f.note ? "a note body" : f.cell ? "a table cell" : `the ${f.container} band` : a.kind === "paragraph" && a.runs.some((u) => u.style.sdtPath?.includes(t)) && i.push(a.id);
|
|
673
|
+
}), l)
|
|
674
|
+
throw new Error(`removeSdt: ${t} has a block-level member in ${l}; not supported — remove it by block id`);
|
|
675
|
+
const d = [];
|
|
676
|
+
for (const a of i) {
|
|
677
|
+
const f = L(this._doc, a), u = s ? f.runs.filter((p) => !p.style.sdtPath?.includes(t)) : f.runs.map((p) => p.style.sdtPath?.includes(t) ? jt(p, t) : p);
|
|
678
|
+
d.push({ type: "setRuns", blockId: a, runs: u });
|
|
679
|
+
}
|
|
680
|
+
for (const a of c.slice().sort((f, u) => r.get(u.id) - r.get(f.id))) {
|
|
681
|
+
const f = r.get(a.id);
|
|
682
|
+
d.push({ type: "removeBlock", blockId: a.id }), s || d.push({ type: "insertBlock", index: f, block: Dt(a, t), where: "body" });
|
|
683
|
+
}
|
|
684
|
+
return d.push({ type: "setSdtProps", id: t, props: null }), this.commit(d);
|
|
685
|
+
}
|
|
686
|
+
// --- ergonomic bulk / structural edits --------------------------------------
|
|
687
|
+
/** Find/replace across every paragraph in the document as ONE undoable step.
|
|
688
|
+
* A string replaces ALL occurrences; a RegExp is applied per run (pass the `g`
|
|
689
|
+
* flag to replace all). Replacement happens WITHIN each run — matches that span
|
|
690
|
+
* a style boundary are not replaced (a deliberate limit so run styling is always
|
|
691
|
+
* preserved). Returns `this`. */
|
|
692
|
+
replaceAllText(t, e) {
|
|
693
|
+
const n = [];
|
|
694
|
+
return k(this._doc, (s) => {
|
|
695
|
+
if (s.kind !== "paragraph") return;
|
|
696
|
+
let r = !1;
|
|
697
|
+
const i = s.runs.map((c) => {
|
|
698
|
+
const l = typeof t == "string" ? c.text.split(t).join(e) : c.text.replace(t, e);
|
|
699
|
+
return l !== c.text && (r = !0), l === c.text ? c : { ...c, text: l };
|
|
700
|
+
});
|
|
701
|
+
r && n.push({ type: "setRuns", blockId: s.id, runs: i });
|
|
702
|
+
}), this.commit(n);
|
|
703
|
+
}
|
|
704
|
+
/** Apply a named paragraph style by its human NAME (e.g. "Heading 1"), resolving
|
|
705
|
+
* it to a styleId via the stylesheet and BAKING the resolved paragraph + run
|
|
706
|
+
* formatting onto the block (the model is concrete), plus setting the `namedStyle`
|
|
707
|
+
* reference. Throws if the document has no stylesheet or no style with that name. */
|
|
708
|
+
setStyleByName(t, e) {
|
|
709
|
+
const n = this._doc.stylesheet, s = n?.styles.find((l) => l.name === e);
|
|
710
|
+
if (!n || !s) throw new Error(`setStyleByName: no style named "${e}"`);
|
|
711
|
+
const r = this.mustParagraph(t), i = mt(n, s.id), c = [{ type: "setParaStyle", blockId: t, patch: { ...i.para, namedStyle: s.id } }];
|
|
712
|
+
if (Object.keys(i.char).length > 0 && r.runs.length > 0) {
|
|
713
|
+
const l = r.runs.reduce((d, a) => d + a.text.length, 0);
|
|
714
|
+
c.push({ type: "setRuns", blockId: t, runs: ft(r.runs, 0, l, i.char) });
|
|
715
|
+
}
|
|
716
|
+
return this.commit(c);
|
|
717
|
+
}
|
|
718
|
+
/** Move a top-level BODY block to a new index among the body blocks (remove +
|
|
719
|
+
* insert as one undoable step). `toIndex` is the destination among the OTHER
|
|
720
|
+
* blocks (after removal), clamped to range. Throws if the block is not a
|
|
721
|
+
* top-level body block. */
|
|
722
|
+
moveBlock(t, e) {
|
|
723
|
+
const n = this._doc.blocks.findIndex((i) => i.id === t);
|
|
724
|
+
if (n === -1) throw new Error(`moveBlock: ${t} is not a top-level body block`);
|
|
725
|
+
const s = this._doc.blocks[n], r = Math.max(0, Math.min(e, this._doc.blocks.length - 1));
|
|
726
|
+
return r === n ? this : this.commit([
|
|
727
|
+
{ type: "removeBlock", blockId: t },
|
|
728
|
+
{ type: "insertBlock", index: r, block: s, where: "body" }
|
|
729
|
+
]);
|
|
730
|
+
}
|
|
731
|
+
/** Insert a row into a table at `rowIndex` (clamped). `cellTexts` fills the new
|
|
732
|
+
* cells left-to-right (missing/extra entries pad/trim to the table's column
|
|
733
|
+
* count); omit for an empty row. New cells inherit a run style from an existing
|
|
734
|
+
* table paragraph (or the document default). */
|
|
735
|
+
insertTableRowAt(t, e, n = []) {
|
|
736
|
+
const s = G(this._doc, t);
|
|
737
|
+
if (!s) throw new Error(`insertTableRowAt: table ${t} not found`);
|
|
738
|
+
const r = s.rows.length > 0 ? ut(s) : Math.max(1, n.length), i = Nt(s.rows) ?? Z, c = Array.from({ length: r }, (d, a) => {
|
|
739
|
+
const f = n[a] ?? "", u = {
|
|
740
|
+
kind: "paragraph",
|
|
741
|
+
id: O(),
|
|
742
|
+
revision: 0,
|
|
743
|
+
runs: f.length > 0 ? [{ text: f, style: i }] : [],
|
|
744
|
+
style: { ...X }
|
|
745
|
+
};
|
|
746
|
+
return { id: O(), blocks: [u] };
|
|
747
|
+
}), l = Math.max(0, Math.min(e, s.rows.length));
|
|
748
|
+
return this.commit([{ type: "insertTableRow", tableId: t, rowIndex: l, row: { cells: c } }]);
|
|
749
|
+
}
|
|
750
|
+
/** Delete the column whose header (first-row cell text) equals `headerText`.
|
|
751
|
+
* Throws if the table or a matching header is not found. */
|
|
752
|
+
deleteColumnByHeader(t, e) {
|
|
753
|
+
const n = G(this._doc, t);
|
|
754
|
+
if (!n) throw new Error(`deleteColumnByHeader: table ${t} not found`);
|
|
755
|
+
const s = n.rows[0], r = s ? s.cells.findIndex((i) => ot(i) === e) : -1;
|
|
756
|
+
if (r === -1) throw new Error(`deleteColumnByHeader: no column headed "${e}" in table ${t}`);
|
|
757
|
+
return this.commit([{ type: "removeTableColumn", tableId: t, colIndex: r }]);
|
|
758
|
+
}
|
|
759
|
+
/** Find the single paragraph holding the contiguous run span tagged with the
|
|
760
|
+
* inline control `id`, plus that span `[from, to)` and its base run style. */
|
|
761
|
+
locateInlineSdt(t) {
|
|
762
|
+
let e;
|
|
763
|
+
return k(this._doc, (n) => {
|
|
764
|
+
if (e || n.kind !== "paragraph") return;
|
|
765
|
+
let s = -1, r = -1;
|
|
766
|
+
n.runs.forEach((i, c) => {
|
|
767
|
+
i.style.sdtPath?.includes(t) && (s === -1 && (s = c), r = c + 1);
|
|
768
|
+
}), s !== -1 && (e = { para: n, from: s, to: r, baseStyle: n.runs[s].style });
|
|
769
|
+
}), e;
|
|
770
|
+
}
|
|
771
|
+
/** Append a `setSdtProps` op clearing a placeholder flag, when set — so filling
|
|
772
|
+
* a control drops its gray placeholder styling, like the interactive editor. */
|
|
773
|
+
withPlaceholderCleared(t, e, n) {
|
|
774
|
+
return e.placeholder ? [...n, { type: "setSdtProps", id: t, props: { ...e, placeholder: !1 } }] : n;
|
|
775
|
+
}
|
|
776
|
+
// --- undo / redo ------------------------------------------------------------
|
|
777
|
+
/** Undo the most recent edit. Returns false when there's nothing to undo. */
|
|
778
|
+
undo() {
|
|
779
|
+
const t = this.undoStack.pop();
|
|
780
|
+
if (!t) return !1;
|
|
781
|
+
let e = this._doc;
|
|
782
|
+
for (const n of t.inverse) e = F(e, n).doc;
|
|
783
|
+
return this._doc = e, this.redoStack.push(t), !0;
|
|
784
|
+
}
|
|
785
|
+
/** Redo the most recently undone edit. Returns false when there's nothing to redo. */
|
|
786
|
+
redo() {
|
|
787
|
+
const t = this.redoStack.pop();
|
|
788
|
+
if (!t) return !1;
|
|
789
|
+
let e = this._doc;
|
|
790
|
+
for (const n of t.forward) e = F(e, n).doc;
|
|
791
|
+
return this._doc = e, this.undoStack.push(t), !0;
|
|
792
|
+
}
|
|
793
|
+
/** Append another document's content after this one — the headless equivalent of
|
|
794
|
+
* Word's "insert file at end". Reconciles every id space (see mergeDocuments) and
|
|
795
|
+
* lands as ONE undoable step. Returns the merge's id map + warnings; the merged
|
|
796
|
+
* document becomes `this.doc`. */
|
|
797
|
+
append(t, e = {}) {
|
|
798
|
+
const n = lt(this._doc, t, e);
|
|
799
|
+
return this.commit([{ type: "setDocument", doc: n.doc }]), n;
|
|
800
|
+
}
|
|
801
|
+
/** Replace a block-level content control's entire content with another document —
|
|
802
|
+
* the templating primitive: find control `sdtId`, drop what's inside it, and splice
|
|
803
|
+
* in `sourceDoc`'s blocks, reconciling every id space (styles, lists, table styles,
|
|
804
|
+
* content controls, fields, notes, bookmarks — see mergeDocuments). The control's
|
|
805
|
+
* ancestry is preserved and PREPENDED onto the inserted blocks, so the source's own
|
|
806
|
+
* nested controls survive nested inside this one. One undoable step; returns the
|
|
807
|
+
* merge's id map + warnings.
|
|
808
|
+
*
|
|
809
|
+
* The control must be a BLOCK-LEVEL control at the TOP LEVEL of the body. A control
|
|
810
|
+
* inside a table cell / header-footer band / note body, or an inline (single-run)
|
|
811
|
+
* control, throws — use `setSdtText` to fill an inline control. */
|
|
812
|
+
replaceSdtContent(t, e, n = {}) {
|
|
813
|
+
if (!x(this._doc, t)) throw new Error(`replaceSdtContent: content control ${t} not found`);
|
|
814
|
+
const s = new Map(this._doc.blocks.map((m, b) => [m.id, b])), r = [];
|
|
815
|
+
let i, c, l = !1;
|
|
816
|
+
if (k(this._doc, (m, b) => {
|
|
817
|
+
m.sdtPath?.includes(t) ? b.container === "body" && !b.cell && !b.note && s.has(m.id) ? (r.push(m.id), i ??= z(m.sdtPath, t)) : c ??= b.note ? "a note body" : b.cell ? "a table cell" : `the ${b.container} band` : m.kind === "paragraph" && m.runs.some((j) => j.style.sdtPath?.includes(t)) && (l = !0);
|
|
818
|
+
}), l) throw new Error(`replaceSdtContent: ${t} is an inline control; use setSdtText`);
|
|
819
|
+
if (c) throw new Error(`replaceSdtContent: ${t} has a block-level member in ${c}; not supported`);
|
|
820
|
+
if (r.length === 0) throw new Error(`replaceSdtContent: ${t} has no block-level content in the body`);
|
|
821
|
+
const d = ct(this._doc, e, n), a = d.sdts[t];
|
|
822
|
+
a?.placeholder && (d.sdts[t] = { ...a, placeholder: !1 });
|
|
823
|
+
const f = i ?? [t], u = d.sourceBlocks.map((m) => ({ ...m, sdtPath: [...f, ...m.sdtPath ?? []] })), p = new Set(r), P = s.get(r[0]), I = [];
|
|
824
|
+
this._doc.blocks.forEach((m, b) => {
|
|
825
|
+
b === P && I.push(...u), p.has(m.id) || I.push(m);
|
|
826
|
+
});
|
|
827
|
+
const B = at(this._doc, d, this._doc.section, I);
|
|
828
|
+
return this.commit([{ type: "setDocument", doc: B }]), { doc: B, idMap: d.idMap, warnings: d.warnings };
|
|
829
|
+
}
|
|
830
|
+
/** Set (or clear, with `null`) a header/footer band on a specific section by its
|
|
831
|
+
* index (see resolveSections / getSections). The final/body section stores its
|
|
832
|
+
* bands on the document; a mid-document section stores them on its break
|
|
833
|
+
* paragraph. Pairs with `append` for a post-merge per-section footer pass. One
|
|
834
|
+
* undoable step. Throws if `sectionIndex` is out of range. */
|
|
835
|
+
setSectionBand(t, e, n) {
|
|
836
|
+
const s = nt(this._doc);
|
|
837
|
+
if (t < 0 || t >= s.length)
|
|
838
|
+
throw new Error(`section ${t} out of range (0..${s.length - 1})`);
|
|
839
|
+
if (t === s.length - 1)
|
|
840
|
+
return this.commit([{ type: "setSectionBand", band: e, blocks: n }]);
|
|
841
|
+
const r = this._doc.blocks[s[t].endBlock];
|
|
842
|
+
if (!r || r.kind !== "paragraph" || !r.style.sectionBreak)
|
|
843
|
+
throw new Error(`section ${t} has no section-break paragraph to carry a band`);
|
|
844
|
+
const i = r.style.sectionBreak, c = { ...i.props };
|
|
845
|
+
return n ? c[e] = n : delete c[e], this.commit([{ type: "setParaStyle", blockId: r.id, patch: { sectionBreak: { type: i.type, props: c } } }]);
|
|
846
|
+
}
|
|
847
|
+
/** Set (or clear) a section's default footer band. See `setSectionBand`. */
|
|
848
|
+
setSectionFooter(t, e) {
|
|
849
|
+
return this.setSectionBand(t, "footer", e);
|
|
850
|
+
}
|
|
851
|
+
/** Set (or clear) a section's default header band. See `setSectionBand`. */
|
|
852
|
+
setSectionHeader(t, e) {
|
|
853
|
+
return this.setSectionBand(t, "header", e);
|
|
854
|
+
}
|
|
855
|
+
// --- convenience queries ----------------------------------------------------
|
|
856
|
+
/** Find paragraphs by text (see query.findParagraphs). */
|
|
857
|
+
find(t) {
|
|
858
|
+
return yt(this._doc, t);
|
|
859
|
+
}
|
|
860
|
+
/** The paragraph with this id, or undefined. */
|
|
861
|
+
getParagraph(t) {
|
|
862
|
+
return L(this._doc, t);
|
|
863
|
+
}
|
|
864
|
+
// --- internals --------------------------------------------------------------
|
|
865
|
+
mustParagraph(t) {
|
|
866
|
+
const e = L(this._doc, t);
|
|
867
|
+
if (!e) throw new Error(`paragraph ${t} not found`);
|
|
868
|
+
return e;
|
|
869
|
+
}
|
|
870
|
+
/** Apply a list of ops as ONE undoable commit, clearing the redo stack. */
|
|
871
|
+
commit(t) {
|
|
872
|
+
if (t.length === 0) return this;
|
|
873
|
+
const e = [];
|
|
874
|
+
let n = this._doc;
|
|
875
|
+
for (const s of t) {
|
|
876
|
+
const r = F(n, s);
|
|
877
|
+
n = r.doc, e.unshift(r.inverse);
|
|
878
|
+
}
|
|
879
|
+
return this._doc = n, this.undoStack.push({ forward: t, inverse: e }), this.redoStack.length = 0, this;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
function Rt(o) {
|
|
883
|
+
const t = { ...o }, e = t;
|
|
884
|
+
for (const n of Ct) delete e[n];
|
|
885
|
+
return t;
|
|
886
|
+
}
|
|
887
|
+
function jt(o, t) {
|
|
888
|
+
const e = et(o.style.sdtPath, t), n = { ...o.style };
|
|
889
|
+
return e ? n.sdtPath = e : delete n.sdtPath, { ...o, style: n };
|
|
890
|
+
}
|
|
891
|
+
function Dt(o, t) {
|
|
892
|
+
const e = et(o.sdtPath, t), n = { ...o, revision: o.revision + 1 }, s = n;
|
|
893
|
+
return e ? s.sdtPath = e : delete s.sdtPath, n;
|
|
894
|
+
}
|
|
895
|
+
function Nt(o) {
|
|
896
|
+
for (const t of o)
|
|
897
|
+
for (const e of t.cells)
|
|
898
|
+
for (const n of e.blocks)
|
|
899
|
+
if (n.kind === "paragraph" && n.runs[0]) return n.runs[0].style;
|
|
900
|
+
}
|
|
901
|
+
function At(o, t = {}) {
|
|
902
|
+
return ht(t.fontRegistry, t.engineOptions).layout(o).pages.map((s) => {
|
|
903
|
+
const r = /* @__PURE__ */ new Set(), i = [];
|
|
904
|
+
for (const l of s.blocks)
|
|
905
|
+
r.has(l.blockId) || (r.add(l.blockId), i.push(l.blockId));
|
|
906
|
+
const c = {
|
|
907
|
+
index: s.index,
|
|
908
|
+
number: s.number,
|
|
909
|
+
widthPx: s.widthPx,
|
|
910
|
+
heightPx: s.heightPx,
|
|
911
|
+
marginPx: s.marginPx,
|
|
912
|
+
contentTopPx: s.contentTopPx,
|
|
913
|
+
contentBottomPx: s.contentBottomPx,
|
|
914
|
+
blockIds: i
|
|
915
|
+
};
|
|
916
|
+
return s.pageColorHex !== void 0 && (c.pageColorHex = s.pageColorHex), c;
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
function ge(o, t, e) {
|
|
920
|
+
for (const n of At(o, e))
|
|
921
|
+
if (n.blockIds.includes(t)) return n.number;
|
|
922
|
+
return null;
|
|
923
|
+
}
|
|
924
|
+
function ke(o, t) {
|
|
925
|
+
for (const e of o) {
|
|
926
|
+
const n = e.blockIds.indexOf(t);
|
|
927
|
+
if (n >= 0) return { index: e.index, order: n };
|
|
928
|
+
}
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
export {
|
|
932
|
+
ye as DocumentEditor,
|
|
933
|
+
ue as blockPath,
|
|
934
|
+
yt as findParagraphs,
|
|
935
|
+
R as getBlockById,
|
|
936
|
+
re as getBookmark,
|
|
937
|
+
ie as getBookmarks,
|
|
938
|
+
ae as getEndnotes,
|
|
939
|
+
ne as getField,
|
|
940
|
+
se as getFieldBlocks,
|
|
941
|
+
St as getFields,
|
|
942
|
+
oe as getFieldsByName,
|
|
943
|
+
ce as getFootnotes,
|
|
944
|
+
Wt as getImageById,
|
|
945
|
+
qt as getImages,
|
|
946
|
+
le as getListItems,
|
|
947
|
+
At as getPages,
|
|
948
|
+
L as getParagraphById,
|
|
949
|
+
Kt as getParagraphs,
|
|
950
|
+
x as getSdt,
|
|
951
|
+
Zt as getSdtAncestors,
|
|
952
|
+
bt as getSdtBlocks,
|
|
953
|
+
Xt as getSdtChildren,
|
|
954
|
+
te as getSdtDescendants,
|
|
955
|
+
kt as getSdtNodes,
|
|
956
|
+
Qt as getSdtRoots,
|
|
957
|
+
ee as getSdtValue,
|
|
958
|
+
st as getSdts,
|
|
959
|
+
Jt as getSdtsByAlias,
|
|
960
|
+
Gt as getSdtsByTag,
|
|
961
|
+
zt as getSections,
|
|
962
|
+
fe as getStyleById,
|
|
963
|
+
de as getStyles,
|
|
964
|
+
G as getTableById,
|
|
965
|
+
Yt as getTables,
|
|
966
|
+
ke as indexOnPage,
|
|
967
|
+
me as mergeAll,
|
|
968
|
+
lt as mergeDocuments,
|
|
969
|
+
ge as pageOfBlock,
|
|
970
|
+
pe as positionOfText,
|
|
971
|
+
he as rangeText,
|
|
972
|
+
nt as resolveSections,
|
|
973
|
+
wt as sdtText,
|
|
974
|
+
V as textOf,
|
|
975
|
+
k as walk,
|
|
976
|
+
Vt as walkRuns
|
|
977
|
+
};
|