@dxos/react-ui-editor 0.3.11-main.2e1a8e1 → 0.3.11-main.2f1331c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +1365 -925
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +1 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +3 -2
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/{yjs.stories.d.ts → hooks.stories.d.ts} +13 -2
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +25 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +23 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/index.d.ts +2 -0
- package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +5 -5
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/semaphore.d.ts +2 -1
- package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness.d.ts +2 -4
- package/dist/types/src/extensions/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/basic.d.ts +2 -2
- package/dist/types/src/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +9 -5
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -7
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +13 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
- package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +8 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
- package/dist/types/src/hooks/awareness-provider.d.ts +7 -4
- package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/hooks/defs.d.ts +1 -4
- package/dist/types/src/hooks/defs.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +3 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +4 -0
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -0
- package/dist/types/src/hooks/useEditorView.d.ts +17 -0
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts +39 -0
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts +2 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/package.json +39 -29
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +15 -19
- package/src/components/TextEditor/TextEditor.tsx +45 -25
- package/src/components/TextEditor/automerge.stories.tsx +1 -2
- package/src/components/TextEditor/comments.stories.tsx +8 -8
- package/src/components/TextEditor/hooks.stories.tsx +106 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +90 -0
- package/src/components/Toolbar/Toolbar.tsx +166 -0
- package/src/components/Toolbar/index.ts +5 -0
- package/src/components/index.ts +1 -0
- package/src/extensions/automerge/automerge.spec.tsx +76 -0
- package/src/extensions/automerge/automerge.test.ts +13 -0
- package/src/extensions/automerge/automerge.ts +44 -10
- package/src/extensions/automerge/cursor.ts +3 -3
- package/src/extensions/automerge/defs.ts +9 -9
- package/src/extensions/automerge/semaphore.ts +17 -19
- package/src/extensions/automerge/update-automerge.ts +12 -6
- package/src/extensions/automerge/update-codemirror.ts +5 -5
- package/src/extensions/awareness.ts +17 -34
- package/src/extensions/basic.ts +17 -15
- package/src/extensions/comments.ts +126 -78
- package/src/extensions/index.ts +0 -7
- package/src/extensions/markdown/bundle.ts +9 -8
- package/src/extensions/markdown/code.ts +150 -0
- package/src/extensions/markdown/formatting.ts +188 -0
- package/src/extensions/markdown/heading.ts +59 -0
- package/src/extensions/markdown/highlight.ts +9 -15
- package/src/extensions/{hr.ts → markdown/hr.ts} +3 -4
- package/src/extensions/markdown/index.ts +8 -0
- package/src/extensions/{link.ts → markdown/link.ts} +5 -2
- package/src/extensions/{tasklist.ts → markdown/tasklist.ts} +2 -3
- package/src/hooks/awareness-provider.ts +24 -20
- package/src/hooks/defs.ts +1 -6
- package/src/hooks/index.ts +3 -2
- package/src/hooks/useActionHandler.ts +62 -0
- package/src/hooks/useEditorView.ts +29 -0
- package/src/hooks/useTextEditor.ts +153 -0
- package/src/hooks/useTextModel.ts +48 -11
- package/src/styles/markdown.ts +9 -10
- package/src/themes/default.ts +4 -4
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts +0 -12
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/code.d.ts.map +0 -1
- package/dist/types/src/extensions/hr.d.ts.map +0 -1
- package/dist/types/src/extensions/image.d.ts.map +0 -1
- package/dist/types/src/extensions/link.d.ts.map +0 -1
- package/dist/types/src/extensions/table.d.ts.map +0 -1
- package/dist/types/src/extensions/tasklist.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts +0 -4
- package/dist/types/src/extensions/yjs/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/index.d.ts +0 -2
- package/dist/types/src/extensions/yjs/index.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.d.ts +0 -4
- package/dist/types/src/extensions/yjs/yjs.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.test.d.ts +0 -2
- package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge.d.ts +0 -4
- package/dist/types/src/hooks/automerge.d.ts.map +0 -1
- package/dist/types/src/hooks/yjs.d.ts +0 -28
- package/dist/types/src/hooks/yjs.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -3
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/proto/gen/schema.d.ts +0 -15
- package/dist/types/src/testing/proto/gen/schema.d.ts.map +0 -1
- package/dist/types/src/testing/proto/index.d.ts +0 -2
- package/dist/types/src/testing/proto/index.d.ts.map +0 -1
- package/dist/types/src/testing/replicator.d.ts +0 -45
- package/dist/types/src/testing/replicator.d.ts.map +0 -1
- package/src/components/TextEditor/codemirror.stories.ts +0 -115
- package/src/components/TextEditor/yjs.stories.tsx +0 -56
- package/src/extensions/code.ts +0 -104
- package/src/extensions/yjs/cursor.ts +0 -22
- package/src/extensions/yjs/index.ts +0 -5
- package/src/extensions/yjs/yjs.test.ts +0 -35
- package/src/extensions/yjs/yjs.ts +0 -16
- package/src/hooks/automerge.ts +0 -53
- package/src/hooks/yjs.ts +0 -157
- package/src/testing/index.ts +0 -6
- package/src/testing/proto/gen/schema.ts +0 -49
- package/src/testing/proto/index.ts +0 -5
- package/src/testing/proto/schema.proto +0 -15
- package/src/testing/replicator.ts +0 -184
- /package/dist/types/src/extensions/{code.d.ts → markdown/code.d.ts} +0 -0
- /package/dist/types/src/extensions/{hr.d.ts → markdown/hr.d.ts} +0 -0
- /package/dist/types/src/extensions/{image.d.ts → markdown/image.d.ts} +0 -0
- /package/dist/types/src/extensions/{link.d.ts → markdown/link.d.ts} +0 -0
- /package/dist/types/src/extensions/{table.d.ts → markdown/table.d.ts} +0 -0
- /package/dist/types/src/extensions/{tasklist.d.ts → markdown/tasklist.d.ts} +0 -0
- /package/src/extensions/{image.ts → markdown/image.ts} +0 -0
- /package/src/extensions/{table.ts → markdown/table.ts} +0 -0
|
@@ -8,13 +8,13 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
8
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
9
9
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
10
10
|
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
11
|
-
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
11
|
import { vim } from "@replit/codemirror-vim";
|
|
13
12
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
|
-
import React, { forwardRef, useCallback, useEffect as
|
|
13
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
15
14
|
import { log as log2 } from "@dxos/log";
|
|
16
|
-
import { useThemeContext
|
|
17
|
-
import {
|
|
15
|
+
import { useThemeContext } from "@dxos/react-ui";
|
|
16
|
+
import { attentionSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
17
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
18
18
|
|
|
19
19
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
20
20
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
@@ -53,13 +53,14 @@ var autocomplete = ({ onSearch }) => {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
56
|
+
import { invertedEffects } from "@codemirror/commands";
|
|
56
57
|
import { StateField } from "@codemirror/state";
|
|
57
|
-
import { EditorView } from "@codemirror/view";
|
|
58
|
-
import { next as
|
|
58
|
+
import { EditorView, ViewPlugin } from "@codemirror/view";
|
|
59
|
+
import { next as A4 } from "@dxos/automerge/automerge";
|
|
59
60
|
|
|
60
61
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
|
61
62
|
import get from "lodash.get";
|
|
62
|
-
import { next as
|
|
63
|
+
import { next as A } from "@dxos/automerge/automerge";
|
|
63
64
|
var cursorConverter = (handle, path) => ({
|
|
64
65
|
// TODO(burdon): Handle assoc to associate with a previous character.
|
|
65
66
|
toCursor: (pos) => {
|
|
@@ -71,7 +72,7 @@ var cursorConverter = (handle, path) => ({
|
|
|
71
72
|
if (typeof value === "string" && value.length <= pos) {
|
|
72
73
|
return "end";
|
|
73
74
|
}
|
|
74
|
-
return
|
|
75
|
+
return A.getCursor(doc, path.slice(), pos);
|
|
75
76
|
},
|
|
76
77
|
fromCursor: (cursor) => {
|
|
77
78
|
if (cursor === "") {
|
|
@@ -89,26 +90,28 @@ var cursorConverter = (handle, path) => ({
|
|
|
89
90
|
return 0;
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
|
-
return
|
|
93
|
+
return A.getCursorPosition(doc, path.slice(), cursor);
|
|
93
94
|
}
|
|
94
95
|
});
|
|
95
96
|
|
|
96
97
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
97
98
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
98
|
-
var effectType = StateEffect.define({});
|
|
99
|
-
var reconcileAnnotationType = Annotation.define();
|
|
100
99
|
var getPath = (state, field) => state.field(field).path;
|
|
101
100
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
102
|
-
var
|
|
101
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
102
|
+
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
103
103
|
newHeads
|
|
104
104
|
});
|
|
105
|
-
var
|
|
105
|
+
var reconcileAnnotation = Annotation.define();
|
|
106
|
+
var isReconcile = (tr) => {
|
|
107
|
+
return !!tr.annotation(reconcileAnnotation);
|
|
108
|
+
};
|
|
106
109
|
|
|
107
110
|
// packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
|
|
108
|
-
import { next as
|
|
111
|
+
import { next as A3 } from "@dxos/automerge/automerge";
|
|
109
112
|
|
|
110
113
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
|
111
|
-
import { next as
|
|
114
|
+
import { next as A2 } from "@dxos/automerge/automerge";
|
|
112
115
|
var updateAutomerge = (field, handle, transactions, state) => {
|
|
113
116
|
const { lastHeads, path } = state.field(field);
|
|
114
117
|
let hasChanges = false;
|
|
@@ -121,11 +124,19 @@ var updateAutomerge = (field, handle, transactions, state) => {
|
|
|
121
124
|
return void 0;
|
|
122
125
|
}
|
|
123
126
|
const newHeads = handle.changeAt(lastHeads, (doc) => {
|
|
127
|
+
const invertedTransactions = [];
|
|
124
128
|
for (const tr of transactions) {
|
|
125
|
-
tr.changes.iterChanges((fromA, toA, _fromB, _toB,
|
|
126
|
-
|
|
129
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
130
|
+
invertedTransactions.push({
|
|
131
|
+
from: fromA,
|
|
132
|
+
del: toA - fromA,
|
|
133
|
+
insert
|
|
134
|
+
});
|
|
127
135
|
});
|
|
128
136
|
}
|
|
137
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
138
|
+
A2.splice(doc, path.slice(), from, del, insert.toString());
|
|
139
|
+
});
|
|
129
140
|
});
|
|
130
141
|
return newHeads ?? void 0;
|
|
131
142
|
};
|
|
@@ -140,13 +151,13 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
140
151
|
selection = selection.map(changeSet, 1);
|
|
141
152
|
view.dispatch({
|
|
142
153
|
changes: changeSet,
|
|
143
|
-
annotations:
|
|
154
|
+
annotations: reconcileAnnotation.of(false)
|
|
144
155
|
});
|
|
145
156
|
}
|
|
146
157
|
}
|
|
147
158
|
view.dispatch({
|
|
148
159
|
selection,
|
|
149
|
-
annotations:
|
|
160
|
+
annotations: reconcileAnnotation.of(false)
|
|
150
161
|
});
|
|
151
162
|
};
|
|
152
163
|
var handlePatch = (patch, target, state) => {
|
|
@@ -167,7 +178,7 @@ var handleInsert = (target, patch) => {
|
|
|
167
178
|
if (index == null) {
|
|
168
179
|
return [];
|
|
169
180
|
}
|
|
170
|
-
const text = patch.values.map((
|
|
181
|
+
const text = patch.values.map((value) => value ? value.toString() : "").join("");
|
|
171
182
|
return [
|
|
172
183
|
{
|
|
173
184
|
from: index,
|
|
@@ -245,36 +256,37 @@ var PatchSemaphore = class {
|
|
|
245
256
|
this._state = _state;
|
|
246
257
|
this._inReconcile = false;
|
|
247
258
|
}
|
|
248
|
-
// NOTE: Cannot destruct view.state.
|
|
249
259
|
reconcile(view) {
|
|
250
|
-
if (this._inReconcile) {
|
|
251
|
-
|
|
260
|
+
if (!this._inReconcile) {
|
|
261
|
+
this._inReconcile = true;
|
|
262
|
+
this.doReconcile(view);
|
|
263
|
+
this._inReconcile = false;
|
|
252
264
|
}
|
|
253
|
-
|
|
265
|
+
}
|
|
266
|
+
doReconcile(view) {
|
|
254
267
|
const path = getPath(view.state, this._state);
|
|
255
268
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
256
269
|
let selection = view.state.selection;
|
|
257
|
-
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !
|
|
270
|
+
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
258
271
|
const toInvert = transactions.slice().reverse();
|
|
259
|
-
for (const
|
|
260
|
-
const inverted =
|
|
272
|
+
for (const tr of toInvert) {
|
|
273
|
+
const inverted = tr.changes.invert(tr.startState.doc);
|
|
261
274
|
selection = selection.map(inverted);
|
|
262
275
|
view.dispatch({
|
|
263
276
|
changes: inverted,
|
|
264
|
-
annotations:
|
|
277
|
+
annotations: reconcileAnnotation.of(true)
|
|
265
278
|
});
|
|
266
279
|
}
|
|
267
280
|
let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
268
281
|
if (newHeads === null || newHeads === void 0) {
|
|
269
|
-
newHeads =
|
|
282
|
+
newHeads = A3.getHeads(this._handle.docSync());
|
|
270
283
|
}
|
|
271
|
-
const diff =
|
|
284
|
+
const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
|
|
272
285
|
updateCodeMirror(view, selection, path, diff);
|
|
273
286
|
view.dispatch({
|
|
274
287
|
effects: updateHeads(newHeads),
|
|
275
|
-
annotations:
|
|
288
|
+
annotations: reconcileAnnotation.of(false)
|
|
276
289
|
});
|
|
277
|
-
this._inReconcile = false;
|
|
278
290
|
}
|
|
279
291
|
};
|
|
280
292
|
|
|
@@ -292,9 +304,9 @@ var Cursor = class _Cursor {
|
|
|
292
304
|
}
|
|
293
305
|
static {
|
|
294
306
|
this.getCursorFromRange = (state, range) => {
|
|
295
|
-
const
|
|
296
|
-
const from =
|
|
297
|
-
const to =
|
|
307
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
308
|
+
const from = cursorConverter2.toCursor(range.from);
|
|
309
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
|
298
310
|
return [
|
|
299
311
|
from,
|
|
300
312
|
to
|
|
@@ -303,10 +315,10 @@ var Cursor = class _Cursor {
|
|
|
303
315
|
}
|
|
304
316
|
static {
|
|
305
317
|
this.getRangeFromCursor = (state, cursor) => {
|
|
306
|
-
const
|
|
318
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
307
319
|
const parts = cursor.split(":");
|
|
308
|
-
const from =
|
|
309
|
-
const to =
|
|
320
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
|
321
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
|
310
322
|
return from !== void 0 && to !== void 0 ? {
|
|
311
323
|
from,
|
|
312
324
|
to
|
|
@@ -316,11 +328,11 @@ var Cursor = class _Cursor {
|
|
|
316
328
|
};
|
|
317
329
|
|
|
318
330
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
319
|
-
var
|
|
320
|
-
const
|
|
331
|
+
var automerge = ({ handle, path }) => {
|
|
332
|
+
const syncState = StateField.define({
|
|
321
333
|
create: () => ({
|
|
322
334
|
path: path.slice(),
|
|
323
|
-
lastHeads:
|
|
335
|
+
lastHeads: A4.getHeads(handle.docSync()),
|
|
324
336
|
unreconciledTransactions: []
|
|
325
337
|
}),
|
|
326
338
|
update: (value, tr) => {
|
|
@@ -331,7 +343,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
331
343
|
};
|
|
332
344
|
let clearUnreconciled = false;
|
|
333
345
|
for (const effect of tr.effects) {
|
|
334
|
-
if (effect.is(
|
|
346
|
+
if (effect.is(updateHeadsEffect)) {
|
|
335
347
|
result.lastHeads = effect.value.newHeads;
|
|
336
348
|
clearUnreconciled = true;
|
|
337
349
|
}
|
|
@@ -339,80 +351,78 @@ var automerge3 = ({ handle, path }) => {
|
|
|
339
351
|
if (clearUnreconciled) {
|
|
340
352
|
result.unreconciledTransactions = [];
|
|
341
353
|
} else {
|
|
342
|
-
if (!
|
|
354
|
+
if (!isReconcile(tr)) {
|
|
343
355
|
result.unreconciledTransactions.push(tr);
|
|
344
356
|
}
|
|
345
357
|
}
|
|
346
358
|
return result;
|
|
347
359
|
}
|
|
348
360
|
});
|
|
349
|
-
const semaphore = new PatchSemaphore(handle,
|
|
361
|
+
const semaphore = new PatchSemaphore(handle, syncState);
|
|
350
362
|
return [
|
|
351
363
|
Cursor.converter.of(cursorConverter(handle, path)),
|
|
364
|
+
syncState,
|
|
365
|
+
// Reconcile external updates.
|
|
366
|
+
ViewPlugin.fromClass(class {
|
|
367
|
+
constructor(_view) {
|
|
368
|
+
this._view = _view;
|
|
369
|
+
handle.addListener("change", this._handleChange.bind(this));
|
|
370
|
+
}
|
|
371
|
+
destroy() {
|
|
372
|
+
handle.removeListener("change", this._handleChange.bind(this));
|
|
373
|
+
}
|
|
374
|
+
_handleChange() {
|
|
375
|
+
semaphore.reconcile(this._view);
|
|
376
|
+
}
|
|
377
|
+
}),
|
|
378
|
+
// Reconcile local updates.
|
|
352
379
|
EditorView.updateListener.of(({ view, changes }) => {
|
|
353
380
|
if (!changes.empty) {
|
|
354
381
|
semaphore.reconcile(view);
|
|
355
382
|
}
|
|
356
383
|
}),
|
|
357
|
-
|
|
384
|
+
// TODO(burdon): Record undo transactions.
|
|
385
|
+
// See https://github.com/yjs/y-codemirror.next/tree/main
|
|
386
|
+
// https://codemirror.net/examples/inverted-effect
|
|
387
|
+
invertedEffects.of((tr) => {
|
|
388
|
+
const effects = [];
|
|
389
|
+
if (!tr.changes.empty) {
|
|
390
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return effects;
|
|
394
|
+
})
|
|
358
395
|
];
|
|
359
396
|
};
|
|
360
397
|
|
|
361
398
|
// packages/ui/react-ui-editor/src/extensions/awareness.ts
|
|
362
399
|
import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
|
|
363
|
-
import { Decoration, EditorView as EditorView2, ViewPlugin, WidgetType } from "@codemirror/view";
|
|
364
|
-
import { useEffect } from "react";
|
|
400
|
+
import { Decoration, EditorView as EditorView2, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
|
365
401
|
import { Event } from "@dxos/async";
|
|
366
402
|
import { Context } from "@dxos/context";
|
|
367
|
-
import { generateName } from "@dxos/display-name";
|
|
368
|
-
import { useThemeContext } from "@dxos/react-ui";
|
|
369
|
-
import { getColorForValue } from "@dxos/react-ui-theme";
|
|
370
403
|
var dummyProvider = {
|
|
371
404
|
remoteStateChange: new Event(),
|
|
372
405
|
open: () => {
|
|
373
406
|
},
|
|
374
407
|
close: () => {
|
|
375
408
|
},
|
|
409
|
+
getRemoteStates: () => [],
|
|
376
410
|
update: () => {
|
|
377
|
-
}
|
|
378
|
-
getRemoteStates: () => []
|
|
411
|
+
}
|
|
379
412
|
};
|
|
380
|
-
var
|
|
413
|
+
var awarenessProvider = Facet2.define({
|
|
381
414
|
combine: (providers) => providers[0] ?? dummyProvider
|
|
382
415
|
});
|
|
383
416
|
var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
384
417
|
var awareness = (provider = dummyProvider) => {
|
|
385
418
|
return [
|
|
386
|
-
|
|
387
|
-
|
|
419
|
+
awarenessProvider.of(provider),
|
|
420
|
+
ViewPlugin2.fromClass(RemoteSelectionsDecorator, {
|
|
388
421
|
decorations: (value) => value.decorations
|
|
389
422
|
}),
|
|
390
423
|
styles
|
|
391
424
|
];
|
|
392
425
|
};
|
|
393
|
-
var useAwareness = ({ awareness: awareness2, peer }) => {
|
|
394
|
-
const { themeMode } = useThemeContext();
|
|
395
|
-
useEffect(() => {
|
|
396
|
-
if (awareness2 && peer) {
|
|
397
|
-
awareness2.setLocalStateField("user", {
|
|
398
|
-
name: peer.name ?? generateName(peer.id),
|
|
399
|
-
color: getColorForValue({
|
|
400
|
-
value: peer.id,
|
|
401
|
-
type: "color"
|
|
402
|
-
}),
|
|
403
|
-
colorLight: getColorForValue({
|
|
404
|
-
value: peer.id,
|
|
405
|
-
themeMode,
|
|
406
|
-
type: "highlight"
|
|
407
|
-
})
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
}, [
|
|
411
|
-
awareness2,
|
|
412
|
-
peer,
|
|
413
|
-
themeMode
|
|
414
|
-
]);
|
|
415
|
-
};
|
|
416
426
|
var RemoteSelectionsDecorator = class {
|
|
417
427
|
constructor(view) {
|
|
418
428
|
this.decorations = RangeSet.of([]);
|
|
@@ -420,7 +430,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
420
430
|
this._lastAnchor = void 0;
|
|
421
431
|
this._lastHead = void 0;
|
|
422
432
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
423
|
-
this._provider = view.state.facet(
|
|
433
|
+
this._provider = view.state.facet(awarenessProvider);
|
|
424
434
|
this._provider.open();
|
|
425
435
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
426
436
|
view.dispatch({
|
|
@@ -574,39 +584,41 @@ var styles = EditorView2.baseTheme({
|
|
|
574
584
|
marginLeft: "-1px",
|
|
575
585
|
marginRight: "-1px",
|
|
576
586
|
boxSizing: "border-box",
|
|
577
|
-
display: "inline"
|
|
587
|
+
display: "inline",
|
|
588
|
+
cursor: "pointer"
|
|
578
589
|
},
|
|
579
590
|
".cm-collab-selectionCaretDot": {
|
|
580
591
|
borderRadius: "50%",
|
|
581
592
|
position: "absolute",
|
|
582
|
-
width: ".
|
|
583
|
-
height: ".
|
|
584
|
-
top: "-.
|
|
585
|
-
left: "-.
|
|
593
|
+
width: ".5em",
|
|
594
|
+
height: ".5em",
|
|
595
|
+
top: "-.25em",
|
|
596
|
+
left: "-.25em",
|
|
586
597
|
backgroundColor: "inherit",
|
|
587
598
|
transition: "transform .3s ease-in-out",
|
|
588
599
|
boxSizing: "border-box"
|
|
589
600
|
},
|
|
590
601
|
".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
|
|
591
|
-
|
|
592
|
-
|
|
602
|
+
transform: "scale(0)",
|
|
603
|
+
transformOrigin: "center"
|
|
593
604
|
},
|
|
594
605
|
".cm-collab-selectionInfo": {
|
|
595
606
|
position: "absolute",
|
|
596
|
-
|
|
597
|
-
|
|
607
|
+
transform: "translate(-50%, 0)",
|
|
608
|
+
top: "-20px",
|
|
609
|
+
left: 0,
|
|
598
610
|
fontSize: ".75em",
|
|
599
|
-
fontFamily: "serif",
|
|
611
|
+
fontFamily: "sans-serif",
|
|
600
612
|
fontStyle: "normal",
|
|
601
613
|
fontWeight: "normal",
|
|
602
614
|
lineHeight: "normal",
|
|
603
615
|
userSelect: "none",
|
|
604
616
|
color: "white",
|
|
605
|
-
|
|
606
|
-
paddingRight: "2px",
|
|
617
|
+
padding: "2px",
|
|
607
618
|
zIndex: 101,
|
|
608
619
|
transition: "opacity .3s ease-in-out",
|
|
609
620
|
backgroundColor: "inherit",
|
|
621
|
+
borderRadius: "2px",
|
|
610
622
|
// These should be separate.
|
|
611
623
|
opacity: 0,
|
|
612
624
|
transitionDelay: "0s",
|
|
@@ -624,18 +636,19 @@ import { history } from "@codemirror/commands";
|
|
|
624
636
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
625
637
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
626
638
|
import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
627
|
-
|
|
628
|
-
|
|
639
|
+
import { isNotFalsy } from "@dxos/util";
|
|
640
|
+
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
|
|
641
|
+
lineWrapping && EditorView3.lineWrapping,
|
|
629
642
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
630
643
|
bracketMatching(),
|
|
631
644
|
closeBrackets(),
|
|
632
645
|
drawSelection(),
|
|
633
646
|
highlightActiveLine(),
|
|
634
647
|
history(),
|
|
635
|
-
_placeholder
|
|
648
|
+
_placeholder && placeholder(_placeholder),
|
|
636
649
|
// https://github.com/codemirror/theme-one-dark
|
|
637
650
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
638
|
-
];
|
|
651
|
+
].filter(isNotFalsy);
|
|
639
652
|
|
|
640
653
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
641
654
|
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
@@ -674,10 +687,10 @@ var blast = (options = defaultOptions) => {
|
|
|
674
687
|
const getPoint = (view, pos) => {
|
|
675
688
|
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
676
689
|
const element = document.elementFromPoint(x, y);
|
|
677
|
-
const { offsetLeft: left = 0, offsetTop:
|
|
690
|
+
const { offsetLeft: left = 0, offsetTop: top2 = 0 } = view.scrollDOM.parentElement ?? {};
|
|
678
691
|
const point = {
|
|
679
692
|
x: x - left,
|
|
680
|
-
y: y -
|
|
693
|
+
y: y - top2
|
|
681
694
|
};
|
|
682
695
|
return {
|
|
683
696
|
element,
|
|
@@ -947,9 +960,14 @@ var random = (min, max) => {
|
|
|
947
960
|
return min + ~~(Math.random() * (max - min + 1));
|
|
948
961
|
};
|
|
949
962
|
|
|
950
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
951
|
-
import {
|
|
952
|
-
import {
|
|
963
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
964
|
+
import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
|
|
965
|
+
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
966
|
+
import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
|
|
967
|
+
import sortBy from "lodash.sortby";
|
|
968
|
+
import { useEffect } from "react";
|
|
969
|
+
import { debounce } from "@dxos/async";
|
|
970
|
+
import { nonNullable } from "@dxos/util";
|
|
953
971
|
|
|
954
972
|
// packages/ui/react-ui-editor/src/styles/cursors.ts
|
|
955
973
|
import * as random2 from "lib0/random";
|
|
@@ -992,34 +1010,15 @@ var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
|
|
|
992
1010
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
993
1011
|
import { mx } from "@dxos/react-ui-theme";
|
|
994
1012
|
var headings = {
|
|
995
|
-
1:
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
1005
|
-
"-ml-[7px]"
|
|
1006
|
-
],
|
|
1007
|
-
4: [
|
|
1008
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
1009
|
-
"-ml-[6px]"
|
|
1010
|
-
],
|
|
1011
|
-
5: [
|
|
1012
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
1013
|
-
"-ml-[5px]"
|
|
1014
|
-
],
|
|
1015
|
-
6: [
|
|
1016
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
1017
|
-
"-ml-[4px]"
|
|
1018
|
-
]
|
|
1019
|
-
};
|
|
1020
|
-
var heading = (level, readonly) => {
|
|
1021
|
-
const [style, offset] = headings[level];
|
|
1022
|
-
return mx(style, readonly && offset);
|
|
1013
|
+
1: "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
1014
|
+
2: "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
1015
|
+
3: "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
1016
|
+
4: "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
1017
|
+
5: "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
1018
|
+
6: "mbs-4 mbe-2 font-medium text-inherit no-underline"
|
|
1019
|
+
};
|
|
1020
|
+
var heading = (level) => {
|
|
1021
|
+
return headings[level];
|
|
1023
1022
|
};
|
|
1024
1023
|
var light = "text-neutral-200 dark:text-neutral-800";
|
|
1025
1024
|
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
@@ -1037,89 +1036,6 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
|
1037
1036
|
var tokens = tailwindConfig({}).theme;
|
|
1038
1037
|
var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
|
|
1039
1038
|
|
|
1040
|
-
// packages/ui/react-ui-editor/src/extensions/code.ts
|
|
1041
|
-
var CODE_REGEX = /```[\s\S]*?```/gs;
|
|
1042
|
-
var styles2 = EditorView5.baseTheme({
|
|
1043
|
-
"& .cm-codeblock": {
|
|
1044
|
-
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1045
|
-
},
|
|
1046
|
-
'&light [aria-readonly="true"] .cm-codeblock': {
|
|
1047
|
-
background: getToken("extend.colors.neutral.50")
|
|
1048
|
-
},
|
|
1049
|
-
'&dark [aria-readonly="true"] .cm-codeblock': {
|
|
1050
|
-
background: getToken("extend.colors.neutral.850")
|
|
1051
|
-
},
|
|
1052
|
-
'& [aria-readonly="true"] .cm-codeblock': {
|
|
1053
|
-
display: "block",
|
|
1054
|
-
paddingInline: "4px !important"
|
|
1055
|
-
},
|
|
1056
|
-
'& [aria-readonly="true"] .cm-codeblock-first': {
|
|
1057
|
-
paddingTop: "4px !important",
|
|
1058
|
-
borderTopLeftRadius: "4px",
|
|
1059
|
-
borderTopRightRadius: "4px"
|
|
1060
|
-
},
|
|
1061
|
-
'& [aria-readonly="true"] .cm-codeblock-last': {
|
|
1062
|
-
paddingBottom: "4px !important",
|
|
1063
|
-
borderBottomLeftRadius: "4px",
|
|
1064
|
-
borderBottomRightRadius: "4px"
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
var getLineRange = (lines, from, to) => {
|
|
1068
|
-
const start = lines.findIndex((line) => line.from >= from);
|
|
1069
|
-
const end = lines.findIndex((line) => line.to >= to);
|
|
1070
|
-
return [
|
|
1071
|
-
start,
|
|
1072
|
-
end
|
|
1073
|
-
];
|
|
1074
|
-
};
|
|
1075
|
-
var code2 = () => {
|
|
1076
|
-
const buildDecorations5 = (view) => {
|
|
1077
|
-
const decorations = [];
|
|
1078
|
-
const text = view.state.doc.sliceString(0);
|
|
1079
|
-
const matches = text.matchAll(CODE_REGEX);
|
|
1080
|
-
const blocks = view.viewportLineBlocks;
|
|
1081
|
-
for (const match of matches) {
|
|
1082
|
-
const range = getLineRange(blocks, match.index, match.index + match[0].length);
|
|
1083
|
-
for (let i = range[0]; i <= range[1]; i++) {
|
|
1084
|
-
const block = blocks[i];
|
|
1085
|
-
decorations.push(Decoration2.line({
|
|
1086
|
-
class: mx2("cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1087
|
-
}).range(block.from));
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
return Decoration2.set(decorations);
|
|
1091
|
-
};
|
|
1092
|
-
return [
|
|
1093
|
-
ViewPlugin2.fromClass(class {
|
|
1094
|
-
constructor(view) {
|
|
1095
|
-
this.hasFocus = false;
|
|
1096
|
-
this.decorations = buildDecorations5(view);
|
|
1097
|
-
}
|
|
1098
|
-
update(update2) {
|
|
1099
|
-
if (
|
|
1100
|
-
// TODO(burdon): Generalize for other extensions.
|
|
1101
|
-
this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
|
|
1102
|
-
) {
|
|
1103
|
-
this.hasFocus = update2.view.hasFocus;
|
|
1104
|
-
this.decorations = buildDecorations5(update2.view);
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
}, {
|
|
1108
|
-
decorations: (value) => value.decorations
|
|
1109
|
-
}),
|
|
1110
|
-
styles2
|
|
1111
|
-
];
|
|
1112
|
-
};
|
|
1113
|
-
|
|
1114
|
-
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1115
|
-
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1116
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
|
|
1117
|
-
import sortBy from "lodash.sortby";
|
|
1118
|
-
import { useEffect as useEffect2 } from "react";
|
|
1119
|
-
import { debounce } from "@dxos/async";
|
|
1120
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1121
|
-
import { nonNullable } from "@dxos/util";
|
|
1122
|
-
|
|
1123
1039
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1124
1040
|
import { log } from "@dxos/log";
|
|
1125
1041
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
@@ -1156,24 +1072,21 @@ var logChanges = (trs) => {
|
|
|
1156
1072
|
};
|
|
1157
1073
|
|
|
1158
1074
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1159
|
-
var
|
|
1160
|
-
var styles3 = EditorView6.baseTheme({
|
|
1075
|
+
var styles2 = EditorView5.baseTheme({
|
|
1161
1076
|
"& .cm-comment": {
|
|
1162
1077
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1163
1078
|
},
|
|
1164
|
-
"& .cm-comment-
|
|
1079
|
+
"& .cm-comment-current": {
|
|
1165
1080
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1166
1081
|
}
|
|
1167
1082
|
});
|
|
1168
|
-
var
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
};
|
|
1176
|
-
var setFocus = (view, id, center = true) => {
|
|
1083
|
+
var commentMark = Decoration2.mark({
|
|
1084
|
+
class: "cm-comment"
|
|
1085
|
+
});
|
|
1086
|
+
var commentCurrentMark = Decoration2.mark({
|
|
1087
|
+
class: "cm-comment-current"
|
|
1088
|
+
});
|
|
1089
|
+
var focusComment = (view, id, center = true) => {
|
|
1177
1090
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
1178
1091
|
if (!comment?.comment.cursor) {
|
|
1179
1092
|
return;
|
|
@@ -1186,11 +1099,11 @@ var setFocus = (view, id, center = true) => {
|
|
|
1186
1099
|
},
|
|
1187
1100
|
effects: [
|
|
1188
1101
|
//
|
|
1189
|
-
|
|
1102
|
+
EditorView5.scrollIntoView(range.from, center ? {
|
|
1190
1103
|
y: "center"
|
|
1191
1104
|
} : void 0),
|
|
1192
1105
|
setSelection.of({
|
|
1193
|
-
|
|
1106
|
+
current: id
|
|
1194
1107
|
})
|
|
1195
1108
|
]
|
|
1196
1109
|
});
|
|
@@ -1235,23 +1148,23 @@ var commentsState = StateField2.define({
|
|
|
1235
1148
|
return value;
|
|
1236
1149
|
}
|
|
1237
1150
|
});
|
|
1238
|
-
var
|
|
1151
|
+
var commentsDecorations = EditorView5.decorations.compute([
|
|
1239
1152
|
commentsState
|
|
1240
1153
|
], (state) => {
|
|
1241
|
-
const { selection: {
|
|
1154
|
+
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
1242
1155
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1243
1156
|
const range = comment.range;
|
|
1244
1157
|
if (!range || range.from === range.to) {
|
|
1245
1158
|
console.warn("Invalid range:", range);
|
|
1246
1159
|
return void 0;
|
|
1247
1160
|
}
|
|
1248
|
-
if (comment.comment.id ===
|
|
1249
|
-
return
|
|
1161
|
+
if (comment.comment.id === current) {
|
|
1162
|
+
return commentCurrentMark.range(range.from, range.to);
|
|
1250
1163
|
} else {
|
|
1251
|
-
return
|
|
1164
|
+
return commentMark.range(range.from, range.to);
|
|
1252
1165
|
}
|
|
1253
1166
|
}).filter(nonNullable);
|
|
1254
|
-
return
|
|
1167
|
+
return Decoration2.set(decorations);
|
|
1255
1168
|
});
|
|
1256
1169
|
var trackPastedComments = (onUpdate) => {
|
|
1257
1170
|
let tracked = null;
|
|
@@ -1273,96 +1186,136 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1273
1186
|
}
|
|
1274
1187
|
};
|
|
1275
1188
|
return [
|
|
1276
|
-
|
|
1189
|
+
EditorView5.domEventHandlers({
|
|
1277
1190
|
cut: handleTrack,
|
|
1278
1191
|
copy: handleTrack
|
|
1279
1192
|
}),
|
|
1280
|
-
//
|
|
1281
|
-
|
|
1193
|
+
// Track deleted comments.
|
|
1194
|
+
invertedEffects2.of((tr) => {
|
|
1195
|
+
const { comments: comments2 } = tr.startState.field(commentsState);
|
|
1196
|
+
const effects = [];
|
|
1197
|
+
tr.changes.iterChangedRanges((fromA, toA) => {
|
|
1198
|
+
for (const { comment: { id }, range: { from, to } } of comments2) {
|
|
1199
|
+
if (from < to && from >= fromA && to <= toA) {
|
|
1200
|
+
effects.push(restoreCommentEffect.of({
|
|
1201
|
+
id,
|
|
1202
|
+
from,
|
|
1203
|
+
to
|
|
1204
|
+
}));
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
return effects;
|
|
1209
|
+
}),
|
|
1210
|
+
// Handle paste or the undo of comment deletion.
|
|
1211
|
+
EditorView5.updateListener.of((update2) => {
|
|
1212
|
+
const restore = [];
|
|
1213
|
+
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1214
|
+
const tr = update2.transactions[i];
|
|
1215
|
+
for (let j = 0; j < restore.length; j++) {
|
|
1216
|
+
restore[j] = mapTrackedComment(restore[j], tr.changes);
|
|
1217
|
+
}
|
|
1218
|
+
for (const effect of tr.effects) {
|
|
1219
|
+
if (effect.is(restoreCommentEffect)) {
|
|
1220
|
+
restore.push(effect.value);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1282
1224
|
if (tracked) {
|
|
1283
|
-
const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1225
|
+
const paste = update2.transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1284
1226
|
if (paste) {
|
|
1285
1227
|
let found = -1;
|
|
1286
1228
|
paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
1287
1229
|
if (text.eq(tracked.text)) {
|
|
1288
|
-
for (let i = transactions.indexOf(paste) + 1; i < transactions.length; i++) {
|
|
1289
|
-
fromB = transactions[i].changes.mapPos(fromB);
|
|
1230
|
+
for (let i = update2.transactions.indexOf(paste) + 1; i < update2.transactions.length; i++) {
|
|
1231
|
+
fromB = update2.transactions[i].changes.mapPos(fromB);
|
|
1290
1232
|
}
|
|
1291
1233
|
found = fromB;
|
|
1292
1234
|
}
|
|
1293
1235
|
});
|
|
1294
1236
|
if (found > -1) {
|
|
1295
1237
|
for (const moved of tracked.comments) {
|
|
1296
|
-
|
|
1238
|
+
restore.push({
|
|
1239
|
+
id: moved.id,
|
|
1297
1240
|
from: found + moved.from,
|
|
1298
1241
|
to: found + moved.to
|
|
1299
|
-
};
|
|
1300
|
-
const cursor = Cursor.getCursorFromRange(state, range);
|
|
1301
|
-
onUpdate(moved.id, cursor);
|
|
1242
|
+
});
|
|
1302
1243
|
}
|
|
1303
1244
|
}
|
|
1304
1245
|
tracked = null;
|
|
1305
1246
|
}
|
|
1306
1247
|
}
|
|
1248
|
+
for (const comment of restore) {
|
|
1249
|
+
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
1250
|
+
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
1251
|
+
if (!exists) {
|
|
1252
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
1253
|
+
onUpdate(comment.id, cursor);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1307
1256
|
})
|
|
1308
1257
|
];
|
|
1309
1258
|
};
|
|
1310
|
-
var
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1259
|
+
var mapTrackedComment = (comment, changes) => ({
|
|
1260
|
+
id: comment.id,
|
|
1261
|
+
from: changes.mapPos(comment.from, 1),
|
|
1262
|
+
to: changes.mapPos(comment.to, 1)
|
|
1263
|
+
});
|
|
1264
|
+
var restoreCommentEffect = StateEffect2.define({
|
|
1265
|
+
map: mapTrackedComment
|
|
1266
|
+
});
|
|
1267
|
+
var optionsFacet = Facet3.define({
|
|
1268
|
+
combine: (providers) => providers[0]
|
|
1269
|
+
});
|
|
1270
|
+
var createComment = (view) => {
|
|
1271
|
+
const options = view.state.facet(optionsFacet);
|
|
1272
|
+
const { from, to } = view.state.selection.main;
|
|
1273
|
+
if (from === to) {
|
|
1274
|
+
return false;
|
|
1275
|
+
}
|
|
1276
|
+
if (to === view.state.doc.length) {
|
|
1277
|
+
view.dispatch({
|
|
1278
|
+
changes: {
|
|
1279
|
+
from: to,
|
|
1280
|
+
insert: "\n"
|
|
1281
|
+
}
|
|
1322
1282
|
});
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1283
|
+
}
|
|
1284
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
1285
|
+
from,
|
|
1286
|
+
to
|
|
1287
|
+
});
|
|
1288
|
+
if (cursor) {
|
|
1289
|
+
const id = options.onCreate?.(cursor, view.coordsAtPos(from));
|
|
1290
|
+
if (id) {
|
|
1328
1291
|
view.dispatch({
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1292
|
+
effects: setSelection.of({
|
|
1293
|
+
current: id
|
|
1294
|
+
}),
|
|
1295
|
+
selection: {
|
|
1296
|
+
anchor: to
|
|
1332
1297
|
}
|
|
1333
1298
|
});
|
|
1299
|
+
return true;
|
|
1334
1300
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
if (id) {
|
|
1342
|
-
view.dispatch({
|
|
1343
|
-
effects: setSelection.of({
|
|
1344
|
-
active: id
|
|
1345
|
-
}),
|
|
1346
|
-
selection: {
|
|
1347
|
-
anchor: from
|
|
1348
|
-
}
|
|
1349
|
-
});
|
|
1350
|
-
return true;
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
return false;
|
|
1354
|
-
};
|
|
1301
|
+
}
|
|
1302
|
+
return false;
|
|
1303
|
+
};
|
|
1304
|
+
var comments = (options = {}) => {
|
|
1305
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1306
|
+
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1355
1307
|
return [
|
|
1308
|
+
optionsFacet.of(options),
|
|
1356
1309
|
commentsState,
|
|
1357
|
-
|
|
1358
|
-
|
|
1310
|
+
commentsDecorations,
|
|
1311
|
+
styles2,
|
|
1359
1312
|
//
|
|
1360
1313
|
// Keymap.
|
|
1361
1314
|
//
|
|
1362
1315
|
options.onCreate ? keymap3.of([
|
|
1363
1316
|
{
|
|
1364
1317
|
key: shortcut,
|
|
1365
|
-
run: callbackWrapper(
|
|
1318
|
+
run: callbackWrapper(createComment)
|
|
1366
1319
|
}
|
|
1367
1320
|
]) : [],
|
|
1368
1321
|
//
|
|
@@ -1398,7 +1351,7 @@ var comments = (options = {}) => {
|
|
|
1398
1351
|
//
|
|
1399
1352
|
// Track deleted ranges and update ranges for decorations.
|
|
1400
1353
|
//
|
|
1401
|
-
|
|
1354
|
+
EditorView5.updateListener.of(({ view, state, changes }) => {
|
|
1402
1355
|
let mod = false;
|
|
1403
1356
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1404
1357
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1428,17 +1381,17 @@ var comments = (options = {}) => {
|
|
|
1428
1381
|
//
|
|
1429
1382
|
// Track selection/proximity.
|
|
1430
1383
|
//
|
|
1431
|
-
|
|
1384
|
+
EditorView5.updateListener.of(({ view, state }) => {
|
|
1432
1385
|
let min = Infinity;
|
|
1433
|
-
const { selection: {
|
|
1386
|
+
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1434
1387
|
const { head } = state.selection.main;
|
|
1435
1388
|
const selection = {};
|
|
1436
1389
|
comments2.forEach(({ comment, range }) => {
|
|
1437
1390
|
if (head >= range.from && head <= range.to) {
|
|
1438
|
-
selection.
|
|
1391
|
+
selection.current = comment.id;
|
|
1439
1392
|
selection.closest = void 0;
|
|
1440
1393
|
}
|
|
1441
|
-
if (!selection.
|
|
1394
|
+
if (!selection.current) {
|
|
1442
1395
|
const d = Math.min(Math.abs(head - range.from), Math.abs(head - range.to));
|
|
1443
1396
|
if (d < min) {
|
|
1444
1397
|
selection.closest = comment.id;
|
|
@@ -1446,7 +1399,7 @@ var comments = (options = {}) => {
|
|
|
1446
1399
|
}
|
|
1447
1400
|
}
|
|
1448
1401
|
});
|
|
1449
|
-
if (selection.
|
|
1402
|
+
if (selection.current !== current || selection.closest !== closest) {
|
|
1450
1403
|
view.dispatch({
|
|
1451
1404
|
effects: setSelection.of(selection)
|
|
1452
1405
|
});
|
|
@@ -1463,9 +1416,9 @@ var comments = (options = {}) => {
|
|
|
1463
1416
|
options.onUpdate ? trackPastedComments(options.onUpdate) : []
|
|
1464
1417
|
];
|
|
1465
1418
|
};
|
|
1466
|
-
var useComments = (view, comments2) => {
|
|
1467
|
-
|
|
1468
|
-
if (view
|
|
1419
|
+
var useComments = (view, comments2 = []) => {
|
|
1420
|
+
useEffect(() => {
|
|
1421
|
+
if (view) {
|
|
1469
1422
|
view.dispatch({
|
|
1470
1423
|
effects: setComments.of(comments2)
|
|
1471
1424
|
});
|
|
@@ -1476,314 +1429,51 @@ var useComments = (view, comments2) => {
|
|
|
1476
1429
|
]);
|
|
1477
1430
|
};
|
|
1478
1431
|
|
|
1479
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1480
|
-
import {
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
const el = document.createElement("div");
|
|
1492
|
-
el.className = "cm-hr";
|
|
1493
|
-
return el;
|
|
1494
|
-
}
|
|
1495
|
-
};
|
|
1496
|
-
var decoration = Decoration4.replace({
|
|
1497
|
-
widget: new HorizontalRuleWidget()
|
|
1498
|
-
});
|
|
1499
|
-
var buildDecorations = (view) => {
|
|
1500
|
-
const builder = new RangeSetBuilder();
|
|
1501
|
-
const { state } = view;
|
|
1502
|
-
const cursor = state.selection.main.head;
|
|
1503
|
-
for (const { from, to } of view.visibleRanges) {
|
|
1504
|
-
syntaxTree(state).iterate({
|
|
1505
|
-
enter: (node) => {
|
|
1506
|
-
if (node.name === "HorizontalRule") {
|
|
1507
|
-
if (cursor <= node.from || cursor >= node.to) {
|
|
1508
|
-
builder.add(node.from, node.to, decoration);
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
},
|
|
1512
|
-
from,
|
|
1513
|
-
to
|
|
1514
|
-
});
|
|
1515
|
-
}
|
|
1516
|
-
return builder.finish();
|
|
1517
|
-
};
|
|
1518
|
-
var hr = () => {
|
|
1519
|
-
return [
|
|
1520
|
-
styles4,
|
|
1521
|
-
ViewPlugin3.fromClass(class {
|
|
1522
|
-
constructor(view) {
|
|
1523
|
-
this.decorations = buildDecorations(view);
|
|
1524
|
-
}
|
|
1525
|
-
update(update2) {
|
|
1526
|
-
this.decorations = buildDecorations(update2.view);
|
|
1527
|
-
}
|
|
1528
|
-
}, {
|
|
1529
|
-
decorations: (v) => v.decorations
|
|
1530
|
-
})
|
|
1531
|
-
];
|
|
1432
|
+
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1433
|
+
import { EditorView as EditorView6 } from "@codemirror/view";
|
|
1434
|
+
var listener = ({ onFocus, onChange }) => {
|
|
1435
|
+
const extensions = [];
|
|
1436
|
+
onFocus && extensions.push(EditorView6.focusChangeEffect.of((_, focused) => {
|
|
1437
|
+
onFocus(focused);
|
|
1438
|
+
return null;
|
|
1439
|
+
}));
|
|
1440
|
+
onChange && extensions.push(EditorView6.updateListener.of((update2) => {
|
|
1441
|
+
onChange(update2.state.doc.toString());
|
|
1442
|
+
}));
|
|
1443
|
+
return extensions;
|
|
1532
1444
|
};
|
|
1533
1445
|
|
|
1534
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1535
|
-
import {
|
|
1536
|
-
import {
|
|
1537
|
-
import {
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
});
|
|
1566
|
-
};
|
|
1567
|
-
var buildDecorations2 = (from, to, state) => {
|
|
1568
|
-
const decorations = [];
|
|
1569
|
-
const cursor = state.selection.main.head;
|
|
1570
|
-
syntaxTree2(state).iterate({
|
|
1571
|
-
enter: (node) => {
|
|
1572
|
-
if (node.name === "Image") {
|
|
1573
|
-
const urlNode = node.node.getChild("URL");
|
|
1574
|
-
if (urlNode) {
|
|
1575
|
-
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1576
|
-
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1577
|
-
decorations.push(Decoration5.replace({
|
|
1578
|
-
block: true,
|
|
1579
|
-
widget: new ImageWidget(url)
|
|
1580
|
-
}).range(hide ? node.from : node.to, node.to));
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
},
|
|
1584
|
-
from,
|
|
1585
|
-
to
|
|
1586
|
-
});
|
|
1587
|
-
return decorations;
|
|
1588
|
-
};
|
|
1589
|
-
var ImageWidget = class extends WidgetType3 {
|
|
1590
|
-
constructor(_url) {
|
|
1591
|
-
super();
|
|
1592
|
-
this._url = _url;
|
|
1593
|
-
}
|
|
1594
|
-
eq(other) {
|
|
1595
|
-
return this._url === other._url;
|
|
1596
|
-
}
|
|
1597
|
-
toDOM(view) {
|
|
1598
|
-
const img = document.createElement("img");
|
|
1599
|
-
img.setAttribute("src", this._url);
|
|
1600
|
-
img.setAttribute("class", "cm-image");
|
|
1601
|
-
img.onload = () => img.classList.add("cm-loaded-image");
|
|
1602
|
-
return img;
|
|
1603
|
-
}
|
|
1604
|
-
};
|
|
1605
|
-
|
|
1606
|
-
// packages/ui/react-ui-editor/src/extensions/link.ts
|
|
1607
|
-
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1608
|
-
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1609
|
-
import { hoverTooltip as hoverTooltip2, Decoration as Decoration6, ViewPlugin as ViewPlugin4, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1610
|
-
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1611
|
-
var link = (options = {}) => {
|
|
1612
|
-
const extensions = [
|
|
1613
|
-
ViewPlugin4.fromClass(class {
|
|
1614
|
-
constructor(view) {
|
|
1615
|
-
this.decorations = buildDecorations3(view, options);
|
|
1616
|
-
}
|
|
1617
|
-
update(update2) {
|
|
1618
|
-
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
1619
|
-
this.decorations = buildDecorations3(update2.view, options);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
}, {
|
|
1623
|
-
decorations: (v) => v.decorations
|
|
1624
|
-
})
|
|
1625
|
-
];
|
|
1626
|
-
if (options.onHover) {
|
|
1627
|
-
extensions.push(
|
|
1628
|
-
// https://codemirror.net/examples/tooltip
|
|
1629
|
-
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1630
|
-
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1631
|
-
hoverTooltip2((view, pos, side) => {
|
|
1632
|
-
const syntax = syntaxTree3(view.state).resolveInner(pos, side);
|
|
1633
|
-
let link2 = null;
|
|
1634
|
-
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1635
|
-
link2 = node.name === "Link" ? node : null;
|
|
1636
|
-
}
|
|
1637
|
-
const url = link2 && link2.getChild("URL");
|
|
1638
|
-
if (!url || !link2) {
|
|
1639
|
-
return null;
|
|
1640
|
-
}
|
|
1641
|
-
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
1642
|
-
return {
|
|
1643
|
-
pos: link2.from,
|
|
1644
|
-
end: link2.to,
|
|
1645
|
-
above: true,
|
|
1646
|
-
create: () => {
|
|
1647
|
-
const el = document.createElement("div");
|
|
1648
|
-
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
1649
|
-
options.onHover(el, urlText);
|
|
1650
|
-
return {
|
|
1651
|
-
dom: el,
|
|
1652
|
-
offset: {
|
|
1653
|
-
x: 0,
|
|
1654
|
-
y: 4
|
|
1655
|
-
}
|
|
1656
|
-
};
|
|
1657
|
-
}
|
|
1658
|
-
};
|
|
1659
|
-
})
|
|
1660
|
-
);
|
|
1661
|
-
}
|
|
1662
|
-
return extensions;
|
|
1663
|
-
};
|
|
1664
|
-
var LinkButton = class extends WidgetType4 {
|
|
1665
|
-
constructor(_url, _onAttach) {
|
|
1666
|
-
super();
|
|
1667
|
-
this._url = _url;
|
|
1668
|
-
this._onAttach = _onAttach;
|
|
1669
|
-
}
|
|
1670
|
-
eq(other) {
|
|
1671
|
-
return this._url === other._url;
|
|
1672
|
-
}
|
|
1673
|
-
toDOM(view) {
|
|
1674
|
-
const el = document.createElement("span");
|
|
1675
|
-
this._onAttach(el, this._url);
|
|
1676
|
-
return el;
|
|
1677
|
-
}
|
|
1678
|
-
};
|
|
1679
|
-
var LinkText = class extends WidgetType4 {
|
|
1680
|
-
constructor(_text, _url) {
|
|
1681
|
-
super();
|
|
1682
|
-
this._text = _text;
|
|
1683
|
-
this._url = _url;
|
|
1684
|
-
}
|
|
1685
|
-
eq(other) {
|
|
1686
|
-
return this._url === other._url;
|
|
1687
|
-
}
|
|
1688
|
-
toDOM(view) {
|
|
1689
|
-
const link2 = document.createElement("a");
|
|
1690
|
-
link2.setAttribute("class", "cm-link");
|
|
1691
|
-
link2.textContent = this._text;
|
|
1692
|
-
if (this._url) {
|
|
1693
|
-
link2.setAttribute("rel", "noreferrer");
|
|
1694
|
-
link2.setAttribute("target", "_blank");
|
|
1695
|
-
link2.href = this._url;
|
|
1696
|
-
} else {
|
|
1697
|
-
link2.onclick = () => {
|
|
1698
|
-
view.dispatch({
|
|
1699
|
-
selection: {
|
|
1700
|
-
anchor: view.posAtDOM(link2)
|
|
1701
|
-
}
|
|
1702
|
-
});
|
|
1703
|
-
};
|
|
1704
|
-
}
|
|
1705
|
-
return link2;
|
|
1706
|
-
}
|
|
1707
|
-
};
|
|
1708
|
-
var buildDecorations3 = (view, options) => {
|
|
1709
|
-
const builder = new RangeSetBuilder2();
|
|
1710
|
-
const { state } = view;
|
|
1711
|
-
const cursor = state.selection.main.head;
|
|
1712
|
-
for (const { from, to } of view.visibleRanges) {
|
|
1713
|
-
syntaxTree3(state).iterate({
|
|
1714
|
-
enter: (node) => {
|
|
1715
|
-
if (node.name === "Link") {
|
|
1716
|
-
const marks2 = node.node.getChildren("LinkMark");
|
|
1717
|
-
const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
|
|
1718
|
-
const urlNode = node.node.getChild("URL");
|
|
1719
|
-
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
1720
|
-
if (!url) {
|
|
1721
|
-
return false;
|
|
1722
|
-
}
|
|
1723
|
-
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1724
|
-
builder.add(node.from, node.to, Decoration6.replace({
|
|
1725
|
-
widget: new LinkText(text, options.link ? url : void 0)
|
|
1726
|
-
}));
|
|
1727
|
-
}
|
|
1728
|
-
if (options.onRender) {
|
|
1729
|
-
builder.add(node.to, node.to, Decoration6.replace({
|
|
1730
|
-
widget: new LinkButton(url, options.onRender)
|
|
1731
|
-
}));
|
|
1732
|
-
}
|
|
1733
|
-
return false;
|
|
1734
|
-
}
|
|
1735
|
-
},
|
|
1736
|
-
from,
|
|
1737
|
-
to
|
|
1738
|
-
});
|
|
1739
|
-
}
|
|
1740
|
-
return builder.finish();
|
|
1741
|
-
};
|
|
1742
|
-
|
|
1743
|
-
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1744
|
-
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1745
|
-
var listener = ({ onFocus, onChange }) => {
|
|
1746
|
-
const extensions = [];
|
|
1747
|
-
onFocus && extensions.push(EditorView9.focusChangeEffect.of((_, focused) => {
|
|
1748
|
-
onFocus(focused);
|
|
1749
|
-
return null;
|
|
1750
|
-
}));
|
|
1751
|
-
onChange && extensions.push(EditorView9.updateListener.of((update2) => {
|
|
1752
|
-
onChange(update2.state.doc.toString());
|
|
1753
|
-
}));
|
|
1754
|
-
return extensions;
|
|
1755
|
-
};
|
|
1756
|
-
|
|
1757
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1758
|
-
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1759
|
-
import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1760
|
-
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1761
|
-
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1762
|
-
import { languages } from "@codemirror/language-data";
|
|
1763
|
-
import { searchKeymap } from "@codemirror/search";
|
|
1764
|
-
import { EditorState } from "@codemirror/state";
|
|
1765
|
-
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1766
|
-
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView10, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1767
|
-
|
|
1768
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1769
|
-
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1770
|
-
import { HighlightStyle } from "@codemirror/language";
|
|
1771
|
-
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1772
|
-
import { Table } from "@lezer/markdown";
|
|
1773
|
-
var markdownTags = {
|
|
1774
|
-
Blockquote: Tag.define(),
|
|
1775
|
-
CodeMark: Tag.define(),
|
|
1776
|
-
CodeText: Tag.define(),
|
|
1777
|
-
EmphasisMark: Tag.define(),
|
|
1778
|
-
HeaderMark: Tag.define(),
|
|
1779
|
-
InlineCode: Tag.define(),
|
|
1780
|
-
LinkLabel: Tag.define(),
|
|
1781
|
-
LinkReference: Tag.define(),
|
|
1782
|
-
ListMark: Tag.define(),
|
|
1783
|
-
QuoteMark: Tag.define(),
|
|
1784
|
-
URL: Tag.define(),
|
|
1785
|
-
// Custom.
|
|
1786
|
-
TableCell: Tag.define()
|
|
1446
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1447
|
+
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1448
|
+
import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1449
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1450
|
+
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1451
|
+
import { languages } from "@codemirror/language-data";
|
|
1452
|
+
import { searchKeymap } from "@codemirror/search";
|
|
1453
|
+
import { EditorState } from "@codemirror/state";
|
|
1454
|
+
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1455
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1456
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1457
|
+
|
|
1458
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1459
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1460
|
+
import { HighlightStyle } from "@codemirror/language";
|
|
1461
|
+
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1462
|
+
import { Table } from "@lezer/markdown";
|
|
1463
|
+
var markdownTags = {
|
|
1464
|
+
Blockquote: Tag.define(),
|
|
1465
|
+
CodeMark: Tag.define(),
|
|
1466
|
+
CodeText: Tag.define(),
|
|
1467
|
+
EmphasisMark: Tag.define(),
|
|
1468
|
+
HeaderMark: Tag.define(),
|
|
1469
|
+
InlineCode: Tag.define(),
|
|
1470
|
+
LinkLabel: Tag.define(),
|
|
1471
|
+
LinkReference: Tag.define(),
|
|
1472
|
+
ListMark: Tag.define(),
|
|
1473
|
+
QuoteMark: Tag.define(),
|
|
1474
|
+
URL: Tag.define(),
|
|
1475
|
+
// Custom.
|
|
1476
|
+
TableCell: Tag.define()
|
|
1787
1477
|
};
|
|
1788
1478
|
Table.defineNodes?.forEach((node) => {
|
|
1789
1479
|
switch (node?.name) {
|
|
@@ -1860,7 +1550,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1860
1550
|
markdownTags.QuoteMark,
|
|
1861
1551
|
markdownTags.EmphasisMark
|
|
1862
1552
|
],
|
|
1863
|
-
class:
|
|
1553
|
+
class: mark
|
|
1864
1554
|
},
|
|
1865
1555
|
// E.g., code block language (after ```).
|
|
1866
1556
|
{
|
|
@@ -1868,7 +1558,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1868
1558
|
tags.function(tags.variableName),
|
|
1869
1559
|
tags.labelName
|
|
1870
1560
|
],
|
|
1871
|
-
class:
|
|
1561
|
+
class: codeMark
|
|
1872
1562
|
},
|
|
1873
1563
|
{
|
|
1874
1564
|
tag: [
|
|
@@ -1879,27 +1569,27 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1879
1569
|
// Headings.
|
|
1880
1570
|
{
|
|
1881
1571
|
tag: tags.heading1,
|
|
1882
|
-
class: heading(1
|
|
1572
|
+
class: heading(1)
|
|
1883
1573
|
},
|
|
1884
1574
|
{
|
|
1885
1575
|
tag: tags.heading2,
|
|
1886
|
-
class: heading(2
|
|
1576
|
+
class: heading(2)
|
|
1887
1577
|
},
|
|
1888
1578
|
{
|
|
1889
1579
|
tag: tags.heading3,
|
|
1890
|
-
class: heading(3
|
|
1580
|
+
class: heading(3)
|
|
1891
1581
|
},
|
|
1892
1582
|
{
|
|
1893
1583
|
tag: tags.heading4,
|
|
1894
|
-
class: heading(4
|
|
1584
|
+
class: heading(4)
|
|
1895
1585
|
},
|
|
1896
1586
|
{
|
|
1897
1587
|
tag: tags.heading5,
|
|
1898
|
-
class: heading(5
|
|
1588
|
+
class: heading(5)
|
|
1899
1589
|
},
|
|
1900
1590
|
{
|
|
1901
1591
|
tag: tags.heading6,
|
|
1902
|
-
class: heading(6
|
|
1592
|
+
class: heading(6)
|
|
1903
1593
|
},
|
|
1904
1594
|
// Emphasis.
|
|
1905
1595
|
{
|
|
@@ -1925,7 +1615,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1925
1615
|
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
1926
1616
|
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
1927
1617
|
// the code, but all other CSS properties will be inherited.
|
|
1928
|
-
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
1618
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font unless changed by an extension.
|
|
1929
1619
|
{
|
|
1930
1620
|
tag: [
|
|
1931
1621
|
markdownTags.CodeText,
|
|
@@ -1954,11 +1644,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1954
1644
|
};
|
|
1955
1645
|
|
|
1956
1646
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1957
|
-
var
|
|
1647
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1958
1648
|
return [
|
|
1649
|
+
lineWrapping && EditorView7.lineWrapping,
|
|
1959
1650
|
EditorState.allowMultipleSelections.of(true),
|
|
1960
1651
|
EditorState.tabSize.of(2),
|
|
1961
|
-
EditorView10.lineWrapping,
|
|
1962
1652
|
// https://github.com/codemirror/basic-setup
|
|
1963
1653
|
bracketMatching2(),
|
|
1964
1654
|
closeBrackets2(),
|
|
@@ -1968,7 +1658,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
1968
1658
|
highlightActiveLine2(),
|
|
1969
1659
|
history2(),
|
|
1970
1660
|
indentOnInput(),
|
|
1971
|
-
_placeholder
|
|
1661
|
+
_placeholder && placeholder2(_placeholder),
|
|
1972
1662
|
// Main extension.
|
|
1973
1663
|
// https://github.com/codemirror/lang-markdown
|
|
1974
1664
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1990,7 +1680,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
1990
1680
|
// https://github.com/codemirror/theme-one-dark
|
|
1991
1681
|
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
|
|
1992
1682
|
// Custom styles.
|
|
1993
|
-
syntaxHighlighting2(markdownHighlightStyle(
|
|
1683
|
+
syntaxHighlighting2(markdownHighlightStyle()),
|
|
1994
1684
|
keymap4.of([
|
|
1995
1685
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1996
1686
|
indentWithTab,
|
|
@@ -2003,47 +1693,580 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
2003
1693
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2004
1694
|
...standardKeymap
|
|
2005
1695
|
])
|
|
2006
|
-
];
|
|
1696
|
+
].filter(isNotFalsy2);
|
|
2007
1697
|
};
|
|
2008
1698
|
|
|
2009
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
2010
|
-
import {
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
1699
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
1700
|
+
import { syntaxTree } from "@codemirror/language";
|
|
1701
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
1702
|
+
import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Decoration3, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1703
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1704
|
+
var styles3 = EditorView8.baseTheme({
|
|
1705
|
+
"& .cm-code": {
|
|
1706
|
+
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1707
|
+
},
|
|
1708
|
+
"& .cm-codeblock": {
|
|
1709
|
+
width: "100%",
|
|
1710
|
+
paddingInline: "1rem !important",
|
|
1711
|
+
position: "relative",
|
|
1712
|
+
"&::after": {
|
|
1713
|
+
content: '""',
|
|
1714
|
+
position: "absolute",
|
|
1715
|
+
inset: 0
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
"&light .cm-codeblock": {
|
|
1719
|
+
"&::after": {
|
|
1720
|
+
background: getToken("extend.semanticColors.input.light"),
|
|
1721
|
+
mixBlendMode: "darken"
|
|
1722
|
+
}
|
|
1723
|
+
},
|
|
1724
|
+
"&dark .cm-codeblock": {
|
|
1725
|
+
"&::after": {
|
|
1726
|
+
background: getToken("extend.semanticColors.input.dark"),
|
|
1727
|
+
mixBlendMode: "lighten"
|
|
1728
|
+
}
|
|
1729
|
+
},
|
|
1730
|
+
"& .cm-codeblock-first": {
|
|
1731
|
+
display: "inline-block",
|
|
1732
|
+
"&::after": {
|
|
1733
|
+
borderTopLeftRadius: ".5rem",
|
|
1734
|
+
borderTopRightRadius: ".5rem"
|
|
1735
|
+
}
|
|
1736
|
+
},
|
|
1737
|
+
"& .cm-codeblock-last": {
|
|
1738
|
+
display: "inline-block",
|
|
1739
|
+
"&::after": {
|
|
1740
|
+
borderBottomLeftRadius: ".5rem",
|
|
1741
|
+
borderBottomRightRadius: ".5rem"
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
});
|
|
1745
|
+
var getLineRange = (lines, from, to) => {
|
|
1746
|
+
const start = lines.findIndex((line) => line.from >= from);
|
|
1747
|
+
const end = lines.findIndex((line) => line.to >= to);
|
|
1748
|
+
return [
|
|
1749
|
+
start,
|
|
1750
|
+
end
|
|
1751
|
+
];
|
|
2036
1752
|
};
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
1753
|
+
var LineWidget = class extends WidgetType2 {
|
|
1754
|
+
constructor(_className) {
|
|
1755
|
+
super();
|
|
1756
|
+
this._className = _className;
|
|
1757
|
+
}
|
|
1758
|
+
toDOM() {
|
|
1759
|
+
const el = document.createElement("span");
|
|
1760
|
+
el.innerHTML = " ";
|
|
1761
|
+
el.className = mx2("cm-code cm-codeblock", this._className);
|
|
1762
|
+
return el;
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
var top = new LineWidget("cm-codeblock-first");
|
|
1766
|
+
var bottom = new LineWidget("cm-codeblock-last");
|
|
1767
|
+
var buildDecorations = (view) => {
|
|
1768
|
+
const builder = new RangeSetBuilder();
|
|
1769
|
+
const { state } = view;
|
|
1770
|
+
const blocks = view.viewportLineBlocks;
|
|
1771
|
+
const cursor = state.selection.main.head;
|
|
1772
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1773
|
+
syntaxTree(state).iterate({
|
|
1774
|
+
enter: (node) => {
|
|
1775
|
+
if (node.name === "FencedCode") {
|
|
1776
|
+
const edit = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
|
|
1777
|
+
const range = getLineRange(blocks, node.from, node.to);
|
|
1778
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
1779
|
+
const block = blocks[i];
|
|
1780
|
+
if (!edit && (i === range[0] || i === range[1])) {
|
|
1781
|
+
builder.add(block.from, block.to, Decoration3.replace({
|
|
1782
|
+
widget: i === range[0] ? top : bottom
|
|
1783
|
+
}));
|
|
1784
|
+
} else {
|
|
1785
|
+
builder.add(block.from, block.from, Decoration3.line({
|
|
1786
|
+
class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1787
|
+
}));
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
from,
|
|
1793
|
+
to
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
return builder.finish();
|
|
1797
|
+
};
|
|
1798
|
+
var code2 = () => {
|
|
1799
|
+
return [
|
|
1800
|
+
ViewPlugin3.fromClass(class {
|
|
1801
|
+
constructor(view) {
|
|
1802
|
+
this.decorations = buildDecorations(view);
|
|
1803
|
+
}
|
|
1804
|
+
update(update2) {
|
|
1805
|
+
this.decorations = buildDecorations(update2.view);
|
|
1806
|
+
}
|
|
1807
|
+
}, {
|
|
1808
|
+
decorations: (value) => value.decorations
|
|
1809
|
+
}),
|
|
1810
|
+
styles3
|
|
1811
|
+
];
|
|
1812
|
+
};
|
|
1813
|
+
|
|
1814
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1815
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1816
|
+
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1817
|
+
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1818
|
+
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1819
|
+
var setHeading = (level) => (view) => {
|
|
1820
|
+
const { selection: { ranges }, doc } = view.state;
|
|
1821
|
+
const changes = [];
|
|
1822
|
+
for (const range of ranges) {
|
|
1823
|
+
const { number } = doc.lineAt(range.anchor);
|
|
1824
|
+
const { from, to } = doc.line(number);
|
|
1825
|
+
const line = doc.sliceString(from, to);
|
|
1826
|
+
const [_, marks, spaces] = line.match(/(#+)(\s+)/) ?? [];
|
|
1827
|
+
const current = marks?.length ?? 0;
|
|
1828
|
+
if (level !== current) {
|
|
1829
|
+
changes.push({
|
|
1830
|
+
from,
|
|
1831
|
+
to: from + current + (spaces?.length ?? 0),
|
|
1832
|
+
insert: "#".repeat(level) + (level > 0 ? " " : "")
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
if (changes.length) {
|
|
1837
|
+
view.dispatch({
|
|
1838
|
+
changes
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
return true;
|
|
1842
|
+
};
|
|
1843
|
+
var toggleStyle = (mark2) => (view) => {
|
|
1844
|
+
const { ranges } = view.state.selection;
|
|
1845
|
+
for (const range of ranges) {
|
|
1846
|
+
if (range.from === range.to) {
|
|
1847
|
+
return false;
|
|
1848
|
+
}
|
|
1849
|
+
view.dispatch({
|
|
1850
|
+
changes: [
|
|
1851
|
+
{
|
|
1852
|
+
from: range.from,
|
|
1853
|
+
insert: mark2
|
|
1854
|
+
},
|
|
1855
|
+
{
|
|
1856
|
+
from: range.to,
|
|
1857
|
+
insert: mark2
|
|
1858
|
+
}
|
|
1859
|
+
]
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
return true;
|
|
1863
|
+
};
|
|
1864
|
+
var snippets = {
|
|
1865
|
+
codeblock: snippet([
|
|
1866
|
+
"```#{lang}",
|
|
1867
|
+
" #{}",
|
|
1868
|
+
"```"
|
|
1869
|
+
].join("\n")),
|
|
1870
|
+
table: snippet([
|
|
1871
|
+
"| #{col1} | #{col2} |",
|
|
1872
|
+
"| ---- | ---- |",
|
|
1873
|
+
"| #{val1} | #{val2} |",
|
|
1874
|
+
"| #{val3} | #{val4} |"
|
|
1875
|
+
].join("\n"))
|
|
1876
|
+
};
|
|
1877
|
+
var insertCodeblock = (view) => {
|
|
1878
|
+
const { selection: { main }, doc } = view.state;
|
|
1879
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1880
|
+
const { from } = doc.line(number);
|
|
1881
|
+
snippets.codeblock(view, null, from, from);
|
|
1882
|
+
};
|
|
1883
|
+
var insertTable = (view) => {
|
|
1884
|
+
const { selection: { main }, doc } = view.state;
|
|
1885
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1886
|
+
const { from } = doc.line(number);
|
|
1887
|
+
snippets.table(view, null, from, from);
|
|
1888
|
+
};
|
|
1889
|
+
var toggleBold = toggleStyle("**");
|
|
1890
|
+
var toggleItalic = toggleStyle("_");
|
|
1891
|
+
var toggleStrikethrough = toggleStyle("~~");
|
|
1892
|
+
var toggleList = (view) => {
|
|
1893
|
+
};
|
|
1894
|
+
var formatting = (options = {}) => {
|
|
1895
|
+
return [
|
|
1896
|
+
keymap5.of([
|
|
1897
|
+
{
|
|
1898
|
+
key: "meta-b",
|
|
1899
|
+
run: toggleBold
|
|
1900
|
+
}
|
|
1901
|
+
]),
|
|
1902
|
+
styling()
|
|
1903
|
+
];
|
|
1904
|
+
};
|
|
1905
|
+
var styling = () => {
|
|
1906
|
+
const buildDecorations7 = (view) => {
|
|
1907
|
+
const builder = new RangeSetBuilder2();
|
|
1908
|
+
const { state } = view;
|
|
1909
|
+
const cursor = state.selection.main.head;
|
|
1910
|
+
const replace = (node, marks) => {
|
|
1911
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
1912
|
+
for (const mark2 of marks) {
|
|
1913
|
+
builder.add(mark2.from, mark2.to, Decoration4.replace({}));
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1918
|
+
syntaxTree2(state).iterate({
|
|
1919
|
+
enter: (node) => {
|
|
1920
|
+
switch (node.name) {
|
|
1921
|
+
case "Emphasis":
|
|
1922
|
+
case "StrongEmphasis": {
|
|
1923
|
+
const marks = node.node.getChildren("EmphasisMark");
|
|
1924
|
+
replace(node, marks);
|
|
1925
|
+
break;
|
|
1926
|
+
}
|
|
1927
|
+
case "Strikethrough": {
|
|
1928
|
+
const marks = node.node.getChildren("StrikethroughMark");
|
|
1929
|
+
replace(node, marks);
|
|
1930
|
+
break;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
},
|
|
1934
|
+
from,
|
|
1935
|
+
to
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
return builder.finish();
|
|
1939
|
+
};
|
|
1940
|
+
return [
|
|
1941
|
+
ViewPlugin4.fromClass(class {
|
|
1942
|
+
constructor(view) {
|
|
1943
|
+
this.decorations = buildDecorations7(view);
|
|
1944
|
+
}
|
|
1945
|
+
update(update2) {
|
|
1946
|
+
this.decorations = buildDecorations7(update2.view);
|
|
1947
|
+
}
|
|
1948
|
+
}, {
|
|
1949
|
+
decorations: (value) => value.decorations
|
|
1950
|
+
})
|
|
1951
|
+
];
|
|
1952
|
+
};
|
|
1953
|
+
|
|
1954
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1955
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1956
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1957
|
+
import { Decoration as Decoration5, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1958
|
+
var buildDecorations2 = (view) => {
|
|
1959
|
+
const builder = new RangeSetBuilder3();
|
|
1960
|
+
const { state } = view;
|
|
1961
|
+
const cursor = state.selection.main.head;
|
|
1962
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1963
|
+
syntaxTree3(state).iterate({
|
|
1964
|
+
enter: (node) => {
|
|
1965
|
+
switch (node.name) {
|
|
1966
|
+
case "ATXHeading1":
|
|
1967
|
+
case "ATXHeading2":
|
|
1968
|
+
case "ATXHeading3":
|
|
1969
|
+
case "ATXHeading4":
|
|
1970
|
+
case "ATXHeading5":
|
|
1971
|
+
case "ATXHeading6": {
|
|
1972
|
+
const mark2 = node.node.getChild("HeaderMark");
|
|
1973
|
+
if (mark2) {
|
|
1974
|
+
if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1975
|
+
builder.add(mark2.from, mark2.to + 1, Decoration5.replace({}));
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
},
|
|
1981
|
+
from,
|
|
1982
|
+
to
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
return builder.finish();
|
|
1986
|
+
};
|
|
1987
|
+
var heading2 = () => {
|
|
1988
|
+
return [
|
|
1989
|
+
ViewPlugin5.fromClass(class {
|
|
1990
|
+
constructor(view) {
|
|
1991
|
+
this.decorations = buildDecorations2(view);
|
|
1992
|
+
}
|
|
1993
|
+
update(update2) {
|
|
1994
|
+
this.decorations = buildDecorations2(update2.view);
|
|
1995
|
+
}
|
|
1996
|
+
}, {
|
|
1997
|
+
decorations: (value) => value.decorations
|
|
1998
|
+
})
|
|
1999
|
+
];
|
|
2000
|
+
};
|
|
2001
|
+
|
|
2002
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
2003
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2004
|
+
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
2005
|
+
import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
2006
|
+
var styles4 = EditorView9.baseTheme({
|
|
2007
|
+
"& .cm-hr": {
|
|
2008
|
+
// Note that block-level decorations should not have vertical margins,
|
|
2009
|
+
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
2013
|
+
toDOM() {
|
|
2014
|
+
const el = document.createElement("div");
|
|
2015
|
+
el.className = "cm-hr";
|
|
2016
|
+
return el;
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
var decoration = Decoration6.replace({
|
|
2020
|
+
widget: new HorizontalRuleWidget()
|
|
2021
|
+
});
|
|
2022
|
+
var buildDecorations3 = (view) => {
|
|
2023
|
+
const builder = new RangeSetBuilder4();
|
|
2024
|
+
const { state } = view;
|
|
2025
|
+
const cursor = state.selection.main.head;
|
|
2026
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2027
|
+
syntaxTree4(state).iterate({
|
|
2028
|
+
enter: (node) => {
|
|
2029
|
+
if (node.name === "HorizontalRule") {
|
|
2030
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
2031
|
+
builder.add(node.from, node.to, decoration);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
},
|
|
2035
|
+
from,
|
|
2036
|
+
to
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
return builder.finish();
|
|
2040
|
+
};
|
|
2041
|
+
var hr = () => {
|
|
2042
|
+
return [
|
|
2043
|
+
ViewPlugin6.fromClass(class {
|
|
2044
|
+
constructor(view) {
|
|
2045
|
+
this.decorations = buildDecorations3(view);
|
|
2046
|
+
}
|
|
2047
|
+
update(update2) {
|
|
2048
|
+
this.decorations = buildDecorations3(update2.view);
|
|
2049
|
+
}
|
|
2050
|
+
}, {
|
|
2051
|
+
decorations: (value) => value.decorations
|
|
2052
|
+
}),
|
|
2053
|
+
styles4
|
|
2054
|
+
];
|
|
2055
|
+
};
|
|
2056
|
+
|
|
2057
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
2058
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
2059
|
+
import { StateField as StateField3 } from "@codemirror/state";
|
|
2060
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2061
|
+
var image = (options = {}) => {
|
|
2062
|
+
return StateField3.define({
|
|
2063
|
+
create: (state) => {
|
|
2064
|
+
return Decoration7.set(buildDecorations4(0, state.doc.length, state));
|
|
2065
|
+
},
|
|
2066
|
+
update: (value, tr) => {
|
|
2067
|
+
if (!tr.docChanged && !tr.selection) {
|
|
2068
|
+
return value;
|
|
2069
|
+
}
|
|
2070
|
+
const cursor = tr.state.selection.main.head;
|
|
2071
|
+
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
2072
|
+
let from = Math.min(cursor, oldCursor);
|
|
2073
|
+
let to = Math.max(cursor, oldCursor);
|
|
2074
|
+
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
2075
|
+
from = Math.min(from, fromB);
|
|
2076
|
+
to = Math.max(to, toB);
|
|
2077
|
+
});
|
|
2078
|
+
from = tr.state.doc.lineAt(from).from;
|
|
2079
|
+
to = tr.state.doc.lineAt(to).to;
|
|
2080
|
+
return value.map(tr.changes).update({
|
|
2081
|
+
filterFrom: from,
|
|
2082
|
+
filterTo: to,
|
|
2083
|
+
filter: () => false,
|
|
2084
|
+
add: buildDecorations4(from, to, tr.state)
|
|
2085
|
+
});
|
|
2086
|
+
},
|
|
2087
|
+
provide: (field) => EditorView10.decorations.from(field)
|
|
2088
|
+
});
|
|
2089
|
+
};
|
|
2090
|
+
var buildDecorations4 = (from, to, state) => {
|
|
2091
|
+
const decorations = [];
|
|
2092
|
+
const cursor = state.selection.main.head;
|
|
2093
|
+
syntaxTree5(state).iterate({
|
|
2094
|
+
enter: (node) => {
|
|
2095
|
+
if (node.name === "Image") {
|
|
2096
|
+
const urlNode = node.node.getChild("URL");
|
|
2097
|
+
if (urlNode) {
|
|
2098
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
2099
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
2100
|
+
decorations.push(Decoration7.replace({
|
|
2101
|
+
block: true,
|
|
2102
|
+
widget: new ImageWidget(url)
|
|
2103
|
+
}).range(hide ? node.from : node.to, node.to));
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
},
|
|
2107
|
+
from,
|
|
2108
|
+
to
|
|
2109
|
+
});
|
|
2110
|
+
return decorations;
|
|
2111
|
+
};
|
|
2112
|
+
var ImageWidget = class extends WidgetType4 {
|
|
2113
|
+
constructor(_url) {
|
|
2114
|
+
super();
|
|
2115
|
+
this._url = _url;
|
|
2116
|
+
}
|
|
2117
|
+
eq(other) {
|
|
2118
|
+
return this._url === other._url;
|
|
2119
|
+
}
|
|
2120
|
+
toDOM(view) {
|
|
2121
|
+
const img = document.createElement("img");
|
|
2122
|
+
img.setAttribute("src", this._url);
|
|
2123
|
+
img.setAttribute("class", "cm-image");
|
|
2124
|
+
img.onload = () => img.classList.add("cm-loaded-image");
|
|
2125
|
+
return img;
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
|
|
2129
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
2130
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
2131
|
+
import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
|
|
2132
|
+
import { hoverTooltip as hoverTooltip2, Decoration as Decoration8, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
2133
|
+
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
2134
|
+
var link = (options = {}) => {
|
|
2135
|
+
const extensions = [
|
|
2136
|
+
ViewPlugin7.fromClass(class {
|
|
2137
|
+
constructor(view) {
|
|
2138
|
+
this.decorations = buildDecorations5(view, options);
|
|
2139
|
+
}
|
|
2140
|
+
update(update2) {
|
|
2141
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
2142
|
+
this.decorations = buildDecorations5(update2.view, options);
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
}, {
|
|
2146
|
+
decorations: (value) => value.decorations
|
|
2147
|
+
})
|
|
2148
|
+
];
|
|
2149
|
+
if (options.onHover) {
|
|
2150
|
+
extensions.push(
|
|
2151
|
+
// https://codemirror.net/examples/tooltip
|
|
2152
|
+
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
2153
|
+
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
2154
|
+
hoverTooltip2((view, pos, side) => {
|
|
2155
|
+
const syntax = syntaxTree6(view.state).resolveInner(pos, side);
|
|
2156
|
+
let link2 = null;
|
|
2157
|
+
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
2158
|
+
link2 = node.name === "Link" ? node : null;
|
|
2159
|
+
}
|
|
2160
|
+
const url = link2 && link2.getChild("URL");
|
|
2161
|
+
if (!url || !link2) {
|
|
2162
|
+
return null;
|
|
2163
|
+
}
|
|
2164
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
2165
|
+
return {
|
|
2166
|
+
pos: link2.from,
|
|
2167
|
+
end: link2.to,
|
|
2168
|
+
above: true,
|
|
2169
|
+
create: () => {
|
|
2170
|
+
const el = document.createElement("div");
|
|
2171
|
+
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
2172
|
+
options.onHover(el, urlText);
|
|
2173
|
+
return {
|
|
2174
|
+
dom: el,
|
|
2175
|
+
offset: {
|
|
2176
|
+
x: 0,
|
|
2177
|
+
y: 4
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
})
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
return extensions;
|
|
2186
|
+
};
|
|
2187
|
+
var LinkButton = class extends WidgetType5 {
|
|
2188
|
+
constructor(_url, _onAttach) {
|
|
2189
|
+
super();
|
|
2190
|
+
this._url = _url;
|
|
2191
|
+
this._onAttach = _onAttach;
|
|
2192
|
+
}
|
|
2193
|
+
eq(other) {
|
|
2194
|
+
return this._url === other._url;
|
|
2195
|
+
}
|
|
2196
|
+
toDOM(view) {
|
|
2197
|
+
const el = document.createElement("span");
|
|
2198
|
+
this._onAttach(el, this._url);
|
|
2199
|
+
return el;
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
var LinkText = class extends WidgetType5 {
|
|
2203
|
+
constructor(_text, _url) {
|
|
2204
|
+
super();
|
|
2205
|
+
this._text = _text;
|
|
2206
|
+
this._url = _url;
|
|
2207
|
+
}
|
|
2208
|
+
eq(other) {
|
|
2209
|
+
return this._url === other._url;
|
|
2210
|
+
}
|
|
2211
|
+
toDOM(view) {
|
|
2212
|
+
const link2 = document.createElement("a");
|
|
2213
|
+
link2.setAttribute("class", "cm-link");
|
|
2214
|
+
link2.textContent = this._text;
|
|
2215
|
+
if (this._url) {
|
|
2216
|
+
link2.setAttribute("rel", "noreferrer");
|
|
2217
|
+
link2.setAttribute("target", "_blank");
|
|
2218
|
+
link2.href = this._url;
|
|
2219
|
+
} else {
|
|
2220
|
+
link2.onclick = () => {
|
|
2221
|
+
view.dispatch({
|
|
2222
|
+
selection: {
|
|
2223
|
+
anchor: view.posAtDOM(link2)
|
|
2224
|
+
}
|
|
2225
|
+
});
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
return link2;
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
var buildDecorations5 = (view, options) => {
|
|
2232
|
+
const builder = new RangeSetBuilder5();
|
|
2233
|
+
const { state } = view;
|
|
2234
|
+
const cursor = state.selection.main.head;
|
|
2235
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2236
|
+
syntaxTree6(state).iterate({
|
|
2237
|
+
enter: (node) => {
|
|
2238
|
+
if (node.name === "Link") {
|
|
2239
|
+
const marks = node.node.getChildren("LinkMark");
|
|
2240
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
2241
|
+
const urlNode = node.node.getChild("URL");
|
|
2242
|
+
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2243
|
+
if (!url) {
|
|
2244
|
+
return false;
|
|
2245
|
+
}
|
|
2246
|
+
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
2247
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
|
2248
|
+
widget: new LinkText(text, options.link ? url : void 0)
|
|
2249
|
+
}));
|
|
2250
|
+
}
|
|
2251
|
+
if (options.onRender) {
|
|
2252
|
+
builder.add(node.to, node.to, Decoration8.replace({
|
|
2253
|
+
widget: new LinkButton(url, options.onRender)
|
|
2254
|
+
}));
|
|
2255
|
+
}
|
|
2256
|
+
return false;
|
|
2257
|
+
}
|
|
2258
|
+
},
|
|
2259
|
+
from,
|
|
2260
|
+
to
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
return builder.finish();
|
|
2041
2264
|
};
|
|
2042
2265
|
|
|
2043
|
-
// packages/ui/react-ui-editor/src/extensions/table.ts
|
|
2044
|
-
import { syntaxTree as
|
|
2045
|
-
import { RangeSetBuilder as
|
|
2046
|
-
import { Decoration as
|
|
2266
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2267
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2268
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
|
|
2269
|
+
import { Decoration as Decoration9, EditorView as EditorView11, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2047
2270
|
var table = (options = {}) => {
|
|
2048
2271
|
return StateField4.define({
|
|
2049
2272
|
create: (state) => update(state, options),
|
|
@@ -2052,7 +2275,7 @@ var table = (options = {}) => {
|
|
|
2052
2275
|
});
|
|
2053
2276
|
};
|
|
2054
2277
|
var update = (state, options) => {
|
|
2055
|
-
const builder = new
|
|
2278
|
+
const builder = new RangeSetBuilder6();
|
|
2056
2279
|
const cursor = state.selection.main.head;
|
|
2057
2280
|
const tables = [];
|
|
2058
2281
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -2060,7 +2283,7 @@ var update = (state, options) => {
|
|
|
2060
2283
|
const table2 = getTable();
|
|
2061
2284
|
return table2.rows?.[table2.rows.length - 1];
|
|
2062
2285
|
};
|
|
2063
|
-
|
|
2286
|
+
syntaxTree7(state).iterate({
|
|
2064
2287
|
enter: (node) => {
|
|
2065
2288
|
switch (node.name) {
|
|
2066
2289
|
case "Table": {
|
|
@@ -2092,16 +2315,16 @@ var update = (state, options) => {
|
|
|
2092
2315
|
});
|
|
2093
2316
|
tables.forEach((table2) => {
|
|
2094
2317
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2095
|
-
hide && builder.add(table2.from, table2.to,
|
|
2318
|
+
hide && builder.add(table2.from, table2.to, Decoration9.replace({
|
|
2096
2319
|
widget: new TableWidget(table2)
|
|
2097
2320
|
}));
|
|
2098
|
-
builder.add(table2.from, table2.to,
|
|
2321
|
+
builder.add(table2.from, table2.to, Decoration9.mark({
|
|
2099
2322
|
class: "cm-table"
|
|
2100
2323
|
}));
|
|
2101
2324
|
});
|
|
2102
2325
|
return builder.finish();
|
|
2103
2326
|
};
|
|
2104
|
-
var TableWidget = class extends
|
|
2327
|
+
var TableWidget = class extends WidgetType6 {
|
|
2105
2328
|
constructor(_table) {
|
|
2106
2329
|
super();
|
|
2107
2330
|
this._table = _table;
|
|
@@ -2138,10 +2361,10 @@ var TableWidget = class extends WidgetType5 {
|
|
|
2138
2361
|
}
|
|
2139
2362
|
};
|
|
2140
2363
|
|
|
2141
|
-
// packages/ui/react-ui-editor/src/extensions/tasklist.ts
|
|
2142
|
-
import { syntaxTree as
|
|
2143
|
-
import { RangeSetBuilder as
|
|
2144
|
-
import { EditorView as EditorView12, Decoration as
|
|
2364
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
2365
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
2366
|
+
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
2367
|
+
import { EditorView as EditorView12, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
2145
2368
|
var styles5 = EditorView12.baseTheme({
|
|
2146
2369
|
"& .cm-task": {
|
|
2147
2370
|
color: getToken("extend.colors.blue.500")
|
|
@@ -2151,7 +2374,7 @@ var styles5 = EditorView12.baseTheme({
|
|
|
2151
2374
|
marginRight: "4px"
|
|
2152
2375
|
}
|
|
2153
2376
|
});
|
|
2154
|
-
var CheckboxWidget = class extends
|
|
2377
|
+
var CheckboxWidget = class extends WidgetType7 {
|
|
2155
2378
|
constructor(_checked) {
|
|
2156
2379
|
super();
|
|
2157
2380
|
this._checked = _checked;
|
|
@@ -2188,23 +2411,23 @@ var CheckboxWidget = class extends WidgetType6 {
|
|
|
2188
2411
|
return false;
|
|
2189
2412
|
}
|
|
2190
2413
|
};
|
|
2191
|
-
var checkedDecoration =
|
|
2414
|
+
var checkedDecoration = Decoration10.replace({
|
|
2192
2415
|
widget: new CheckboxWidget(true)
|
|
2193
2416
|
});
|
|
2194
|
-
var uncheckedDecoration =
|
|
2417
|
+
var uncheckedDecoration = Decoration10.replace({
|
|
2195
2418
|
widget: new CheckboxWidget(false)
|
|
2196
2419
|
});
|
|
2197
|
-
var
|
|
2198
|
-
const builder = new
|
|
2420
|
+
var buildDecorations6 = (view) => {
|
|
2421
|
+
const builder = new RangeSetBuilder7();
|
|
2199
2422
|
const { state } = view;
|
|
2200
2423
|
const cursor = state.selection.main.head;
|
|
2201
2424
|
for (const { from, to } of view.visibleRanges) {
|
|
2202
|
-
|
|
2425
|
+
syntaxTree8(state).iterate({
|
|
2203
2426
|
enter: (node) => {
|
|
2204
2427
|
if (node.name === "TaskMarker") {
|
|
2205
2428
|
if (cursor < node.from || cursor > node.to) {
|
|
2206
2429
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2207
|
-
builder.add(node.from - 2, node.from - 1,
|
|
2430
|
+
builder.add(node.from - 2, node.from - 1, Decoration10.mark({
|
|
2208
2431
|
class: "cm-task"
|
|
2209
2432
|
}));
|
|
2210
2433
|
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
@@ -2219,24 +2442,58 @@ var buildDecorations4 = (view) => {
|
|
|
2219
2442
|
};
|
|
2220
2443
|
var tasklist = (options = {}) => {
|
|
2221
2444
|
return [
|
|
2222
|
-
|
|
2445
|
+
ViewPlugin8.fromClass(class {
|
|
2223
2446
|
constructor(view) {
|
|
2224
|
-
this.decorations =
|
|
2447
|
+
this.decorations = buildDecorations6(view);
|
|
2225
2448
|
}
|
|
2226
2449
|
update(update2) {
|
|
2227
2450
|
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
2228
|
-
this.decorations =
|
|
2451
|
+
this.decorations = buildDecorations6(update2.view);
|
|
2229
2452
|
}
|
|
2230
2453
|
}
|
|
2231
2454
|
}, {
|
|
2232
|
-
decorations: (
|
|
2455
|
+
decorations: (value) => value.decorations
|
|
2233
2456
|
}),
|
|
2234
2457
|
styles5
|
|
2235
2458
|
];
|
|
2236
2459
|
};
|
|
2237
2460
|
|
|
2461
|
+
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
2462
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
2463
|
+
var mention = ({ onSearch }) => {
|
|
2464
|
+
return autocompletion2({
|
|
2465
|
+
// TODO(burdon): Not working.
|
|
2466
|
+
activateOnTyping: true,
|
|
2467
|
+
// activateOnTypingDelay: 100,
|
|
2468
|
+
// selectOnOpen: true,
|
|
2469
|
+
closeOnBlur: false,
|
|
2470
|
+
// defaultKeymap: false,
|
|
2471
|
+
icons: false,
|
|
2472
|
+
override: [
|
|
2473
|
+
(context) => {
|
|
2474
|
+
console.log(context);
|
|
2475
|
+
const match = context.matchBefore(/@(\w+)?/);
|
|
2476
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
2477
|
+
return null;
|
|
2478
|
+
}
|
|
2479
|
+
return {
|
|
2480
|
+
from: match.from,
|
|
2481
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
|
2482
|
+
label: `@${value}`
|
|
2483
|
+
}))
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
]
|
|
2487
|
+
});
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
// packages/ui/react-ui-editor/src/extensions/outliner.ts
|
|
2491
|
+
var outliner = (options = {}) => {
|
|
2492
|
+
return [];
|
|
2493
|
+
};
|
|
2494
|
+
|
|
2238
2495
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
2239
|
-
import { keymap as
|
|
2496
|
+
import { keymap as keymap6 } from "@codemirror/view";
|
|
2240
2497
|
var defaultItems = [
|
|
2241
2498
|
"hello world!",
|
|
2242
2499
|
"this is a test.",
|
|
@@ -2246,7 +2503,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2246
2503
|
let t;
|
|
2247
2504
|
let idx = 0;
|
|
2248
2505
|
return [
|
|
2249
|
-
|
|
2506
|
+
keymap6.of([
|
|
2250
2507
|
{
|
|
2251
2508
|
// Reset.
|
|
2252
2509
|
key: "alt-meta-'",
|
|
@@ -2292,27 +2549,6 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2292
2549
|
];
|
|
2293
2550
|
};
|
|
2294
2551
|
|
|
2295
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2296
|
-
import { yCollab } from "y-codemirror.next";
|
|
2297
|
-
|
|
2298
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/cursor.ts
|
|
2299
|
-
import * as Y from "yjs";
|
|
2300
|
-
import { arrayToString, stringToArray } from "@dxos/util";
|
|
2301
|
-
var cursorConverter2 = (text) => ({
|
|
2302
|
-
toCursor: (index, assoc) => {
|
|
2303
|
-
return arrayToString(Y.encodeRelativePosition(Y.createRelativePositionFromTypeIndex(text, index, assoc)));
|
|
2304
|
-
},
|
|
2305
|
-
fromCursor: (cursor) => {
|
|
2306
|
-
return Y.createAbsolutePositionFromRelativePosition(Y.decodeRelativePosition(stringToArray(cursor)), text.doc)?.index ?? 0;
|
|
2307
|
-
}
|
|
2308
|
-
});
|
|
2309
|
-
|
|
2310
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2311
|
-
var yjs = (content, awareness2) => [
|
|
2312
|
-
Cursor.converter.of(cursorConverter2(content)),
|
|
2313
|
-
yCollab(content, awareness2)
|
|
2314
|
-
];
|
|
2315
|
-
|
|
2316
2552
|
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
2317
2553
|
import get3 from "lodash.get";
|
|
2318
2554
|
var defaultTheme = {
|
|
@@ -2344,8 +2580,9 @@ var defaultTheme = {
|
|
|
2344
2580
|
outline: "none"
|
|
2345
2581
|
},
|
|
2346
2582
|
".cm-scroller": {
|
|
2347
|
-
overflow:
|
|
2348
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2583
|
+
// overflow: 'visible',
|
|
2584
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2585
|
+
lineHeight: 1.4
|
|
2349
2586
|
},
|
|
2350
2587
|
".cm-content": {
|
|
2351
2588
|
padding: 0,
|
|
@@ -2379,7 +2616,7 @@ var defaultTheme = {
|
|
|
2379
2616
|
paddingInline: 0
|
|
2380
2617
|
},
|
|
2381
2618
|
".cm-activeLine": {
|
|
2382
|
-
background: "
|
|
2619
|
+
background: "transparent"
|
|
2383
2620
|
},
|
|
2384
2621
|
//
|
|
2385
2622
|
// Selection
|
|
@@ -2550,31 +2787,35 @@ var codeTheme = {
|
|
|
2550
2787
|
};
|
|
2551
2788
|
|
|
2552
2789
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2553
|
-
var
|
|
2790
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2554
2791
|
var EditorModes = [
|
|
2555
2792
|
"default",
|
|
2556
2793
|
"vim"
|
|
2557
2794
|
];
|
|
2558
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly,
|
|
2559
|
-
const
|
|
2560
|
-
tabBehavior: "limited"
|
|
2561
|
-
});
|
|
2562
|
-
const { themeMode } = useThemeContext2();
|
|
2795
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2796
|
+
const { themeMode } = useThemeContext();
|
|
2563
2797
|
const rootRef = useRef(null);
|
|
2564
2798
|
const [view, setView] = useState(null);
|
|
2565
2799
|
useImperativeHandle(forwardedRef, () => view, [
|
|
2566
2800
|
view
|
|
2567
2801
|
]);
|
|
2568
|
-
|
|
2569
|
-
if (
|
|
2802
|
+
useEffect2(() => {
|
|
2803
|
+
if (autoFocus && !view?.hasFocus) {
|
|
2804
|
+
if (view?.state.selection.main?.from === 0) {
|
|
2805
|
+
const { to } = view.state.doc.lineAt(0);
|
|
2806
|
+
view?.dispatch({
|
|
2807
|
+
selection: {
|
|
2808
|
+
anchor: to
|
|
2809
|
+
}
|
|
2810
|
+
});
|
|
2811
|
+
}
|
|
2570
2812
|
view?.focus();
|
|
2571
2813
|
}
|
|
2572
2814
|
}, [
|
|
2573
2815
|
view,
|
|
2574
|
-
|
|
2816
|
+
autoFocus
|
|
2575
2817
|
]);
|
|
2576
|
-
|
|
2577
|
-
useEffect3(() => {
|
|
2818
|
+
useEffect2(() => {
|
|
2578
2819
|
if (!model || !rootRef.current) {
|
|
2579
2820
|
return;
|
|
2580
2821
|
}
|
|
@@ -2585,8 +2826,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2585
2826
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2586
2827
|
EditorView13.exceptionSink.of((err) => {
|
|
2587
2828
|
log2.catch(err, void 0, {
|
|
2588
|
-
F:
|
|
2589
|
-
L:
|
|
2829
|
+
F: __dxlog_file3,
|
|
2830
|
+
L: 134,
|
|
2590
2831
|
S: void 0,
|
|
2591
2832
|
C: (f, a) => f(...a)
|
|
2592
2833
|
});
|
|
@@ -2603,15 +2844,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2603
2844
|
class: slots.content?.className ?? ""
|
|
2604
2845
|
}),
|
|
2605
2846
|
// State.
|
|
2847
|
+
EditorView13.editable.of(!readonly),
|
|
2606
2848
|
EditorState2.readOnly.of(!!readonly),
|
|
2607
2849
|
// Storage and replication.
|
|
2608
2850
|
// NOTE: This must come before user extensions.
|
|
2609
2851
|
model.extension,
|
|
2610
|
-
// TODO(burdon): Factor out (
|
|
2852
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2611
2853
|
editorMode === "vim" && vim(),
|
|
2612
2854
|
// Custom.
|
|
2613
2855
|
...extensions
|
|
2614
|
-
].filter(
|
|
2856
|
+
].filter(isNotFalsy3)
|
|
2615
2857
|
});
|
|
2616
2858
|
const newView = new EditorView13({
|
|
2617
2859
|
state,
|
|
@@ -2620,11 +2862,10 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2620
2862
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
2621
2863
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
2622
2864
|
dispatchTransactions: (trs, view2) => {
|
|
2623
|
-
view2.update(trs);
|
|
2624
|
-
const debug = false;
|
|
2625
2865
|
if (debug) {
|
|
2626
2866
|
logChanges(trs);
|
|
2627
2867
|
}
|
|
2868
|
+
view2.update(trs);
|
|
2628
2869
|
}
|
|
2629
2870
|
});
|
|
2630
2871
|
view?.destroy();
|
|
@@ -2649,7 +2890,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2649
2890
|
}
|
|
2650
2891
|
case "Escape": {
|
|
2651
2892
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2652
|
-
|
|
2893
|
+
view?.focus();
|
|
2653
2894
|
}
|
|
2654
2895
|
break;
|
|
2655
2896
|
}
|
|
@@ -2662,23 +2903,23 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2662
2903
|
key: model.id,
|
|
2663
2904
|
role: "none",
|
|
2664
2905
|
tabIndex: 0,
|
|
2665
|
-
onKeyUp: handleKeyUp,
|
|
2666
2906
|
...slots.root,
|
|
2667
|
-
...editorMode !==
|
|
2907
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2908
|
+
onKeyUp: handleKeyUp,
|
|
2668
2909
|
ref: rootRef
|
|
2669
2910
|
});
|
|
2670
2911
|
});
|
|
2671
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3,
|
|
2672
|
-
const { themeMode } =
|
|
2912
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions = [], ...props }, forwardedRef) => {
|
|
2913
|
+
const { themeMode } = useThemeContext();
|
|
2673
2914
|
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2674
2915
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2675
2916
|
ref: forwardedRef,
|
|
2676
2917
|
readonly,
|
|
2677
2918
|
extensions: [
|
|
2678
|
-
|
|
2919
|
+
createBasicBundle({
|
|
2679
2920
|
themeMode,
|
|
2680
2921
|
placeholder: placeholder3,
|
|
2681
|
-
|
|
2922
|
+
lineWrapping
|
|
2682
2923
|
}),
|
|
2683
2924
|
...extensions
|
|
2684
2925
|
],
|
|
@@ -2688,15 +2929,14 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2688
2929
|
});
|
|
2689
2930
|
});
|
|
2690
2931
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions = [], ...props }, forwardedRef) => {
|
|
2691
|
-
const { themeMode } =
|
|
2932
|
+
const { themeMode } = useThemeContext();
|
|
2692
2933
|
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2693
2934
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2694
2935
|
ref: forwardedRef,
|
|
2695
2936
|
readonly,
|
|
2696
2937
|
extensions: [
|
|
2697
|
-
|
|
2938
|
+
createMarkdownExtensions({
|
|
2698
2939
|
themeMode,
|
|
2699
|
-
readonly,
|
|
2700
2940
|
placeholder: placeholder3
|
|
2701
2941
|
}),
|
|
2702
2942
|
...extensions
|
|
@@ -2709,7 +2949,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2709
2949
|
var defaultSlots = {
|
|
2710
2950
|
root: {
|
|
2711
2951
|
// TODO(burdon): Add focusRing by default/as property?
|
|
2712
|
-
className: mx3("flex flex-col grow overflow-y-auto",
|
|
2952
|
+
className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
|
|
2713
2953
|
},
|
|
2714
2954
|
editor: {
|
|
2715
2955
|
className: "h-full p-2"
|
|
@@ -2722,22 +2962,178 @@ var defaultMarkdownSlots = {
|
|
|
2722
2962
|
...defaultSlots
|
|
2723
2963
|
};
|
|
2724
2964
|
|
|
2725
|
-
// packages/ui/react-ui-editor/src/
|
|
2726
|
-
import
|
|
2727
|
-
import {
|
|
2728
|
-
import
|
|
2965
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
2966
|
+
import { At, CaretRight, ChatText, Code, Image, Link, ListBullets, ListChecks, ListNumbers, TextStrikethrough, Table as Table2, TextB, TextItalic } from "@phosphor-icons/react";
|
|
2967
|
+
import { createContext } from "@radix-ui/react-context";
|
|
2968
|
+
import React2 from "react";
|
|
2969
|
+
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
2970
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
2971
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
2972
|
+
var ToolbarRoot = ({ children, onAction }) => {
|
|
2973
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
2974
|
+
onAction
|
|
2975
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
2976
|
+
density: "fine"
|
|
2977
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
2978
|
+
role: "toolbar",
|
|
2979
|
+
className: "flex w-full shrink-0 p-2 gap-4 items-center whitespace-nowrap overflow-hidden"
|
|
2980
|
+
}, children)));
|
|
2981
|
+
};
|
|
2982
|
+
var ToolbarButton = ({ Icon, onClick, title }) => {
|
|
2983
|
+
const { onAction } = useToolbarContext("ToolbarButton");
|
|
2984
|
+
const handleClick = () => {
|
|
2985
|
+
const action = onClick();
|
|
2986
|
+
if (action) {
|
|
2987
|
+
onAction?.(action);
|
|
2988
|
+
}
|
|
2989
|
+
};
|
|
2990
|
+
return /* @__PURE__ */ React2.createElement(Button, {
|
|
2991
|
+
variant: "ghost",
|
|
2992
|
+
classNames: "p-2",
|
|
2993
|
+
onClick: handleClick,
|
|
2994
|
+
title
|
|
2995
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
2996
|
+
className: getSize(5)
|
|
2997
|
+
}));
|
|
2998
|
+
};
|
|
2999
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3000
|
+
className: "grow"
|
|
3001
|
+
});
|
|
3002
|
+
var MarkdownHeading = () => {
|
|
3003
|
+
const { onAction } = useToolbarContext("MarkdownFormatting");
|
|
3004
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3005
|
+
defaultValue: "0",
|
|
3006
|
+
onValueChange: (value) => onAction?.({
|
|
3007
|
+
type: "heading",
|
|
3008
|
+
data: parseInt(value)
|
|
3009
|
+
})
|
|
3010
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
3011
|
+
classNames: "w-[8rem]"
|
|
3012
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3013
|
+
value: "0"
|
|
3014
|
+
}, "Paragraph"), [
|
|
3015
|
+
1,
|
|
3016
|
+
2,
|
|
3017
|
+
3,
|
|
3018
|
+
4,
|
|
3019
|
+
5,
|
|
3020
|
+
6
|
|
3021
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3022
|
+
key: level,
|
|
3023
|
+
value: String(level)
|
|
3024
|
+
}, "Heading ", level))))));
|
|
3025
|
+
};
|
|
3026
|
+
var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3027
|
+
role: "none"
|
|
3028
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3029
|
+
Icon: TextB,
|
|
3030
|
+
title: "Bold",
|
|
3031
|
+
onClick: () => ({
|
|
3032
|
+
type: "bold"
|
|
3033
|
+
})
|
|
3034
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3035
|
+
Icon: TextItalic,
|
|
3036
|
+
title: "Italic",
|
|
3037
|
+
onClick: () => ({
|
|
3038
|
+
type: "italic"
|
|
3039
|
+
})
|
|
3040
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3041
|
+
Icon: TextStrikethrough,
|
|
3042
|
+
title: "Strike-through",
|
|
3043
|
+
onClick: () => ({
|
|
3044
|
+
type: "strikethrough"
|
|
3045
|
+
})
|
|
3046
|
+
}));
|
|
3047
|
+
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3048
|
+
role: "none"
|
|
3049
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3050
|
+
Icon: ListBullets,
|
|
3051
|
+
title: "Bullet list",
|
|
3052
|
+
onClick: () => ({
|
|
3053
|
+
type: "list"
|
|
3054
|
+
})
|
|
3055
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3056
|
+
Icon: ListNumbers,
|
|
3057
|
+
title: "Numbered list",
|
|
3058
|
+
onClick: () => ({
|
|
3059
|
+
type: "list-ordered"
|
|
3060
|
+
})
|
|
3061
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3062
|
+
Icon: ListChecks,
|
|
3063
|
+
title: "Task list",
|
|
3064
|
+
onClick: () => ({
|
|
3065
|
+
type: "list-tasks"
|
|
3066
|
+
})
|
|
3067
|
+
}));
|
|
3068
|
+
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3069
|
+
role: "none"
|
|
3070
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3071
|
+
Icon: CaretRight,
|
|
3072
|
+
title: "Block quite",
|
|
3073
|
+
onClick: () => ({
|
|
3074
|
+
type: "blockquote"
|
|
3075
|
+
})
|
|
3076
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3077
|
+
Icon: Code,
|
|
3078
|
+
title: "Code block",
|
|
3079
|
+
onClick: () => ({
|
|
3080
|
+
type: "codeblock"
|
|
3081
|
+
})
|
|
3082
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3083
|
+
Icon: Table2,
|
|
3084
|
+
title: "Table",
|
|
3085
|
+
onClick: () => ({
|
|
3086
|
+
type: "table"
|
|
3087
|
+
})
|
|
3088
|
+
}));
|
|
3089
|
+
var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3090
|
+
role: "none"
|
|
3091
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3092
|
+
Icon: Link,
|
|
3093
|
+
title: "Link",
|
|
3094
|
+
onClick: () => ({
|
|
3095
|
+
type: "link"
|
|
3096
|
+
})
|
|
3097
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3098
|
+
Icon: At,
|
|
3099
|
+
title: "Mention",
|
|
3100
|
+
onClick: () => ({
|
|
3101
|
+
type: "mention"
|
|
3102
|
+
})
|
|
3103
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3104
|
+
Icon: Image,
|
|
3105
|
+
title: "Image",
|
|
3106
|
+
onClick: () => ({
|
|
3107
|
+
type: "image"
|
|
3108
|
+
})
|
|
3109
|
+
}));
|
|
3110
|
+
var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null), /* @__PURE__ */ React2.createElement(MarkdownLinks, null));
|
|
3111
|
+
var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
|
|
3112
|
+
Icon: ChatText,
|
|
3113
|
+
title: "Create comment",
|
|
3114
|
+
onClick: () => ({
|
|
3115
|
+
type: "comment"
|
|
3116
|
+
})
|
|
3117
|
+
});
|
|
3118
|
+
var Toolbar = {
|
|
3119
|
+
Root: ToolbarRoot,
|
|
3120
|
+
Button: ToolbarButton,
|
|
3121
|
+
Separator: ToolbarSeparator,
|
|
3122
|
+
Markdown: MarkdownStandard,
|
|
3123
|
+
Extended: MarkdownExtended
|
|
3124
|
+
};
|
|
2729
3125
|
|
|
2730
3126
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2731
3127
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2732
3128
|
import { Context as Context2 } from "@dxos/context";
|
|
2733
|
-
import { invariant as
|
|
3129
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2734
3130
|
import { log as log3 } from "@dxos/log";
|
|
2735
|
-
var
|
|
3131
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2736
3132
|
var DEBOUNCE_INTERVAL = 100;
|
|
2737
3133
|
var SpaceAwarenessProvider = class {
|
|
2738
3134
|
constructor(params) {
|
|
2739
|
-
this.remoteStateChange = new Event2();
|
|
2740
3135
|
this._remoteStates = /* @__PURE__ */ new Map();
|
|
3136
|
+
this.remoteStateChange = new Event2();
|
|
2741
3137
|
this._space = params.space;
|
|
2742
3138
|
this._channel = params.channel;
|
|
2743
3139
|
this._peerId = params.peerId;
|
|
@@ -2754,7 +3150,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2754
3150
|
await sleep(DEBOUNCE_INTERVAL);
|
|
2755
3151
|
}
|
|
2756
3152
|
});
|
|
2757
|
-
|
|
3153
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
2758
3154
|
switch (message.payload.kind) {
|
|
2759
3155
|
case "query": {
|
|
2760
3156
|
this._handleQueryMessage();
|
|
@@ -2765,16 +3161,15 @@ var SpaceAwarenessProvider = class {
|
|
|
2765
3161
|
break;
|
|
2766
3162
|
}
|
|
2767
3163
|
}
|
|
2768
|
-
});
|
|
2769
|
-
this._ctx.onDispose(unsubscribe);
|
|
3164
|
+
}));
|
|
2770
3165
|
void this._space.postMessage(this._channel, {
|
|
2771
3166
|
kind: "query"
|
|
2772
3167
|
}).catch((err) => {
|
|
2773
3168
|
log3.debug("failed to query awareness", {
|
|
2774
3169
|
err
|
|
2775
3170
|
}, {
|
|
2776
|
-
F:
|
|
2777
|
-
L:
|
|
3171
|
+
F: __dxlog_file4,
|
|
3172
|
+
L: 89,
|
|
2778
3173
|
S: this,
|
|
2779
3174
|
C: (f, a) => f(...a)
|
|
2780
3175
|
});
|
|
@@ -2785,10 +3180,13 @@ var SpaceAwarenessProvider = class {
|
|
|
2785
3180
|
this._ctx = void 0;
|
|
2786
3181
|
this._postTask = void 0;
|
|
2787
3182
|
}
|
|
3183
|
+
getRemoteStates() {
|
|
3184
|
+
return Array.from(this._remoteStates.values());
|
|
3185
|
+
}
|
|
2788
3186
|
update(position) {
|
|
2789
|
-
|
|
2790
|
-
F:
|
|
2791
|
-
L:
|
|
3187
|
+
invariant2(this._postTask, void 0, {
|
|
3188
|
+
F: __dxlog_file4,
|
|
3189
|
+
L: 104,
|
|
2792
3190
|
S: this,
|
|
2793
3191
|
A: [
|
|
2794
3192
|
"this._postTask",
|
|
@@ -2802,13 +3200,10 @@ var SpaceAwarenessProvider = class {
|
|
|
2802
3200
|
};
|
|
2803
3201
|
this._postTask.schedule();
|
|
2804
3202
|
}
|
|
2805
|
-
getRemoteStates() {
|
|
2806
|
-
return Array.from(this._remoteStates.values());
|
|
2807
|
-
}
|
|
2808
3203
|
_handleQueryMessage() {
|
|
2809
|
-
|
|
2810
|
-
F:
|
|
2811
|
-
L:
|
|
3204
|
+
invariant2(this._postTask, void 0, {
|
|
3205
|
+
F: __dxlog_file4,
|
|
3206
|
+
L: 115,
|
|
2812
3207
|
S: this,
|
|
2813
3208
|
A: [
|
|
2814
3209
|
"this._postTask",
|
|
@@ -2818,9 +3213,9 @@ var SpaceAwarenessProvider = class {
|
|
|
2818
3213
|
this._postTask.schedule();
|
|
2819
3214
|
}
|
|
2820
3215
|
_handlePostMessage(message) {
|
|
2821
|
-
|
|
2822
|
-
F:
|
|
2823
|
-
L:
|
|
3216
|
+
invariant2(message.kind === "post", void 0, {
|
|
3217
|
+
F: __dxlog_file4,
|
|
3218
|
+
L: 120,
|
|
2824
3219
|
S: this,
|
|
2825
3220
|
A: [
|
|
2826
3221
|
"message.kind === 'post'",
|
|
@@ -2839,182 +3234,177 @@ var modelState = StateField5.define({
|
|
|
2839
3234
|
update: (model) => model
|
|
2840
3235
|
});
|
|
2841
3236
|
|
|
2842
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
2843
|
-
var
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
3237
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3238
|
+
var useActionHandler = (view) => {
|
|
3239
|
+
return (action) => {
|
|
3240
|
+
if (!view) {
|
|
3241
|
+
return;
|
|
3242
|
+
}
|
|
3243
|
+
switch (action.type) {
|
|
3244
|
+
case "heading":
|
|
3245
|
+
setHeading(parseInt(action.data))(view);
|
|
3246
|
+
break;
|
|
3247
|
+
case "bold":
|
|
3248
|
+
toggleBold(view);
|
|
3249
|
+
break;
|
|
3250
|
+
case "italic":
|
|
3251
|
+
toggleItalic(view);
|
|
3252
|
+
break;
|
|
3253
|
+
case "strikethrough":
|
|
3254
|
+
toggleStrikethrough(view);
|
|
3255
|
+
break;
|
|
3256
|
+
case "list":
|
|
3257
|
+
toggleList(view);
|
|
3258
|
+
break;
|
|
3259
|
+
case "codeblock":
|
|
3260
|
+
insertCodeblock(view);
|
|
3261
|
+
break;
|
|
3262
|
+
case "table":
|
|
3263
|
+
insertTable(view);
|
|
3264
|
+
break;
|
|
3265
|
+
case "comment":
|
|
3266
|
+
createComment(view);
|
|
3267
|
+
break;
|
|
3268
|
+
}
|
|
3269
|
+
setTimeout(() => {
|
|
3270
|
+
view.focus();
|
|
3271
|
+
view.dispatch({
|
|
3272
|
+
selection: view.state.selection
|
|
3273
|
+
});
|
|
3274
|
+
});
|
|
2876
3275
|
};
|
|
2877
|
-
return model;
|
|
2878
3276
|
};
|
|
2879
3277
|
|
|
2880
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
2881
|
-
import
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
F: __dxlog_file6,
|
|
2891
|
-
L: 22,
|
|
2892
|
-
S: void 0,
|
|
2893
|
-
A: [
|
|
2894
|
-
"text?.doc && text?.content",
|
|
2895
|
-
""
|
|
2896
|
-
]
|
|
2897
|
-
});
|
|
2898
|
-
const provider = space ? new YAwarenessProvider({
|
|
2899
|
-
space,
|
|
2900
|
-
doc: text.doc,
|
|
2901
|
-
channel: `yjs.awareness.${text.id}`
|
|
2902
|
-
}) : void 0;
|
|
2903
|
-
const model = {
|
|
2904
|
-
id: text.doc.guid,
|
|
2905
|
-
content: text.content,
|
|
2906
|
-
text: () => text.content.toString(),
|
|
2907
|
-
extension: [
|
|
2908
|
-
modelState.init(() => model),
|
|
2909
|
-
yjs(text.content, provider?.awareness)
|
|
2910
|
-
],
|
|
2911
|
-
awareness: provider?.awareness,
|
|
2912
|
-
peer: identity ? {
|
|
2913
|
-
id: identity.identityKey.toHex(),
|
|
2914
|
-
name: identity.profile?.displayName
|
|
2915
|
-
} : void 0
|
|
2916
|
-
};
|
|
2917
|
-
return model;
|
|
3278
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3279
|
+
import { useState as useState2 } from "react";
|
|
3280
|
+
var useEditorView = () => {
|
|
3281
|
+
const [view, setView] = useState2(null);
|
|
3282
|
+
return [
|
|
3283
|
+
(ref) => {
|
|
3284
|
+
setView(ref);
|
|
3285
|
+
},
|
|
3286
|
+
view
|
|
3287
|
+
];
|
|
2918
3288
|
};
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
_handleSpaceMessage({ payload }) {
|
|
2967
|
-
log4("space message", payload, {
|
|
2968
|
-
F: __dxlog_file6,
|
|
2969
|
-
L: 110,
|
|
2970
|
-
S: this,
|
|
2971
|
-
C: (f, a) => f(...a)
|
|
2972
|
-
});
|
|
2973
|
-
const data = new Uint8Array(Array.from(Object.values(payload)));
|
|
2974
|
-
const encoder = this._readMessage(data);
|
|
2975
|
-
if (encoder) {
|
|
2976
|
-
void this._space.postMessage(this._channel, encoding.toUint8Array(encoder));
|
|
3289
|
+
|
|
3290
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3291
|
+
import { EditorSelection, EditorState as EditorState3 } from "@codemirror/state";
|
|
3292
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
3293
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
3294
|
+
import { log as log4 } from "@dxos/log";
|
|
3295
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
3296
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
3297
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
3298
|
+
const onUpdate = useRef2();
|
|
3299
|
+
const [view, setView] = useState3();
|
|
3300
|
+
const parentRef = useRef2(null);
|
|
3301
|
+
useEffect3(() => {
|
|
3302
|
+
if (parentRef.current) {
|
|
3303
|
+
const state = EditorState3.create({
|
|
3304
|
+
doc,
|
|
3305
|
+
selection,
|
|
3306
|
+
extensions: [
|
|
3307
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3308
|
+
EditorView14.exceptionSink.of((err) => {
|
|
3309
|
+
log4.catch(err, void 0, {
|
|
3310
|
+
F: __dxlog_file5,
|
|
3311
|
+
L: 57,
|
|
3312
|
+
S: void 0,
|
|
3313
|
+
C: (f, a) => f(...a)
|
|
3314
|
+
});
|
|
3315
|
+
}),
|
|
3316
|
+
extensions,
|
|
3317
|
+
EditorView14.updateListener.of(() => {
|
|
3318
|
+
onUpdate.current?.();
|
|
3319
|
+
})
|
|
3320
|
+
].filter(isNotFalsy4)
|
|
3321
|
+
});
|
|
3322
|
+
const view2 = new EditorView14({
|
|
3323
|
+
parent: parentRef.current,
|
|
3324
|
+
scrollTo,
|
|
3325
|
+
state,
|
|
3326
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3327
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3328
|
+
dispatchTransactions: (trs, view3) => {
|
|
3329
|
+
if (debug) {
|
|
3330
|
+
logChanges(trs);
|
|
3331
|
+
}
|
|
3332
|
+
view3.update(trs);
|
|
3333
|
+
}
|
|
3334
|
+
});
|
|
3335
|
+
setView(view2);
|
|
2977
3336
|
}
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3337
|
+
return () => {
|
|
3338
|
+
view?.destroy();
|
|
3339
|
+
};
|
|
3340
|
+
}, [
|
|
3341
|
+
parentRef
|
|
3342
|
+
]);
|
|
3343
|
+
useEffect3(() => {
|
|
3344
|
+
if (view) {
|
|
3345
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
3346
|
+
selection = EditorSelection.single(view.state.doc.line(1).to);
|
|
2988
3347
|
}
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
3348
|
+
if (selection || scrollTo) {
|
|
3349
|
+
onUpdate.current = () => {
|
|
3350
|
+
onUpdate.current = void 0;
|
|
3351
|
+
view.dispatch({
|
|
3352
|
+
selection,
|
|
3353
|
+
effects: scrollTo && [
|
|
3354
|
+
scrollTo
|
|
3355
|
+
],
|
|
3356
|
+
scrollIntoView: !scrollTo
|
|
3357
|
+
});
|
|
3358
|
+
};
|
|
2994
3359
|
}
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
return encoder;
|
|
3360
|
+
if (autoFocus) {
|
|
3361
|
+
view.focus();
|
|
2998
3362
|
}
|
|
2999
3363
|
}
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
}
|
|
3364
|
+
}, [
|
|
3365
|
+
view,
|
|
3366
|
+
autoFocus,
|
|
3367
|
+
selection,
|
|
3368
|
+
scrollTo
|
|
3369
|
+
]);
|
|
3370
|
+
return {
|
|
3371
|
+
parentRef,
|
|
3372
|
+
view
|
|
3373
|
+
};
|
|
3374
|
+
};
|
|
3375
|
+
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
3376
|
+
return [
|
|
3377
|
+
//
|
|
3378
|
+
EditorState3.readOnly.of(readonly),
|
|
3379
|
+
EditorView14.editable.of(!readonly)
|
|
3380
|
+
];
|
|
3381
|
+
};
|
|
3382
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
3383
|
+
return [
|
|
3384
|
+
//
|
|
3385
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3386
|
+
theme && EditorView14.theme(theme),
|
|
3387
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3388
|
+
EditorView14.editorAttributes.of({
|
|
3389
|
+
class: slots?.editor?.className ?? ""
|
|
3390
|
+
}),
|
|
3391
|
+
EditorView14.contentAttributes.of({
|
|
3392
|
+
class: slots?.content?.className ?? ""
|
|
3393
|
+
})
|
|
3394
|
+
].filter(isNotFalsy4);
|
|
3010
3395
|
};
|
|
3011
3396
|
|
|
3012
3397
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
3013
|
-
import
|
|
3398
|
+
import get4 from "lodash.get";
|
|
3399
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
3400
|
+
import { generateName } from "@dxos/display-name";
|
|
3401
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
3402
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
3014
3403
|
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
3404
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
3015
3405
|
var useTextModel = (props) => {
|
|
3016
3406
|
const { identity, space, text } = props;
|
|
3017
|
-
const [model, setModel] =
|
|
3407
|
+
const [model, setModel] = useState4();
|
|
3018
3408
|
useEffect4(() => setModel(createModel(props)), [
|
|
3019
3409
|
identity,
|
|
3020
3410
|
space,
|
|
@@ -3022,18 +3412,54 @@ var useTextModel = (props) => {
|
|
|
3022
3412
|
]);
|
|
3023
3413
|
return model;
|
|
3024
3414
|
};
|
|
3025
|
-
var createModel = (
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3415
|
+
var createModel = ({ space, identity, text }) => {
|
|
3416
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3417
|
+
F: __dxlog_file6,
|
|
3418
|
+
L: 34,
|
|
3419
|
+
S: void 0,
|
|
3420
|
+
A: [
|
|
3421
|
+
"isAutomergeObject(text)",
|
|
3422
|
+
""
|
|
3423
|
+
]
|
|
3424
|
+
});
|
|
3425
|
+
const obj = text;
|
|
3426
|
+
const doc = getRawDoc(obj, [
|
|
3427
|
+
obj.field
|
|
3428
|
+
]);
|
|
3429
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
3430
|
+
space,
|
|
3431
|
+
channel: `automerge.awareness.${obj.id}`,
|
|
3432
|
+
info: {
|
|
3433
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
3434
|
+
color: cursorColor.color,
|
|
3435
|
+
lightColor: cursorColor.light
|
|
3436
|
+
},
|
|
3437
|
+
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
3438
|
+
});
|
|
3439
|
+
const extensions = [
|
|
3440
|
+
//
|
|
3441
|
+
modelState.init(() => model),
|
|
3442
|
+
automerge({
|
|
3443
|
+
handle: doc.handle,
|
|
3444
|
+
path: doc.path
|
|
3445
|
+
})
|
|
3446
|
+
];
|
|
3447
|
+
if (awarenessProvider2) {
|
|
3448
|
+
extensions.push(awareness(awarenessProvider2));
|
|
3033
3449
|
}
|
|
3450
|
+
const model = {
|
|
3451
|
+
id: obj.id,
|
|
3452
|
+
content: doc,
|
|
3453
|
+
text: () => get4(doc.handle.docSync(), doc.path),
|
|
3454
|
+
extension: extensions,
|
|
3455
|
+
peer: identity ? {
|
|
3456
|
+
id: identity.identityKey.toHex(),
|
|
3457
|
+
name: identity.profile?.displayName
|
|
3458
|
+
} : void 0
|
|
3459
|
+
};
|
|
3460
|
+
return model;
|
|
3034
3461
|
};
|
|
3035
3462
|
export {
|
|
3036
|
-
AwarenessProvider,
|
|
3037
3463
|
BaseTextEditor,
|
|
3038
3464
|
Cursor,
|
|
3039
3465
|
Doc,
|
|
@@ -3043,32 +3469,39 @@ export {
|
|
|
3043
3469
|
SpaceAwarenessProvider,
|
|
3044
3470
|
TextEditor,
|
|
3045
3471
|
TextKind,
|
|
3046
|
-
|
|
3472
|
+
Toolbar,
|
|
3047
3473
|
YText,
|
|
3048
3474
|
YXmlFragment,
|
|
3049
3475
|
autocomplete,
|
|
3050
|
-
|
|
3476
|
+
automerge,
|
|
3051
3477
|
awareness,
|
|
3052
|
-
|
|
3478
|
+
awarenessProvider,
|
|
3053
3479
|
blast,
|
|
3054
3480
|
callbackWrapper,
|
|
3055
3481
|
code2 as code,
|
|
3056
3482
|
codeTheme,
|
|
3057
3483
|
comments,
|
|
3058
|
-
|
|
3059
|
-
|
|
3484
|
+
createBasicBundle,
|
|
3485
|
+
createComment,
|
|
3486
|
+
createDataExtensions,
|
|
3487
|
+
createMarkdownExtensions,
|
|
3488
|
+
createThemeExtensions,
|
|
3060
3489
|
defaultMarkdownSlots,
|
|
3061
3490
|
defaultOptions,
|
|
3062
3491
|
defaultSlots,
|
|
3063
3492
|
defaultTextSlots,
|
|
3064
3493
|
defaultTheme,
|
|
3494
|
+
focusComment,
|
|
3495
|
+
formatting,
|
|
3065
3496
|
getToken,
|
|
3497
|
+
heading2 as heading,
|
|
3066
3498
|
hr,
|
|
3067
3499
|
image,
|
|
3500
|
+
insertCodeblock,
|
|
3501
|
+
insertTable,
|
|
3068
3502
|
link,
|
|
3069
3503
|
listener,
|
|
3070
3504
|
logChanges,
|
|
3071
|
-
markdownBundle,
|
|
3072
3505
|
markdownHighlightStyle,
|
|
3073
3506
|
markdownTags,
|
|
3074
3507
|
markdownTagsExtensions,
|
|
@@ -3077,16 +3510,23 @@ export {
|
|
|
3077
3510
|
modelState,
|
|
3078
3511
|
outliner,
|
|
3079
3512
|
setComments,
|
|
3080
|
-
|
|
3513
|
+
setHeading,
|
|
3081
3514
|
setSelection,
|
|
3082
3515
|
table,
|
|
3083
3516
|
tags2 as tags,
|
|
3084
3517
|
tasklist,
|
|
3085
3518
|
textTheme,
|
|
3519
|
+
toggleBold,
|
|
3520
|
+
toggleItalic,
|
|
3521
|
+
toggleList,
|
|
3522
|
+
toggleStrikethrough,
|
|
3523
|
+
toggleStyle,
|
|
3086
3524
|
typewriter,
|
|
3087
|
-
|
|
3525
|
+
useActionHandler,
|
|
3088
3526
|
useComments,
|
|
3527
|
+
useEditorView,
|
|
3528
|
+
useTextEditor,
|
|
3089
3529
|
useTextModel,
|
|
3090
|
-
|
|
3530
|
+
useToolbarContext
|
|
3091
3531
|
};
|
|
3092
3532
|
//# sourceMappingURL=index.mjs.map
|