@dxos/react-ui-editor 0.3.11-main.5e1976a → 0.3.11-main.604a65a
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 +1245 -654
- 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.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/hooks.stories.d.ts +23 -0
- 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 +1 -1
- package/dist/types/src/extensions/basic.d.ts +1 -1
- package/dist/types/src/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +6 -2
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -6
- 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/index.d.ts +2 -0
- 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 +36 -14
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- 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 -26
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +14 -18
- package/src/components/TextEditor/TextEditor.tsx +24 -12
- package/src/components/TextEditor/automerge.stories.tsx +1 -2
- package/src/components/TextEditor/comments.stories.tsx +3 -3
- 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 +26 -11
- 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 +3 -3
- package/src/extensions/basic.ts +15 -13
- package/src/extensions/comments.ts +113 -65
- package/src/extensions/index.ts +0 -6
- 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/index.ts +2 -0
- package/src/hooks/useActionHandler.ts +62 -0
- package/src/hooks/useEditorView.ts +29 -0
- package/src/hooks/useTextEditor.ts +143 -19
- package/src/hooks/useTextModel.ts +11 -8
- package/src/styles/markdown.ts +9 -10
- package/src/themes/default.ts +4 -4
- 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/src/extensions/code.ts +0 -104
- /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
13
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
15
14
|
import { log as log2 } from "@dxos/log";
|
|
16
15
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
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,14 +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
58
|
import { EditorView, ViewPlugin } from "@codemirror/view";
|
|
58
|
-
import { next as
|
|
59
|
-
import { invariant } from "@dxos/invariant";
|
|
59
|
+
import { next as A4 } from "@dxos/automerge/automerge";
|
|
60
60
|
|
|
61
61
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
|
62
62
|
import get from "lodash.get";
|
|
63
|
-
import { next as
|
|
63
|
+
import { next as A } from "@dxos/automerge/automerge";
|
|
64
64
|
var cursorConverter = (handle, path) => ({
|
|
65
65
|
// TODO(burdon): Handle assoc to associate with a previous character.
|
|
66
66
|
toCursor: (pos) => {
|
|
@@ -72,7 +72,7 @@ var cursorConverter = (handle, path) => ({
|
|
|
72
72
|
if (typeof value === "string" && value.length <= pos) {
|
|
73
73
|
return "end";
|
|
74
74
|
}
|
|
75
|
-
return
|
|
75
|
+
return A.getCursor(doc, path.slice(), pos);
|
|
76
76
|
},
|
|
77
77
|
fromCursor: (cursor) => {
|
|
78
78
|
if (cursor === "") {
|
|
@@ -90,26 +90,28 @@ var cursorConverter = (handle, path) => ({
|
|
|
90
90
|
return 0;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
return
|
|
93
|
+
return A.getCursorPosition(doc, path.slice(), cursor);
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
98
98
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
99
|
-
var effectType = StateEffect.define({});
|
|
100
|
-
var reconcileAnnotationType = Annotation.define();
|
|
101
99
|
var getPath = (state, field) => state.field(field).path;
|
|
102
100
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
103
|
-
var
|
|
101
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
102
|
+
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
104
103
|
newHeads
|
|
105
104
|
});
|
|
106
|
-
var
|
|
105
|
+
var reconcileAnnotation = Annotation.define();
|
|
106
|
+
var isReconcile = (tr) => {
|
|
107
|
+
return !!tr.annotation(reconcileAnnotation);
|
|
108
|
+
};
|
|
107
109
|
|
|
108
110
|
// packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
|
|
109
|
-
import { next as
|
|
111
|
+
import { next as A3 } from "@dxos/automerge/automerge";
|
|
110
112
|
|
|
111
113
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
|
112
|
-
import { next as
|
|
114
|
+
import { next as A2 } from "@dxos/automerge/automerge";
|
|
113
115
|
var updateAutomerge = (field, handle, transactions, state) => {
|
|
114
116
|
const { lastHeads, path } = state.field(field);
|
|
115
117
|
let hasChanges = false;
|
|
@@ -122,11 +124,19 @@ var updateAutomerge = (field, handle, transactions, state) => {
|
|
|
122
124
|
return void 0;
|
|
123
125
|
}
|
|
124
126
|
const newHeads = handle.changeAt(lastHeads, (doc) => {
|
|
127
|
+
const invertedTransactions = [];
|
|
125
128
|
for (const tr of transactions) {
|
|
126
|
-
tr.changes.iterChanges((fromA, toA, _fromB, _toB,
|
|
127
|
-
|
|
129
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
130
|
+
invertedTransactions.push({
|
|
131
|
+
from: fromA,
|
|
132
|
+
del: toA - fromA,
|
|
133
|
+
insert
|
|
134
|
+
});
|
|
128
135
|
});
|
|
129
136
|
}
|
|
137
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
138
|
+
A2.splice(doc, path.slice(), from, del, insert.toString());
|
|
139
|
+
});
|
|
130
140
|
});
|
|
131
141
|
return newHeads ?? void 0;
|
|
132
142
|
};
|
|
@@ -141,13 +151,13 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
141
151
|
selection = selection.map(changeSet, 1);
|
|
142
152
|
view.dispatch({
|
|
143
153
|
changes: changeSet,
|
|
144
|
-
annotations:
|
|
154
|
+
annotations: reconcileAnnotation.of(false)
|
|
145
155
|
});
|
|
146
156
|
}
|
|
147
157
|
}
|
|
148
158
|
view.dispatch({
|
|
149
159
|
selection,
|
|
150
|
-
annotations:
|
|
160
|
+
annotations: reconcileAnnotation.of(false)
|
|
151
161
|
});
|
|
152
162
|
};
|
|
153
163
|
var handlePatch = (patch, target, state) => {
|
|
@@ -168,7 +178,7 @@ var handleInsert = (target, patch) => {
|
|
|
168
178
|
if (index == null) {
|
|
169
179
|
return [];
|
|
170
180
|
}
|
|
171
|
-
const text = patch.values.map((
|
|
181
|
+
const text = patch.values.map((value) => value ? value.toString() : "").join("");
|
|
172
182
|
return [
|
|
173
183
|
{
|
|
174
184
|
from: index,
|
|
@@ -246,36 +256,37 @@ var PatchSemaphore = class {
|
|
|
246
256
|
this._state = _state;
|
|
247
257
|
this._inReconcile = false;
|
|
248
258
|
}
|
|
249
|
-
// NOTE: Cannot destruct view.state.
|
|
250
259
|
reconcile(view) {
|
|
251
|
-
if (this._inReconcile) {
|
|
252
|
-
|
|
260
|
+
if (!this._inReconcile) {
|
|
261
|
+
this._inReconcile = true;
|
|
262
|
+
this.doReconcile(view);
|
|
263
|
+
this._inReconcile = false;
|
|
253
264
|
}
|
|
254
|
-
|
|
265
|
+
}
|
|
266
|
+
doReconcile(view) {
|
|
255
267
|
const path = getPath(view.state, this._state);
|
|
256
268
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
257
269
|
let selection = view.state.selection;
|
|
258
|
-
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !
|
|
270
|
+
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
259
271
|
const toInvert = transactions.slice().reverse();
|
|
260
|
-
for (const
|
|
261
|
-
const inverted =
|
|
272
|
+
for (const tr of toInvert) {
|
|
273
|
+
const inverted = tr.changes.invert(tr.startState.doc);
|
|
262
274
|
selection = selection.map(inverted);
|
|
263
275
|
view.dispatch({
|
|
264
276
|
changes: inverted,
|
|
265
|
-
annotations:
|
|
277
|
+
annotations: reconcileAnnotation.of(true)
|
|
266
278
|
});
|
|
267
279
|
}
|
|
268
280
|
let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
269
281
|
if (newHeads === null || newHeads === void 0) {
|
|
270
|
-
newHeads =
|
|
282
|
+
newHeads = A3.getHeads(this._handle.docSync());
|
|
271
283
|
}
|
|
272
|
-
const diff =
|
|
284
|
+
const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
|
|
273
285
|
updateCodeMirror(view, selection, path, diff);
|
|
274
286
|
view.dispatch({
|
|
275
287
|
effects: updateHeads(newHeads),
|
|
276
|
-
annotations:
|
|
288
|
+
annotations: reconcileAnnotation.of(false)
|
|
277
289
|
});
|
|
278
|
-
this._inReconcile = false;
|
|
279
290
|
}
|
|
280
291
|
};
|
|
281
292
|
|
|
@@ -317,12 +328,11 @@ var Cursor = class _Cursor {
|
|
|
317
328
|
};
|
|
318
329
|
|
|
319
330
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
320
|
-
var
|
|
321
|
-
|
|
322
|
-
const state = StateField.define({
|
|
331
|
+
var automerge = ({ handle, path }) => {
|
|
332
|
+
const syncState = StateField.define({
|
|
323
333
|
create: () => ({
|
|
324
334
|
path: path.slice(),
|
|
325
|
-
lastHeads:
|
|
335
|
+
lastHeads: A4.getHeads(handle.docSync()),
|
|
326
336
|
unreconciledTransactions: []
|
|
327
337
|
}),
|
|
328
338
|
update: (value, tr) => {
|
|
@@ -333,7 +343,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
333
343
|
};
|
|
334
344
|
let clearUnreconciled = false;
|
|
335
345
|
for (const effect of tr.effects) {
|
|
336
|
-
if (effect.is(
|
|
346
|
+
if (effect.is(updateHeadsEffect)) {
|
|
337
347
|
result.lastHeads = effect.value.newHeads;
|
|
338
348
|
clearUnreconciled = true;
|
|
339
349
|
}
|
|
@@ -341,29 +351,21 @@ var automerge3 = ({ handle, path }) => {
|
|
|
341
351
|
if (clearUnreconciled) {
|
|
342
352
|
result.unreconciledTransactions = [];
|
|
343
353
|
} else {
|
|
344
|
-
if (!
|
|
354
|
+
if (!isReconcile(tr)) {
|
|
345
355
|
result.unreconciledTransactions.push(tr);
|
|
346
356
|
}
|
|
347
357
|
}
|
|
348
358
|
return result;
|
|
349
359
|
}
|
|
350
360
|
});
|
|
351
|
-
const semaphore = new PatchSemaphore(handle,
|
|
361
|
+
const semaphore = new PatchSemaphore(handle, syncState);
|
|
352
362
|
return [
|
|
353
363
|
Cursor.converter.of(cursorConverter(handle, path)),
|
|
364
|
+
syncState,
|
|
354
365
|
// Reconcile external updates.
|
|
355
366
|
ViewPlugin.fromClass(class {
|
|
356
367
|
constructor(_view) {
|
|
357
368
|
this._view = _view;
|
|
358
|
-
invariant(this._view, void 0, {
|
|
359
|
-
F: __dxlog_file,
|
|
360
|
-
L: 66,
|
|
361
|
-
S: this,
|
|
362
|
-
A: [
|
|
363
|
-
"this._view",
|
|
364
|
-
""
|
|
365
|
-
]
|
|
366
|
-
});
|
|
367
369
|
handle.addListener("change", this._handleChange.bind(this));
|
|
368
370
|
}
|
|
369
371
|
destroy() {
|
|
@@ -379,7 +381,17 @@ var automerge3 = ({ handle, path }) => {
|
|
|
379
381
|
semaphore.reconcile(view);
|
|
380
382
|
}
|
|
381
383
|
}),
|
|
382
|
-
|
|
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
|
+
})
|
|
383
395
|
];
|
|
384
396
|
};
|
|
385
397
|
|
|
@@ -398,13 +410,13 @@ var dummyProvider = {
|
|
|
398
410
|
update: () => {
|
|
399
411
|
}
|
|
400
412
|
};
|
|
401
|
-
var
|
|
413
|
+
var awarenessProvider = Facet2.define({
|
|
402
414
|
combine: (providers) => providers[0] ?? dummyProvider
|
|
403
415
|
});
|
|
404
416
|
var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
405
417
|
var awareness = (provider = dummyProvider) => {
|
|
406
418
|
return [
|
|
407
|
-
|
|
419
|
+
awarenessProvider.of(provider),
|
|
408
420
|
ViewPlugin2.fromClass(RemoteSelectionsDecorator, {
|
|
409
421
|
decorations: (value) => value.decorations
|
|
410
422
|
}),
|
|
@@ -418,7 +430,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
418
430
|
this._lastAnchor = void 0;
|
|
419
431
|
this._lastHead = void 0;
|
|
420
432
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
421
|
-
this._provider = view.state.facet(
|
|
433
|
+
this._provider = view.state.facet(awarenessProvider);
|
|
422
434
|
this._provider.open();
|
|
423
435
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
424
436
|
view.dispatch({
|
|
@@ -624,24 +636,25 @@ 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";
|
|
642
655
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
643
|
-
import { invariant
|
|
644
|
-
var
|
|
656
|
+
import { invariant } from "@dxos/invariant";
|
|
657
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
645
658
|
var defaultOptions = {
|
|
646
659
|
effect: 2,
|
|
647
660
|
maxParticles: 200,
|
|
@@ -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,
|
|
@@ -767,8 +780,8 @@ var Blaster = class {
|
|
|
767
780
|
return this._node;
|
|
768
781
|
}
|
|
769
782
|
initialize() {
|
|
770
|
-
|
|
771
|
-
F:
|
|
783
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
784
|
+
F: __dxlog_file,
|
|
772
785
|
L: 138,
|
|
773
786
|
S: this,
|
|
774
787
|
A: [
|
|
@@ -804,8 +817,8 @@ var Blaster = class {
|
|
|
804
817
|
}
|
|
805
818
|
}
|
|
806
819
|
start() {
|
|
807
|
-
|
|
808
|
-
F:
|
|
820
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
821
|
+
F: __dxlog_file,
|
|
809
822
|
L: 177,
|
|
810
823
|
S: this,
|
|
811
824
|
A: [
|
|
@@ -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,98 +1036,15 @@ 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
|
-
ViewPlugin3.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 } from "react";
|
|
1119
|
-
import { debounce } from "@dxos/async";
|
|
1120
|
-
import { invariant as invariant3 } 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
|
-
var
|
|
1041
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1126
1042
|
var callbackWrapper = (fn) => (...args) => {
|
|
1127
1043
|
try {
|
|
1128
1044
|
return fn(...args);
|
|
1129
1045
|
} catch (err) {
|
|
1130
1046
|
log.catch(err, void 0, {
|
|
1131
|
-
F:
|
|
1047
|
+
F: __dxlog_file2,
|
|
1132
1048
|
L: 18,
|
|
1133
1049
|
S: void 0,
|
|
1134
1050
|
C: (f, a) => f(...a)
|
|
@@ -1156,8 +1072,7 @@ 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
|
},
|
|
@@ -1165,15 +1080,13 @@ var styles3 = EditorView6.baseTheme({
|
|
|
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,7 +1099,7 @@ 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({
|
|
@@ -1235,7 +1148,7 @@ 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
1154
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1246,12 +1159,12 @@ var highlightDecorations = EditorView6.decorations.compute([
|
|
|
1246
1159
|
return void 0;
|
|
1247
1160
|
}
|
|
1248
1161
|
if (comment.comment.id === current) {
|
|
1249
|
-
return
|
|
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
|
-
current: 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,7 +1381,7 @@ 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
1386
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1434
1387
|
const { head } = state.selection.main;
|
|
@@ -1476,294 +1429,31 @@ 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
|
-
ViewPlugin4.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
|
-
return value;
|
|
1546
|
-
}
|
|
1547
|
-
const cursor = tr.state.selection.main.head;
|
|
1548
|
-
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
1549
|
-
let from = Math.min(cursor, oldCursor);
|
|
1550
|
-
let to = Math.max(cursor, oldCursor);
|
|
1551
|
-
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
1552
|
-
from = Math.min(from, fromB);
|
|
1553
|
-
to = Math.max(to, toB);
|
|
1554
|
-
});
|
|
1555
|
-
from = tr.state.doc.lineAt(from).from;
|
|
1556
|
-
to = tr.state.doc.lineAt(to).to;
|
|
1557
|
-
return value.map(tr.changes).update({
|
|
1558
|
-
filterFrom: from,
|
|
1559
|
-
filterTo: to,
|
|
1560
|
-
filter: () => false,
|
|
1561
|
-
add: buildDecorations2(from, to, tr.state)
|
|
1562
|
-
});
|
|
1563
|
-
},
|
|
1564
|
-
provide: (field) => EditorView8.decorations.from(field)
|
|
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 ViewPlugin5, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1610
|
-
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1611
|
-
var link = (options = {}) => {
|
|
1612
|
-
const extensions = [
|
|
1613
|
-
ViewPlugin5.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";
|
|
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";
|
|
1767
1457
|
|
|
1768
1458
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1769
1459
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -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
|
])
|
|
1696
|
+
].filter(isNotFalsy2);
|
|
1697
|
+
};
|
|
1698
|
+
|
|
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
|
+
];
|
|
1752
|
+
};
|
|
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
|
|
2006
1811
|
];
|
|
2007
1812
|
};
|
|
2008
1813
|
|
|
2009
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
2010
|
-
import {
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
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) {
|
|
2025
2162
|
return null;
|
|
2026
2163
|
}
|
|
2164
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
2027
2165
|
return {
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
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
|
+
}
|
|
2032
2181
|
};
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
|
-
}
|
|
2182
|
+
})
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
return extensions;
|
|
2036
2186
|
};
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
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-'",
|
|
@@ -2323,8 +2580,9 @@ var defaultTheme = {
|
|
|
2323
2580
|
outline: "none"
|
|
2324
2581
|
},
|
|
2325
2582
|
".cm-scroller": {
|
|
2326
|
-
overflow:
|
|
2327
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2583
|
+
// overflow: 'visible',
|
|
2584
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2585
|
+
lineHeight: 1.4
|
|
2328
2586
|
},
|
|
2329
2587
|
".cm-content": {
|
|
2330
2588
|
padding: 0,
|
|
@@ -2358,7 +2616,7 @@ var defaultTheme = {
|
|
|
2358
2616
|
paddingInline: 0
|
|
2359
2617
|
},
|
|
2360
2618
|
".cm-activeLine": {
|
|
2361
|
-
background: "
|
|
2619
|
+
background: "transparent"
|
|
2362
2620
|
},
|
|
2363
2621
|
//
|
|
2364
2622
|
// Selection
|
|
@@ -2529,15 +2787,12 @@ var codeTheme = {
|
|
|
2529
2787
|
};
|
|
2530
2788
|
|
|
2531
2789
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2532
|
-
var
|
|
2790
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2533
2791
|
var EditorModes = [
|
|
2534
2792
|
"default",
|
|
2535
2793
|
"vim"
|
|
2536
2794
|
];
|
|
2537
2795
|
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2538
|
-
const tabsterDOMAttribute = useFocusableGroup({
|
|
2539
|
-
tabBehavior: "limited"
|
|
2540
|
-
});
|
|
2541
2796
|
const { themeMode } = useThemeContext();
|
|
2542
2797
|
const rootRef = useRef(null);
|
|
2543
2798
|
const [view, setView] = useState(null);
|
|
@@ -2545,7 +2800,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2545
2800
|
view
|
|
2546
2801
|
]);
|
|
2547
2802
|
useEffect2(() => {
|
|
2548
|
-
if (autoFocus) {
|
|
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
|
+
}
|
|
2549
2812
|
view?.focus();
|
|
2550
2813
|
}
|
|
2551
2814
|
}, [
|
|
@@ -2563,8 +2826,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2563
2826
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2564
2827
|
EditorView13.exceptionSink.of((err) => {
|
|
2565
2828
|
log2.catch(err, void 0, {
|
|
2566
|
-
F:
|
|
2567
|
-
L:
|
|
2829
|
+
F: __dxlog_file3,
|
|
2830
|
+
L: 134,
|
|
2568
2831
|
S: void 0,
|
|
2569
2832
|
C: (f, a) => f(...a)
|
|
2570
2833
|
});
|
|
@@ -2581,15 +2844,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2581
2844
|
class: slots.content?.className ?? ""
|
|
2582
2845
|
}),
|
|
2583
2846
|
// State.
|
|
2847
|
+
EditorView13.editable.of(!readonly),
|
|
2584
2848
|
EditorState2.readOnly.of(!!readonly),
|
|
2585
2849
|
// Storage and replication.
|
|
2586
2850
|
// NOTE: This must come before user extensions.
|
|
2587
2851
|
model.extension,
|
|
2588
|
-
// TODO(burdon): Factor out (
|
|
2852
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2589
2853
|
editorMode === "vim" && vim(),
|
|
2590
2854
|
// Custom.
|
|
2591
2855
|
...extensions
|
|
2592
|
-
].filter(
|
|
2856
|
+
].filter(isNotFalsy3)
|
|
2593
2857
|
});
|
|
2594
2858
|
const newView = new EditorView13({
|
|
2595
2859
|
state,
|
|
@@ -2626,7 +2890,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2626
2890
|
}
|
|
2627
2891
|
case "Escape": {
|
|
2628
2892
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2629
|
-
|
|
2893
|
+
view?.focus();
|
|
2630
2894
|
}
|
|
2631
2895
|
break;
|
|
2632
2896
|
}
|
|
@@ -2639,9 +2903,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2639
2903
|
key: model.id,
|
|
2640
2904
|
role: "none",
|
|
2641
2905
|
tabIndex: 0,
|
|
2642
|
-
onKeyUp: handleKeyUp,
|
|
2643
2906
|
...slots.root,
|
|
2644
|
-
...editorMode !==
|
|
2907
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2908
|
+
onKeyUp: handleKeyUp,
|
|
2645
2909
|
ref: rootRef
|
|
2646
2910
|
});
|
|
2647
2911
|
});
|
|
@@ -2652,7 +2916,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2652
2916
|
ref: forwardedRef,
|
|
2653
2917
|
readonly,
|
|
2654
2918
|
extensions: [
|
|
2655
|
-
|
|
2919
|
+
createBasicBundle({
|
|
2656
2920
|
themeMode,
|
|
2657
2921
|
placeholder: placeholder3,
|
|
2658
2922
|
lineWrapping
|
|
@@ -2671,9 +2935,8 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2671
2935
|
ref: forwardedRef,
|
|
2672
2936
|
readonly,
|
|
2673
2937
|
extensions: [
|
|
2674
|
-
|
|
2938
|
+
createMarkdownExtensions({
|
|
2675
2939
|
themeMode,
|
|
2676
|
-
readonly,
|
|
2677
2940
|
placeholder: placeholder3
|
|
2678
2941
|
}),
|
|
2679
2942
|
...extensions
|
|
@@ -2699,12 +2962,173 @@ var defaultMarkdownSlots = {
|
|
|
2699
2962
|
...defaultSlots
|
|
2700
2963
|
};
|
|
2701
2964
|
|
|
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
|
+
};
|
|
3125
|
+
|
|
2702
3126
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2703
3127
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2704
3128
|
import { Context as Context2 } from "@dxos/context";
|
|
2705
|
-
import { invariant as
|
|
3129
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2706
3130
|
import { log as log3 } from "@dxos/log";
|
|
2707
|
-
var
|
|
3131
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2708
3132
|
var DEBOUNCE_INTERVAL = 100;
|
|
2709
3133
|
var SpaceAwarenessProvider = class {
|
|
2710
3134
|
constructor(params) {
|
|
@@ -2744,7 +3168,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2744
3168
|
log3.debug("failed to query awareness", {
|
|
2745
3169
|
err
|
|
2746
3170
|
}, {
|
|
2747
|
-
F:
|
|
3171
|
+
F: __dxlog_file4,
|
|
2748
3172
|
L: 89,
|
|
2749
3173
|
S: this,
|
|
2750
3174
|
C: (f, a) => f(...a)
|
|
@@ -2760,8 +3184,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2760
3184
|
return Array.from(this._remoteStates.values());
|
|
2761
3185
|
}
|
|
2762
3186
|
update(position) {
|
|
2763
|
-
|
|
2764
|
-
F:
|
|
3187
|
+
invariant2(this._postTask, void 0, {
|
|
3188
|
+
F: __dxlog_file4,
|
|
2765
3189
|
L: 104,
|
|
2766
3190
|
S: this,
|
|
2767
3191
|
A: [
|
|
@@ -2777,8 +3201,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2777
3201
|
this._postTask.schedule();
|
|
2778
3202
|
}
|
|
2779
3203
|
_handleQueryMessage() {
|
|
2780
|
-
|
|
2781
|
-
F:
|
|
3204
|
+
invariant2(this._postTask, void 0, {
|
|
3205
|
+
F: __dxlog_file4,
|
|
2782
3206
|
L: 115,
|
|
2783
3207
|
S: this,
|
|
2784
3208
|
A: [
|
|
@@ -2789,8 +3213,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2789
3213
|
this._postTask.schedule();
|
|
2790
3214
|
}
|
|
2791
3215
|
_handlePostMessage(message) {
|
|
2792
|
-
|
|
2793
|
-
F:
|
|
3216
|
+
invariant2(message.kind === "post", void 0, {
|
|
3217
|
+
F: __dxlog_file4,
|
|
2794
3218
|
L: 120,
|
|
2795
3219
|
S: this,
|
|
2796
3220
|
A: [
|
|
@@ -2810,9 +3234,50 @@ var modelState = StateField5.define({
|
|
|
2810
3234
|
update: (model) => model
|
|
2811
3235
|
});
|
|
2812
3236
|
|
|
2813
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
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
|
+
});
|
|
3275
|
+
};
|
|
3276
|
+
};
|
|
3277
|
+
|
|
3278
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
2814
3279
|
import { useState as useState2 } from "react";
|
|
2815
|
-
var
|
|
3280
|
+
var useEditorView = () => {
|
|
2816
3281
|
const [view, setView] = useState2(null);
|
|
2817
3282
|
return [
|
|
2818
3283
|
(ref) => {
|
|
@@ -2822,19 +3287,125 @@ var useTextEditor = () => {
|
|
|
2822
3287
|
];
|
|
2823
3288
|
};
|
|
2824
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);
|
|
3336
|
+
}
|
|
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);
|
|
3347
|
+
}
|
|
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
|
+
};
|
|
3359
|
+
}
|
|
3360
|
+
if (autoFocus) {
|
|
3361
|
+
view.focus();
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
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);
|
|
3395
|
+
};
|
|
3396
|
+
|
|
2825
3397
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
2826
3398
|
import get4 from "lodash.get";
|
|
2827
|
-
import { useEffect as
|
|
3399
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2828
3400
|
import { generateName } from "@dxos/display-name";
|
|
2829
3401
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
2830
|
-
import { invariant as
|
|
3402
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2831
3403
|
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
2832
|
-
|
|
2833
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
3404
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
2834
3405
|
var useTextModel = (props) => {
|
|
2835
3406
|
const { identity, space, text } = props;
|
|
2836
|
-
const [model, setModel] =
|
|
2837
|
-
|
|
3407
|
+
const [model, setModel] = useState4();
|
|
3408
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
2838
3409
|
identity,
|
|
2839
3410
|
space,
|
|
2840
3411
|
text
|
|
@@ -2842,9 +3413,9 @@ var useTextModel = (props) => {
|
|
|
2842
3413
|
return model;
|
|
2843
3414
|
};
|
|
2844
3415
|
var createModel = ({ space, identity, text }) => {
|
|
2845
|
-
|
|
2846
|
-
F:
|
|
2847
|
-
L:
|
|
3416
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3417
|
+
F: __dxlog_file6,
|
|
3418
|
+
L: 34,
|
|
2848
3419
|
S: void 0,
|
|
2849
3420
|
A: [
|
|
2850
3421
|
"isAutomergeObject(text)",
|
|
@@ -2855,7 +3426,7 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2855
3426
|
const doc = getRawDoc(obj, [
|
|
2856
3427
|
obj.field
|
|
2857
3428
|
]);
|
|
2858
|
-
const
|
|
3429
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
2859
3430
|
space,
|
|
2860
3431
|
channel: `automerge.awareness.${obj.id}`,
|
|
2861
3432
|
info: {
|
|
@@ -2865,19 +3436,22 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2865
3436
|
},
|
|
2866
3437
|
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
2867
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));
|
|
3449
|
+
}
|
|
2868
3450
|
const model = {
|
|
2869
3451
|
id: obj.id,
|
|
2870
3452
|
content: doc,
|
|
2871
3453
|
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2872
|
-
extension:
|
|
2873
|
-
modelState.init(() => model),
|
|
2874
|
-
automerge3({
|
|
2875
|
-
handle: doc.handle,
|
|
2876
|
-
path: doc.path
|
|
2877
|
-
}),
|
|
2878
|
-
awarenessProvider && AwarenessProvider.of(awarenessProvider),
|
|
2879
|
-
awareness()
|
|
2880
|
-
].filter(isNotNullOrUndefined),
|
|
3454
|
+
extension: extensions,
|
|
2881
3455
|
peer: identity ? {
|
|
2882
3456
|
id: identity.identityKey.toHex(),
|
|
2883
3457
|
name: identity.profile?.displayName
|
|
@@ -2886,7 +3460,6 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2886
3460
|
return model;
|
|
2887
3461
|
};
|
|
2888
3462
|
export {
|
|
2889
|
-
AwarenessProvider,
|
|
2890
3463
|
BaseTextEditor,
|
|
2891
3464
|
Cursor,
|
|
2892
3465
|
Doc,
|
|
@@ -2896,29 +3469,39 @@ export {
|
|
|
2896
3469
|
SpaceAwarenessProvider,
|
|
2897
3470
|
TextEditor,
|
|
2898
3471
|
TextKind,
|
|
3472
|
+
Toolbar,
|
|
2899
3473
|
YText,
|
|
2900
3474
|
YXmlFragment,
|
|
2901
3475
|
autocomplete,
|
|
2902
|
-
|
|
3476
|
+
automerge,
|
|
2903
3477
|
awareness,
|
|
2904
|
-
|
|
3478
|
+
awarenessProvider,
|
|
2905
3479
|
blast,
|
|
2906
3480
|
callbackWrapper,
|
|
2907
3481
|
code2 as code,
|
|
2908
3482
|
codeTheme,
|
|
2909
3483
|
comments,
|
|
3484
|
+
createBasicBundle,
|
|
3485
|
+
createComment,
|
|
3486
|
+
createDataExtensions,
|
|
3487
|
+
createMarkdownExtensions,
|
|
3488
|
+
createThemeExtensions,
|
|
2910
3489
|
defaultMarkdownSlots,
|
|
2911
3490
|
defaultOptions,
|
|
2912
3491
|
defaultSlots,
|
|
2913
3492
|
defaultTextSlots,
|
|
2914
3493
|
defaultTheme,
|
|
3494
|
+
focusComment,
|
|
3495
|
+
formatting,
|
|
2915
3496
|
getToken,
|
|
3497
|
+
heading2 as heading,
|
|
2916
3498
|
hr,
|
|
2917
3499
|
image,
|
|
3500
|
+
insertCodeblock,
|
|
3501
|
+
insertTable,
|
|
2918
3502
|
link,
|
|
2919
3503
|
listener,
|
|
2920
3504
|
logChanges,
|
|
2921
|
-
markdownBundle,
|
|
2922
3505
|
markdownHighlightStyle,
|
|
2923
3506
|
markdownTags,
|
|
2924
3507
|
markdownTagsExtensions,
|
|
@@ -2927,15 +3510,23 @@ export {
|
|
|
2927
3510
|
modelState,
|
|
2928
3511
|
outliner,
|
|
2929
3512
|
setComments,
|
|
2930
|
-
|
|
3513
|
+
setHeading,
|
|
2931
3514
|
setSelection,
|
|
2932
3515
|
table,
|
|
2933
3516
|
tags2 as tags,
|
|
2934
3517
|
tasklist,
|
|
2935
3518
|
textTheme,
|
|
3519
|
+
toggleBold,
|
|
3520
|
+
toggleItalic,
|
|
3521
|
+
toggleList,
|
|
3522
|
+
toggleStrikethrough,
|
|
3523
|
+
toggleStyle,
|
|
2936
3524
|
typewriter,
|
|
3525
|
+
useActionHandler,
|
|
2937
3526
|
useComments,
|
|
3527
|
+
useEditorView,
|
|
2938
3528
|
useTextEditor,
|
|
2939
|
-
useTextModel
|
|
3529
|
+
useTextModel,
|
|
3530
|
+
useToolbarContext
|
|
2940
3531
|
};
|
|
2941
3532
|
//# sourceMappingURL=index.mjs.map
|