@w100n/documents 0.16.4 → 0.17.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/{Compare-M57FG4R3.js → Compare-RHAUAKUJ.js} +2 -2
- package/dist/{SheetView-OEKOHMKW.js → SheetView-SBLAFGTL.js} +5 -5
- package/dist/{TextEditor-5S7FSLIZ.js → TextEditor-X2GSL4QM.js} +119 -27
- package/dist/TextEditor-X2GSL4QM.js.map +1 -0
- package/dist/{chunk-AKJGYZME.js → chunk-A6AHJCEK.js} +67 -832
- package/dist/chunk-A6AHJCEK.js.map +1 -0
- package/dist/{chunk-3D2G5NBI.js → chunk-ASTNK6WZ.js} +2 -2
- package/dist/{chunk-VNXZVOPN.js → chunk-B7C6NBBQ.js} +929 -1
- package/dist/chunk-B7C6NBBQ.js.map +1 -0
- package/dist/chunk-FFXAOK4A.js +39 -0
- package/dist/chunk-FFXAOK4A.js.map +1 -0
- package/dist/{chunk-EQLBYW42.js → chunk-GSIPTCQH.js} +9 -1
- package/dist/chunk-GSIPTCQH.js.map +1 -0
- package/dist/collab.cjs +170 -2
- package/dist/collab.cjs.map +1 -1
- package/dist/collab.d.cts +1 -1
- package/dist/collab.d.ts +1 -1
- package/dist/collab.js +3 -3
- package/dist/index.cjs +1204 -540
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +313 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +871 -494
- package/dist/index.js.map +1 -1
- package/dist/kinds.d.cts +1 -1
- package/dist/kinds.d.ts +1 -1
- package/dist/memory.cjs +3 -2
- package/dist/memory.cjs.map +1 -1
- package/dist/memory.d.cts +1 -1
- package/dist/memory.d.ts +1 -1
- package/dist/memory.js +3 -2
- package/dist/memory.js.map +1 -1
- package/dist/{types-BUO0OzOl.d.cts → types-CHmV8GLx.d.cts} +1 -0
- package/dist/{types-BUO0OzOl.d.ts → types-CHmV8GLx.d.ts} +1 -0
- package/package.json +1 -1
- package/dist/TextEditor-5S7FSLIZ.js.map +0 -1
- package/dist/chunk-AKJGYZME.js.map +0 -1
- package/dist/chunk-EQLBYW42.js.map +0 -1
- package/dist/chunk-VNXZVOPN.js.map +0 -1
- /package/dist/{Compare-M57FG4R3.js.map → Compare-RHAUAKUJ.js.map} +0 -0
- /package/dist/{SheetView-OEKOHMKW.js.map → SheetView-SBLAFGTL.js.map} +0 -0
- /package/dist/{chunk-3D2G5NBI.js.map → chunk-ASTNK6WZ.js.map} +0 -0
|
@@ -3,17 +3,17 @@ import {
|
|
|
3
3
|
fromMarkdown,
|
|
4
4
|
toMarkdown,
|
|
5
5
|
track
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GSIPTCQH.js";
|
|
7
7
|
import {
|
|
8
|
+
kit,
|
|
8
9
|
texts
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-B7C6NBBQ.js";
|
|
10
11
|
import {
|
|
11
12
|
attr,
|
|
12
13
|
attrs,
|
|
13
14
|
entry,
|
|
14
15
|
escape,
|
|
15
16
|
inflate,
|
|
16
|
-
mathml,
|
|
17
17
|
parse,
|
|
18
18
|
readDocx,
|
|
19
19
|
unescape,
|
|
@@ -43,755 +43,7 @@ import { prosemirrorJSONToYXmlFragment, updateYFragment, yXmlFragmentToProseMirr
|
|
|
43
43
|
import * as Y2 from "yjs";
|
|
44
44
|
|
|
45
45
|
// package.json
|
|
46
|
-
var version = "0.
|
|
47
|
-
|
|
48
|
-
// src/editor/extensions.ts
|
|
49
|
-
import { Extension as Extension2, Mark, Node } from "@tiptap/core";
|
|
50
|
-
import Collaboration from "@tiptap/extension-collaboration";
|
|
51
|
-
import CollaborationCaret from "@tiptap/extension-collaboration-caret";
|
|
52
|
-
import Highlight from "@tiptap/extension-highlight";
|
|
53
|
-
import Image from "@tiptap/extension-image";
|
|
54
|
-
import { TaskItem, TaskList } from "@tiptap/extension-list";
|
|
55
|
-
import { TableKit } from "@tiptap/extension-table";
|
|
56
|
-
import { Color, FontFamily, FontSize, TextStyle } from "@tiptap/extension-text-style";
|
|
57
|
-
import { Plugin as Plugin2, PluginKey as PluginKey2, TextSelection } from "@tiptap/pm/state";
|
|
58
|
-
import { StepMap } from "@tiptap/pm/transform";
|
|
59
|
-
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
60
|
-
import StarterKit from "@tiptap/starter-kit";
|
|
61
|
-
import { ySyncPluginKey } from "@tiptap/y-tiptap";
|
|
62
|
-
|
|
63
|
-
// src/editor/pager.ts
|
|
64
|
-
import { Extension } from "@tiptap/core";
|
|
65
|
-
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
66
|
-
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
67
|
-
var a4 = { width: 793.73, height: 1122.53, margins: [96, 96, 96, 96] };
|
|
68
|
-
var letter = { width: 816, height: 1056 };
|
|
69
|
-
var paging = new PluginKey("w100n-pager");
|
|
70
|
-
var skip = (el) => el.classList.contains("w100n-text-gap") || el.classList.contains("ProseMirror-gapcursor");
|
|
71
|
-
function measure(view) {
|
|
72
|
-
const { page } = paging.getState(view.state);
|
|
73
|
-
const [top, , bottom] = page.margins;
|
|
74
|
-
const room = page.height - top - bottom;
|
|
75
|
-
const els = [...view.dom.children];
|
|
76
|
-
const gaps = [];
|
|
77
|
-
const line = page.width - page.margins[1] - page.margins[3];
|
|
78
|
-
const area = (list) => list.length ? 14 + list.reduce((h, text) => h + 15 * Math.max(1, Math.ceil(text.length * 5.6 / line)), 0) : 0;
|
|
79
|
-
let notes2 = [];
|
|
80
|
-
let count = 0;
|
|
81
|
-
let i = 0;
|
|
82
|
-
let shift = 0;
|
|
83
|
-
let start = 0;
|
|
84
|
-
let last = 0;
|
|
85
|
-
view.state.doc.forEach((node, offset) => {
|
|
86
|
-
let el = els[i++];
|
|
87
|
-
while (el && skip(el)) {
|
|
88
|
-
if (el.classList.contains("w100n-text-gap")) shift += el.offsetHeight;
|
|
89
|
-
el = els[i++];
|
|
90
|
-
}
|
|
91
|
-
if (!el) return;
|
|
92
|
-
const y = el.offsetTop - shift;
|
|
93
|
-
const end = y + el.offsetHeight;
|
|
94
|
-
const mine = [];
|
|
95
|
-
node.descendants((d) => {
|
|
96
|
-
if (d.type.name === "footnote") mine.push(`${count + mine.length + 1} ${d.attrs.text}`);
|
|
97
|
-
});
|
|
98
|
-
if (node.type.name === "pageBreak") {
|
|
99
|
-
gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
|
|
100
|
-
notes2 = [];
|
|
101
|
-
start = end;
|
|
102
|
-
} else if (end > start + room - area([...notes2, ...mine]) && y > start) {
|
|
103
|
-
gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
|
|
104
|
-
notes2 = [];
|
|
105
|
-
start = y;
|
|
106
|
-
}
|
|
107
|
-
notes2.push(...mine);
|
|
108
|
-
count += mine.length;
|
|
109
|
-
while (end > start + room) start += room;
|
|
110
|
-
last = end;
|
|
111
|
-
});
|
|
112
|
-
gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last), page: gaps.length + 1, end: true, notes: notes2 });
|
|
113
|
-
return gaps.map((g) => ({ ...g, height: Math.max(0, Math.round(g.height)) }));
|
|
114
|
-
}
|
|
115
|
-
var Pager = Extension.create({
|
|
116
|
-
name: "pager",
|
|
117
|
-
addProseMirrorPlugins: () => [new Plugin({
|
|
118
|
-
key: paging,
|
|
119
|
-
state: {
|
|
120
|
-
init: () => ({ set: DecorationSet.empty, page: a4, marks: { header: "", footer: "" }, flow: false }),
|
|
121
|
-
apply(tr, value2) {
|
|
122
|
-
const next = tr.getMeta(paging);
|
|
123
|
-
return { set: next?.set ?? value2.set.map(tr.mapping, tr.doc), page: next?.page ?? value2.page, marks: next?.marks ?? value2.marks, flow: next?.flow ?? value2.flow };
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
props: { decorations: (state) => paging.getState(state).set },
|
|
127
|
-
view(view) {
|
|
128
|
-
let timer = 0;
|
|
129
|
-
let sig = "";
|
|
130
|
-
const run = () => {
|
|
131
|
-
if (!view.dom.isConnected) return;
|
|
132
|
-
const { marks, flow } = paging.getState(view.state);
|
|
133
|
-
if (flow) {
|
|
134
|
-
if (sig !== "flow") view.dispatch(view.state.tr.setMeta(paging, { set: DecorationSet.empty }).setMeta("addToHistory", false));
|
|
135
|
-
sig = "flow";
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const gaps = measure(view);
|
|
139
|
-
const next = gaps.map((g) => `${g.pos}:${g.height}:${g.notes.join("\n")}`).join() + `|${marks.header}|${marks.footer}`;
|
|
140
|
-
if (next === sig) return;
|
|
141
|
-
sig = next;
|
|
142
|
-
const line = (parent, cls, text) => {
|
|
143
|
-
if (!text) return;
|
|
144
|
-
const span2 = document.createElement("span");
|
|
145
|
-
span2.className = cls;
|
|
146
|
-
span2.textContent = text;
|
|
147
|
-
parent.append(span2);
|
|
148
|
-
};
|
|
149
|
-
const first = Decoration.widget(0, () => {
|
|
150
|
-
const el = document.createElement("div");
|
|
151
|
-
el.className = "w100n-text-first";
|
|
152
|
-
el.contentEditable = "false";
|
|
153
|
-
line(el, "w100n-text-head", marks.header);
|
|
154
|
-
return el;
|
|
155
|
-
}, { key: `first:${marks.header}`, side: -1, ignoreSelection: true });
|
|
156
|
-
const set = DecorationSet.create(view.state.doc, [first, ...gaps.map((g) => Decoration.widget(g.pos, () => {
|
|
157
|
-
const el = document.createElement("div");
|
|
158
|
-
el.className = g.end ? "w100n-text-gap is-end" : "w100n-text-gap";
|
|
159
|
-
el.style.height = `${g.height}px`;
|
|
160
|
-
el.dataset.page = String(g.page);
|
|
161
|
-
el.contentEditable = "false";
|
|
162
|
-
line(el, "w100n-text-foot", marks.footer);
|
|
163
|
-
if (!g.end) line(el, "w100n-text-head", marks.header);
|
|
164
|
-
if (g.notes.length) {
|
|
165
|
-
const list = document.createElement("div");
|
|
166
|
-
list.className = "w100n-text-footnotes";
|
|
167
|
-
for (const note of g.notes) {
|
|
168
|
-
const p = document.createElement("p");
|
|
169
|
-
const n = document.createElement("sup");
|
|
170
|
-
n.textContent = note.slice(0, note.indexOf(" "));
|
|
171
|
-
p.append(n, note.slice(note.indexOf(" ")));
|
|
172
|
-
list.append(p);
|
|
173
|
-
}
|
|
174
|
-
el.append(list);
|
|
175
|
-
}
|
|
176
|
-
return el;
|
|
177
|
-
}, { key: `${g.pos}:${g.height}:${g.page}:${marks.header}:${marks.footer}:${g.notes.join("\n")}`, side: -1, ignoreSelection: true }))]);
|
|
178
|
-
view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
|
|
179
|
-
};
|
|
180
|
-
const later = (ms) => {
|
|
181
|
-
clearTimeout(timer);
|
|
182
|
-
timer = window.setTimeout(run, ms);
|
|
183
|
-
};
|
|
184
|
-
const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => later(200));
|
|
185
|
-
watch?.observe(view.dom);
|
|
186
|
-
later(0);
|
|
187
|
-
return {
|
|
188
|
-
update: (next, prev) => {
|
|
189
|
-
const now = paging.getState(next.state), was = paging.getState(prev);
|
|
190
|
-
if (now.page !== was.page || now.marks !== was.marks || now.flow !== was.flow) later(0);
|
|
191
|
-
else if (next.state.doc !== prev.doc) later(400);
|
|
192
|
-
},
|
|
193
|
-
destroy: () => {
|
|
194
|
-
clearTimeout(timer);
|
|
195
|
-
watch?.disconnect();
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
})]
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// src/editor/extensions.ts
|
|
203
|
-
var notes = new PluginKey2("w100n-notes");
|
|
204
|
-
var blocks = [
|
|
205
|
-
"paragraph",
|
|
206
|
-
"heading",
|
|
207
|
-
"bulletList",
|
|
208
|
-
"orderedList",
|
|
209
|
-
"listItem",
|
|
210
|
-
"taskList",
|
|
211
|
-
"taskItem",
|
|
212
|
-
"blockquote",
|
|
213
|
-
"codeBlock",
|
|
214
|
-
"horizontalRule",
|
|
215
|
-
"table",
|
|
216
|
-
"tableRow",
|
|
217
|
-
"tableHeader",
|
|
218
|
-
"tableCell",
|
|
219
|
-
"pageBreak",
|
|
220
|
-
"toc"
|
|
221
|
-
];
|
|
222
|
-
var changed = (trs) => {
|
|
223
|
-
const ranges = [];
|
|
224
|
-
trs.forEach((tr, n) => tr.steps.forEach((step, i) => {
|
|
225
|
-
const slice = step.slice;
|
|
226
|
-
if (!slice || !slice.openStart && !slice.openEnd && !slice.content.firstChild?.isBlock) return;
|
|
227
|
-
const after = tr.mapping.slice(i + 1);
|
|
228
|
-
for (const later of trs.slice(n + 1)) after.appendMapping(later.mapping);
|
|
229
|
-
step.getMap().forEach((_a, _b, from, to) => ranges.push([after.map(from, -1), after.map(to, 1)]));
|
|
230
|
-
}));
|
|
231
|
-
return ranges;
|
|
232
|
-
};
|
|
233
|
-
var Cells = Extension2.create({
|
|
234
|
-
name: "cells",
|
|
235
|
-
addGlobalAttributes: () => [
|
|
236
|
-
{ types: ["tableCell", "tableHeader"], attributes: { background: { default: null, parseHTML: (el) => el.dataset.fill ?? null, renderHTML: (attrs2) => attrs2.background ? { "data-fill": attrs2.background, style: `background-color: ${attrs2.background}` } : {} } } },
|
|
237
|
-
{ types: ["table"], attributes: { borders: { default: null, parseHTML: (el) => el.dataset.borders ?? null, renderHTML: (attrs2) => attrs2.borders ? { "data-borders": attrs2.borders } : {} } } }
|
|
238
|
-
]
|
|
239
|
-
});
|
|
240
|
-
var searching = new PluginKey2("w100n-search");
|
|
241
|
-
var lookup = (doc, query, matchCase) => {
|
|
242
|
-
const hits = [];
|
|
243
|
-
if (!query) return hits;
|
|
244
|
-
const needle = matchCase ? query : query.toLowerCase();
|
|
245
|
-
doc.descendants((node, pos) => {
|
|
246
|
-
if (!node.isTextblock) return true;
|
|
247
|
-
let text = "";
|
|
248
|
-
const at = [];
|
|
249
|
-
node.forEach((child, offset) => {
|
|
250
|
-
const part = child.isText ? child.text : "\uFFFC";
|
|
251
|
-
for (let i = 0; i < part.length; i++) at.push(pos + 1 + offset + i);
|
|
252
|
-
text += part;
|
|
253
|
-
});
|
|
254
|
-
const hay = matchCase ? text : text.toLowerCase();
|
|
255
|
-
for (let i = hay.indexOf(needle); i >= 0; i = hay.indexOf(needle, i + needle.length)) hits.push({ from: at[i], to: at[i + needle.length - 1] + 1 });
|
|
256
|
-
return false;
|
|
257
|
-
});
|
|
258
|
-
return hits;
|
|
259
|
-
};
|
|
260
|
-
var Search = Extension2.create({
|
|
261
|
-
name: "search",
|
|
262
|
-
addProseMirrorPlugins: () => [new Plugin2({
|
|
263
|
-
key: searching,
|
|
264
|
-
state: {
|
|
265
|
-
init: () => ({ query: "", matchCase: false, hits: [], at: 0, set: DecorationSet2.empty }),
|
|
266
|
-
apply(tr, value2) {
|
|
267
|
-
const meta = tr.getMeta(searching);
|
|
268
|
-
if (!meta && !tr.docChanged) return value2;
|
|
269
|
-
const next = { ...value2, ...meta };
|
|
270
|
-
const hits = lookup(tr.doc, next.query, next.matchCase);
|
|
271
|
-
const at = hits.length ? (next.at % hits.length + hits.length) % hits.length : 0;
|
|
272
|
-
return { ...next, hits, at, set: DecorationSet2.create(tr.doc, hits.map((h, i) => Decoration2.inline(h.from, h.to, { class: i === at ? "w100n-found is-current" : "w100n-found" }))) };
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
props: { decorations: (state) => searching.getState(state).set }
|
|
276
|
-
})]
|
|
277
|
-
});
|
|
278
|
-
var replace = (editor, text, all) => {
|
|
279
|
-
const { hits, at } = searching.getState(editor.state);
|
|
280
|
-
if (!hits.length) return 0;
|
|
281
|
-
const tr = editor.state.tr;
|
|
282
|
-
for (const hit of all ? [...hits].reverse() : [hits[at]]) tr.insertText(text, hit.from, hit.to);
|
|
283
|
-
editor.view.dispatch(tr);
|
|
284
|
-
return all ? hits.length : 1;
|
|
285
|
-
};
|
|
286
|
-
var cleanPaste = (html) => html.replace(/<!--\[if[\s\S]*?<!\[endif\]-->/g, "").replace(/<o:p>[\s\S]*?<\/o:p>/g, "").replace(/\sclass=("|')?Mso[^"'\s>]*\1?/g, "").replace(/<img\b[^>]*\ssrc=("|')file:[^"']*\1[^>]*>/gi, "").replace(/\sstyle=("|')([^"']*)\1/g, (_, q, css) => {
|
|
287
|
-
const kept = css.split(";").map((x) => x.trim()).filter((x) => x && !/^mso-|^tab-stops|^font-family:\s*["']?(Symbol|Wingdings)/i.test(x)).join("; ");
|
|
288
|
-
return kept ? ` style=${q}${kept}${q}` : "";
|
|
289
|
-
});
|
|
290
|
-
var Blocks = Extension2.create({
|
|
291
|
-
name: "blocks",
|
|
292
|
-
addGlobalAttributes: () => [{
|
|
293
|
-
types: blocks,
|
|
294
|
-
attributes: {
|
|
295
|
-
align: { default: null, parseHTML: (el) => el.style.textAlign || null, renderHTML: (attrs2) => attrs2.align ? { style: `text-align: ${attrs2.align}` } : {} },
|
|
296
|
-
indent: { default: 0, parseHTML: (el) => Number(el.dataset.indent) || 0, renderHTML: (attrs2) => attrs2.indent ? { "data-indent": attrs2.indent, style: `margin-left: ${attrs2.indent * 0.5}in` } : {} },
|
|
297
|
-
line: { default: null, parseHTML: (el) => Number(el.dataset.line) || null, renderHTML: (attrs2) => attrs2.line ? { "data-line": attrs2.line, style: `line-height: ${attrs2.line * 1.15}` } : {} },
|
|
298
|
-
after: { default: null, parseHTML: (el) => el.dataset.after ? Number(el.dataset.after) : null, renderHTML: (attrs2) => attrs2.after === null || attrs2.after === void 0 ? {} : { "data-after": attrs2.after, style: `margin-bottom: ${attrs2.after}pt` } },
|
|
299
|
-
ref: { default: null, rendered: false, keepOnSplit: false }
|
|
300
|
-
}
|
|
301
|
-
}],
|
|
302
|
-
addProseMirrorPlugins: () => [new Plugin2({
|
|
303
|
-
appendTransaction(trs, _old, state) {
|
|
304
|
-
const ranges = changed(trs);
|
|
305
|
-
if (!ranges.length) return null;
|
|
306
|
-
const seen2 = /* @__PURE__ */ new Map();
|
|
307
|
-
const drop = [];
|
|
308
|
-
const visit = (node, pos2) => {
|
|
309
|
-
const ref = node.attrs.ref;
|
|
310
|
-
if (!ref) return;
|
|
311
|
-
const first = seen2.get(ref);
|
|
312
|
-
if (!first) seen2.set(ref, { pos: pos2, node });
|
|
313
|
-
else if (!first.node.textContent && node.textContent) {
|
|
314
|
-
drop.push(first.pos);
|
|
315
|
-
seen2.set(ref, { pos: pos2, node });
|
|
316
|
-
} else drop.push(pos2);
|
|
317
|
-
};
|
|
318
|
-
const from = Math.max(0, Math.min(...ranges.map((r) => r[0])));
|
|
319
|
-
const to = Math.min(state.doc.content.size, Math.max(...ranges.map((r) => r[1])));
|
|
320
|
-
const $from = state.doc.resolve(from);
|
|
321
|
-
const $to = state.doc.resolve(to);
|
|
322
|
-
const start = Math.max(0, $from.index(0) - 1);
|
|
323
|
-
const end = Math.min(state.doc.childCount, $to.index(0) + 2);
|
|
324
|
-
let pos = 0;
|
|
325
|
-
for (let i = 0; i < start; i++) pos += state.doc.child(i).nodeSize;
|
|
326
|
-
for (let i = start; i < end; i++) {
|
|
327
|
-
const top = state.doc.child(i);
|
|
328
|
-
visit(top, pos);
|
|
329
|
-
top.descendants((node, at) => visit(node, pos + 1 + at));
|
|
330
|
-
pos += top.nodeSize;
|
|
331
|
-
}
|
|
332
|
-
if (!drop.length) return null;
|
|
333
|
-
const tr = state.tr;
|
|
334
|
-
for (const at of drop) tr.setNodeAttribute(at, "ref", null);
|
|
335
|
-
return tr;
|
|
336
|
-
}
|
|
337
|
-
})]
|
|
338
|
-
});
|
|
339
|
-
var PageBreak = Node.create({
|
|
340
|
-
name: "pageBreak",
|
|
341
|
-
group: "block",
|
|
342
|
-
atom: true,
|
|
343
|
-
selectable: true,
|
|
344
|
-
addOptions: () => ({ label: "" }),
|
|
345
|
-
parseHTML: () => [{ tag: "div[data-page-break]" }],
|
|
346
|
-
renderHTML() {
|
|
347
|
-
return ["div", { "data-page-break": "", "data-label": this.options.label, class: "w100n-text-break", contenteditable: "false" }];
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
var Formula = Node.create({
|
|
351
|
-
name: "math",
|
|
352
|
-
group: "inline",
|
|
353
|
-
inline: true,
|
|
354
|
-
atom: true,
|
|
355
|
-
selectable: true,
|
|
356
|
-
addAttributes: () => ({ latex: { default: "", parseHTML: (el) => el.getAttribute("data-math") ?? "" } }),
|
|
357
|
-
parseHTML: () => [{ tag: "span[data-math]" }],
|
|
358
|
-
renderHTML: ({ node }) => ["span", { "data-math": node.attrs.latex, class: "w100n-math" }],
|
|
359
|
-
addNodeView: () => ({ node }) => {
|
|
360
|
-
const dom = document.createElement("span");
|
|
361
|
-
dom.className = "w100n-math";
|
|
362
|
-
dom.dataset.math = node.attrs.latex;
|
|
363
|
-
dom.contentEditable = "false";
|
|
364
|
-
dom.innerHTML = mathml(node.attrs.latex);
|
|
365
|
-
return { dom };
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
var Footnote = Node.create({
|
|
369
|
-
name: "footnote",
|
|
370
|
-
group: "inline",
|
|
371
|
-
inline: true,
|
|
372
|
-
atom: true,
|
|
373
|
-
selectable: true,
|
|
374
|
-
addAttributes: () => ({
|
|
375
|
-
id: { default: null, parseHTML: (el) => el.getAttribute("data-note-id") },
|
|
376
|
-
text: { default: "", parseHTML: (el) => el.getAttribute("title") ?? "" }
|
|
377
|
-
}),
|
|
378
|
-
parseHTML: () => [{ tag: "sup[data-footnote]" }],
|
|
379
|
-
renderHTML: ({ node }) => ["sup", { "data-footnote": "", "data-note-id": node.attrs.id ?? void 0, title: node.attrs.text, class: "w100n-fn", contenteditable: "false" }]
|
|
380
|
-
});
|
|
381
|
-
var EndNotes = Extension2.create({
|
|
382
|
-
name: "endNotes",
|
|
383
|
-
addProseMirrorPlugins: () => [new Plugin2({
|
|
384
|
-
props: {
|
|
385
|
-
decorations(state) {
|
|
386
|
-
const notes2 = [];
|
|
387
|
-
state.doc.descendants((n) => {
|
|
388
|
-
if (n.type.name === "footnote") notes2.push(n.attrs.text);
|
|
389
|
-
});
|
|
390
|
-
if (!notes2.length) return null;
|
|
391
|
-
return DecorationSet2.create(state.doc, [Decoration2.widget(state.doc.content.size, () => {
|
|
392
|
-
const list = document.createElement("div");
|
|
393
|
-
list.className = "w100n-text-endnotes";
|
|
394
|
-
list.contentEditable = "false";
|
|
395
|
-
notes2.forEach((text, i) => {
|
|
396
|
-
const p = list.appendChild(document.createElement("p"));
|
|
397
|
-
p.appendChild(document.createElement("sup")).textContent = String(i + 1);
|
|
398
|
-
p.append(text);
|
|
399
|
-
});
|
|
400
|
-
return list;
|
|
401
|
-
}, { key: notes2.join("\n"), side: 1, ignoreSelection: true })]);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
})]
|
|
405
|
-
});
|
|
406
|
-
var headings = (doc, after) => {
|
|
407
|
-
const found = [];
|
|
408
|
-
doc.descendants((node, pos) => {
|
|
409
|
-
if (pos > after && node.type.name === "heading" && node.attrs.level <= 3 && node.textContent.trim()) found.push({ pos, level: node.attrs.level, text: node.textContent.trim() });
|
|
410
|
-
return !node.isTextblock;
|
|
411
|
-
});
|
|
412
|
-
return found;
|
|
413
|
-
};
|
|
414
|
-
function entries(doc, relative2, after) {
|
|
415
|
-
const list = headings(doc, after).map((h) => [h.level, h.text]);
|
|
416
|
-
const top = relative2 && list.length ? Math.min(...list.map(([level]) => level)) - 1 : 0;
|
|
417
|
-
return list.map(([level, text]) => [level - top, text]);
|
|
418
|
-
}
|
|
419
|
-
var Toc = Node.create({
|
|
420
|
-
name: "toc",
|
|
421
|
-
group: "block",
|
|
422
|
-
atom: true,
|
|
423
|
-
selectable: true,
|
|
424
|
-
addOptions: () => ({ relative: false, label: "", empty: "" }),
|
|
425
|
-
addAttributes: () => ({ entries: { default: "[]" }, title: { default: null } }),
|
|
426
|
-
parseHTML: () => [{ tag: "nav[data-toc]" }],
|
|
427
|
-
renderHTML() {
|
|
428
|
-
return ["nav", { "data-toc": "", class: "w100n-text-toc" }];
|
|
429
|
-
},
|
|
430
|
-
addNodeView() {
|
|
431
|
-
return ({ editor, getPos }) => {
|
|
432
|
-
const dom = document.createElement("nav");
|
|
433
|
-
dom.className = "w100n-text-toc";
|
|
434
|
-
dom.contentEditable = "false";
|
|
435
|
-
const paint2 = () => {
|
|
436
|
-
const at = getPos() ?? 0;
|
|
437
|
-
const list = entries(editor.state.doc, this.options.relative, at);
|
|
438
|
-
const head = document.createElement("b");
|
|
439
|
-
head.textContent = this.options.label;
|
|
440
|
-
const items = list.map(([level, text], i) => {
|
|
441
|
-
const go = document.createElement("button");
|
|
442
|
-
go.type = "button";
|
|
443
|
-
go.textContent = text;
|
|
444
|
-
go.dataset.level = String(level);
|
|
445
|
-
go.onclick = () => {
|
|
446
|
-
const hit = headings(editor.state.doc, getPos() ?? 0)[i];
|
|
447
|
-
if (hit) editor.view.nodeDOM(hit.pos)?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
448
|
-
};
|
|
449
|
-
return go;
|
|
450
|
-
});
|
|
451
|
-
const empty = document.createElement("small");
|
|
452
|
-
empty.textContent = this.options.empty;
|
|
453
|
-
dom.replaceChildren(head, ...items.length ? items : [empty]);
|
|
454
|
-
};
|
|
455
|
-
paint2();
|
|
456
|
-
return {
|
|
457
|
-
dom,
|
|
458
|
-
update: (node) => {
|
|
459
|
-
if (node.type.name !== "toc") return false;
|
|
460
|
-
paint2();
|
|
461
|
-
return true;
|
|
462
|
-
},
|
|
463
|
-
ignoreMutation: () => true
|
|
464
|
-
};
|
|
465
|
-
};
|
|
466
|
-
},
|
|
467
|
-
addProseMirrorPlugins() {
|
|
468
|
-
const relative2 = this.options.relative;
|
|
469
|
-
return [new Plugin2({
|
|
470
|
-
appendTransaction(trs, _old, state) {
|
|
471
|
-
if (!trs.some((tr2) => tr2.docChanged && !tr2.getMeta(ySyncPluginKey))) return null;
|
|
472
|
-
const at = [];
|
|
473
|
-
state.doc.forEach((node, pos) => {
|
|
474
|
-
if (node.type.name === "toc") at.push(pos);
|
|
475
|
-
});
|
|
476
|
-
if (!at.length) return null;
|
|
477
|
-
const tr = state.tr;
|
|
478
|
-
for (const pos of at) {
|
|
479
|
-
const fresh2 = JSON.stringify(entries(state.doc, relative2, pos));
|
|
480
|
-
if (state.doc.nodeAt(pos).attrs.entries !== fresh2) tr.setNodeAttribute(pos, "entries", fresh2);
|
|
481
|
-
}
|
|
482
|
-
return tr.docChanged ? tr : null;
|
|
483
|
-
}
|
|
484
|
-
})];
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
var revision = (name, tag) => Mark.create({
|
|
488
|
-
name,
|
|
489
|
-
inclusive: false,
|
|
490
|
-
excludes: "insertion deletion",
|
|
491
|
-
addAttributes: () => ({ id: { default: null }, author: { default: "" }, date: { default: "" } }),
|
|
492
|
-
parseHTML: () => [{ tag: `${tag}[data-rev]` }],
|
|
493
|
-
renderHTML: ({ HTMLAttributes }) => [tag, { "data-rev": HTMLAttributes.id, class: "w100n-text-rev", title: HTMLAttributes.author }, 0]
|
|
494
|
-
});
|
|
495
|
-
var seen = /* @__PURE__ */ new WeakMap();
|
|
496
|
-
function changes(doc) {
|
|
497
|
-
const hit = seen.get(doc);
|
|
498
|
-
if (hit) return hit;
|
|
499
|
-
const out = [];
|
|
500
|
-
doc.descendants((node, pos) => {
|
|
501
|
-
if (!node.isText) return;
|
|
502
|
-
const mark = node.marks.find((m) => m.type.name === "insertion" || m.type.name === "deletion");
|
|
503
|
-
if (!mark) return;
|
|
504
|
-
const last = out[out.length - 1];
|
|
505
|
-
if (last && last.id === mark.attrs.id && last.kind === mark.type.name && last.to === pos) Object.assign(last, { text: last.text + node.text, to: pos + node.nodeSize });
|
|
506
|
-
else out.push({ id: mark.attrs.id, kind: mark.type.name, author: mark.attrs.author, date: mark.attrs.date, text: node.text, from: pos, to: pos + node.nodeSize });
|
|
507
|
-
});
|
|
508
|
-
seen.set(doc, out);
|
|
509
|
-
return out;
|
|
510
|
-
}
|
|
511
|
-
function decide(editor, accept, id) {
|
|
512
|
-
const { state } = editor;
|
|
513
|
-
const tr = state.tr;
|
|
514
|
-
for (const c of changes(state.doc).filter((c2) => !id || c2.id === id).reverse()) {
|
|
515
|
-
if (c.kind === "insertion" === accept) tr.removeMark(c.from, c.to, state.schema.marks[c.kind].create({ id: c.id, author: c.author, date: c.date }));
|
|
516
|
-
else tr.delete(c.from, c.to);
|
|
517
|
-
}
|
|
518
|
-
if (tr.docChanged) editor.view.dispatch(tr);
|
|
519
|
-
}
|
|
520
|
-
var suggesting = new PluginKey2("w100n-suggest");
|
|
521
|
-
var Suggest = Extension2.create({
|
|
522
|
-
name: "suggest",
|
|
523
|
-
addProseMirrorPlugins() {
|
|
524
|
-
const stamp = (state, kind, from, to) => {
|
|
525
|
-
const me = suggesting.getState(state).me;
|
|
526
|
-
const own = [state.doc.resolve(from).nodeBefore, state.doc.resolve(to).nodeAfter].flatMap((n) => n?.marks ?? []).find((m) => m.type.name === kind && m.attrs.author === me);
|
|
527
|
-
return state.schema.marks[kind].create(own ? own.attrs : { id: Math.random().toString(36).slice(2, 10), author: me, date: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z") });
|
|
528
|
-
};
|
|
529
|
-
const strike = (tr, state, from, to) => {
|
|
530
|
-
const parts2 = [];
|
|
531
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
532
|
-
if (!node.isText) return;
|
|
533
|
-
const a = Math.max(from, pos), b = Math.min(to, pos + node.nodeSize);
|
|
534
|
-
if (b > a && !node.marks.some((m) => m.type.name === "deletion")) parts2.push({ from: a, to: b, added: node.marks.some((m) => m.type.name === "insertion") });
|
|
535
|
-
});
|
|
536
|
-
const mark = stamp(state, "deletion", from, to);
|
|
537
|
-
for (const p of parts2.reverse()) {
|
|
538
|
-
if (p.added) tr.delete(p.from, p.to);
|
|
539
|
-
else tr.addMark(p.from, p.to, mark);
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
|
-
const type = (view, from, to, text) => {
|
|
543
|
-
const { state } = view;
|
|
544
|
-
const tr = state.tr;
|
|
545
|
-
if (to > from) strike(tr, state, from, to);
|
|
546
|
-
const at = tr.mapping.map(to);
|
|
547
|
-
const kept = (state.storedMarks ?? state.doc.resolve(from).marks()).filter((m) => m.type.name !== "insertion" && m.type.name !== "deletion");
|
|
548
|
-
tr.insert(at, state.schema.text(text, [...kept, stamp(state, "insertion", from, to)]));
|
|
549
|
-
tr.setSelection(TextSelection.create(tr.doc, at + text.length));
|
|
550
|
-
view.dispatch(tr.scrollIntoView());
|
|
551
|
-
return true;
|
|
552
|
-
};
|
|
553
|
-
return [new Plugin2({
|
|
554
|
-
key: suggesting,
|
|
555
|
-
state: {
|
|
556
|
-
init: () => ({ on: false, me: "" }),
|
|
557
|
-
apply: (tr, value2) => tr.getMeta(suggesting) ?? value2
|
|
558
|
-
},
|
|
559
|
-
props: {
|
|
560
|
-
handleTextInput(view, from, to, text) {
|
|
561
|
-
return suggesting.getState(view.state).on && type(view, from, to, text);
|
|
562
|
-
},
|
|
563
|
-
handlePaste(view, _event, slice) {
|
|
564
|
-
if (!suggesting.getState(view.state).on) return false;
|
|
565
|
-
const { from, to } = view.state.selection;
|
|
566
|
-
return type(view, from, to, slice.content.textBetween(0, slice.content.size, "\n"));
|
|
567
|
-
},
|
|
568
|
-
handleKeyDown(view, event) {
|
|
569
|
-
const { state } = view;
|
|
570
|
-
if (!suggesting.getState(state).on || event.key !== "Backspace" && event.key !== "Delete" || event.metaKey || event.ctrlKey || event.altKey) return false;
|
|
571
|
-
const { from, to, empty, $from } = state.selection;
|
|
572
|
-
const back = event.key === "Backspace";
|
|
573
|
-
let at = from;
|
|
574
|
-
if (empty) {
|
|
575
|
-
const skip2 = (pos) => state.doc.resolve(pos)[back ? "nodeBefore" : "nodeAfter"]?.marks.some((m) => m.type.name === "deletion");
|
|
576
|
-
while (skip2(at)) at += back ? -1 : 1;
|
|
577
|
-
if (back ? at <= $from.start() : at >= $from.end()) return false;
|
|
578
|
-
}
|
|
579
|
-
const tr = state.tr;
|
|
580
|
-
if (empty) strike(tr, state, back ? at - 1 : at, back ? at : at + 1);
|
|
581
|
-
else strike(tr, state, from, to);
|
|
582
|
-
const caret = empty ? tr.mapping.map(back ? at - 1 : at + 1, back ? -1 : 1) : tr.mapping.map(back ? from : to);
|
|
583
|
-
tr.setSelection(TextSelection.create(tr.doc, caret));
|
|
584
|
-
view.dispatch(tr.scrollIntoView());
|
|
585
|
-
return true;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
})];
|
|
589
|
-
}
|
|
590
|
-
});
|
|
591
|
-
var Note = Mark.create({
|
|
592
|
-
name: "comment",
|
|
593
|
-
inclusive: false,
|
|
594
|
-
excludes: "",
|
|
595
|
-
addAttributes: () => ({ id: { default: null, renderHTML: (attrs2) => ({ "data-comment": attrs2.id }) } }),
|
|
596
|
-
renderHTML: ({ HTMLAttributes }) => ["span", HTMLAttributes, 0]
|
|
597
|
-
});
|
|
598
|
-
var locks = new PluginKey2("w100n-locks");
|
|
599
|
-
var locked = (node) => node.type.name === "paragraph" && String(node.attrs.ref ?? "").startsWith("lock:");
|
|
600
|
-
var scan = (doc) => {
|
|
601
|
-
const spans = [];
|
|
602
|
-
doc.descendants((node, pos) => {
|
|
603
|
-
if (!locked(node)) return true;
|
|
604
|
-
spans.push({ from: pos, to: pos + node.nodeSize });
|
|
605
|
-
return false;
|
|
606
|
-
});
|
|
607
|
-
return spans;
|
|
608
|
-
};
|
|
609
|
-
var Locks = Extension2.create({
|
|
610
|
-
name: "locks",
|
|
611
|
-
addOptions: () => ({ label: "" }),
|
|
612
|
-
addProseMirrorPlugins() {
|
|
613
|
-
const shade = (doc, spans) => DecorationSet2.create(doc, spans.map((s) => Decoration2.node(s.from, s.to, { class: "w100n-text-lock", contenteditable: "false", "data-label": this.options.label })));
|
|
614
|
-
return [new Plugin2({
|
|
615
|
-
key: locks,
|
|
616
|
-
state: {
|
|
617
|
-
init: (_config, state) => {
|
|
618
|
-
const spans = scan(state.doc);
|
|
619
|
-
return { spans, set: shade(state.doc, spans) };
|
|
620
|
-
},
|
|
621
|
-
apply(tr, value2) {
|
|
622
|
-
if (!tr.docChanged) return value2;
|
|
623
|
-
const fresh2 = tr.steps.some((step) => {
|
|
624
|
-
let found = false;
|
|
625
|
-
step.slice?.content.descendants((node) => {
|
|
626
|
-
found || (found = locked(node));
|
|
627
|
-
return !found;
|
|
628
|
-
});
|
|
629
|
-
return found;
|
|
630
|
-
});
|
|
631
|
-
const spans = fresh2 ? scan(tr.doc) : value2.spans.map((s) => ({ from: tr.mapping.map(s.from, 1), to: tr.mapping.map(s.to, -1) })).filter((s) => s.to > s.from);
|
|
632
|
-
return { spans, set: spans.length ? shade(tr.doc, spans) : DecorationSet2.empty };
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
filterTransaction(tr, state) {
|
|
636
|
-
let spans = locks.getState(state).spans;
|
|
637
|
-
if (!spans.length || !tr.docChanged) return true;
|
|
638
|
-
return tr.mapping.maps.every((map) => {
|
|
639
|
-
let ok = true;
|
|
640
|
-
map.forEach((from, to) => {
|
|
641
|
-
for (const s of spans) if ((from < s.to && to > s.from || from > s.from && from < s.to) && !(from <= s.from && to >= s.to)) ok = false;
|
|
642
|
-
});
|
|
643
|
-
spans = spans.map((s) => ({ from: map.map(s.from, 1), to: map.map(s.to, -1) }));
|
|
644
|
-
return ok;
|
|
645
|
-
});
|
|
646
|
-
},
|
|
647
|
-
props: {
|
|
648
|
-
decorations: (state) => locks.getState(state).set,
|
|
649
|
-
handleKeyDown(view, event) {
|
|
650
|
-
const back = event.key === "Backspace";
|
|
651
|
-
const { $from, empty } = view.state.selection;
|
|
652
|
-
if (!back && event.key !== "Delete" || !empty || $from.depth < 1) return false;
|
|
653
|
-
if (back ? $from.parentOffset !== 0 : $from.parentOffset !== $from.parent.content.size) return false;
|
|
654
|
-
const at = back ? $from.before() : $from.after();
|
|
655
|
-
const node = back ? view.state.doc.resolve(at).nodeBefore : view.state.doc.resolve(at).nodeAfter;
|
|
656
|
-
if (!node || !locked(node)) return false;
|
|
657
|
-
view.dispatch(view.state.tr.delete(back ? at - node.nodeSize : at, back ? at : at + node.nodeSize));
|
|
658
|
-
return true;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
})];
|
|
662
|
-
}
|
|
663
|
-
});
|
|
664
|
-
var paint = (doc, spots, active, pending2) => DecorationSet2.create(doc, [
|
|
665
|
-
...spots.filter((s) => s.to > s.from).map((s) => Decoration2.inline(s.from, s.to, { class: s.id === active ? "w100n-text-note is-active" : "w100n-text-note", "data-note": s.id })),
|
|
666
|
-
...pending2 && pending2.to > pending2.from ? [Decoration2.inline(pending2.from, pending2.to, { class: "w100n-text-note is-active" })] : []
|
|
667
|
-
]);
|
|
668
|
-
var remap = (tr) => {
|
|
669
|
-
const start = tr.before.content.findDiffStart(tr.doc.content);
|
|
670
|
-
if (!tr.getMeta(ySyncPluginKey) || start === null) return tr.mapping;
|
|
671
|
-
let { a, b } = tr.before.content.findDiffEnd(tr.doc.content);
|
|
672
|
-
if (a < start) [a, b] = [start, b + start - a];
|
|
673
|
-
if (b < start) [a, b] = [a + start - b, start];
|
|
674
|
-
return new StepMap([start, a - start, b - start]);
|
|
675
|
-
};
|
|
676
|
-
var Notes = Extension2.create({
|
|
677
|
-
name: "notes",
|
|
678
|
-
addProseMirrorPlugins: () => [new Plugin2({
|
|
679
|
-
key: notes,
|
|
680
|
-
state: {
|
|
681
|
-
init: (_config, state) => ({ spots: [], active: null, pending: null, set: DecorationSet2.create(state.doc, []) }),
|
|
682
|
-
apply(tr, value2) {
|
|
683
|
-
const next = tr.getMeta(notes);
|
|
684
|
-
if (!next && (!tr.docChanged || !value2.spots.length && !value2.pending)) return value2;
|
|
685
|
-
const by = remap(tr);
|
|
686
|
-
const map = (r) => ({ ...r, from: by.map(r.from, 1), to: by.map(r.to, -1) });
|
|
687
|
-
const merged = { ...value2, spots: value2.spots.map(map), pending: value2.pending && map(value2.pending), ...next };
|
|
688
|
-
return { ...merged, set: paint(tr.doc, merged.spots, merged.active, merged.pending) };
|
|
689
|
-
}
|
|
690
|
-
},
|
|
691
|
-
props: { decorations: (state) => notes.getState(state).set }
|
|
692
|
-
})]
|
|
693
|
-
});
|
|
694
|
-
var script = (name, tag, other) => Mark.create({
|
|
695
|
-
name,
|
|
696
|
-
excludes: other,
|
|
697
|
-
parseHTML: () => [{ tag }, { style: `vertical-align=${name === "superscript" ? "super" : "sub"}` }],
|
|
698
|
-
renderHTML: () => [tag, 0],
|
|
699
|
-
addKeyboardShortcuts() {
|
|
700
|
-
return { [name === "superscript" ? "Mod-." : "Mod-,"]: () => this.editor.commands.toggleMark(name) };
|
|
701
|
-
}
|
|
702
|
-
});
|
|
703
|
-
function kit(kind, t, live) {
|
|
704
|
-
return [
|
|
705
|
-
StarterKit.configure({ trailingNode: false, link: { openOnClick: false, autolink: true, defaultProtocol: "https" }, dropcursor: { color: "#8b5cf6", width: 2 }, ...live ? { undoRedo: false } : {} }),
|
|
706
|
-
TaskList,
|
|
707
|
-
TaskItem.configure({ nested: true, a11y: { checkboxLabel: (node) => node.textContent || t.tasks } }),
|
|
708
|
-
TableKit.configure({ table: { resizable: true, cellMinWidth: 32 } }),
|
|
709
|
-
Cells,
|
|
710
|
-
Search,
|
|
711
|
-
Image.extend({
|
|
712
|
-
addAttributes() {
|
|
713
|
-
return { ...this.parent?.(), wrap: { default: null, parseHTML: (el) => el.dataset.wrap ?? null, renderHTML: (attrs2) => attrs2.wrap ? { "data-wrap": attrs2.wrap } : {} } };
|
|
714
|
-
}
|
|
715
|
-
}).configure({ inline: true, allowBase64: true, resize: { enabled: true, directions: ["top-left", "top-right", "bottom-left", "bottom-right"], minWidth: 24, minHeight: 24, alwaysPreserveAspectRatio: true } }),
|
|
716
|
-
Highlight.configure({ multicolor: true }),
|
|
717
|
-
TextStyle,
|
|
718
|
-
Color,
|
|
719
|
-
FontSize,
|
|
720
|
-
FontFamily,
|
|
721
|
-
script("superscript", "sup", "subscript"),
|
|
722
|
-
script("subscript", "sub", "superscript"),
|
|
723
|
-
Blocks,
|
|
724
|
-
PageBreak.configure({ label: t.pageBreak }),
|
|
725
|
-
Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
|
|
726
|
-
Note,
|
|
727
|
-
Notes,
|
|
728
|
-
Formula,
|
|
729
|
-
Footnote,
|
|
730
|
-
EndNotes,
|
|
731
|
-
...kind === "docx" ? [Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
|
|
732
|
-
...live ? [Collaboration.configure({ document: live.doc }), CollaborationCaret.configure({ provider: live.link, user: live.user })] : []
|
|
733
|
-
];
|
|
734
|
-
}
|
|
735
|
-
var textblocks = (editor, change) => editor.chain().focus().command(({ tr, state }) => {
|
|
736
|
-
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
|
|
737
|
-
if (!node.isTextblock) return true;
|
|
738
|
-
for (const [key2, value2] of Object.entries(change(node.attrs))) if (node.attrs[key2] !== value2) tr.setNodeAttribute(pos, key2, value2);
|
|
739
|
-
return false;
|
|
740
|
-
});
|
|
741
|
-
return true;
|
|
742
|
-
}).run();
|
|
743
|
-
var align = (editor, value2) => textblocks(editor, () => ({ align: value2 === "left" ? null : value2 }));
|
|
744
|
-
var spacing = (editor, change) => textblocks(editor, () => change);
|
|
745
|
-
var indent = (editor, step) => {
|
|
746
|
-
const type = editor.isActive("taskItem") ? "taskItem" : editor.isActive("listItem") ? "listItem" : null;
|
|
747
|
-
if (type) return step > 0 ? editor.chain().focus().sinkListItem(type).run() : editor.chain().focus().liftListItem(type).run();
|
|
748
|
-
return textblocks(editor, (attrs2) => ({ indent: Math.min(8, Math.max(0, Number(attrs2.indent) + step)) }));
|
|
749
|
-
};
|
|
750
|
-
var clear = (editor) => {
|
|
751
|
-
const chain = editor.chain().focus();
|
|
752
|
-
for (const mark of ["bold", "italic", "underline", "strike", "code", "highlight", "textStyle"]) chain.unsetMark(mark);
|
|
753
|
-
chain.run();
|
|
754
|
-
return textblocks(editor, () => ({ align: null, indent: 0 }));
|
|
755
|
-
};
|
|
756
|
-
function locate(doc, list) {
|
|
757
|
-
if (!list.length) return [];
|
|
758
|
-
const marked = /* @__PURE__ */ new Map();
|
|
759
|
-
doc.descendants((node, pos) => {
|
|
760
|
-
if (!node.isText) return;
|
|
761
|
-
for (const mark of node.marks) {
|
|
762
|
-
if (mark.type.name !== "comment") continue;
|
|
763
|
-
const found = marked.get(mark.attrs.id);
|
|
764
|
-
if (found) Object.assign(found, { to: pos + node.nodeSize, text: found.text + node.text });
|
|
765
|
-
else marked.set(mark.attrs.id, { from: pos, to: pos + node.nodeSize, text: node.text });
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
const claimed = /* @__PURE__ */ new Set();
|
|
769
|
-
const search = (quote) => {
|
|
770
|
-
const line = quote.split("\n").find((part) => part.trim())?.trim();
|
|
771
|
-
let hit = null;
|
|
772
|
-
if (line) doc.descendants((node, pos) => {
|
|
773
|
-
if (hit) return false;
|
|
774
|
-
if (!node.isTextblock) return true;
|
|
775
|
-
const at = node.textBetween(0, node.content.size, void 0, "\uFFFC").indexOf(line);
|
|
776
|
-
if (at >= 0) hit = { from: pos + 1 + at, to: pos + 1 + at + line.length };
|
|
777
|
-
return false;
|
|
778
|
-
});
|
|
779
|
-
return hit;
|
|
780
|
-
};
|
|
781
|
-
return list.flatMap((c) => {
|
|
782
|
-
const own = [c.anchor, c.id].find((id) => id && marked.has(id));
|
|
783
|
-
let range = own ? marked.get(own) : void 0;
|
|
784
|
-
if (!range) {
|
|
785
|
-
const twin = [...marked].find(([id, m]) => !claimed.has(id) && m.text === c.quote);
|
|
786
|
-
if (twin) {
|
|
787
|
-
claimed.add(twin[0]);
|
|
788
|
-
range = twin[1];
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
range ?? (range = search(c.quote));
|
|
792
|
-
return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
|
|
793
|
-
});
|
|
794
|
-
}
|
|
46
|
+
var version = "0.17.0";
|
|
795
47
|
|
|
796
48
|
// src/sheets/model.ts
|
|
797
49
|
var SheetRefusal = class extends Error {
|
|
@@ -1051,16 +303,16 @@ var Pack = class {
|
|
|
1051
303
|
}
|
|
1052
304
|
build() {
|
|
1053
305
|
const out = [];
|
|
1054
|
-
const
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1055
307
|
for (const e of this.entries) {
|
|
1056
308
|
const name = e.name.replace(/^\//, "");
|
|
1057
|
-
|
|
309
|
+
seen.add(name);
|
|
1058
310
|
const next = this.changed.get(name);
|
|
1059
311
|
if (next === null) continue;
|
|
1060
312
|
out.push(next === void 0 ? e : entry(e.name, typeof next === "string" ? new TextEncoder().encode(next) : next, e));
|
|
1061
313
|
}
|
|
1062
314
|
const like = this.entries[0];
|
|
1063
|
-
for (const [name, next] of this.changed) if (!
|
|
315
|
+
for (const [name, next] of this.changed) if (!seen.has(name) && next !== null) out.push(entry(name, typeof next === "string" ? new TextEncoder().encode(next) : next, like));
|
|
1064
316
|
return zip(out);
|
|
1065
317
|
}
|
|
1066
318
|
};
|
|
@@ -1363,9 +615,9 @@ var Styles = class {
|
|
|
1363
615
|
if (flags.diagonalUp === "1" || flags.diagonalUp === "true") bd.bl_tr = line;
|
|
1364
616
|
}
|
|
1365
617
|
if (Object.keys(bd).length) s.bd = bd;
|
|
1366
|
-
const
|
|
1367
|
-
if (
|
|
1368
|
-
const al = Object.fromEntries(attrs(
|
|
618
|
+
const align = /<(?:\w+:)?alignment\b[^>]*>/.exec(xf)?.[0];
|
|
619
|
+
if (align) {
|
|
620
|
+
const al = Object.fromEntries(attrs(align));
|
|
1369
621
|
const ht = across.indexOf(al.horizontal === "centerContinuous" ? "center" : al.horizontal);
|
|
1370
622
|
if (ht > 0) s.ht = ht;
|
|
1371
623
|
const vt = down.indexOf(al.vertical);
|
|
@@ -1573,12 +825,12 @@ function load(bytes) {
|
|
|
1573
825
|
const sst = stringsPart ? pack.text(stringsPart) : null;
|
|
1574
826
|
if (sst) for (const m of sst.matchAll(/<(?:\w+:)?si\b[^>]*?(?:\/>|>([\s\S]*?)<\/(?:\w+:)?si>)/g)) strings.push(m[1] ? runs(m[1]) : "");
|
|
1575
827
|
const date1904 = /<(?:\w+:)?workbookPr\b[^>]*\bdate1904="(1|true)"/.test(xml);
|
|
1576
|
-
const
|
|
828
|
+
const entries = [];
|
|
1577
829
|
for (const m of xml.matchAll(/<(?:\w+:)?sheet\b[^>]*\/?>/g)) {
|
|
1578
830
|
const tag = m[0];
|
|
1579
831
|
const rid = /\s[\w]+:id="([^"]*)"/.exec(tag)?.[1] ?? "";
|
|
1580
832
|
const rel = rels.find((r) => r.id === rid);
|
|
1581
|
-
|
|
833
|
+
entries.push({ name: attr2(tag, "name") ?? "", sheetId: Number(attr2(tag, "sheetId")), rid, xml: tag, sheet: rel?.type === "worksheet" });
|
|
1582
834
|
}
|
|
1583
835
|
const book = {
|
|
1584
836
|
id: "book",
|
|
@@ -1592,7 +844,7 @@ function load(bytes) {
|
|
|
1592
844
|
defaultStyle: styles.looks[0]
|
|
1593
845
|
};
|
|
1594
846
|
if (date1904) book.dateSystem = "date1904";
|
|
1595
|
-
const
|
|
847
|
+
const notes = {};
|
|
1596
848
|
const validations = {};
|
|
1597
849
|
const filters = {};
|
|
1598
850
|
const model = { book, lines: {}, origin: { sheets: {}, lines: {} } };
|
|
@@ -1603,7 +855,7 @@ function load(bytes) {
|
|
|
1603
855
|
if (!(id in book.styles)) book.styles[id] = styles.looks[xf] ?? {};
|
|
1604
856
|
return id;
|
|
1605
857
|
};
|
|
1606
|
-
for (const entry2 of
|
|
858
|
+
for (const entry2 of entries) {
|
|
1607
859
|
if (!entry2.sheet) continue;
|
|
1608
860
|
const rel = rels.find((r) => r.id === entry2.rid);
|
|
1609
861
|
const sxml = pack.text(rel.target);
|
|
@@ -1806,7 +1058,7 @@ function load(bytes) {
|
|
|
1806
1058
|
sheetNotes.push(note);
|
|
1807
1059
|
const [r, c] = cell(ref);
|
|
1808
1060
|
if (r < 0) continue;
|
|
1809
|
-
((_b =
|
|
1061
|
+
((_b = notes[sid] ?? (notes[sid] = {}))[r] ?? (_b[r] = {}))[c] = { note: note.text, width: 160, height: 72, show: false, id: `n${sheetNotes.length - 1}`, row: r, col: c };
|
|
1810
1062
|
maxRow = Math.max(maxRow, r);
|
|
1811
1063
|
maxCol = Math.max(maxCol, c);
|
|
1812
1064
|
}
|
|
@@ -1857,18 +1109,18 @@ function load(bytes) {
|
|
|
1857
1109
|
const name = attr2(m[0], "name") ?? "";
|
|
1858
1110
|
if (name.startsWith("_xlnm.") || /^(1|true)$/.test(attr2(m[0], "hidden") ?? "")) continue;
|
|
1859
1111
|
const local = attr2(m[0], "localSheetId");
|
|
1860
|
-
const scoped = local === null ? null :
|
|
1112
|
+
const scoped = local === null ? null : entries[Number(local)];
|
|
1861
1113
|
const id = `d${Object.keys(names).length}`;
|
|
1862
1114
|
names[id] = { id, name, formulaOrRefString: plain(unescape(m[2])), localSheetId: scoped ? `s${scoped.sheetId}` : "AllDefaultWorkbook" };
|
|
1863
1115
|
}
|
|
1864
1116
|
const resources = book.resources;
|
|
1865
1117
|
if (Object.keys(names).length) resources.push({ name: "SHEET_DEFINED_NAME_PLUGIN", data: JSON.stringify(names) });
|
|
1866
|
-
if (Object.keys(
|
|
1118
|
+
if (Object.keys(notes).length) resources.push({ name: "SHEET_NOTE_PLUGIN", data: JSON.stringify(notes) });
|
|
1867
1119
|
if (Object.keys(validations).length) resources.push({ name: "SHEET_DATA_VALIDATION_PLUGIN", data: JSON.stringify(validations) });
|
|
1868
1120
|
if (Object.keys(filters).length) resources.push({ name: "SHEET_FILTER_PLUGIN", data: JSON.stringify(filters) });
|
|
1869
|
-
const shown =
|
|
1121
|
+
const shown = entries[active];
|
|
1870
1122
|
if (shown?.sheet && book.sheetOrder.includes(`s${shown.sheetId}`)) model.active = `s${shown.sheetId}`;
|
|
1871
|
-
return { model, book: { pack, part, xml, rels, styles, stylesPart: stylesPart ?? null, sheets, entries
|
|
1123
|
+
return { model, book: { pack, part, xml, rels, styles, stylesPart: stylesPart ?? null, sheets, entries } };
|
|
1872
1124
|
}
|
|
1873
1125
|
var kinds = { whole: "whole", decimal: "decimal", list: "list", textLength: "textLength", custom: "custom" };
|
|
1874
1126
|
var stops = { information: 0, stop: 1, warning: 2 };
|
|
@@ -2001,7 +1253,7 @@ function equalValue(a, b) {
|
|
|
2001
1253
|
if (typeof a === "number" && typeof b === "number") return a === b || Math.abs(a - b) <= 1e-9 * Math.max(1, Math.abs(a), Math.abs(b));
|
|
2002
1254
|
return a === b;
|
|
2003
1255
|
}
|
|
2004
|
-
function
|
|
1256
|
+
function lookup(book, s) {
|
|
2005
1257
|
if (!s) return {};
|
|
2006
1258
|
return (typeof s === "string" ? book.styles[s] : s) ?? {};
|
|
2007
1259
|
}
|
|
@@ -2153,15 +1405,15 @@ function writeXlsx(original, model) {
|
|
|
2153
1405
|
const fOf = formulas(cells);
|
|
2154
1406
|
const rowStyle = (sh, r) => sh.rowData?.[r]?.s;
|
|
2155
1407
|
const colStyle = (sh, c) => sh.columnData?.[c]?.s;
|
|
2156
|
-
const
|
|
1408
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2157
1409
|
const looks = (bk, sh, r, c, x) => {
|
|
2158
1410
|
const s = x?.s ?? colStyle(sh, c) ?? rowStyle(sh, r);
|
|
2159
1411
|
const id = typeof s === "string" ? (bk === cur ? "c" : "b") + s : "";
|
|
2160
|
-
const known = id &&
|
|
1412
|
+
const known = id && seen.get(id);
|
|
2161
1413
|
if (known) return known;
|
|
2162
|
-
const look = norm({ ...defaults, ...
|
|
1414
|
+
const look = norm({ ...defaults, ...lookup(bk, s) });
|
|
2163
1415
|
const made2 = { look, json: JSON.stringify(look) };
|
|
2164
|
-
if (id)
|
|
1416
|
+
if (id) seen.set(id, made2);
|
|
2165
1417
|
return made2;
|
|
2166
1418
|
};
|
|
2167
1419
|
const xfOf = (s) => typeof s === "string" && /^x\d+$/.test(s) ? Number(s.slice(1)) : 0;
|
|
@@ -2169,7 +1421,7 @@ function writeXlsx(original, model) {
|
|
|
2169
1421
|
if (same(norm(styles.looks[was] ?? {}), look) || was === 0 && same(defaults, look)) return was;
|
|
2170
1422
|
return styles.find(look) ?? styles.derive(was, look);
|
|
2171
1423
|
};
|
|
2172
|
-
let
|
|
1424
|
+
let changed = !rec || rows.moved || cols.moved;
|
|
2173
1425
|
let reused = 0, total = 0;
|
|
2174
1426
|
for (const [r, line] of Object.entries(oldCells)) for (const c of Object.keys(line ?? {})) if (rows.map(+r) >= 0 && cols.map(+c) >= 0) total++;
|
|
2175
1427
|
const body = [];
|
|
@@ -2192,18 +1444,18 @@ function writeXlsx(original, model) {
|
|
|
2192
1444
|
tag = setAttr(tag, "r", String(r + 1));
|
|
2193
1445
|
if (orow && (rows.moved || cols.moved)) tag = setAttr(tag, "spans", null);
|
|
2194
1446
|
if (Math.abs((rd.h ?? -1) - (od.h ?? -1)) > 0.5) {
|
|
2195
|
-
|
|
1447
|
+
changed = true;
|
|
2196
1448
|
tag = setAttr(setAttr(tag, "ht", rd.h === void 0 ? null : String(pt.row(rd.h))), "customHeight", rd.h === void 0 ? null : "1");
|
|
2197
1449
|
}
|
|
2198
1450
|
const hidden = !!rd.hd || filtered.has(r);
|
|
2199
1451
|
if (hidden !== !!od.hd) {
|
|
2200
|
-
|
|
1452
|
+
changed = true;
|
|
2201
1453
|
tag = setAttr(tag, "hidden", hidden ? "1" : null);
|
|
2202
1454
|
}
|
|
2203
|
-
const look = rd.s ? norm({ ...defaults, ...
|
|
2204
|
-
const was = od.s ? norm({ ...defaults, ...
|
|
1455
|
+
const look = rd.s ? norm({ ...defaults, ...lookup(cur, rd.s) }) : null;
|
|
1456
|
+
const was = od.s ? norm({ ...defaults, ...lookup(base.book, od.s) }) : null;
|
|
2205
1457
|
if (!same(look, was)) {
|
|
2206
|
-
|
|
1458
|
+
changed = true;
|
|
2207
1459
|
tag = setAttr(setAttr(tag, "s", look ? String(xfFor(look, xfOf(od.s))) : null), "customFormat", look ? "1" : null);
|
|
2208
1460
|
}
|
|
2209
1461
|
const line = cells[r] ?? {};
|
|
@@ -2224,7 +1476,7 @@ function writeXlsx(original, model) {
|
|
|
2224
1476
|
const raw = xml.slice(orec.start, orec.end);
|
|
2225
1477
|
parts2.push(rows.moved || cols.moved ? raw.replace(/^<[^>]*>/, (t) => setAttr(t, "r", a1(r, c))) : raw);
|
|
2226
1478
|
} else {
|
|
2227
|
-
if (!unchanged)
|
|
1479
|
+
if (!unchanged) changed = true;
|
|
2228
1480
|
const xf = xfFor(look2.look, xfOf(ox?.s ?? colStyle(sheet, c) ?? rowStyle(sheet, r)));
|
|
2229
1481
|
const out = cellXml(p, a1(r, c), xf, x, f, v);
|
|
2230
1482
|
if (!out) continue;
|
|
@@ -2238,7 +1490,7 @@ function writeXlsx(original, model) {
|
|
|
2238
1490
|
if (!parts2.length && !orow && !rd.h && !hidden && !look) continue;
|
|
2239
1491
|
body.push(parts2.length ? `${tag}${parts2.join("")}</${p}row>` : tag.replace(/>$/, "/>"));
|
|
2240
1492
|
}
|
|
2241
|
-
if (rec && reused !== total)
|
|
1493
|
+
if (rec && reused !== total) changed = true;
|
|
2242
1494
|
let head = xml.slice(0, rec ? rec.bounds[0] : xml.indexOf("<sheetData"));
|
|
2243
1495
|
let tail = xml.slice(rec ? rec.bounds[3] : xml.indexOf("<sheetData/>") + 12);
|
|
2244
1496
|
const mine = (s) => s === null || s === rec?.name;
|
|
@@ -2248,33 +1500,33 @@ function writeXlsx(original, model) {
|
|
|
2248
1500
|
}
|
|
2249
1501
|
const colXml = columns(p, rec, sheet, old, cols, defaults, cur, base.book, xfFor, xfOf);
|
|
2250
1502
|
if (colXml !== void 0) {
|
|
2251
|
-
|
|
1503
|
+
changed = true;
|
|
2252
1504
|
head = place(head, "cols", colXml);
|
|
2253
1505
|
}
|
|
2254
1506
|
const merges = (sheet.mergeData ?? []).map((m) => span(m)).sort();
|
|
2255
1507
|
const oldMerges = [...rec?.merges ?? []].map((m) => span(box(m))).sort();
|
|
2256
1508
|
if (!same(merges, oldMerges)) {
|
|
2257
|
-
|
|
1509
|
+
changed = true;
|
|
2258
1510
|
tail = place(tail, "mergeCells", merges.length ? `<${p}mergeCells count="${merges.length}">${merges.map((m) => `<${p}mergeCell ref="${m}"/>`).join("")}</${p}mergeCells>` : null);
|
|
2259
1511
|
}
|
|
2260
1512
|
const freeze = sheet.freeze && (sheet.freeze.xSplit > 0 || sheet.freeze.ySplit > 0) ? [sheet.freeze.xSplit, sheet.freeze.ySplit] : [0, 0];
|
|
2261
1513
|
const oldFreeze = old.freeze ? [old.freeze.xSplit, old.freeze.ySplit] : [0, 0];
|
|
2262
1514
|
if (!same(freeze, oldFreeze)) {
|
|
2263
|
-
|
|
1515
|
+
changed = true;
|
|
2264
1516
|
head = frozen(head, p, freeze[0], freeze[1]);
|
|
2265
1517
|
}
|
|
2266
1518
|
if ((sheet.showGridlines ?? 1) !== (old.showGridlines ?? 1)) {
|
|
2267
|
-
|
|
1519
|
+
changed = true;
|
|
2268
1520
|
head = head.replace(/<(?:\w+:)?sheetView\b[^>]*?>/, (t) => setAttr(t, "showGridLines", sheet.showGridlines === 0 ? "0" : null));
|
|
2269
1521
|
}
|
|
2270
1522
|
if ((sheet.tabColor ?? "") !== (old.tabColor ?? "")) {
|
|
2271
|
-
|
|
1523
|
+
changed = true;
|
|
2272
1524
|
head = tabColour(head, p, sheet.tabColor ?? "");
|
|
2273
1525
|
}
|
|
2274
1526
|
const rules = (curRules ? curRules[sid] ?? [] : rec ? baseRules[rec.sid] ?? [] : []).map((r) => ({ ...r, ranges: r.ranges.map((b) => ({ startRow: b.startRow, startColumn: b.startColumn, endRow: b.endRow, endColumn: b.endColumn })) }));
|
|
2275
1527
|
const oldRules = (rec ? baseRules[rec.sid] ?? [] : []).map((r) => ({ ...r, ranges: r.ranges.map((b) => squeeze(b, rows.map, cols.map)).filter(Boolean) }));
|
|
2276
1528
|
if (curRules && !same(rules.map(canonRule), oldRules.map(canonRule))) {
|
|
2277
|
-
|
|
1529
|
+
changed = true;
|
|
2278
1530
|
const known = new Map((rec?.validations ?? []).map((v, i) => [`dv${i}`, v]));
|
|
2279
1531
|
const shown = new Set(rules.map((r) => r.uid));
|
|
2280
1532
|
const hiddenRules = [...known].filter(([uid, v]) => !shown.has(uid) && !(rec && baseRules[rec.sid]?.some((r) => r.uid === uid)) && v).map(([, v]) => rows.moved || cols.moved ? remapZone(v, mine, rows, cols) : v);
|
|
@@ -2289,19 +1541,19 @@ function writeXlsx(original, model) {
|
|
|
2289
1541
|
return b && span(b);
|
|
2290
1542
|
})() : null;
|
|
2291
1543
|
if (curFilters && (fref !== oref || !same(filter?.filterColumns ?? [], oldFilter?.filterColumns ?? []))) {
|
|
2292
|
-
|
|
1544
|
+
changed = true;
|
|
2293
1545
|
tail = place(tail, "autoFilter", filter?.ref ? filterXml(p, filter.ref, filter.filterColumns ?? []) : null);
|
|
2294
1546
|
filterNames.set(entry2.sheetId, filter?.ref ? `${quoted(sheet.name)}!${span(filter.ref).split(":").map((s) => s.replace(/([A-Z]+)(\d+)/, "$$$1$$$2")).join(":")}` : null);
|
|
2295
1547
|
}
|
|
2296
|
-
const
|
|
1548
|
+
const notes = Object.values(curNotes?.[sid] ?? {}).flatMap((line) => Object.values(line ?? {})).filter((n) => n && !blank(n.note));
|
|
2297
1549
|
const oldNotes = (rec?.notes ?? []).map((n) => ({ ref: n.ref, text: n.text }));
|
|
2298
|
-
const nowNotes =
|
|
1550
|
+
const nowNotes = notes.map((n) => ({ ref: a1(n.row, n.col), text: n.note })).sort((a, b) => a.ref.localeCompare(b.ref));
|
|
2299
1551
|
if (curNotes && !same(nowNotes, [...oldNotes].sort((a, b) => a.ref.localeCompare(b.ref)))) {
|
|
2300
|
-
|
|
2301
|
-
tail = writeNotes(book, entry2, tail, p,
|
|
1552
|
+
changed = true;
|
|
1553
|
+
tail = writeNotes(book, entry2, tail, p, notes, rows, cols, types, defaultsNeeded, fresh2);
|
|
2302
1554
|
}
|
|
2303
1555
|
const rename = (s) => names.size ? s.replace(/<(xm:f|(?:\w+:)?formula\d?)>([\s\S]*?)<\/\1>/g, (_, n, f) => `<${n}>${escape([...names].reduce((g, [from, to]) => renamed(g, from, to), unescape(f)))}</${n}>`) : s;
|
|
2304
|
-
if (!
|
|
1556
|
+
if (!changed) {
|
|
2305
1557
|
if (rec && rename(xml) !== xml) pack.put(entry2.part, rename(xml));
|
|
2306
1558
|
continue;
|
|
2307
1559
|
}
|
|
@@ -2492,7 +1744,7 @@ function cellXml(p, ref, xf, x, f, v) {
|
|
|
2492
1744
|
function columns(p, rec, sheet, old, cols, defaults, cur, baseBook, xfFor, xfOf) {
|
|
2493
1745
|
const now = sheet.columnData ?? {}, was = old.columnData ?? {};
|
|
2494
1746
|
const count = sheet.columnCount ?? 26;
|
|
2495
|
-
const look = (bk, s) => s ? norm({ ...defaults, ...
|
|
1747
|
+
const look = (bk, s) => s ? norm({ ...defaults, ...lookup(bk, s) }) : null;
|
|
2496
1748
|
let differs = cols.moved;
|
|
2497
1749
|
for (let c = 0; c < count && !differs; c++) {
|
|
2498
1750
|
const c0 = cols.from(c);
|
|
@@ -2608,7 +1860,7 @@ function filterXml(p, ref, columns2) {
|
|
|
2608
1860
|
}).join("");
|
|
2609
1861
|
return body ? `<${p}autoFilter ref="${span(ref)}">${body}</${p}autoFilter>` : `<${p}autoFilter ref="${span(ref)}"/>`;
|
|
2610
1862
|
}
|
|
2611
|
-
function writeNotes(book, entry2, tail, p,
|
|
1863
|
+
function writeNotes(book, entry2, tail, p, notes, rows, cols, types, defaults, fresh2) {
|
|
2612
1864
|
const { pack } = book;
|
|
2613
1865
|
const rec = entry2.rec;
|
|
2614
1866
|
const relsPart = relsOf(entry2.part);
|
|
@@ -2635,7 +1887,7 @@ function writeNotes(book, entry2, tail, p, notes2, rows, cols, types, defaults,
|
|
|
2635
1887
|
const [r, c] = cell(n.ref);
|
|
2636
1888
|
return [a1(rows.map(r), cols.map(c)), n];
|
|
2637
1889
|
}));
|
|
2638
|
-
const list = [...
|
|
1890
|
+
const list = [...notes].sort((a, b) => a.row - b.row || a.col - b.col).map((n) => {
|
|
2639
1891
|
const ref = a1(n.row, n.col);
|
|
2640
1892
|
const was = byOld.get(ref);
|
|
2641
1893
|
if (was && was.text === n.note) return setAttr(was.xml.slice(0, was.xml.indexOf(">") + 1), "ref", ref) + was.xml.slice(was.xml.indexOf(">") + 1);
|
|
@@ -2656,7 +1908,7 @@ function writeNotes(book, entry2, tail, p, notes2, rows, cols, types, defaults,
|
|
|
2656
1908
|
return "";
|
|
2657
1909
|
});
|
|
2658
1910
|
let id = Math.max(1024, ...[...vml.matchAll(/_x0000_s(\d+)/g)].map((m) => Number(m[1])));
|
|
2659
|
-
const out =
|
|
1911
|
+
const out = notes.map((n) => {
|
|
2660
1912
|
const ref = a1(n.row, n.col);
|
|
2661
1913
|
const was = shapes.get(ref);
|
|
2662
1914
|
if (was) return was.replace(/<x:Row>\d+<\/x:Row>/, `<x:Row>${n.row}</x:Row>`).replace(/<x:Column>\d+<\/x:Column>/, `<x:Column>${n.col}</x:Column>`).replace(/<x:Anchor>([^<]*)<\/x:Anchor>/, `<x:Anchor>${n.col + 1}, 15, ${n.row}, 2, ${n.col + 3}, 15, ${n.row + 4}, 16</x:Anchor>`);
|
|
@@ -2717,7 +1969,7 @@ function made(config, lines2) {
|
|
|
2717
1969
|
function fill(doc, model) {
|
|
2718
1970
|
const { book: wb, lines: lines2 } = model;
|
|
2719
1971
|
const book = doc.getMap("book");
|
|
2720
|
-
const
|
|
1972
|
+
const notes = JSON.parse(wb.resources?.find((r) => r.name === "SHEET_NOTE_PLUGIN")?.data ?? "{}");
|
|
2721
1973
|
doc.transact(() => {
|
|
2722
1974
|
book.set("head", strip({ id: wb.id, name: wb.name, appVersion: wb.appVersion, locale: wb.locale, defaultStyle: wb.defaultStyle, dateSystem: wb.dateSystem }));
|
|
2723
1975
|
book.set("extras", (wb.resources ?? []).filter((r) => r.name !== "SHEET_NOTE_PLUGIN"));
|
|
@@ -2751,7 +2003,7 @@ function fill(doc, model) {
|
|
|
2751
2003
|
for (const [r, rd] of Object.entries(sheet.rowData ?? {})) if (rd) rowData.set(l.rows[+r], strip({ h: rd.h, hd: rd.hd, ia: rd.ia, s: typeof rd.s === "string" ? rd.s : void 0 }));
|
|
2752
2004
|
for (const [c, cd] of Object.entries(sheet.columnData ?? {})) if (cd) colData.set(l.cols[+c], strip({ w: cd.w, hd: cd.hd, s: typeof cd.s === "string" ? cd.s : void 0 }));
|
|
2753
2005
|
for (const b of sheet.mergeData ?? []) merges.set([l.rows[b.startRow], l.cols[b.startColumn], l.rows[b.endRow], l.cols[b.endColumn]].join(":"), 1);
|
|
2754
|
-
for (const [r, line] of Object.entries(
|
|
2006
|
+
for (const [r, line] of Object.entries(notes[sid] ?? {})) for (const [c, n] of Object.entries(line)) kept.set(spot(l.rows[+r], l.cols[+c]), { note: n.note, width: n.width, height: n.height });
|
|
2755
2007
|
}
|
|
2756
2008
|
});
|
|
2757
2009
|
}
|
|
@@ -2785,7 +2037,7 @@ function build(doc) {
|
|
|
2785
2037
|
const sheetOrder = [...new Set(order2.toArray())].filter((sid) => sheets.has(sid));
|
|
2786
2038
|
const wb = { ...book.get("head"), styles: styles.toJSON(), sheetOrder, sheets: {}, resources: [] };
|
|
2787
2039
|
const model = { book: wb, lines: {}, origin: { sheets: {}, lines: {} } };
|
|
2788
|
-
const
|
|
2040
|
+
const notes = {};
|
|
2789
2041
|
for (const sid of sheetOrder) {
|
|
2790
2042
|
const { rows, cols } = pieces(sheets.get(sid));
|
|
2791
2043
|
const l = { rows: rows.toArray(), cols: cols.toArray() };
|
|
@@ -2793,14 +2045,14 @@ function build(doc) {
|
|
|
2793
2045
|
wb.sheets[sid] = sheetOf(doc, sid, l);
|
|
2794
2046
|
notesOf(sheets.get(sid), l).forEach((n, i) => {
|
|
2795
2047
|
var _a, _b;
|
|
2796
|
-
((_a =
|
|
2048
|
+
((_a = notes[sid] ?? (notes[sid] = {}))[_b = n.row] ?? (_a[_b] = {}))[n.col] = { ...n, show: false, id: `n${i}` };
|
|
2797
2049
|
});
|
|
2798
2050
|
const o = origin.get(sid);
|
|
2799
2051
|
if (!o) continue;
|
|
2800
2052
|
model.origin.sheets[sid] = o.id;
|
|
2801
2053
|
model.origin.lines[sid] = { rows: typeof o.rows === "number" ? numbered("r", o.rows) : o.rows, cols: typeof o.cols === "number" ? numbered("c", o.cols) : o.cols };
|
|
2802
2054
|
}
|
|
2803
|
-
wb.resources.push({ name: "SHEET_NOTE_PLUGIN", data: JSON.stringify(
|
|
2055
|
+
wb.resources.push({ name: "SHEET_NOTE_PLUGIN", data: JSON.stringify(notes) });
|
|
2804
2056
|
const active = book.get("active");
|
|
2805
2057
|
if (active && sheetOrder.includes(active)) model.active = active;
|
|
2806
2058
|
return model;
|
|
@@ -3134,11 +2386,11 @@ function follow(doc, author) {
|
|
|
3134
2386
|
var pending = (doc) => doc.getMap("editors").size > 0;
|
|
3135
2387
|
var Refusal = class extends Error {
|
|
3136
2388
|
};
|
|
3137
|
-
function applyText(doc, kind,
|
|
2389
|
+
function applyText(doc, kind, changes, origin) {
|
|
3138
2390
|
const schema = schemaOf(kind);
|
|
3139
2391
|
const fragment = doc.getXmlFragment("default");
|
|
3140
2392
|
const step = new Transform(yXmlFragmentToProseMirrorRootNode(fragment, schema));
|
|
3141
|
-
for (const c of
|
|
2393
|
+
for (const c of changes) {
|
|
3142
2394
|
const hits = [];
|
|
3143
2395
|
step.doc.descendants((node, pos) => {
|
|
3144
2396
|
if (!node.isTextblock) return true;
|
|
@@ -3152,14 +2404,14 @@ function applyText(doc, kind, changes2, origin) {
|
|
|
3152
2404
|
else step.delete(at, at + c.find.length);
|
|
3153
2405
|
}
|
|
3154
2406
|
updateYFragment({ transact: (run) => doc.transact(run, origin) }, fragment, step.doc, { mapping: /* @__PURE__ */ new Map(), isOMark: /* @__PURE__ */ new Map() });
|
|
3155
|
-
return
|
|
2407
|
+
return changes.length;
|
|
3156
2408
|
}
|
|
3157
2409
|
async function write(kind, base, node, load2, setup) {
|
|
3158
2410
|
if (kind === "docx") return writeDocx(base, node.toJSON(), load2, setup);
|
|
3159
2411
|
const parsed = fromMarkdown(new TextDecoder().decode(base));
|
|
3160
2412
|
return new TextEncoder().encode(toMarkdown(node, track(parsed, node.type.schema.nodeFromJSON(parsed.doc))).text).buffer;
|
|
3161
2413
|
}
|
|
3162
|
-
var
|
|
2414
|
+
var blocks = (fragment, schema) => {
|
|
3163
2415
|
const out = [];
|
|
3164
2416
|
const walk = (parent) => parent.toArray().forEach((child) => {
|
|
3165
2417
|
if (!(child instanceof Y2.XmlElement) || !schema.nodes[child.nodeName]?.isBlock) return;
|
|
@@ -3184,7 +2436,7 @@ async function save(doc, kind, base, put, load2, note) {
|
|
|
3184
2436
|
if (kind === "xlsx" || kind === "csv") return workbook(doc, kind, base, put, who, note);
|
|
3185
2437
|
const schema = schemaOf(kind);
|
|
3186
2438
|
const fragment = doc.getXmlFragment("default");
|
|
3187
|
-
const list =
|
|
2439
|
+
const list = blocks(fragment, schema);
|
|
3188
2440
|
const node = yXmlFragmentToProseMirrorRootNode(fragment, schema);
|
|
3189
2441
|
let touched = false;
|
|
3190
2442
|
const watch = (tr) => {
|
|
@@ -3193,10 +2445,10 @@ async function save(doc, kind, base, put, load2, note) {
|
|
|
3193
2445
|
doc.on("afterTransaction", watch);
|
|
3194
2446
|
try {
|
|
3195
2447
|
const bytes = await write(kind, base, node, load2, doc.getMap("setup").size ? doc.getMap("setup").toJSON() : void 0);
|
|
3196
|
-
const
|
|
3197
|
-
const id =
|
|
2448
|
+
const changed = !same2(bytes, base);
|
|
2449
|
+
const id = changed ? await put(bytes, note ?? named((texts[who[0].language] ?? texts.en).editedNote, who)) : null;
|
|
3198
2450
|
const refs = [];
|
|
3199
|
-
if (
|
|
2451
|
+
if (changed) schema.nodeFromJSON(await parse2(kind, bytes)).descendants((n) => {
|
|
3200
2452
|
if (n.isBlock) refs.push([n.type.name, n.attrs.ref ?? null]);
|
|
3201
2453
|
});
|
|
3202
2454
|
doc.transact(() => {
|
|
@@ -3209,7 +2461,7 @@ async function save(doc, kind, base, put, load2, note) {
|
|
|
3209
2461
|
if (id) doc.getMap("meta").set("version", id);
|
|
3210
2462
|
if (!touched) who.forEach((w) => editors.delete(w.id));
|
|
3211
2463
|
}, ours);
|
|
3212
|
-
return { bytes:
|
|
2464
|
+
return { bytes: changed ? bytes : base, version: id };
|
|
3213
2465
|
} finally {
|
|
3214
2466
|
doc.off("afterTransaction", watch);
|
|
3215
2467
|
}
|
|
@@ -3224,37 +2476,20 @@ async function workbook(doc, kind, base, put, who, note) {
|
|
|
3224
2476
|
doc.on("afterTransaction", watch);
|
|
3225
2477
|
try {
|
|
3226
2478
|
const bytes = writeSheet(base, model, kind);
|
|
3227
|
-
const
|
|
3228
|
-
const id =
|
|
2479
|
+
const changed = !same2(bytes, base);
|
|
2480
|
+
const id = changed ? await put(bytes, note ?? named((sheetTexts[who[0].language] ?? sheetTexts.en).editedNote, who)) : null;
|
|
3229
2481
|
doc.transact(() => {
|
|
3230
|
-
if (
|
|
2482
|
+
if (changed) settle(doc, model, bytes, kind);
|
|
3231
2483
|
if (id) doc.getMap("meta").set("version", id);
|
|
3232
2484
|
if (!touched) who.forEach((w) => editors.delete(w.id));
|
|
3233
2485
|
}, ours);
|
|
3234
|
-
return { bytes:
|
|
2486
|
+
return { bytes: changed ? bytes : base, version: id };
|
|
3235
2487
|
} finally {
|
|
3236
2488
|
doc.off("afterTransaction", watch);
|
|
3237
2489
|
}
|
|
3238
2490
|
}
|
|
3239
2491
|
|
|
3240
2492
|
export {
|
|
3241
|
-
a4,
|
|
3242
|
-
letter,
|
|
3243
|
-
paging,
|
|
3244
|
-
notes,
|
|
3245
|
-
searching,
|
|
3246
|
-
replace,
|
|
3247
|
-
cleanPaste,
|
|
3248
|
-
entries,
|
|
3249
|
-
changes,
|
|
3250
|
-
decide,
|
|
3251
|
-
suggesting,
|
|
3252
|
-
kit,
|
|
3253
|
-
align,
|
|
3254
|
-
spacing,
|
|
3255
|
-
indent,
|
|
3256
|
-
clear,
|
|
3257
|
-
locate,
|
|
3258
2493
|
SheetRefusal,
|
|
3259
2494
|
fresh,
|
|
3260
2495
|
insert,
|
|
@@ -3289,4 +2524,4 @@ export {
|
|
|
3289
2524
|
applyText,
|
|
3290
2525
|
save
|
|
3291
2526
|
};
|
|
3292
|
-
//# sourceMappingURL=chunk-
|
|
2527
|
+
//# sourceMappingURL=chunk-A6AHJCEK.js.map
|