@arbidocs/blocks 0.4.111 → 0.4.113
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/{NativeDocxEditor-AQKRZBIU.cjs → NativeDocxEditor-AQZSUGET.cjs} +8 -8
- package/dist/{NativeDocxEditor-AQKRZBIU.cjs.map → NativeDocxEditor-AQZSUGET.cjs.map} +1 -1
- package/dist/{NativeDocxEditor-IN2HEO5I.js → NativeDocxEditor-MBCBXYDZ.js} +4 -4
- package/dist/{NativeDocxEditor-IN2HEO5I.js.map → NativeDocxEditor-MBCBXYDZ.js.map} +1 -1
- package/dist/chat/index.cjs +131 -131
- package/dist/chat/index.js +4 -4
- package/dist/{chunk-2C7TCVQZ.js → chunk-3OT37I24.js} +30 -297
- package/dist/chunk-3OT37I24.js.map +1 -0
- package/dist/{chunk-HBBJYRGI.cjs → chunk-5U4WY2VW.cjs} +9 -9
- package/dist/{chunk-HBBJYRGI.cjs.map → chunk-5U4WY2VW.cjs.map} +1 -1
- package/dist/{chunk-XKSFJYOD.cjs → chunk-5UHAWSEX.cjs} +4 -4
- package/dist/{chunk-XKSFJYOD.cjs.map → chunk-5UHAWSEX.cjs.map} +1 -1
- package/dist/{chunk-KZJAG7T3.js → chunk-7XF5SFJ2.js} +3 -3
- package/dist/{chunk-KZJAG7T3.js.map → chunk-7XF5SFJ2.js.map} +1 -1
- package/dist/{chunk-VGOFFCMT.cjs → chunk-B6MVQCXW.cjs} +3 -3
- package/dist/{chunk-VGOFFCMT.cjs.map → chunk-B6MVQCXW.cjs.map} +1 -1
- package/dist/{chunk-VLOPZHFH.js → chunk-D3N67Q4D.js} +3 -3
- package/dist/{chunk-VLOPZHFH.js.map → chunk-D3N67Q4D.js.map} +1 -1
- package/dist/{chunk-XIGWUDOD.cjs → chunk-ETBB5KMN.cjs} +61 -316
- package/dist/chunk-ETBB5KMN.cjs.map +1 -0
- package/dist/{chunk-Q6B77ZWZ.js → chunk-GIBRZ54P.js} +3 -3
- package/dist/{chunk-Q6B77ZWZ.js.map → chunk-GIBRZ54P.js.map} +1 -1
- package/dist/{chunk-2WO5L7YT.cjs → chunk-HF4PAYBM.cjs} +5 -5
- package/dist/{chunk-2WO5L7YT.cjs.map → chunk-HF4PAYBM.cjs.map} +1 -1
- package/dist/chunk-I2QSDQQV.cjs +126 -0
- package/dist/chunk-I2QSDQQV.cjs.map +1 -0
- package/dist/{chunk-BV7FEMSI.js → chunk-OKERRHLH.js} +3 -3
- package/dist/{chunk-BV7FEMSI.js.map → chunk-OKERRHLH.js.map} +1 -1
- package/dist/{chunk-CXZ7FPTQ.js → chunk-PKZYL2KU.js} +3 -3
- package/dist/{chunk-CXZ7FPTQ.js.map → chunk-PKZYL2KU.js.map} +1 -1
- package/dist/{chunk-NRUPUDWB.js → chunk-PXE5BNK6.js} +3 -3
- package/dist/{chunk-NRUPUDWB.js.map → chunk-PXE5BNK6.js.map} +1 -1
- package/dist/chunk-QXMR5YHC.js +80 -0
- package/dist/chunk-QXMR5YHC.js.map +1 -0
- package/dist/{chunk-TF47ATYS.cjs → chunk-RUFNJRLW.cjs} +4 -4
- package/dist/{chunk-TF47ATYS.cjs.map → chunk-RUFNJRLW.cjs.map} +1 -1
- package/dist/{chunk-HBF4BDRU.cjs → chunk-S6BOINC4.cjs} +7 -7
- package/dist/{chunk-HBF4BDRU.cjs.map → chunk-S6BOINC4.cjs.map} +1 -1
- package/dist/{chunk-6RHHMBZ5.js → chunk-TAXKPPNC.js} +5 -5
- package/dist/{chunk-6RHHMBZ5.js.map → chunk-TAXKPPNC.js.map} +1 -1
- package/dist/{chunk-WTM65ZNG.js → chunk-TKJSCHSX.js} +3 -3
- package/dist/{chunk-WTM65ZNG.js.map → chunk-TKJSCHSX.js.map} +1 -1
- package/dist/{chunk-2UAJVK3C.cjs → chunk-UAMZXRYJ.cjs} +4 -4
- package/dist/{chunk-2UAJVK3C.cjs.map → chunk-UAMZXRYJ.cjs.map} +1 -1
- package/dist/{chunk-WPVIOGDG.cjs → chunk-US5ASM4G.cjs} +22 -22
- package/dist/{chunk-WPVIOGDG.cjs.map → chunk-US5ASM4G.cjs.map} +1 -1
- package/dist/{chunk-CECWAIHL.js → chunk-XFZ7HNPG.js} +3 -3
- package/dist/{chunk-CECWAIHL.js.map → chunk-XFZ7HNPG.js.map} +1 -1
- package/dist/{chunk-VP4KJ4LK.cjs → chunk-XZB2QP76.cjs} +7 -7
- package/dist/{chunk-VP4KJ4LK.cjs.map → chunk-XZB2QP76.cjs.map} +1 -1
- package/dist/connect/docx.cjs +7 -7
- package/dist/connect/docx.js +5 -5
- package/dist/connect/index.cjs +29 -29
- package/dist/connect/index.js +11 -11
- package/dist/docx/definitions/commands.d.ts +3 -52
- package/dist/docx/definitions/fragment.d.ts +5 -31
- package/dist/docx/definitions/port.d.ts +2 -22
- package/dist/docx/index.cjs +47 -47
- package/dist/docx/index.js +4 -4
- package/dist/docx/references/commands.d.ts +3 -89
- package/dist/docx/references/port.d.ts +2 -11
- package/dist/index.cjs +386 -386
- package/dist/index.js +13 -13
- package/dist/settings/index.cjs +1 -1
- package/dist/settings/index.js +1 -1
- package/dist/shell/Shell.d.ts +5 -0
- package/dist/shell/index.cjs +60 -60
- package/dist/shell/index.js +3 -3
- package/dist/studio/index.cjs +4 -4
- package/dist/studio/index.js +3 -3
- package/dist/tags/definitions.d.ts +4 -25
- package/dist/tags/ooxml.d.ts +1 -19
- package/node_modules/@arbidocs/coedit/dist/commands.cjs +687 -0
- package/node_modules/@arbidocs/coedit/dist/commands.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/commands.d.cts +263 -157
- package/node_modules/@arbidocs/coedit/dist/commands.d.ts +263 -157
- package/node_modules/@arbidocs/coedit/dist/commands.js +646 -2
- package/node_modules/@arbidocs/coedit/dist/commands.js.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/port-ip7WByvH.d.cts +188 -0
- package/node_modules/@arbidocs/coedit/dist/port-ip7WByvH.d.ts +188 -0
- package/node_modules/@arbidocs/coedit/dist/server.cjs +675 -65
- package/node_modules/@arbidocs/coedit/dist/server.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/server.d.cts +15 -4
- package/node_modules/@arbidocs/coedit/dist/server.d.ts +15 -4
- package/node_modules/@arbidocs/coedit/dist/server.js +676 -67
- package/node_modules/@arbidocs/coedit/dist/server.js.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/template.d.cts +3 -17
- package/node_modules/@arbidocs/coedit/dist/template.d.ts +3 -17
- package/node_modules/@arbidocs/coedit/dist/track-eYC94jTp.d.cts +17 -0
- package/node_modules/@arbidocs/coedit/dist/track-eYC94jTp.d.ts +17 -0
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +4 -4
- package/dist/chunk-2A4MDHJR.cjs +0 -198
- package/dist/chunk-2A4MDHJR.cjs.map +0 -1
- package/dist/chunk-2C7TCVQZ.js.map +0 -1
- package/dist/chunk-EPHGD4YV.js +0 -174
- package/dist/chunk-EPHGD4YV.js.map +0 -1
- package/dist/chunk-XIGWUDOD.cjs.map +0 -1
|
@@ -1,14 +1,536 @@
|
|
|
1
1
|
import { Awareness } from 'y-protocols/awareness';
|
|
2
2
|
import { createServerAutomationHost } from '@docx-editor.dev/core/automation';
|
|
3
3
|
import { createCollaborationDocumentPort, historyGroupOfJournal } from '@docx-editor.dev/core/collaboration/replication';
|
|
4
|
-
import { TreePackageStore, validateRasterHeader, headlessViewOfStore, ORIGIN_IDS, readOoxmlPackage, writeOoxmlPackage, readOoxmlPart, validateExternalTarget, relsPartNameFor, contentTypesPartBytes, withContentTypeOverride } from '@docx-editor.dev/core/store';
|
|
4
|
+
import { TreePackageStore, validateRasterHeader, headlessViewOfStore, ORIGIN_IDS, readOoxmlPackage, writeOoxmlPackage, readOoxmlPart, validateExternalTarget, relsPartNameFor, contentTypesPartBytes, withContentTypeOverride, readXml } from '@docx-editor.dev/core/store';
|
|
5
|
+
import { resolveNumberingLevel, resolveStoryListItems, buildStyleCascadeTable, withNumberingStyleLinks, buildNumberingIndex } from '@docx-editor.dev/core/layout';
|
|
6
|
+
import { zipSync, strToU8, strFromU8, unzipSync } from 'fflate';
|
|
5
7
|
import * as Y3 from 'yjs';
|
|
6
8
|
import { createCollaborationStatusTracker, safeParticipantColor } from '@docx-editor.dev/core/collaboration';
|
|
7
9
|
|
|
8
10
|
// src/server.ts
|
|
9
11
|
|
|
12
|
+
// src/commands/read.ts
|
|
13
|
+
var DEFINED_TERM_STYLE = "DefinedTerm";
|
|
14
|
+
var CROSS_REFERENCE_STYLE = "CrossReference";
|
|
15
|
+
var BROKEN_CROSS_REFERENCE_STYLE = "CrossReferenceBroken";
|
|
16
|
+
var WATCHED_STYLES = /* @__PURE__ */ new Set([BROKEN_CROSS_REFERENCE_STYLE]);
|
|
17
|
+
var attr = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
|
|
18
|
+
var FIELD_ATOM = "\uFFFC";
|
|
19
|
+
var HEADING_STYLE = /^(heading|berschrift|titre|t[ií]tulo|titolo|kop)\s*\d/i;
|
|
20
|
+
function readParagraphs(root) {
|
|
21
|
+
const out = [];
|
|
22
|
+
const body = root.children?.find((n) => n.kind === "body") ?? root;
|
|
23
|
+
const visit = (node, topLevel, pending) => {
|
|
24
|
+
for (const child of node.children ?? []) {
|
|
25
|
+
if (child.kind === "paragraph") {
|
|
26
|
+
out.push(readParagraph(child, topLevel, pending.splice(0)));
|
|
27
|
+
} else if (child.localName === "bookmarkStart") {
|
|
28
|
+
const name = attr(child, "name");
|
|
29
|
+
if (name) pending.push(name);
|
|
30
|
+
} else if (child.localName === "tbl" || child.localName === "tr" || child.localName === "tc") {
|
|
31
|
+
visit(child, false, pending);
|
|
32
|
+
} else if (child.localName === "sdt" || child.localName === "sdtContent") {
|
|
33
|
+
visit(child, topLevel, pending);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
visit(body, true, []);
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function readParagraph(node, topLevel, bookmarks) {
|
|
41
|
+
let text = "";
|
|
42
|
+
const links = [];
|
|
43
|
+
let styleId;
|
|
44
|
+
let outline = false;
|
|
45
|
+
let fieldDepth = 0;
|
|
46
|
+
const marks = [];
|
|
47
|
+
let runStyle;
|
|
48
|
+
const fields = [];
|
|
49
|
+
const notes = [];
|
|
50
|
+
let current = null;
|
|
51
|
+
const field = (c) => {
|
|
52
|
+
const type = attr(c, "fldCharType");
|
|
53
|
+
if (type === "begin") {
|
|
54
|
+
if (fieldDepth === 0) {
|
|
55
|
+
current = { offset: text.length, instruction: "", result: "", inResult: false };
|
|
56
|
+
text += FIELD_ATOM;
|
|
57
|
+
}
|
|
58
|
+
fieldDepth++;
|
|
59
|
+
} else if (type === "separate" && fieldDepth === 1 && current) current.inResult = true;
|
|
60
|
+
else if (type === "end") {
|
|
61
|
+
fieldDepth = Math.max(0, fieldDepth - 1);
|
|
62
|
+
if (fieldDepth === 0 && current) {
|
|
63
|
+
const { offset, instruction, result } = current;
|
|
64
|
+
fields.push({ offset, instruction: instruction.trim(), result });
|
|
65
|
+
current = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const walk = (n, link) => {
|
|
70
|
+
for (const c of n.children ?? []) {
|
|
71
|
+
if (c.localName === "fldChar") {
|
|
72
|
+
field(c);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (c.localName === "fldSimple") {
|
|
76
|
+
if (fieldDepth === 0) text += FIELD_ATOM;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (c.localName === "instrText") {
|
|
80
|
+
if (fieldDepth === 1 && current)
|
|
81
|
+
current.instruction += (c.children ?? []).map((t) => t.value ?? "").join("");
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (c.kind === "paragraphProperties" || c.localName === "pPr") {
|
|
85
|
+
for (const p of c.children ?? []) {
|
|
86
|
+
if (p.localName === "pStyle") styleId = attr(p, "val");
|
|
87
|
+
if (p.localName === "outlineLvl" && Number(attr(p, "val")) < 9) outline = true;
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (c.localName === "delText" || c.localName === "del" || c.localName === "rPr") continue;
|
|
92
|
+
if (c.localName === "r") {
|
|
93
|
+
const rStyle = c.children?.find((x) => x.localName === "rPr")?.children?.find((x) => x.localName === "rStyle");
|
|
94
|
+
const watched = rStyle && attr(rStyle, "val");
|
|
95
|
+
runStyle = watched && WATCHED_STYLES.has(watched) ? watched : void 0;
|
|
96
|
+
walk(c, link);
|
|
97
|
+
runStyle = void 0;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if ((c.localName === "footnoteReference" || c.localName === "endnoteReference") && fieldDepth === 0) {
|
|
101
|
+
notes.push({
|
|
102
|
+
offset: text.length,
|
|
103
|
+
kind: c.localName === "footnoteReference" ? "footnote" : "endnote",
|
|
104
|
+
id: attr(c, "id") ?? ""
|
|
105
|
+
});
|
|
106
|
+
text += FIELD_ATOM;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (c.localName === "bookmarkStart") {
|
|
110
|
+
const name = attr(c, "name");
|
|
111
|
+
if (name) bookmarks.push(name);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (c.localName === "hyperlink") {
|
|
115
|
+
const anchor = attr(c, "anchor");
|
|
116
|
+
const next = anchor ? { anchor, text: "", offset: text.length } : void 0;
|
|
117
|
+
walk(c, next ?? link);
|
|
118
|
+
if (next) links.push(next);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (c.kind === "textValue") {
|
|
122
|
+
if (fieldDepth > 0) {
|
|
123
|
+
const open = current;
|
|
124
|
+
if (fieldDepth === 1 && open?.inResult) open.result += c.value ?? "";
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (runStyle && c.value) {
|
|
128
|
+
const last = marks[marks.length - 1];
|
|
129
|
+
if (last && last.styleId === runStyle && last.offset + last.text.length === text.length)
|
|
130
|
+
last.text += c.value;
|
|
131
|
+
else marks.push({ styleId: runStyle, offset: text.length, text: c.value });
|
|
132
|
+
}
|
|
133
|
+
text += c.value ?? "";
|
|
134
|
+
if (link) link.text += c.value ?? "";
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (c.localName === "tab" && fieldDepth === 0) text += " ";
|
|
138
|
+
walk(c, link);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
walk(node);
|
|
142
|
+
const paraId = attr(node, "paraId");
|
|
143
|
+
return {
|
|
144
|
+
id: node.id,
|
|
145
|
+
...paraId ? { paraId } : {},
|
|
146
|
+
text,
|
|
147
|
+
heading: outline || !!styleId && HEADING_STYLE.test(styleId),
|
|
148
|
+
styleId,
|
|
149
|
+
topLevel,
|
|
150
|
+
bookmarks,
|
|
151
|
+
links,
|
|
152
|
+
...fields.length ? { fields } : {},
|
|
153
|
+
...marks.length ? { marks } : {},
|
|
154
|
+
...notes.length ? { notes } : {}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function documentNumbering(source) {
|
|
158
|
+
let numbering;
|
|
159
|
+
let cascade;
|
|
160
|
+
const index = () => {
|
|
161
|
+
if (!numbering) {
|
|
162
|
+
cascade = buildStyleCascadeTable(
|
|
163
|
+
source.stylesRoot(),
|
|
164
|
+
void 0,
|
|
165
|
+
source.settingsRoot()
|
|
166
|
+
);
|
|
167
|
+
numbering = withNumberingStyleLinks(
|
|
168
|
+
buildNumberingIndex(source.numberingRoot()),
|
|
169
|
+
cascade
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
return numbering;
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
listItems: () => {
|
|
176
|
+
const body = source.root().children?.find((n) => n.kind === "body");
|
|
177
|
+
const items = resolveStoryListItems(
|
|
178
|
+
body?.children ?? [],
|
|
179
|
+
index(),
|
|
180
|
+
cascade
|
|
181
|
+
);
|
|
182
|
+
const out = /* @__PURE__ */ new Map();
|
|
183
|
+
for (const [id, item] of items)
|
|
184
|
+
out.set(id, {
|
|
185
|
+
numId: item.numId,
|
|
186
|
+
ilvl: item.ilvl,
|
|
187
|
+
markerText: item.markerText,
|
|
188
|
+
numFmt: item.numFmt
|
|
189
|
+
});
|
|
190
|
+
return out;
|
|
191
|
+
},
|
|
192
|
+
levelOf: (numId, ilvl) => {
|
|
193
|
+
const level = resolveNumberingLevel(index(), numId, ilvl)?.level;
|
|
194
|
+
return level ? { lvlText: level.lvlText, numFmt: level.numFmt } : null;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
var W_NAMESPACES = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"';
|
|
199
|
+
var INVALID_XML = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
|
|
200
|
+
var esc = (text) => text.replace(INVALID_XML, "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
201
|
+
var documentXml = (body) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
202
|
+
<w:document ${W_NAMESPACES}><w:body>${body}</w:body></w:document>`;
|
|
203
|
+
var stylesXml = (defaults, styles) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
204
|
+
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">${defaults}${styles}</w:styles>`;
|
|
205
|
+
var CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
206
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`;
|
|
207
|
+
var ROOT_RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
208
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`;
|
|
209
|
+
var documentRels = (more = "") => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
210
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>${more}</Relationships>`;
|
|
211
|
+
var coreXml = (title, at) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
212
|
+
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc(
|
|
213
|
+
title
|
|
214
|
+
)}</dc:title><dcterms:created xsi:type="dcterms:W3CDTF">${at}</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">${at}</dcterms:modified></cp:coreProperties>`;
|
|
215
|
+
function docxPackage(parts) {
|
|
216
|
+
const at = new Date(parts.at ?? Date.now()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
217
|
+
return zipSync({
|
|
218
|
+
"[Content_Types].xml": strToU8(CONTENT_TYPES),
|
|
219
|
+
"_rels/.rels": strToU8(ROOT_RELS),
|
|
220
|
+
"docProps/core.xml": strToU8(coreXml(parts.title, at)),
|
|
221
|
+
"word/document.xml": strToU8(parts.document),
|
|
222
|
+
"word/styles.xml": strToU8(parts.styles),
|
|
223
|
+
"word/_rels/document.xml.rels": strToU8(documentRels(parts.relationships))
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/commands/references.ts
|
|
228
|
+
var RUN_PARTS = /* @__PURE__ */ new Set(["rPr", "t", "tab", "br", "lastRenderedPageBreak"]);
|
|
229
|
+
var SKIPPED = /* @__PURE__ */ new Set(["pPr", "bookmarkStart", "bookmarkEnd", "proofErr", "permStart", "permEnd"]);
|
|
230
|
+
function serialize(node) {
|
|
231
|
+
if (node.kind === "textValue") return esc(node.value ?? "");
|
|
232
|
+
const name = `${node.prefix ?? "w"}:${node.localName}`;
|
|
233
|
+
const attrs = (node.attributes ?? []).map((a) => ` ${a.prefix ? `${a.prefix}:` : ""}${a.localName}="${esc(a.value)}"`).join("");
|
|
234
|
+
const children = (node.children ?? []).map((c) => serialize(c)).join("");
|
|
235
|
+
return children ? `<${name}${attrs}>${children}</${name}>` : `<${name}${attrs}/>`;
|
|
236
|
+
}
|
|
237
|
+
function paragraphRunsXml(paragraph) {
|
|
238
|
+
const runs = [];
|
|
239
|
+
for (const child of paragraph.children ?? []) {
|
|
240
|
+
if (child.localName && SKIPPED.has(child.localName)) continue;
|
|
241
|
+
if (child.localName !== "r") return null;
|
|
242
|
+
if ((child.children ?? []).some((c) => !c.localName || !RUN_PARTS.has(c.localName))) return null;
|
|
243
|
+
runs.push(serialize(child));
|
|
244
|
+
}
|
|
245
|
+
return runs.length ? runs.join("") : null;
|
|
246
|
+
}
|
|
247
|
+
var W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
248
|
+
var TemplateError = class extends Error {
|
|
249
|
+
constructor(message) {
|
|
250
|
+
super(message);
|
|
251
|
+
this.name = "TemplateError";
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
function parse(xml, part = "part") {
|
|
255
|
+
const read = readXml(xml, { maxBytes: 64 * 1024 * 1024, maxElements: 2e6 });
|
|
256
|
+
if (!read.ok) throw new TemplateError(`${part} is not readable XML (${read.reason})`);
|
|
257
|
+
const convert = (node) => node.type === "text" ? node.value : { name: node.name, attrs: { ...node.attributes }, children: node.children.map(convert) };
|
|
258
|
+
const root = read.nodes.map(convert).find((n) => typeof n !== "string");
|
|
259
|
+
if (!root) throw new TemplateError(`${part} has no root element`);
|
|
260
|
+
const w = root.attrs["xmlns:w"];
|
|
261
|
+
if (w !== void 0 && w !== W_NS) throw new TemplateError(`${part} binds w: to ${w}`);
|
|
262
|
+
return root;
|
|
263
|
+
}
|
|
264
|
+
var escText = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
265
|
+
var escAttr = (s) => escText(s).replace(/"/g, """);
|
|
266
|
+
function serialize2(root) {
|
|
267
|
+
const out = ['<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'];
|
|
268
|
+
const walk = (node) => {
|
|
269
|
+
if (typeof node === "string") return void out.push(escText(node));
|
|
270
|
+
out.push("<", node.name);
|
|
271
|
+
for (const [k, v] of Object.entries(node.attrs)) out.push(" ", k, '="', escAttr(v), '"');
|
|
272
|
+
if (node.children.length === 0) return void out.push("/>");
|
|
273
|
+
out.push(">");
|
|
274
|
+
node.children.forEach(walk);
|
|
275
|
+
out.push("</", node.name, ">");
|
|
276
|
+
};
|
|
277
|
+
walk(root);
|
|
278
|
+
return out.join("");
|
|
279
|
+
}
|
|
280
|
+
var el = (name, attrs = {}, children = []) => ({
|
|
281
|
+
name,
|
|
282
|
+
attrs,
|
|
283
|
+
children
|
|
284
|
+
});
|
|
285
|
+
var isEl = (n) => typeof n === "object" && n !== null;
|
|
286
|
+
var kids = (e, name) => e.children.filter((c) => isEl(c) && (name === void 0 || c.name === name));
|
|
287
|
+
var kid = (e, name) => e ? kids(e, name)[0] : void 0;
|
|
288
|
+
|
|
289
|
+
// src/template/pkg.ts
|
|
290
|
+
var REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
291
|
+
var RT = {
|
|
292
|
+
officeDocument: `${REL}/officeDocument`};
|
|
293
|
+
var Pkg = class _Pkg {
|
|
294
|
+
files;
|
|
295
|
+
types;
|
|
296
|
+
constructor(files) {
|
|
297
|
+
this.files = files;
|
|
298
|
+
const ct = this.find("[Content_Types].xml");
|
|
299
|
+
if (!ct) throw new TemplateError("not a Word package: no [Content_Types].xml");
|
|
300
|
+
this.types = parse(strFromU8(files.get(ct)), "[Content_Types].xml");
|
|
301
|
+
}
|
|
302
|
+
static read(bytes) {
|
|
303
|
+
let files;
|
|
304
|
+
try {
|
|
305
|
+
files = unzipSync(bytes);
|
|
306
|
+
} catch {
|
|
307
|
+
throw new TemplateError("not a Word package: not a zip");
|
|
308
|
+
}
|
|
309
|
+
return new _Pkg(new Map(Object.entries(files).filter(([n]) => !n.endsWith("/"))));
|
|
310
|
+
}
|
|
311
|
+
write() {
|
|
312
|
+
this.files.set(
|
|
313
|
+
this.find("[Content_Types].xml") ?? "[Content_Types].xml",
|
|
314
|
+
strToU8(serialize2(this.types))
|
|
315
|
+
);
|
|
316
|
+
return zipSync(Object.fromEntries(this.files), { level: 6 });
|
|
317
|
+
}
|
|
318
|
+
/** The stored name of a part, matched case-insensitively as OPC does. */
|
|
319
|
+
find(name) {
|
|
320
|
+
const key = name.replace(/^\//, "").toLowerCase();
|
|
321
|
+
for (const n of this.files.keys()) if (n.toLowerCase() === key) return n;
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
has(name) {
|
|
325
|
+
return this.find(name) !== void 0;
|
|
326
|
+
}
|
|
327
|
+
text(name) {
|
|
328
|
+
const n = this.find(name);
|
|
329
|
+
return n === void 0 ? void 0 : strFromU8(this.files.get(n));
|
|
330
|
+
}
|
|
331
|
+
xml(name) {
|
|
332
|
+
const t = this.text(name);
|
|
333
|
+
return t === void 0 ? void 0 : parse(t, name);
|
|
334
|
+
}
|
|
335
|
+
setXml(name, root, contentType) {
|
|
336
|
+
this.files.set(this.find(name) ?? name, strToU8(serialize2(root)));
|
|
337
|
+
if (contentType) this.setContentType(name, contentType);
|
|
338
|
+
}
|
|
339
|
+
setBytes(name, bytes, contentType) {
|
|
340
|
+
this.files.set(this.find(name) ?? name, bytes);
|
|
341
|
+
if (contentType) this.setContentType(name, contentType);
|
|
342
|
+
}
|
|
343
|
+
remove(name) {
|
|
344
|
+
const n = this.find(name);
|
|
345
|
+
if (n === void 0) return;
|
|
346
|
+
this.files.delete(n);
|
|
347
|
+
this.types.children = this.types.children.filter(
|
|
348
|
+
(c) => !(typeof c !== "string" && c.name === "Override" && c.attrs.PartName.toLowerCase() === `/${n.toLowerCase()}`)
|
|
349
|
+
);
|
|
350
|
+
this.files.delete(relsName(n));
|
|
351
|
+
}
|
|
352
|
+
contentType(name) {
|
|
353
|
+
const part = `/${name.replace(/^\//, "")}`.toLowerCase();
|
|
354
|
+
const override = kids(this.types, "Override").find(
|
|
355
|
+
(o) => o.attrs.PartName.toLowerCase() === part
|
|
356
|
+
);
|
|
357
|
+
if (override) return override.attrs.ContentType;
|
|
358
|
+
const ext = part.slice(part.lastIndexOf(".") + 1);
|
|
359
|
+
return kids(this.types, "Default").find((d) => d.attrs.Extension.toLowerCase() === ext)?.attrs.ContentType;
|
|
360
|
+
}
|
|
361
|
+
setContentType(name, type) {
|
|
362
|
+
const part = `/${name.replace(/^\//, "")}`;
|
|
363
|
+
const override = kids(this.types, "Override").find(
|
|
364
|
+
(o) => o.attrs.PartName.toLowerCase() === part.toLowerCase()
|
|
365
|
+
);
|
|
366
|
+
if (override) override.attrs.ContentType = type;
|
|
367
|
+
else this.types.children.push(el("Override", { PartName: part, ContentType: type }));
|
|
368
|
+
}
|
|
369
|
+
/** A `Default` for an extension (media), unless one exists. */
|
|
370
|
+
ensureDefault(ext, type) {
|
|
371
|
+
if (!kids(this.types, "Default").some(
|
|
372
|
+
(d) => d.attrs.Extension.toLowerCase() === ext.toLowerCase()
|
|
373
|
+
))
|
|
374
|
+
this.types.children.unshift(el("Default", { Extension: ext, ContentType: type }));
|
|
375
|
+
}
|
|
376
|
+
rels(owner) {
|
|
377
|
+
const root = this.xml(relsName(owner));
|
|
378
|
+
if (!root) return [];
|
|
379
|
+
return kids(root, "Relationship").map((r) => ({
|
|
380
|
+
id: r.attrs.Id,
|
|
381
|
+
type: r.attrs.Type,
|
|
382
|
+
target: r.attrs.Target,
|
|
383
|
+
external: r.attrs.TargetMode === "External"
|
|
384
|
+
}));
|
|
385
|
+
}
|
|
386
|
+
setRels(owner, rels) {
|
|
387
|
+
const root = el(
|
|
388
|
+
"Relationships",
|
|
389
|
+
{ xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" },
|
|
390
|
+
rels.map(
|
|
391
|
+
(r) => el("Relationship", {
|
|
392
|
+
Id: r.id,
|
|
393
|
+
Type: r.type,
|
|
394
|
+
Target: r.target,
|
|
395
|
+
...r.external ? { TargetMode: "External" } : {}
|
|
396
|
+
})
|
|
397
|
+
)
|
|
398
|
+
);
|
|
399
|
+
this.setXml(relsName(owner), root);
|
|
400
|
+
}
|
|
401
|
+
/** Add a relationship from `owner`; returns its new id. */
|
|
402
|
+
addRel(owner, type, target, external = false) {
|
|
403
|
+
const rels = this.rels(owner);
|
|
404
|
+
const id = freshId(new Set(rels.map((r) => r.id)), "rIdT");
|
|
405
|
+
rels.push({ id, type, target, external });
|
|
406
|
+
this.setRels(owner, rels);
|
|
407
|
+
return id;
|
|
408
|
+
}
|
|
409
|
+
/** The part a relationship of `owner` points at (internal targets only). */
|
|
410
|
+
target(owner, rel) {
|
|
411
|
+
return resolveTarget(owner, rel.target);
|
|
412
|
+
}
|
|
413
|
+
/** The first internal part of a relationship type from `owner`. */
|
|
414
|
+
partOf(owner, type) {
|
|
415
|
+
const rel = this.rels(owner).find((r) => r.type === type && !r.external);
|
|
416
|
+
return rel && this.find(this.target(owner, rel));
|
|
417
|
+
}
|
|
418
|
+
/** The main document part (`word/document.xml` by convention). */
|
|
419
|
+
get main() {
|
|
420
|
+
const main = this.partOf("", RT.officeDocument);
|
|
421
|
+
if (!main) throw new TemplateError("not a Word package: no main document part");
|
|
422
|
+
return main;
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
function relsName(owner) {
|
|
426
|
+
const slash = owner.lastIndexOf("/");
|
|
427
|
+
return `${owner.slice(0, slash + 1)}_rels/${owner.slice(slash + 1)}.rels`;
|
|
428
|
+
}
|
|
429
|
+
function resolveTarget(owner, target) {
|
|
430
|
+
if (target.startsWith("/")) return target.slice(1);
|
|
431
|
+
const base = owner.slice(0, owner.lastIndexOf("/") + 1).split("/").filter(Boolean);
|
|
432
|
+
for (const seg of target.split("/")) {
|
|
433
|
+
if (seg === "..") base.pop();
|
|
434
|
+
else if (seg !== "." && seg !== "") base.push(seg);
|
|
435
|
+
}
|
|
436
|
+
return base.join("/");
|
|
437
|
+
}
|
|
438
|
+
function freshId(taken, prefix) {
|
|
439
|
+
for (let i = 1; ; i++) if (!taken.has(`${prefix}${i}`)) return `${prefix}${i}`;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/template/track.ts
|
|
443
|
+
var TRACKED = /* @__PURE__ */ new Set(["w:ins", "w:del", "w:moveFrom", "w:moveTo"]);
|
|
444
|
+
function trackInsertion(fragment, revision, covered) {
|
|
445
|
+
const pkg = Pkg.read(fragment);
|
|
446
|
+
const main = pkg.main;
|
|
447
|
+
const root = pkg.xml(main);
|
|
448
|
+
const body = kid(root, "w:body");
|
|
449
|
+
if (!root || !body) return fragment;
|
|
450
|
+
const attrs = { "w:id": "1", "w:author": revision.author, "w:date": revision.date };
|
|
451
|
+
const lastParagraph = body.children.filter(isEl).findLast((c) => c.name === "w:p");
|
|
452
|
+
const visit = (node) => {
|
|
453
|
+
node.children = node.children.map((child) => {
|
|
454
|
+
if (!isEl(child)) return child;
|
|
455
|
+
if (child.name === "w:r") return TRACKED.has(node.name) ? child : el("w:ins", attrs, [child]);
|
|
456
|
+
if (TRACKED.has(child.name)) return child;
|
|
457
|
+
if (child.name === "w:tr") {
|
|
458
|
+
markRow(child, attrs);
|
|
459
|
+
return child;
|
|
460
|
+
}
|
|
461
|
+
visit(child);
|
|
462
|
+
if (child.name === "w:p" && (covered || child !== lastParagraph)) markParagraph(child, attrs);
|
|
463
|
+
return child;
|
|
464
|
+
});
|
|
465
|
+
};
|
|
466
|
+
visit(body);
|
|
467
|
+
pkg.setXml(main, root);
|
|
468
|
+
return pkg.write();
|
|
469
|
+
}
|
|
470
|
+
function markParagraph(p, attrs) {
|
|
471
|
+
let pPr = kid(p, "w:pPr");
|
|
472
|
+
if (!pPr) p.children.unshift(pPr = el("w:pPr"));
|
|
473
|
+
let rPr = kid(pPr, "w:rPr");
|
|
474
|
+
if (!rPr) {
|
|
475
|
+
rPr = el("w:rPr");
|
|
476
|
+
const at = pPr.children.findIndex(
|
|
477
|
+
(c) => isEl(c) && (c.name === "w:sectPr" || c.name === "w:pPrChange")
|
|
478
|
+
);
|
|
479
|
+
pPr.children.splice(at < 0 ? pPr.children.length : at, 0, rPr);
|
|
480
|
+
}
|
|
481
|
+
if (!kid(rPr, "w:ins")) rPr.children.unshift(el("w:ins", attrs));
|
|
482
|
+
}
|
|
483
|
+
function markRow(tr, attrs) {
|
|
484
|
+
let trPr = kid(tr, "w:trPr");
|
|
485
|
+
if (!trPr) {
|
|
486
|
+
trPr = el("w:trPr");
|
|
487
|
+
const after = tr.children.findIndex((c) => isEl(c) && c.name === "w:tblPrEx");
|
|
488
|
+
tr.children.splice(after + 1, 0, trPr);
|
|
489
|
+
}
|
|
490
|
+
if (kid(trPr, "w:ins")) return;
|
|
491
|
+
const at = trPr.children.findIndex((c) => isEl(c) && c.name === "w:trPrChange");
|
|
492
|
+
trPr.children.splice(at < 0 ? trPr.children.length : at, 0, el("w:ins", attrs));
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/commands/fragment.ts
|
|
496
|
+
var CHARACTER_STYLES = {
|
|
497
|
+
[DEFINED_TERM_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${DEFINED_TERM_STYLE}"><w:name w:val="Defined Term"/><w:rPr><w:u w:val="dotted" w:color="7F7F7F"/></w:rPr></w:style>`,
|
|
498
|
+
[CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference"/><w:rPr><w:color w:val="1F4E79"/><w:u w:val="dotted" w:color="8EA9C1"/></w:rPr></w:style>`,
|
|
499
|
+
[BROKEN_CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${BROKEN_CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference Broken"/><w:basedOn w:val="${CROSS_REFERENCE_STYLE}"/><w:rPr><w:color w:val="C00000"/><w:u w:val="wave" w:color="C00000"/></w:rPr></w:style>`
|
|
500
|
+
};
|
|
501
|
+
function stylesUsed(body) {
|
|
502
|
+
return [...new Set([...body.matchAll(/<w:rStyle w:val="([^"]+)"/g)].map((m) => m[1]))];
|
|
503
|
+
}
|
|
504
|
+
var fragmentStyles = (ids) => stylesXml(
|
|
505
|
+
"",
|
|
506
|
+
`<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style>${ids.map((id) => CHARACTER_STYLES[id] ?? "").join("")}`
|
|
507
|
+
);
|
|
508
|
+
function fragmentPackage(body, covered, {
|
|
509
|
+
revision,
|
|
510
|
+
relationships,
|
|
511
|
+
styles = stylesUsed(body)
|
|
512
|
+
} = {}) {
|
|
513
|
+
const untracked = docxPackage({
|
|
514
|
+
document: documentXml(body),
|
|
515
|
+
styles: fragmentStyles(styles),
|
|
516
|
+
title: "Defined terms",
|
|
517
|
+
relationships
|
|
518
|
+
});
|
|
519
|
+
return revision ? trackInsertion(untracked, revision, covered) : untracked;
|
|
520
|
+
}
|
|
521
|
+
var attr2 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
|
|
522
|
+
function documentStyleIds(root) {
|
|
523
|
+
const ids = /* @__PURE__ */ new Set();
|
|
524
|
+
for (const style of root?.children ?? [])
|
|
525
|
+
if (style.localName === "style") {
|
|
526
|
+
const id = attr2(style, "styleId");
|
|
527
|
+
if (id) ids.add(id);
|
|
528
|
+
}
|
|
529
|
+
return ids;
|
|
530
|
+
}
|
|
531
|
+
|
|
10
532
|
// src/rich.ts
|
|
11
|
-
var
|
|
533
|
+
var WML2 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
12
534
|
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
13
535
|
"ins",
|
|
14
536
|
"del",
|
|
@@ -23,24 +545,24 @@ var WRAPPERS = /* @__PURE__ */ new Set([
|
|
|
23
545
|
"sdtContent"
|
|
24
546
|
]);
|
|
25
547
|
var TEXT_ELEMENTS = /* @__PURE__ */ new Set(["t", "delText", "instrText"]);
|
|
26
|
-
var
|
|
27
|
-
var isWml = (
|
|
28
|
-
function describe(
|
|
29
|
-
const desc = { ns:
|
|
30
|
-
if (
|
|
548
|
+
var isEl2 = (n) => typeof n !== "string";
|
|
549
|
+
var isWml = (el2, local) => el2.ns === WML2 && el2.local === local;
|
|
550
|
+
function describe(el2) {
|
|
551
|
+
const desc = { ns: el2.ns, local: el2.local, attrs: el2.attrs, bindings: el2.bindings };
|
|
552
|
+
if (el2.prefix !== void 0) desc.prefix = el2.prefix;
|
|
31
553
|
return desc;
|
|
32
554
|
}
|
|
33
555
|
function withChildren(desc, children, id) {
|
|
34
|
-
const
|
|
556
|
+
const el2 = {
|
|
35
557
|
ns: desc.ns,
|
|
36
558
|
local: desc.local,
|
|
37
559
|
attrs: desc.attrs,
|
|
38
560
|
bindings: desc.bindings,
|
|
39
561
|
children
|
|
40
562
|
};
|
|
41
|
-
if (desc.prefix !== void 0)
|
|
42
|
-
if (id !== void 0)
|
|
43
|
-
return
|
|
563
|
+
if (desc.prefix !== void 0) el2.prefix = desc.prefix;
|
|
564
|
+
if (id !== void 0) el2._id = id;
|
|
565
|
+
return el2;
|
|
44
566
|
}
|
|
45
567
|
var counter = 0;
|
|
46
568
|
function newRunId() {
|
|
@@ -57,7 +579,7 @@ function encodeRun(run, wrappers, out) {
|
|
|
57
579
|
let rPr = null;
|
|
58
580
|
let start = 0;
|
|
59
581
|
const first = children[0];
|
|
60
|
-
if (first !== void 0 &&
|
|
582
|
+
if (first !== void 0 && isEl2(first) && isWml(first, "rPr")) {
|
|
61
583
|
rPr = first;
|
|
62
584
|
start = 1;
|
|
63
585
|
}
|
|
@@ -65,9 +587,9 @@ function encodeRun(run, wrappers, out) {
|
|
|
65
587
|
let produced = false;
|
|
66
588
|
for (let i = start; i < children.length; i++) {
|
|
67
589
|
const child = children[i];
|
|
68
|
-
if (!
|
|
590
|
+
if (!isEl2(child)) fail();
|
|
69
591
|
const only = child.children[0];
|
|
70
|
-
if (child.ns ===
|
|
592
|
+
if (child.ns === WML2 && TEXT_ELEMENTS.has(child.local) && child.children.length === 1 && typeof only === "string" && only.length > 0) {
|
|
71
593
|
const tx = describe(child);
|
|
72
594
|
for (let c = 0; c < only.length; c++) out.push({ v: only[c], a: { ...base, tx, k: null } });
|
|
73
595
|
} else {
|
|
@@ -77,16 +599,16 @@ function encodeRun(run, wrappers, out) {
|
|
|
77
599
|
}
|
|
78
600
|
if (!produced)
|
|
79
601
|
out.push({
|
|
80
|
-
v: { x: { ns:
|
|
602
|
+
v: { x: { ns: WML2, local: "e", attrs: [], bindings: [], children: [] } },
|
|
81
603
|
a: { ...base, tx: null, k: "e" }
|
|
82
604
|
});
|
|
83
605
|
}
|
|
84
606
|
function encodeInline(children, wrappers, out) {
|
|
85
607
|
for (const child of children) {
|
|
86
|
-
if (!
|
|
87
|
-
if (child.ns ===
|
|
608
|
+
if (!isEl2(child)) fail();
|
|
609
|
+
if (child.ns === WML2 && child.local === "r") {
|
|
88
610
|
encodeRun(child, wrappers, out);
|
|
89
|
-
} else if (child.ns ===
|
|
611
|
+
} else if (child.ns === WML2 && WRAPPERS.has(child.local)) {
|
|
90
612
|
const before = out.length;
|
|
91
613
|
const desc = { ...describe(child), head: [], id: child._id ?? newRunId() };
|
|
92
614
|
let ok = true;
|
|
@@ -102,10 +624,10 @@ function encodeInline(children, wrappers, out) {
|
|
|
102
624
|
out.length = before;
|
|
103
625
|
out.push(atom(child, wrappers));
|
|
104
626
|
}
|
|
105
|
-
} else if (child.ns ===
|
|
627
|
+
} else if (child.ns === WML2 && child.local === "sdt") {
|
|
106
628
|
const last = child.children[child.children.length - 1];
|
|
107
629
|
const head = child.children.slice(0, -1);
|
|
108
|
-
if (last !== void 0 &&
|
|
630
|
+
if (last !== void 0 && isEl2(last) && isWml(last, "sdtContent") && head.every(isEl2)) {
|
|
109
631
|
const before = out.length;
|
|
110
632
|
const sdt = {
|
|
111
633
|
...describe(child),
|
|
@@ -132,14 +654,14 @@ function encodeInline(children, wrappers, out) {
|
|
|
132
654
|
}
|
|
133
655
|
}
|
|
134
656
|
}
|
|
135
|
-
function atom(
|
|
136
|
-
return { v: { x:
|
|
657
|
+
function atom(el2, wrappers) {
|
|
658
|
+
return { v: { x: el2 }, a: { r: null, ra: null, ri: null, w: wrappers, tx: null, k: "a" } };
|
|
137
659
|
}
|
|
138
660
|
function encodeParagraph(children) {
|
|
139
661
|
const head = [];
|
|
140
662
|
let start = 0;
|
|
141
663
|
const first = children[0];
|
|
142
|
-
if (first !== void 0 &&
|
|
664
|
+
if (first !== void 0 && isEl2(first) && isWml(first, "pPr")) {
|
|
143
665
|
head.push(first);
|
|
144
666
|
start = 1;
|
|
145
667
|
}
|
|
@@ -316,8 +838,8 @@ function writeUnits(text, units) {
|
|
|
316
838
|
function isRichParagraph(map) {
|
|
317
839
|
return map.has("inline");
|
|
318
840
|
}
|
|
319
|
-
function isParagraphEl(
|
|
320
|
-
return
|
|
841
|
+
function isParagraphEl(el2) {
|
|
842
|
+
return el2.ns === WML2 && el2.local === "p";
|
|
321
843
|
}
|
|
322
844
|
function fieldsOf(map, xml) {
|
|
323
845
|
map.set("ns", xml.ns);
|
|
@@ -339,7 +861,7 @@ function createRichParagraph(xml, encoded) {
|
|
|
339
861
|
const map = new Y3.Map();
|
|
340
862
|
fieldsOf(map, xml);
|
|
341
863
|
const children = new Y3.Array();
|
|
342
|
-
children.push(encoded.head.map((
|
|
864
|
+
children.push(encoded.head.map((el2) => xmlToLive(el2)));
|
|
343
865
|
map.set("children", children);
|
|
344
866
|
const inline = new Y3.Text();
|
|
345
867
|
writeUnits(inline, encoded.units);
|
|
@@ -378,14 +900,14 @@ function liveToXml(map) {
|
|
|
378
900
|
var escapeText = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
379
901
|
var escapeAttr = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/\t/g, "	").replace(/\n/g, " ").replace(/\r/g, " ");
|
|
380
902
|
var qualified = (prefix, local) => prefix ? `${prefix}:${local}` : local;
|
|
381
|
-
function serializeXml(
|
|
903
|
+
function serializeXml(el2, scope) {
|
|
382
904
|
const inScope = new Map(scope);
|
|
383
|
-
for (const b of
|
|
384
|
-
let out = `<${qualified(
|
|
385
|
-
for (const b of
|
|
905
|
+
for (const b of el2.bindings) inScope.set(b.prefix, b.ns);
|
|
906
|
+
let out = `<${qualified(el2.prefix, el2.local)}`;
|
|
907
|
+
for (const b of el2.bindings) {
|
|
386
908
|
out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
|
|
387
909
|
}
|
|
388
|
-
for (const a of
|
|
910
|
+
for (const a of el2.attrs) {
|
|
389
911
|
let p = a.prefix;
|
|
390
912
|
if (a.ns !== "" && !p) {
|
|
391
913
|
for (const [candidate, uri] of inScope) {
|
|
@@ -397,20 +919,20 @@ function serializeXml(el, scope) {
|
|
|
397
919
|
}
|
|
398
920
|
out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
|
|
399
921
|
}
|
|
400
|
-
if (
|
|
922
|
+
if (el2.children.length === 0) return `${out}/>`;
|
|
401
923
|
out += ">";
|
|
402
|
-
for (const child of
|
|
924
|
+
for (const child of el2.children) {
|
|
403
925
|
out += typeof child === "string" ? escapeText(child) : serializeXml(child, inScope);
|
|
404
926
|
}
|
|
405
|
-
return `${out}</${qualified(
|
|
927
|
+
return `${out}</${qualified(el2.prefix, el2.local)}>`;
|
|
406
928
|
}
|
|
407
|
-
function serializeLive(
|
|
408
|
-
if (isRichParagraph(
|
|
409
|
-
const prefix =
|
|
410
|
-
const local =
|
|
411
|
-
const bindings =
|
|
412
|
-
const attrs =
|
|
413
|
-
const children =
|
|
929
|
+
function serializeLive(el2, scope) {
|
|
930
|
+
if (isRichParagraph(el2)) return serializeXml(liveToXml(el2), scope);
|
|
931
|
+
const prefix = el2.get("prefix");
|
|
932
|
+
const local = el2.get("local");
|
|
933
|
+
const bindings = el2.get("bindings").toArray();
|
|
934
|
+
const attrs = el2.get("attrs").toArray();
|
|
935
|
+
const children = el2.get("children").toArray();
|
|
414
936
|
const inScope = new Map(scope);
|
|
415
937
|
for (const b of bindings) inScope.set(b.prefix, b.ns);
|
|
416
938
|
let out = `<${qualified(prefix, local)}`;
|
|
@@ -458,8 +980,8 @@ function canonicalToXml(node) {
|
|
|
458
980
|
if (node.prefix !== void 0) xml.prefix = node.prefix;
|
|
459
981
|
return xml;
|
|
460
982
|
}
|
|
461
|
-
function encodeElement(
|
|
462
|
-
return xmlToLive(canonicalToXml(
|
|
983
|
+
function encodeElement(el2) {
|
|
984
|
+
return xmlToLive(canonicalToXml(el2));
|
|
463
985
|
}
|
|
464
986
|
function bootstrap(doc, pkg) {
|
|
465
987
|
doc.transact(() => {
|
|
@@ -644,14 +1166,14 @@ function materialize(doc, cache, changed = null) {
|
|
|
644
1166
|
sinkSafe: validateExternalTarget(r.rawTarget).ok
|
|
645
1167
|
});
|
|
646
1168
|
}
|
|
647
|
-
const
|
|
1169
|
+
const relsName2 = relsPartNameFor(owner);
|
|
648
1170
|
const read = readOoxmlPart(relationshipsXml(records), {
|
|
649
|
-
name:
|
|
1171
|
+
name: relsName2,
|
|
650
1172
|
contentType: RELS_CONTENT_TYPE
|
|
651
1173
|
});
|
|
652
1174
|
if (!read.ok)
|
|
653
1175
|
throw new MaterializeError(`relationships of ${owner} are not valid: ${read.reason}`);
|
|
654
|
-
parts.set(
|
|
1176
|
+
parts.set(relsName2, read.part);
|
|
655
1177
|
}
|
|
656
1178
|
const contentTypes = {
|
|
657
1179
|
defaults: new Map(doc.getMap("ctDefaults")),
|
|
@@ -717,14 +1239,14 @@ var RegistryError = class extends Error {
|
|
|
717
1239
|
this.name = "RegistryError";
|
|
718
1240
|
}
|
|
719
1241
|
};
|
|
720
|
-
function childrenOf(
|
|
721
|
-
return
|
|
1242
|
+
function childrenOf(el2) {
|
|
1243
|
+
return el2.get("children");
|
|
722
1244
|
}
|
|
723
|
-
function attrsOf(
|
|
724
|
-
return
|
|
1245
|
+
function attrsOf(el2) {
|
|
1246
|
+
return el2.get("attrs");
|
|
725
1247
|
}
|
|
726
|
-
function bindingsOf(
|
|
727
|
-
return
|
|
1248
|
+
function bindingsOf(el2) {
|
|
1249
|
+
return el2.get("bindings");
|
|
728
1250
|
}
|
|
729
1251
|
var IDENTIFIED = /* @__PURE__ */ new Set([
|
|
730
1252
|
"r",
|
|
@@ -751,7 +1273,7 @@ function plainToXml(node) {
|
|
|
751
1273
|
children: node.children.map(plainToXml)
|
|
752
1274
|
};
|
|
753
1275
|
if (node.prefix !== void 0) xml.prefix = node.prefix;
|
|
754
|
-
if (node.ns ===
|
|
1276
|
+
if (node.ns === WML2 && IDENTIFIED.has(node.local)) {
|
|
755
1277
|
node.rid ??= newRunId();
|
|
756
1278
|
xml._id = node.rid;
|
|
757
1279
|
}
|
|
@@ -952,7 +1474,7 @@ var NodeRegistry = class {
|
|
|
952
1474
|
const stored = head.toArray().map((child) => liveToXml(child));
|
|
953
1475
|
if (JSON.stringify(stored) !== JSON.stringify(encoded.head)) {
|
|
954
1476
|
head.delete(0, head.length);
|
|
955
|
-
head.push(encoded.head.map((
|
|
1477
|
+
head.push(encoded.head.map((el2) => xmlToLive(el2)));
|
|
956
1478
|
}
|
|
957
1479
|
const inline = live.get("inline");
|
|
958
1480
|
applyUnits(inline, readUnits(inline), encoded.units);
|
|
@@ -1086,14 +1608,14 @@ function attrJson(qname, value) {
|
|
|
1086
1608
|
function setAttribute(registry, id, qname, value) {
|
|
1087
1609
|
const entry = registry.require(id);
|
|
1088
1610
|
if ("plain" in entry) {
|
|
1089
|
-
const
|
|
1090
|
-
const index2 =
|
|
1611
|
+
const el2 = asPlainElement(entry.plain, id);
|
|
1612
|
+
const index2 = el2.attrs.findIndex((a) => sameAttr(a, qname));
|
|
1091
1613
|
if (value === null) {
|
|
1092
|
-
if (index2 >= 0)
|
|
1614
|
+
if (index2 >= 0) el2.attrs.splice(index2, 1);
|
|
1093
1615
|
} else if (index2 >= 0) {
|
|
1094
|
-
|
|
1616
|
+
el2.attrs[index2] = attrJson(qname, value);
|
|
1095
1617
|
} else {
|
|
1096
|
-
|
|
1618
|
+
el2.attrs.push(attrJson(qname, value));
|
|
1097
1619
|
}
|
|
1098
1620
|
return;
|
|
1099
1621
|
}
|
|
@@ -1109,12 +1631,12 @@ function setNamespaceBinding(registry, id, prefix, uri) {
|
|
|
1109
1631
|
const entry = registry.require(id);
|
|
1110
1632
|
const binding = uri === null ? null : { prefix, ns: uri };
|
|
1111
1633
|
if ("plain" in entry) {
|
|
1112
|
-
const
|
|
1113
|
-
const index2 =
|
|
1114
|
-
if (index2 >= 0)
|
|
1634
|
+
const el2 = asPlainElement(entry.plain, id);
|
|
1635
|
+
const index2 = el2.bindings.findIndex((b) => b.prefix === prefix);
|
|
1636
|
+
if (index2 >= 0) el2.bindings.splice(index2, 1);
|
|
1115
1637
|
if (binding) {
|
|
1116
|
-
if (index2 >= 0)
|
|
1117
|
-
else
|
|
1638
|
+
if (index2 >= 0) el2.bindings.splice(index2, 0, binding);
|
|
1639
|
+
else el2.bindings.push(binding);
|
|
1118
1640
|
}
|
|
1119
1641
|
return;
|
|
1120
1642
|
}
|
|
@@ -1837,8 +2359,8 @@ function openRoomStore(options) {
|
|
|
1837
2359
|
return {
|
|
1838
2360
|
store,
|
|
1839
2361
|
session,
|
|
1840
|
-
transact(build) {
|
|
1841
|
-
const result = store.transact(
|
|
2362
|
+
transact(build, scope = { kind: "body" }) {
|
|
2363
|
+
const result = store.transact(scope, build, {
|
|
1842
2364
|
origin: ORIGIN_IDS.mutationAgent,
|
|
1843
2365
|
actorId: options.identity.actorId,
|
|
1844
2366
|
recordsHistory: false
|
|
@@ -1871,7 +2393,94 @@ function openRoomStore(options) {
|
|
|
1871
2393
|
throw error;
|
|
1872
2394
|
}
|
|
1873
2395
|
}
|
|
2396
|
+
function roomCommandsPort(room, { revision, actorId } = {}) {
|
|
2397
|
+
const view = () => room.view();
|
|
2398
|
+
const root = () => view().part().root;
|
|
2399
|
+
const numbering = () => documentNumbering({
|
|
2400
|
+
root,
|
|
2401
|
+
stylesRoot: () => view().stylesRoot(),
|
|
2402
|
+
numberingRoot: () => view().numberingRoot(),
|
|
2403
|
+
settingsRoot: () => view().settingsRoot()
|
|
2404
|
+
});
|
|
2405
|
+
let caret = null;
|
|
2406
|
+
const at = () => {
|
|
2407
|
+
if (!caret) throw new Error("No position to write at.");
|
|
2408
|
+
return caret;
|
|
2409
|
+
};
|
|
2410
|
+
const apply = (op) => {
|
|
2411
|
+
const result = room.transact((ctx) => {
|
|
2412
|
+
ctx.apply(op);
|
|
2413
|
+
});
|
|
2414
|
+
if (!result.ok) throw new Error(`The editor refused the change (${op.op}).`);
|
|
2415
|
+
};
|
|
2416
|
+
const find = (node, id) => {
|
|
2417
|
+
if (node.id === id) return node;
|
|
2418
|
+
for (const child of node.children ?? []) {
|
|
2419
|
+
const found = find(child, id);
|
|
2420
|
+
if (found) return found;
|
|
2421
|
+
}
|
|
2422
|
+
return void 0;
|
|
2423
|
+
};
|
|
2424
|
+
return {
|
|
2425
|
+
paragraphs: () => readParagraphs(root()),
|
|
2426
|
+
caret: () => caret,
|
|
2427
|
+
setCaret: (point) => {
|
|
2428
|
+
caret = point;
|
|
2429
|
+
},
|
|
2430
|
+
deleteRange: (from, to) => {
|
|
2431
|
+
if (from.paragraphId !== to.paragraphId) throw new Error("A deletion stays in one paragraph.");
|
|
2432
|
+
apply({
|
|
2433
|
+
op: "deleteText",
|
|
2434
|
+
paragraphId: from.paragraphId,
|
|
2435
|
+
start: from.offset,
|
|
2436
|
+
end: to.offset,
|
|
2437
|
+
...revision ? { revision } : {}
|
|
2438
|
+
});
|
|
2439
|
+
},
|
|
2440
|
+
paste: (body, _text, covered, relationships) => {
|
|
2441
|
+
const point = at();
|
|
2442
|
+
const defined = documentStyleIds(view().stylesRoot());
|
|
2443
|
+
const styles = stylesUsed(body).filter((id) => !defined.has(id));
|
|
2444
|
+
const result = room.store.applyFragmentPaste(
|
|
2445
|
+
{ kind: "body" },
|
|
2446
|
+
{
|
|
2447
|
+
paragraphId: point.paragraphId,
|
|
2448
|
+
offset: point.offset,
|
|
2449
|
+
fragmentBytes: fragmentPackage(body, covered, { revision, relationships, styles }),
|
|
2450
|
+
lastMarkCovered: covered,
|
|
2451
|
+
actorId
|
|
2452
|
+
}
|
|
2453
|
+
);
|
|
2454
|
+
if (result.ok) room.flush();
|
|
2455
|
+
return result.ok;
|
|
2456
|
+
},
|
|
2457
|
+
splitParagraph: () => {
|
|
2458
|
+
const point = at();
|
|
2459
|
+
apply({ op: "splitParagraph", paragraphId: point.paragraphId, offset: point.offset });
|
|
2460
|
+
const paragraphs = readParagraphs(root());
|
|
2461
|
+
const next = paragraphs[paragraphs.findIndex((p) => p.id === point.paragraphId) + 1];
|
|
2462
|
+
caret = next ? { paragraphId: next.id, offset: 0 } : point;
|
|
2463
|
+
},
|
|
2464
|
+
typeText: (text) => {
|
|
2465
|
+
const point = at();
|
|
2466
|
+
apply({
|
|
2467
|
+
op: "insertText",
|
|
2468
|
+
paragraphId: point.paragraphId,
|
|
2469
|
+
offset: point.offset,
|
|
2470
|
+
text,
|
|
2471
|
+
...revision ? { revision } : {}
|
|
2472
|
+
});
|
|
2473
|
+
caret = { paragraphId: point.paragraphId, offset: point.offset + text.length };
|
|
2474
|
+
},
|
|
2475
|
+
listItems: () => numbering().listItems(),
|
|
2476
|
+
levelOf: (numId, ilvl) => numbering().levelOf(numId, ilvl),
|
|
2477
|
+
runsXml: (paragraphId) => {
|
|
2478
|
+
const node = find(root(), paragraphId);
|
|
2479
|
+
return node ? paragraphRunsXml(node) : null;
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2482
|
+
}
|
|
1874
2483
|
|
|
1875
|
-
export { COLLAB_PROTOCOL, CollaborationCompatibilityError, DOCUMENT_COLLABORATION_VERSIONS, assertCompatibleVersions, assertRoomFormat, normalizeDocx, openRoomAutomation, openRoomStore, readRoom, seedRoom };
|
|
2484
|
+
export { COLLAB_PROTOCOL, CollaborationCompatibilityError, DOCUMENT_COLLABORATION_VERSIONS, assertCompatibleVersions, assertRoomFormat, normalizeDocx, openRoomAutomation, openRoomStore, readRoom, roomCommandsPort, seedRoom };
|
|
1876
2485
|
//# sourceMappingURL=server.js.map
|
|
1877
2486
|
//# sourceMappingURL=server.js.map
|