wendang-react 0.6.2 → 0.6.4
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/NOTICE.md +1 -1
- package/README.md +105 -0
- package/dist/bindings/yjs.js +1 -5
- package/dist/chunks/AnchoredPanel-C7jMoPze.js +1 -0
- package/dist/chunks/DocumentExportMenu-CUMsgq3w.js +2 -0
- package/dist/chunks/Dropdown-D98tXfe0.js +3 -0
- package/dist/chunks/MindMapCanvas-CVXQXNOg.js +163 -0
- package/dist/chunks/MindMapViewer-BI8zbQM1.js +13 -0
- package/dist/chunks/SpreadsheetViewer-CoQ4VIgj.js +23 -0
- package/dist/chunks/code-highlight-BmaqTe1m.js +1 -30
- package/dist/chunks/code-highlight-engine-BFDzDPzy.js +1 -40
- package/dist/chunks/comment-hint-BhUxKjKK.js +14 -0
- package/dist/chunks/composition-state-Bl-U1R_2.js +1 -40
- package/dist/chunks/extensions-C1fCBnEs.js +14 -0
- package/dist/chunks/fuzzy-match-DYQR-4w2.js +1 -89
- package/dist/chunks/hooks-C53Dp0pr.js +1 -35
- package/dist/chunks/i18n-B0kCsIjc.js +2 -0
- package/dist/chunks/index-COeA2QcQ.js +15 -0
- package/dist/chunks/katex-WjrodtTU.js +1 -71
- package/dist/chunks/locale-DWpIJ_9X.js +1 -0
- package/dist/chunks/mind-map-controller-Ce76mETT.js +1 -0
- package/dist/chunks/mind-map-delete-CVsxdXfs.js +1 -31
- package/dist/chunks/mind-map-input-CEWRz_t6.js +1 -43
- package/dist/chunks/mind-topic-text-Bn1waxff.js +31 -0
- package/dist/chunks/popover-placement-D3xVYdkt.js +1 -47
- package/dist/chunks/worksheet-engine-c84sdD4N.js +1 -0
- package/dist/chunks/worksheet-preview-DsDVWxIM.js +1 -129
- package/dist/document/viewer.js +30 -289
- package/dist/document.js +120 -3622
- package/dist/export/json.js +1 -5
- package/dist/export/markdown.js +1 -2
- package/dist/export/mindmap.js +1 -2
- package/dist/export/pdf.js +1 -6
- package/dist/export/word.js +1 -2
- package/dist/export.js +1 -2
- package/dist/i18n.js +1 -0
- package/dist/index.js +1 -8
- package/dist/locales/en-US.js +1 -0
- package/dist/locales/es-ES.js +1 -0
- package/dist/locales/ja-JP.js +1 -0
- package/dist/locales/ko-KR.js +1 -0
- package/dist/locales/zh-CN.js +1 -0
- package/dist/locales/zh-TW.js +1 -0
- package/dist/mindmap/viewer.js +1 -6
- package/dist/mindmap.js +3 -123
- package/dist/shared.js +1 -52
- package/dist/spreadsheet/viewer.js +1 -5
- package/dist/spreadsheet/xlsx.js +1 -299
- package/dist/spreadsheet.js +2 -120
- package/dist/styles/callout.css +1 -34
- package/dist/styles/code-block.css +1 -58
- package/dist/styles/content-style.css +1 -619
- package/dist/styles/content-tokens.css +1 -29
- package/dist/styles/editor-interaction.css +1 -621
- package/dist/styles/file-video.css +1 -12
- package/dist/styles/image-preview.css +1 -103
- package/dist/styles/mind-map-block.css +1 -14
- package/dist/styles/mind-map-canvas.css +1 -80
- package/dist/styles/mind-map-comments.css +1 -93
- package/dist/styles/mind-map-details.css +1 -7
- package/dist/styles/mind-map-preview.css +1 -7
- package/dist/styles/mind-map-topic.css +1 -112
- package/dist/styles/page-picker.css +1 -47
- package/dist/styles/renderer.css +1 -45
- package/dist/styles/spreadsheet-editor.css +1 -3
- package/dist/styles/tokens.css +1 -142
- package/dist/styles/video-dialog.css +1 -41
- package/dist/styles/video-embed.css +1 -35
- package/dist/styles.css +1 -2631
- package/dist/types/editor/BlockAffordance.d.ts +5 -2
- package/dist/types/editor/CalloutView.d.ts +2 -1
- package/dist/types/editor/ImagePreview.d.ts +1 -1
- package/dist/types/editor/PagePicker.d.ts +1 -1
- package/dist/types/editor/extensions.d.ts +4 -1
- package/dist/types/engine/editor/block-commands.d.ts +1 -1
- package/dist/types/engine/editor/block-menu-hover.d.ts +16 -0
- package/dist/types/engine/editor/extensions/locale.d.ts +3 -0
- package/dist/types/engine/editor/nodes/image-nodeview.d.ts +1 -1
- package/dist/types/engine/host.d.ts +60 -2
- package/dist/types/engine/renderer/attachments.d.ts +3 -3
- package/dist/types/engine/shared/video-feedback.d.ts +1 -1
- package/dist/types/engine/worksheets/worksheet-engine.d.ts +1 -0
- package/dist/types/engine/worksheets/worksheet-xlsx.d.ts +6 -1
- package/dist/types/engine/wui/core/overlay-scrollbar.d.ts +4 -0
- package/dist/types/host-types.d.ts +2 -60
- package/dist/types/host.d.ts +8 -1
- package/dist/types/i18n.d.ts +3 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/locales/en-US.d.ts +1 -0
- package/dist/types/locales/es-ES.d.ts +1 -0
- package/dist/types/locales/ja-JP.d.ts +1 -0
- package/dist/types/locales/ko-KR.d.ts +1 -0
- package/dist/types/locales/zh-CN.d.ts +1 -0
- package/dist/types/locales/zh-TW.d.ts +1 -0
- package/dist/types/spreadsheet/xlsx.d.ts +1 -1
- package/dist/types/wui/Dropdown.d.ts +2 -1
- package/dist/types/wui/index.d.ts +2 -1
- package/integrity.json +3135 -0
- package/package.json +15 -5
- package/verify-integrity.mjs +138 -0
- package/dist/chunks/AnchoredPanel-CSXrveAT.js +0 -68
- package/dist/chunks/DocumentExportMenu-DgDXDChd.js +0 -75
- package/dist/chunks/MindMapCanvas-I5M1SIyX.js +0 -2090
- package/dist/chunks/MindMapViewer-Nu3nEVHQ.js +0 -180
- package/dist/chunks/SpreadsheetViewer-CLDlnWyM.js +0 -163
- package/dist/chunks/comment-hint-Coq1laiR.js +0 -296
- package/dist/chunks/extensions-DMQedgOl.js +0 -4210
- package/dist/chunks/host-C-V688Rq.js +0 -197
- package/dist/chunks/index-CqaMYb3A.js +0 -720
- package/dist/chunks/mind-map-controller-B6SxK3GZ.js +0 -479
- package/dist/chunks/mind-topic-text-DYQR2Dzf.js +0 -446
- package/dist/chunks/nodes-iKqTGr_N.js +0 -291
- package/dist/chunks/worksheet-engine-TJ54m0KC.js +0 -125
- package/third-party-notices/wendang-export@0.6.0-NOTICE.md.txt +0 -51
- package/third-party-notices/wendang-export@0.6.1-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-NOTICE.md.txt +0 -70
- /package/third-party-notices/{wendang-export@0.6.0-LICENSE.txt → wendang-export@0.6.3-LICENSE.txt} +0 -0
- /package/third-party-notices/{wendang-export@0.6.1-NOTICE.md.txt → wendang-export@0.6.3-NOTICE.md.txt} +0 -0
|
@@ -1,479 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { closeHistory } from "@tiptap/pm/history";
|
|
3
|
-
import { yUndoPluginKey } from "@tiptap/y-tiptap";
|
|
4
|
-
import { p as planMindTopicDeletion } from "./mind-map-delete-CVsxdXfs.js";
|
|
5
|
-
import { textDifference, MIND_MAP_MAX_TOPICS, mindMapId, mindMapTree, mindMapDescendants, mindMapOutline, projectMindSideMove, canMoveMindTopic, mindMapBranchSides, MIND_MAP_MAX_TEXT, readMindMap, MIND_MAP_VERSION } from "wendang/internal/mind-map";
|
|
6
|
-
import { searchMindMap, topicTitle, topicField } from "wendang/internal/mind-map-phase2";
|
|
7
|
-
function createMindMapController(editor, getPos, context = {}) {
|
|
8
|
-
var _a;
|
|
9
|
-
const listeners = /* @__PURE__ */ new Set(), sessions = /* @__PURE__ */ new Map();
|
|
10
|
-
let disposed = false;
|
|
11
|
-
const initialPosition = getPos();
|
|
12
|
-
const identity = typeof initialPosition === "number" ? (_a = editor.state.doc.nodeAt(initialPosition)) == null ? void 0 : _a.attrs.id : void 0;
|
|
13
|
-
let composing = false;
|
|
14
|
-
function composition(active) {
|
|
15
|
-
var _a2;
|
|
16
|
-
if (active === composing) return;
|
|
17
|
-
composing = active;
|
|
18
|
-
const storage = (_a2 = editor.storage) == null ? void 0 : _a2.mindMap;
|
|
19
|
-
if (storage) storage.composing = Math.max(0, storage.composing + (active ? 1 : -1));
|
|
20
|
-
}
|
|
21
|
-
function current() {
|
|
22
|
-
if (disposed || editor.isDestroyed) return null;
|
|
23
|
-
const pos = getPos();
|
|
24
|
-
if (typeof pos !== "number") return null;
|
|
25
|
-
const node = editor.state.doc.nodeAt(pos);
|
|
26
|
-
if ((node == null ? void 0 : node.type.name) !== "mindMap" || node.attrs.id !== identity) return null;
|
|
27
|
-
const model = readMindMap(node.toJSON());
|
|
28
|
-
return model ? { node, pos, model } : null;
|
|
29
|
-
}
|
|
30
|
-
function topicAt(id) {
|
|
31
|
-
const map = current();
|
|
32
|
-
if (!map) return null;
|
|
33
|
-
let found = null;
|
|
34
|
-
map.node.forEach((node, offset) => {
|
|
35
|
-
if (node.attrs.id === id) found = { node, pos: map.pos + offset + 1 };
|
|
36
|
-
});
|
|
37
|
-
return found;
|
|
38
|
-
}
|
|
39
|
-
function topicInsertPos(map) {
|
|
40
|
-
let pos = map.pos + 1;
|
|
41
|
-
map.node.forEach((n) => {
|
|
42
|
-
if (n.type.name === "mindMapTopic") pos += n.nodeSize;
|
|
43
|
-
});
|
|
44
|
-
return pos;
|
|
45
|
-
}
|
|
46
|
-
function fieldAt(id, field) {
|
|
47
|
-
const t = topicAt(id);
|
|
48
|
-
if (!t) return null;
|
|
49
|
-
if (field === "title") return { ...t, text: topicTitle(t.node.toJSON()) };
|
|
50
|
-
let found = null;
|
|
51
|
-
t.node.forEach((n, offset) => {
|
|
52
|
-
if (n.type.name === (field === "description" ? "mindMapDescription" : "mindMapNote")) found = { node: n, pos: t.pos + 1 + offset, text: n.textContent };
|
|
53
|
-
});
|
|
54
|
-
return found;
|
|
55
|
-
}
|
|
56
|
-
const editable = () => !!current() && editor.isEditable;
|
|
57
|
-
function structuralChange(tr) {
|
|
58
|
-
var _a2;
|
|
59
|
-
const map = current();
|
|
60
|
-
if (map && map.node.attrs.formatVersion < MIND_MAP_VERSION) {
|
|
61
|
-
const mapped = tr.doc.nodeAt(tr.mapping.map(map.pos));
|
|
62
|
-
if ((mapped == null ? void 0 : mapped.type.name) === "mindMap") tr.setNodeMarkup(tr.mapping.map(map.pos), void 0, { ...mapped.attrs, formatVersion: MIND_MAP_VERSION });
|
|
63
|
-
}
|
|
64
|
-
const undoManager = (_a2 = yUndoPluginKey.getState(editor.state)) == null ? void 0 : _a2.undoManager;
|
|
65
|
-
undoManager == null ? void 0 : undoManager.stopCapturing();
|
|
66
|
-
editor.view.dispatch(closeHistory(tr));
|
|
67
|
-
undoManager == null ? void 0 : undoManager.stopCapturing();
|
|
68
|
-
}
|
|
69
|
-
function notify() {
|
|
70
|
-
for (const fn of listeners) fn();
|
|
71
|
-
}
|
|
72
|
-
function onTransaction({ transaction }) {
|
|
73
|
-
for (const [id, s] of sessions) {
|
|
74
|
-
const locate = (doc) => {
|
|
75
|
-
let result = null;
|
|
76
|
-
doc.descendants((node, pos) => {
|
|
77
|
-
if (node.type.name === "mindMapTopic" && node.attrs.id === id.split("::")[0]) {
|
|
78
|
-
result = { node, pos };
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
return !result;
|
|
82
|
-
});
|
|
83
|
-
return result;
|
|
84
|
-
};
|
|
85
|
-
const field = id.split("::")[1] || "title";
|
|
86
|
-
const before = locate(transaction.before), after = locate(transaction.doc);
|
|
87
|
-
if (!before || !after) {
|
|
88
|
-
sessions.delete(id);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const getText = (n) => field === "title" ? topicTitle(n.toJSON()) : topicField(n.toJSON(), field);
|
|
92
|
-
const diff = textDifference(getText(before.node), getText(after.node));
|
|
93
|
-
const shift = diff.text.length - (diff.to - diff.from);
|
|
94
|
-
s.boundaries = s.boundaries.map((p) => {
|
|
95
|
-
const offset = Math.max(0, Math.min(getText(before.node).length, p));
|
|
96
|
-
const mapped = offset < diff.from ? offset : offset >= diff.to ? offset + shift : diff.from + diff.text.length;
|
|
97
|
-
return Math.max(0, Math.min(getText(after.node).length, mapped));
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
notify();
|
|
101
|
-
}
|
|
102
|
-
editor.on("transaction", onTransaction);
|
|
103
|
-
editor.on("update", notify);
|
|
104
|
-
function beginText(id, field = "title") {
|
|
105
|
-
var _a2, _b, _c;
|
|
106
|
-
const t = fieldAt(id, field);
|
|
107
|
-
if (!t) return;
|
|
108
|
-
const text2 = t.text;
|
|
109
|
-
sessions.set(`${id}::${field}`, { text: text2, boundaries: Array.from({ length: text2.length + 1 }, (_, i) => i) });
|
|
110
|
-
const local = (_b = (_a2 = context.awareness) == null ? void 0 : _a2.getLocalState()) == null ? void 0 : _b.mindMap;
|
|
111
|
-
if ((local == null ? void 0 : local.blockId) === identity) (_c = context.awareness) == null ? void 0 : _c.setLocalStateField("mindMap", { ...local, topicId: id, editing: true });
|
|
112
|
-
}
|
|
113
|
-
function text(id, next, field = "title") {
|
|
114
|
-
if (!editable() || next.length > (field === "title" ? MIND_MAP_MAX_TEXT : 4e3)) return false;
|
|
115
|
-
let t = fieldAt(id, field);
|
|
116
|
-
if (!t && field !== "title") {
|
|
117
|
-
const topic = topicAt(id);
|
|
118
|
-
if (!topic) return false;
|
|
119
|
-
let pos = topic.pos + topic.node.nodeSize - 1;
|
|
120
|
-
if (field === "description") topic.node.forEach((n, offset) => {
|
|
121
|
-
if (n.type.name === "mindMapNote") pos = topic.pos + 1 + offset;
|
|
122
|
-
});
|
|
123
|
-
structuralChange(editor.state.tr.insert(pos, editor.schema.nodes[field === "description" ? "mindMapDescription" : "mindMapNote"].create()));
|
|
124
|
-
t = fieldAt(id, field);
|
|
125
|
-
}
|
|
126
|
-
if (!t) return false;
|
|
127
|
-
const key = `${id}::${field}`;
|
|
128
|
-
if (!sessions.has(key)) beginText(id, field);
|
|
129
|
-
const s = sessions.get(key);
|
|
130
|
-
const diff = textDifference(s.text, next);
|
|
131
|
-
if (diff.from === diff.to && !diff.text) return true;
|
|
132
|
-
const from = t.pos + 1 + s.boundaries[diff.from], to = t.pos + 1 + s.boundaries[diff.to];
|
|
133
|
-
if (from < t.pos + 1 || to > t.pos + 1 + t.text.length || from > to) return false;
|
|
134
|
-
const tr = editor.state.tr.insertText(diff.text, from, to);
|
|
135
|
-
editor.view.dispatch(tr);
|
|
136
|
-
const mapped = sessions.get(key);
|
|
137
|
-
if (!mapped) return false;
|
|
138
|
-
mapped.boundaries = [
|
|
139
|
-
...mapped.boundaries.slice(0, diff.from),
|
|
140
|
-
...Array.from({ length: diff.text.length + 1 }, (_, i) => from - t.pos - 1 + i),
|
|
141
|
-
...mapped.boundaries.slice(diff.to + 1)
|
|
142
|
-
];
|
|
143
|
-
mapped.text = next;
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
|
-
function patch(id, attrs) {
|
|
147
|
-
const t = topicAt(id);
|
|
148
|
-
if (!editable() || !t) return false;
|
|
149
|
-
structuralChange(editor.state.tr.setNodeMarkup(t.pos, void 0, { ...t.node.attrs, ...attrs }));
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
function orderAt(tr, siblings, index) {
|
|
153
|
-
var _a2, _b, _c;
|
|
154
|
-
const previous = ((_a2 = siblings[index - 1]) == null ? void 0 : _a2.order) ?? (((_b = siblings[index]) == null ? void 0 : _b.order) ?? 0) - 2048;
|
|
155
|
-
const next = ((_c = siblings[index]) == null ? void 0 : _c.order) ?? previous + 2048;
|
|
156
|
-
const value = (previous + next) / 2;
|
|
157
|
-
if (value > previous && value < next && Math.abs(value) < 1e12 && next - previous > Number.EPSILON * Math.max(1, Math.abs(previous), Math.abs(next)) * 8) return value;
|
|
158
|
-
siblings.forEach((t, i) => {
|
|
159
|
-
const existing = topicAt(t.id);
|
|
160
|
-
if (existing) tr.setNodeMarkup(existing.pos, void 0, { ...existing.node.attrs, order: i * 1024 });
|
|
161
|
-
});
|
|
162
|
-
return index * 1024 - 512;
|
|
163
|
-
}
|
|
164
|
-
function freezeBranchSides(tr, map) {
|
|
165
|
-
const sides = mindMapBranchSides(map.model);
|
|
166
|
-
for (const [id, side] of sides) {
|
|
167
|
-
const entry = topicAt(id);
|
|
168
|
-
tr.setNodeMarkup(entry.pos, void 0, { ...tr.doc.nodeAt(entry.pos).attrs, side });
|
|
169
|
-
}
|
|
170
|
-
return sides;
|
|
171
|
-
}
|
|
172
|
-
function insertTopic(parentId, referenceId, label = "新主题", placement = "after", requestedSide) {
|
|
173
|
-
const map = current();
|
|
174
|
-
if (!editable() || !map || map.model.topics.length >= MIND_MAP_MAX_TOPICS || !topicAt(parentId)) return null;
|
|
175
|
-
if (requestedSide !== void 0 && (parentId !== map.model.rootId || map.model.layout === "down" || requestedSide !== -1 && requestedSide !== 1)) return null;
|
|
176
|
-
const siblings = mindMapTree(map.model).filter((t) => t.parentId === parentId);
|
|
177
|
-
const at = siblings.findIndex((t) => t.id === referenceId);
|
|
178
|
-
if (referenceId && at < 0) return null;
|
|
179
|
-
const tr = editor.state.tr;
|
|
180
|
-
const order = orderAt(tr, siblings, at >= 0 ? at + (placement === "after" ? 1 : 0) : siblings.length);
|
|
181
|
-
const id = mindMapId();
|
|
182
|
-
const changeLayout = requestedSide !== void 0 && map.model.layout !== "both" && requestedSide !== (map.model.layout === "left" ? -1 : 1);
|
|
183
|
-
const sides = map.model.layout === "both" || changeLayout ? freezeBranchSides(tr, map) : mindMapBranchSides(map.model);
|
|
184
|
-
const side = requestedSide ?? (parentId === map.model.rootId ? referenceId ? sides.get(referenceId) : map.model.layout === "left" ? -1 : 1 : null);
|
|
185
|
-
const node = editor.schema.nodes.mindMapTopic.create(
|
|
186
|
-
{ id, parentId, order, side },
|
|
187
|
-
label ? editor.schema.text(label.slice(0, MIND_MAP_MAX_TEXT)) : void 0
|
|
188
|
-
);
|
|
189
|
-
if (changeLayout) tr.setNodeMarkup(map.pos, void 0, { ...map.node.attrs, layout: "both" });
|
|
190
|
-
structuralChange(tr.insert(topicInsertPos(map), node));
|
|
191
|
-
return id;
|
|
192
|
-
}
|
|
193
|
-
function add(parentId, afterId, label = "新主题") {
|
|
194
|
-
return insertTopic(parentId, afterId, label);
|
|
195
|
-
}
|
|
196
|
-
function addRootChild(side, label = "新主题") {
|
|
197
|
-
const map = current();
|
|
198
|
-
return map ? insertTopic(map.model.rootId, void 0, label, "after", side) : null;
|
|
199
|
-
}
|
|
200
|
-
function addSibling(id, placement, label = "新主题") {
|
|
201
|
-
const map = current();
|
|
202
|
-
if (!map || id === map.model.rootId) return null;
|
|
203
|
-
const topic = mindMapTree(map.model).find((t) => t.id === id);
|
|
204
|
-
return (topic == null ? void 0 : topic.parentId) ? insertTopic(topic.parentId, id, label, placement) : null;
|
|
205
|
-
}
|
|
206
|
-
function move(id, targetId, mode = "child") {
|
|
207
|
-
const map = current();
|
|
208
|
-
if (!map || !editable()) return false;
|
|
209
|
-
const tree = mindMapTree(map.model), target = tree.find((t) => t.id === targetId);
|
|
210
|
-
if (!target) return false;
|
|
211
|
-
const parentId = mode === "child" ? targetId : target.parentId;
|
|
212
|
-
if (!canMoveMindTopic(map.model, id, parentId) || id === targetId) return false;
|
|
213
|
-
const siblings = tree.filter((t) => t.parentId === parentId && t.id !== id);
|
|
214
|
-
const tr = editor.state.tr;
|
|
215
|
-
let index;
|
|
216
|
-
if (mode === "child") index = siblings.length;
|
|
217
|
-
else {
|
|
218
|
-
const at = siblings.findIndex((t) => t.id === targetId);
|
|
219
|
-
if (at < 0) return false;
|
|
220
|
-
index = mode === "before" ? at : at + 1;
|
|
221
|
-
}
|
|
222
|
-
const order = orderAt(tr, siblings, index), node = topicAt(id);
|
|
223
|
-
const sides = mindMapBranchSides(map.model);
|
|
224
|
-
if (parentId === map.model.rootId) {
|
|
225
|
-
for (const sibling of tree.filter((t) => t.parentId === parentId && t.id !== id)) {
|
|
226
|
-
const entry = topicAt(sibling.id);
|
|
227
|
-
tr.setNodeMarkup(entry.pos, void 0, { ...tr.doc.nodeAt(entry.pos).attrs, side: sides.get(sibling.id) });
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
const side = parentId === map.model.rootId ? sides.get(mode === "child" ? id : targetId) ?? (map.model.layout === "left" ? -1 : 1) : null;
|
|
231
|
-
tr.setNodeMarkup(node.pos, void 0, { ...tr.doc.nodeAt(node.pos).attrs, parentId, order, side });
|
|
232
|
-
structuralChange(tr);
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
function moveToSide(id, side, beforeId) {
|
|
236
|
-
const map = current();
|
|
237
|
-
if (!map || !editable()) return false;
|
|
238
|
-
const projected = projectMindSideMove(map.model, id, side, beforeId);
|
|
239
|
-
if (!projected) return false;
|
|
240
|
-
const tr = editor.state.tr;
|
|
241
|
-
for (const topic of projected.topics) {
|
|
242
|
-
const before = map.model.topics.find((t) => t.id === topic.id);
|
|
243
|
-
if (before.parentId === topic.parentId && before.order === topic.order && before.side === topic.side) continue;
|
|
244
|
-
const entry = topicAt(topic.id);
|
|
245
|
-
tr.setNodeMarkup(entry.pos, void 0, { ...entry.node.attrs, parentId: topic.parentId, order: topic.order, side: topic.side ?? null });
|
|
246
|
-
}
|
|
247
|
-
if (map.model.layout !== projected.layout) tr.setNodeMarkup(map.pos, void 0, { ...map.node.attrs, layout: projected.layout });
|
|
248
|
-
if (tr.docChanged) structuralChange(tr);
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
function remove(id) {
|
|
252
|
-
return removeMany([id]);
|
|
253
|
-
}
|
|
254
|
-
function removeMany(selection) {
|
|
255
|
-
const map = current();
|
|
256
|
-
if (!editable() || !map) return false;
|
|
257
|
-
const plan = planMindTopicDeletion(map.model, selection);
|
|
258
|
-
if (!plan) return false;
|
|
259
|
-
const { ids } = plan;
|
|
260
|
-
const ranges = [];
|
|
261
|
-
map.node.forEach((t, offset) => {
|
|
262
|
-
if (ids.has(t.attrs.id) || t.type.name === "mindMapRelation" && (ids.has(t.attrs.source) || ids.has(t.attrs.target))) ranges.push({ from: map.pos + 1 + offset, to: map.pos + 1 + offset + t.nodeSize });
|
|
263
|
-
});
|
|
264
|
-
const tr = editor.state.tr;
|
|
265
|
-
if (map.model.layout === "both") freezeBranchSides(tr, map);
|
|
266
|
-
for (const range of ranges.reverse()) tr.delete(range.from, range.to);
|
|
267
|
-
structuralChange(tr);
|
|
268
|
-
return true;
|
|
269
|
-
}
|
|
270
|
-
function settings(attrs) {
|
|
271
|
-
const map = current();
|
|
272
|
-
if (!editable() || !map) return false;
|
|
273
|
-
const tr = editor.state.tr;
|
|
274
|
-
if (attrs.layout && attrs.layout !== map.model.layout) for (const topic of map.model.topics.filter((t) => t.parentId === map.model.rootId)) {
|
|
275
|
-
const entry = topicAt(topic.id);
|
|
276
|
-
if (entry.node.attrs.side !== null) tr.setNodeMarkup(entry.pos, void 0, { ...entry.node.attrs, side: null });
|
|
277
|
-
}
|
|
278
|
-
structuralChange(tr.setNodeMarkup(map.pos, void 0, { ...map.node.attrs, ...attrs }));
|
|
279
|
-
return true;
|
|
280
|
-
}
|
|
281
|
-
function addParent(id) {
|
|
282
|
-
const map = current(), t = topicAt(id);
|
|
283
|
-
if (!map || !t || !editable() || id === map.model.rootId || map.model.topics.length >= 500) return null;
|
|
284
|
-
const projected = mindMapTree(map.model).find((n) => n.id === id);
|
|
285
|
-
const newId = mindMapId(), tr = editor.state.tr;
|
|
286
|
-
if (map.model.layout === "both") freezeBranchSides(tr, map);
|
|
287
|
-
tr.setNodeMarkup(t.pos, void 0, { ...t.node.attrs, parentId: newId, order: 0 });
|
|
288
|
-
tr.insert(topicInsertPos(map), editor.schema.nodes.mindMapTopic.create({ id: newId, parentId: projected.parentId, order: projected.order, side: mindMapBranchSides(map.model).get(id) ?? null }, editor.schema.text("父主题")));
|
|
289
|
-
structuralChange(tr);
|
|
290
|
-
return newId;
|
|
291
|
-
}
|
|
292
|
-
function indent(id, out = false) {
|
|
293
|
-
const map = current();
|
|
294
|
-
if (!map) return false;
|
|
295
|
-
const tree = mindMapTree(map.model), topic = tree.find((t) => t.id === id);
|
|
296
|
-
if (!topic || !topic.parentId) return false;
|
|
297
|
-
if (out) {
|
|
298
|
-
const parent = tree.find((t) => t.id === topic.parentId);
|
|
299
|
-
return !!(parent == null ? void 0 : parent.parentId) && move(id, parent.id, "after");
|
|
300
|
-
}
|
|
301
|
-
const siblings = tree.filter((t) => t.parentId === topic.parentId), at = siblings.findIndex((t) => t.id === id);
|
|
302
|
-
return at > 0 && move(id, siblings[at - 1].id);
|
|
303
|
-
}
|
|
304
|
-
function format(id, from, to, mark, attrs) {
|
|
305
|
-
const t = fieldAt(id, "title"), type = editor.schema.marks[mark];
|
|
306
|
-
if (!editable() || !t || !type || from < 0 || to > t.text.length || to <= from) return false;
|
|
307
|
-
const start = t.pos + 1 + from, end = t.pos + 1 + to, tr = editor.state.tr;
|
|
308
|
-
if (!attrs && editor.state.doc.rangeHasMark(start, end, type)) tr.removeMark(start, end, type);
|
|
309
|
-
else tr.addMark(start, end, type.create(attrs));
|
|
310
|
-
structuralChange(tr);
|
|
311
|
-
return true;
|
|
312
|
-
}
|
|
313
|
-
function clearFormat(id, from, to, marks) {
|
|
314
|
-
const t = fieldAt(id, "title");
|
|
315
|
-
if (!editable() || !t || from < 0 || to > t.text.length || to <= from) return false;
|
|
316
|
-
const tr = editor.state.tr;
|
|
317
|
-
if (marks) for (const name of marks) {
|
|
318
|
-
const mark = editor.schema.marks[name];
|
|
319
|
-
if (mark) tr.removeMark(t.pos + 1 + from, t.pos + 1 + to, mark);
|
|
320
|
-
}
|
|
321
|
-
else tr.removeMark(t.pos + 1 + from, t.pos + 1 + to);
|
|
322
|
-
structuralChange(tr);
|
|
323
|
-
return true;
|
|
324
|
-
}
|
|
325
|
-
function replace(query, replacement, target) {
|
|
326
|
-
const map = current();
|
|
327
|
-
if (!map || !editable() || !query) return 0;
|
|
328
|
-
const hits = target ? [target] : searchMindMap(map.model, query), tr = editor.state.tr;
|
|
329
|
-
if (hits.length > 5e3) return -1;
|
|
330
|
-
const counts = /* @__PURE__ */ new Map();
|
|
331
|
-
for (const hit of hits) counts.set(`${hit.id}::${hit.field}`, (counts.get(`${hit.id}::${hit.field}`) ?? 0) + 1);
|
|
332
|
-
for (const [key, count] of counts) {
|
|
333
|
-
const [id, field] = key.split("::"), t = fieldAt(id, field);
|
|
334
|
-
if (t && t.text.length + count * (replacement.length - query.length) > (field === "title" ? 2e3 : 4e3)) return -2;
|
|
335
|
-
}
|
|
336
|
-
const ranges = hits.flatMap((hit) => {
|
|
337
|
-
const t = fieldAt(hit.id, hit.field);
|
|
338
|
-
if (!t || t.text.slice(hit.from, hit.to).toLocaleLowerCase() !== query.toLocaleLowerCase()) return [];
|
|
339
|
-
if (t.text.length + replacement.length - query.length > (hit.field === "title" ? 2e3 : 4e3)) return [];
|
|
340
|
-
return [{ from: t.pos + 1 + hit.from, to: t.pos + 1 + hit.to }];
|
|
341
|
-
}).sort((a, b) => b.from - a.from);
|
|
342
|
-
for (const r of ranges) tr.insertText(replacement, r.from, r.to);
|
|
343
|
-
if (ranges.length) structuralChange(tr);
|
|
344
|
-
return ranges.length;
|
|
345
|
-
}
|
|
346
|
-
function relation(value) {
|
|
347
|
-
const map = current();
|
|
348
|
-
if (!map || !editable() || value.source === value.target || !topicAt(value.source) || !topicAt(value.target)) return false;
|
|
349
|
-
let found = null;
|
|
350
|
-
map.node.forEach((node, offset) => {
|
|
351
|
-
if (node.type.name === "mindMapRelation" && node.attrs.id === value.id) found = { node, pos: map.pos + 1 + offset };
|
|
352
|
-
});
|
|
353
|
-
const prior = found, attrs = { ...value, id: value.id ?? mindMapId(), label: value.label.slice(0, 200) };
|
|
354
|
-
structuralChange(prior ? editor.state.tr.setNodeMarkup(prior.pos, void 0, attrs) : editor.state.tr.insert(map.pos + map.node.nodeSize - 1, editor.schema.nodes.mindMapRelation.create(attrs)));
|
|
355
|
-
return true;
|
|
356
|
-
}
|
|
357
|
-
function deleteRelation(id) {
|
|
358
|
-
const map = current();
|
|
359
|
-
if (!map || !editable()) return false;
|
|
360
|
-
const tr = editor.state.tr;
|
|
361
|
-
let found = false;
|
|
362
|
-
map.node.forEach((node, offset) => {
|
|
363
|
-
if (node.type.name === "mindMapRelation" && node.attrs.id === id) {
|
|
364
|
-
tr.delete(map.pos + 1 + offset, map.pos + 1 + offset + node.nodeSize);
|
|
365
|
-
found = true;
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
if (found) structuralChange(tr);
|
|
369
|
-
return found;
|
|
370
|
-
}
|
|
371
|
-
function copyBranch(id) {
|
|
372
|
-
const map = current();
|
|
373
|
-
if (!map) return [];
|
|
374
|
-
const ids = mindMapDescendants(map.model, id);
|
|
375
|
-
const topics = new Map((map.node.toJSON().content ?? []).map((t) => {
|
|
376
|
-
var _a2;
|
|
377
|
-
return [String((_a2 = t.attrs) == null ? void 0 : _a2.id), t];
|
|
378
|
-
}));
|
|
379
|
-
return [
|
|
380
|
-
...mindMapOutline(map.model).filter((t) => ids.has(t.id)).map((t) => topics.get(t.id)),
|
|
381
|
-
...(map.node.toJSON().content ?? []).filter((t) => {
|
|
382
|
-
var _a2, _b;
|
|
383
|
-
return t.type === "mindMapRelation" && ids.has(String((_a2 = t.attrs) == null ? void 0 : _a2.source)) && ids.has(String((_b = t.attrs) == null ? void 0 : _b.target));
|
|
384
|
-
})
|
|
385
|
-
];
|
|
386
|
-
}
|
|
387
|
-
function pasteBranch(parentId, branch) {
|
|
388
|
-
var _a2, _b, _c, _d;
|
|
389
|
-
const map = current();
|
|
390
|
-
if (!editable() || !map || !topicAt(parentId) || !branch.length || branch.filter((t) => t.type === "mindMapTopic").length + map.model.topics.length > MIND_MAP_MAX_TOPICS) return null;
|
|
391
|
-
const topics = branch.filter((t) => t.type === "mindMapTopic");
|
|
392
|
-
if (!topics.length) return null;
|
|
393
|
-
const ids = new Map(topics.map((t) => {
|
|
394
|
-
var _a3;
|
|
395
|
-
return [String((_a3 = t.attrs) == null ? void 0 : _a3.id), mindMapId()];
|
|
396
|
-
}));
|
|
397
|
-
const siblings = mindMapTree(map.model).filter((t) => t.parentId === parentId);
|
|
398
|
-
const nodes = topics.map((t, i) => {
|
|
399
|
-
var _a3, _b2, _c2, _d2, _e;
|
|
400
|
-
return editor.schema.nodeFromJSON({ ...t, attrs: {
|
|
401
|
-
...t.attrs,
|
|
402
|
-
id: ids.get(String((_a3 = t.attrs) == null ? void 0 : _a3.id)),
|
|
403
|
-
parentId: ids.get(String((_b2 = t.attrs) == null ? void 0 : _b2.parentId)) ?? parentId,
|
|
404
|
-
order: ids.has(String((_c2 = t.attrs) == null ? void 0 : _c2.parentId)) ? Number((_d2 = t.attrs) == null ? void 0 : _d2.order) || 0 : (((_e = siblings.at(-1)) == null ? void 0 : _e.order) ?? -1) + 1 + i
|
|
405
|
-
} });
|
|
406
|
-
});
|
|
407
|
-
const tr = editor.state.tr.insert(topicInsertPos(map), nodes);
|
|
408
|
-
for (const r of branch.filter((t) => t.type === "mindMapRelation")) {
|
|
409
|
-
if (ids.has(String((_a2 = r.attrs) == null ? void 0 : _a2.source)) && ids.has(String((_b = r.attrs) == null ? void 0 : _b.target)))
|
|
410
|
-
tr.insert(tr.mapping.map(map.pos + map.node.nodeSize - 1), editor.schema.nodes.mindMapRelation.create({ ...r.attrs, id: mindMapId(), source: ids.get(String((_c = r.attrs) == null ? void 0 : _c.source)), target: ids.get(String((_d = r.attrs) == null ? void 0 : _d.target)) }));
|
|
411
|
-
}
|
|
412
|
-
structuralChange(tr);
|
|
413
|
-
return nodes[0].attrs.id;
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
context,
|
|
417
|
-
snapshot: () => {
|
|
418
|
-
var _a2;
|
|
419
|
-
return ((_a2 = current()) == null ? void 0 : _a2.model) ?? null;
|
|
420
|
-
},
|
|
421
|
-
editable,
|
|
422
|
-
beginText,
|
|
423
|
-
text,
|
|
424
|
-
composition,
|
|
425
|
-
patch,
|
|
426
|
-
addParent,
|
|
427
|
-
indent,
|
|
428
|
-
format,
|
|
429
|
-
clearFormat,
|
|
430
|
-
replace,
|
|
431
|
-
relation,
|
|
432
|
-
deleteRelation,
|
|
433
|
-
hasActiveText: () => sessions.size > 0,
|
|
434
|
-
endText: (id, field = "title") => {
|
|
435
|
-
var _a2, _b, _c;
|
|
436
|
-
sessions.delete(`${id}::${field}`);
|
|
437
|
-
const local = (_b = (_a2 = context.awareness) == null ? void 0 : _a2.getLocalState()) == null ? void 0 : _b.mindMap;
|
|
438
|
-
if ((local == null ? void 0 : local.blockId) === identity) (_c = context.awareness) == null ? void 0 : _c.setLocalStateField("mindMap", { ...local, editing: sessions.size > 0 });
|
|
439
|
-
},
|
|
440
|
-
add,
|
|
441
|
-
addRootChild,
|
|
442
|
-
addSibling,
|
|
443
|
-
move,
|
|
444
|
-
moveToSide,
|
|
445
|
-
remove,
|
|
446
|
-
removeMany,
|
|
447
|
-
settings,
|
|
448
|
-
copyBranch,
|
|
449
|
-
pasteBranch,
|
|
450
|
-
undo: () => editable() && editor.commands.undo(),
|
|
451
|
-
redo: () => editable() && editor.commands.redo(),
|
|
452
|
-
canUndo: () => editable() && editor.can().undo(),
|
|
453
|
-
canRedo: () => editable() && editor.can().redo(),
|
|
454
|
-
canExport: () => {
|
|
455
|
-
var _a2;
|
|
456
|
-
return ((_a2 = context.canExport) == null ? void 0 : _a2.call(context)) ?? false;
|
|
457
|
-
},
|
|
458
|
-
status: () => {
|
|
459
|
-
var _a2;
|
|
460
|
-
return ((_a2 = context.status) == null ? void 0 : _a2.call(context)) ?? "";
|
|
461
|
-
},
|
|
462
|
-
subscribe(fn) {
|
|
463
|
-
listeners.add(fn);
|
|
464
|
-
return () => listeners.delete(fn);
|
|
465
|
-
},
|
|
466
|
-
dispose() {
|
|
467
|
-
composition(false);
|
|
468
|
-
disposed = true;
|
|
469
|
-
editor.off("transaction", onTransaction);
|
|
470
|
-
editor.off("update", notify);
|
|
471
|
-
notify();
|
|
472
|
-
listeners.clear();
|
|
473
|
-
sessions.clear();
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
export {
|
|
478
|
-
createMindMapController as c
|
|
479
|
-
};
|