@dxos/react-ui-editor 0.3.11-main.4faaf44 → 0.3.11-main.5052d1a
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 +786 -244
- 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/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/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 -1
- 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/index.d.ts +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- 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/themes/default.d.ts.map +1 -1
- package/package.json +38 -25
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +10 -16
- package/src/components/TextEditor/TextEditor.tsx +24 -12
- 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/markdown/bundle.ts +10 -5
- package/src/extensions/markdown/code.ts +36 -13
- package/src/extensions/markdown/formatting.ts +188 -0
- package/src/extensions/markdown/heading.ts +1 -1
- package/src/extensions/markdown/index.ts +1 -0
- package/src/extensions/markdown/link.ts +4 -0
- 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/themes/default.ts +4 -2
|
@@ -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,
|
|
@@ -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: [
|
|
@@ -948,12 +961,12 @@ var random = (min, max) => {
|
|
|
948
961
|
};
|
|
949
962
|
|
|
950
963
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
951
|
-
import {
|
|
964
|
+
import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
|
|
965
|
+
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
952
966
|
import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
|
|
953
967
|
import sortBy from "lodash.sortby";
|
|
954
968
|
import { useEffect } from "react";
|
|
955
969
|
import { debounce } from "@dxos/async";
|
|
956
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
957
970
|
import { nonNullable } from "@dxos/util";
|
|
958
971
|
|
|
959
972
|
// packages/ui/react-ui-editor/src/styles/cursors.ts
|
|
@@ -1025,13 +1038,13 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
|
|
|
1025
1038
|
|
|
1026
1039
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1027
1040
|
import { log } from "@dxos/log";
|
|
1028
|
-
var
|
|
1041
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1029
1042
|
var callbackWrapper = (fn) => (...args) => {
|
|
1030
1043
|
try {
|
|
1031
1044
|
return fn(...args);
|
|
1032
1045
|
} catch (err) {
|
|
1033
1046
|
log.catch(err, void 0, {
|
|
1034
|
-
F:
|
|
1047
|
+
F: __dxlog_file2,
|
|
1035
1048
|
L: 18,
|
|
1036
1049
|
S: void 0,
|
|
1037
1050
|
C: (f, a) => f(...a)
|
|
@@ -1059,7 +1072,6 @@ var logChanges = (trs) => {
|
|
|
1059
1072
|
};
|
|
1060
1073
|
|
|
1061
1074
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1062
|
-
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1063
1075
|
var styles2 = EditorView5.baseTheme({
|
|
1064
1076
|
"& .cm-comment": {
|
|
1065
1077
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
@@ -1068,15 +1080,13 @@ var styles2 = EditorView5.baseTheme({
|
|
|
1068
1080
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1069
1081
|
}
|
|
1070
1082
|
});
|
|
1071
|
-
var
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
};
|
|
1079
|
-
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) => {
|
|
1080
1090
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
1081
1091
|
if (!comment?.comment.cursor) {
|
|
1082
1092
|
return;
|
|
@@ -1138,7 +1148,7 @@ var commentsState = StateField2.define({
|
|
|
1138
1148
|
return value;
|
|
1139
1149
|
}
|
|
1140
1150
|
});
|
|
1141
|
-
var
|
|
1151
|
+
var commentsDecorations = EditorView5.decorations.compute([
|
|
1142
1152
|
commentsState
|
|
1143
1153
|
], (state) => {
|
|
1144
1154
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1149,9 +1159,9 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1149
1159
|
return void 0;
|
|
1150
1160
|
}
|
|
1151
1161
|
if (comment.comment.id === current) {
|
|
1152
|
-
return
|
|
1162
|
+
return commentCurrentMark.range(range.from, range.to);
|
|
1153
1163
|
} else {
|
|
1154
|
-
return
|
|
1164
|
+
return commentMark.range(range.from, range.to);
|
|
1155
1165
|
}
|
|
1156
1166
|
}).filter(nonNullable);
|
|
1157
1167
|
return Decoration2.set(decorations);
|
|
@@ -1180,84 +1190,124 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1180
1190
|
cut: handleTrack,
|
|
1181
1191
|
copy: handleTrack
|
|
1182
1192
|
}),
|
|
1183
|
-
//
|
|
1184
|
-
|
|
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
|
+
}
|
|
1185
1224
|
if (tracked) {
|
|
1186
|
-
const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1225
|
+
const paste = update2.transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1187
1226
|
if (paste) {
|
|
1188
1227
|
let found = -1;
|
|
1189
1228
|
paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
1190
1229
|
if (text.eq(tracked.text)) {
|
|
1191
|
-
for (let i = transactions.indexOf(paste) + 1; i < transactions.length; i++) {
|
|
1192
|
-
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);
|
|
1193
1232
|
}
|
|
1194
1233
|
found = fromB;
|
|
1195
1234
|
}
|
|
1196
1235
|
});
|
|
1197
1236
|
if (found > -1) {
|
|
1198
1237
|
for (const moved of tracked.comments) {
|
|
1199
|
-
|
|
1238
|
+
restore.push({
|
|
1239
|
+
id: moved.id,
|
|
1200
1240
|
from: found + moved.from,
|
|
1201
1241
|
to: found + moved.to
|
|
1202
|
-
};
|
|
1203
|
-
const cursor = Cursor.getCursorFromRange(state, range);
|
|
1204
|
-
onUpdate(moved.id, cursor);
|
|
1242
|
+
});
|
|
1205
1243
|
}
|
|
1206
1244
|
}
|
|
1207
1245
|
tracked = null;
|
|
1208
1246
|
}
|
|
1209
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
|
+
}
|
|
1210
1256
|
})
|
|
1211
1257
|
];
|
|
1212
1258
|
};
|
|
1213
|
-
var
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
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
|
+
}
|
|
1225
1282
|
});
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
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) {
|
|
1231
1291
|
view.dispatch({
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1292
|
+
effects: setSelection.of({
|
|
1293
|
+
current: id
|
|
1294
|
+
}),
|
|
1295
|
+
selection: {
|
|
1296
|
+
anchor: to
|
|
1235
1297
|
}
|
|
1236
1298
|
});
|
|
1299
|
+
return true;
|
|
1237
1300
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
if (id) {
|
|
1245
|
-
view.dispatch({
|
|
1246
|
-
effects: setSelection.of({
|
|
1247
|
-
current: id
|
|
1248
|
-
}),
|
|
1249
|
-
selection: {
|
|
1250
|
-
anchor: from
|
|
1251
|
-
}
|
|
1252
|
-
});
|
|
1253
|
-
return true;
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
return false;
|
|
1257
|
-
};
|
|
1301
|
+
}
|
|
1302
|
+
return false;
|
|
1303
|
+
};
|
|
1304
|
+
var comments = (options = {}) => {
|
|
1305
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1306
|
+
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1258
1307
|
return [
|
|
1308
|
+
optionsFacet.of(options),
|
|
1259
1309
|
commentsState,
|
|
1260
|
-
|
|
1310
|
+
commentsDecorations,
|
|
1261
1311
|
styles2,
|
|
1262
1312
|
//
|
|
1263
1313
|
// Keymap.
|
|
@@ -1265,7 +1315,7 @@ var comments = (options = {}) => {
|
|
|
1265
1315
|
options.onCreate ? keymap3.of([
|
|
1266
1316
|
{
|
|
1267
1317
|
key: shortcut,
|
|
1268
|
-
run: callbackWrapper(
|
|
1318
|
+
run: callbackWrapper(createComment)
|
|
1269
1319
|
}
|
|
1270
1320
|
]) : [],
|
|
1271
1321
|
//
|
|
@@ -1403,6 +1453,7 @@ import { searchKeymap } from "@codemirror/search";
|
|
|
1403
1453
|
import { EditorState } from "@codemirror/state";
|
|
1404
1454
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1405
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";
|
|
1406
1457
|
|
|
1407
1458
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1408
1459
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1593,11 +1644,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1593
1644
|
};
|
|
1594
1645
|
|
|
1595
1646
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1596
|
-
var
|
|
1647
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1597
1648
|
return [
|
|
1649
|
+
lineWrapping && EditorView7.lineWrapping,
|
|
1598
1650
|
EditorState.allowMultipleSelections.of(true),
|
|
1599
1651
|
EditorState.tabSize.of(2),
|
|
1600
|
-
EditorView7.lineWrapping,
|
|
1601
1652
|
// https://github.com/codemirror/basic-setup
|
|
1602
1653
|
bracketMatching2(),
|
|
1603
1654
|
closeBrackets2(),
|
|
@@ -1607,7 +1658,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1607
1658
|
highlightActiveLine2(),
|
|
1608
1659
|
history2(),
|
|
1609
1660
|
indentOnInput(),
|
|
1610
|
-
_placeholder
|
|
1661
|
+
_placeholder && placeholder2(_placeholder),
|
|
1611
1662
|
// Main extension.
|
|
1612
1663
|
// https://github.com/codemirror/lang-markdown
|
|
1613
1664
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1642,7 +1693,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1642
1693
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1643
1694
|
...standardKeymap
|
|
1644
1695
|
])
|
|
1645
|
-
];
|
|
1696
|
+
].filter(isNotFalsy2);
|
|
1646
1697
|
};
|
|
1647
1698
|
|
|
1648
1699
|
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
@@ -1652,26 +1703,43 @@ import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Dec
|
|
|
1652
1703
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1653
1704
|
var styles3 = EditorView8.baseTheme({
|
|
1654
1705
|
"& .cm-code": {
|
|
1655
|
-
paddingInline: "1rem !important",
|
|
1656
1706
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1657
1707
|
},
|
|
1658
1708
|
"& .cm-codeblock": {
|
|
1659
|
-
|
|
1660
|
-
|
|
1709
|
+
width: "100%",
|
|
1710
|
+
paddingInline: "1rem !important",
|
|
1711
|
+
position: "relative",
|
|
1712
|
+
"&::after": {
|
|
1713
|
+
content: '""',
|
|
1714
|
+
position: "absolute",
|
|
1715
|
+
inset: 0
|
|
1716
|
+
}
|
|
1661
1717
|
},
|
|
1662
|
-
"&light .cm-codeblock
|
|
1663
|
-
|
|
1718
|
+
"&light .cm-codeblock": {
|
|
1719
|
+
"&::after": {
|
|
1720
|
+
background: getToken("extend.semanticColors.input.light"),
|
|
1721
|
+
mixBlendMode: "darken"
|
|
1722
|
+
}
|
|
1664
1723
|
},
|
|
1665
|
-
"&dark .cm-codeblock
|
|
1666
|
-
|
|
1724
|
+
"&dark .cm-codeblock": {
|
|
1725
|
+
"&::after": {
|
|
1726
|
+
background: getToken("extend.semanticColors.input.dark"),
|
|
1727
|
+
mixBlendMode: "lighten"
|
|
1728
|
+
}
|
|
1667
1729
|
},
|
|
1668
1730
|
"& .cm-codeblock-first": {
|
|
1669
|
-
|
|
1670
|
-
|
|
1731
|
+
display: "inline-block",
|
|
1732
|
+
"&::after": {
|
|
1733
|
+
borderTopLeftRadius: ".5rem",
|
|
1734
|
+
borderTopRightRadius: ".5rem"
|
|
1735
|
+
}
|
|
1671
1736
|
},
|
|
1672
1737
|
"& .cm-codeblock-last": {
|
|
1673
|
-
|
|
1674
|
-
|
|
1738
|
+
display: "inline-block",
|
|
1739
|
+
"&::after": {
|
|
1740
|
+
borderBottomLeftRadius: ".5rem",
|
|
1741
|
+
borderBottomRightRadius: ".5rem"
|
|
1742
|
+
}
|
|
1675
1743
|
}
|
|
1676
1744
|
});
|
|
1677
1745
|
var getLineRange = (lines, from, to) => {
|
|
@@ -1715,7 +1783,7 @@ var buildDecorations = (view) => {
|
|
|
1715
1783
|
}));
|
|
1716
1784
|
} else {
|
|
1717
1785
|
builder.add(block.from, block.from, Decoration3.line({
|
|
1718
|
-
class: mx2("cm-code cm-codeblock")
|
|
1786
|
+
class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1719
1787
|
}));
|
|
1720
1788
|
}
|
|
1721
1789
|
}
|
|
@@ -1743,16 +1811,156 @@ var code2 = () => {
|
|
|
1743
1811
|
];
|
|
1744
1812
|
};
|
|
1745
1813
|
|
|
1746
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
1814
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1815
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1747
1816
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1748
1817
|
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1749
|
-
import { Decoration as Decoration4, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
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";
|
|
1750
1958
|
var buildDecorations2 = (view) => {
|
|
1751
|
-
const builder = new
|
|
1959
|
+
const builder = new RangeSetBuilder3();
|
|
1752
1960
|
const { state } = view;
|
|
1753
1961
|
const cursor = state.selection.main.head;
|
|
1754
1962
|
for (const { from, to } of view.visibleRanges) {
|
|
1755
|
-
|
|
1963
|
+
syntaxTree3(state).iterate({
|
|
1756
1964
|
enter: (node) => {
|
|
1757
1965
|
switch (node.name) {
|
|
1758
1966
|
case "ATXHeading1":
|
|
@@ -1763,8 +1971,8 @@ var buildDecorations2 = (view) => {
|
|
|
1763
1971
|
case "ATXHeading6": {
|
|
1764
1972
|
const mark2 = node.node.getChild("HeaderMark");
|
|
1765
1973
|
if (mark2) {
|
|
1766
|
-
if (view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1767
|
-
builder.add(mark2.from, mark2.to + 1,
|
|
1974
|
+
if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1975
|
+
builder.add(mark2.from, mark2.to + 1, Decoration5.replace({}));
|
|
1768
1976
|
}
|
|
1769
1977
|
}
|
|
1770
1978
|
}
|
|
@@ -1778,7 +1986,7 @@ var buildDecorations2 = (view) => {
|
|
|
1778
1986
|
};
|
|
1779
1987
|
var heading2 = () => {
|
|
1780
1988
|
return [
|
|
1781
|
-
|
|
1989
|
+
ViewPlugin5.fromClass(class {
|
|
1782
1990
|
constructor(view) {
|
|
1783
1991
|
this.decorations = buildDecorations2(view);
|
|
1784
1992
|
}
|
|
@@ -1792,9 +2000,9 @@ var heading2 = () => {
|
|
|
1792
2000
|
};
|
|
1793
2001
|
|
|
1794
2002
|
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
1795
|
-
import { syntaxTree as
|
|
1796
|
-
import { RangeSetBuilder as
|
|
1797
|
-
import { Decoration as
|
|
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";
|
|
1798
2006
|
var styles4 = EditorView9.baseTheme({
|
|
1799
2007
|
"& .cm-hr": {
|
|
1800
2008
|
// Note that block-level decorations should not have vertical margins,
|
|
@@ -1808,15 +2016,15 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1808
2016
|
return el;
|
|
1809
2017
|
}
|
|
1810
2018
|
};
|
|
1811
|
-
var decoration =
|
|
2019
|
+
var decoration = Decoration6.replace({
|
|
1812
2020
|
widget: new HorizontalRuleWidget()
|
|
1813
2021
|
});
|
|
1814
2022
|
var buildDecorations3 = (view) => {
|
|
1815
|
-
const builder = new
|
|
2023
|
+
const builder = new RangeSetBuilder4();
|
|
1816
2024
|
const { state } = view;
|
|
1817
2025
|
const cursor = state.selection.main.head;
|
|
1818
2026
|
for (const { from, to } of view.visibleRanges) {
|
|
1819
|
-
|
|
2027
|
+
syntaxTree4(state).iterate({
|
|
1820
2028
|
enter: (node) => {
|
|
1821
2029
|
if (node.name === "HorizontalRule") {
|
|
1822
2030
|
if (cursor <= node.from || cursor >= node.to) {
|
|
@@ -1832,7 +2040,7 @@ var buildDecorations3 = (view) => {
|
|
|
1832
2040
|
};
|
|
1833
2041
|
var hr = () => {
|
|
1834
2042
|
return [
|
|
1835
|
-
|
|
2043
|
+
ViewPlugin6.fromClass(class {
|
|
1836
2044
|
constructor(view) {
|
|
1837
2045
|
this.decorations = buildDecorations3(view);
|
|
1838
2046
|
}
|
|
@@ -1847,13 +2055,13 @@ var hr = () => {
|
|
|
1847
2055
|
};
|
|
1848
2056
|
|
|
1849
2057
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
1850
|
-
import { syntaxTree as
|
|
2058
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
1851
2059
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1852
|
-
import { Decoration as
|
|
2060
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1853
2061
|
var image = (options = {}) => {
|
|
1854
2062
|
return StateField3.define({
|
|
1855
2063
|
create: (state) => {
|
|
1856
|
-
return
|
|
2064
|
+
return Decoration7.set(buildDecorations4(0, state.doc.length, state));
|
|
1857
2065
|
},
|
|
1858
2066
|
update: (value, tr) => {
|
|
1859
2067
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -1882,14 +2090,14 @@ var image = (options = {}) => {
|
|
|
1882
2090
|
var buildDecorations4 = (from, to, state) => {
|
|
1883
2091
|
const decorations = [];
|
|
1884
2092
|
const cursor = state.selection.main.head;
|
|
1885
|
-
|
|
2093
|
+
syntaxTree5(state).iterate({
|
|
1886
2094
|
enter: (node) => {
|
|
1887
2095
|
if (node.name === "Image") {
|
|
1888
2096
|
const urlNode = node.node.getChild("URL");
|
|
1889
2097
|
if (urlNode) {
|
|
1890
2098
|
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1891
2099
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1892
|
-
decorations.push(
|
|
2100
|
+
decorations.push(Decoration7.replace({
|
|
1893
2101
|
block: true,
|
|
1894
2102
|
widget: new ImageWidget(url)
|
|
1895
2103
|
}).range(hide ? node.from : node.to, node.to));
|
|
@@ -1919,13 +2127,13 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1919
2127
|
};
|
|
1920
2128
|
|
|
1921
2129
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
1922
|
-
import { syntaxTree as
|
|
1923
|
-
import { RangeSetBuilder as
|
|
1924
|
-
import { hoverTooltip as hoverTooltip2, Decoration as
|
|
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";
|
|
1925
2133
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1926
2134
|
var link = (options = {}) => {
|
|
1927
2135
|
const extensions = [
|
|
1928
|
-
|
|
2136
|
+
ViewPlugin7.fromClass(class {
|
|
1929
2137
|
constructor(view) {
|
|
1930
2138
|
this.decorations = buildDecorations5(view, options);
|
|
1931
2139
|
}
|
|
@@ -1944,7 +2152,7 @@ var link = (options = {}) => {
|
|
|
1944
2152
|
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1945
2153
|
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1946
2154
|
hoverTooltip2((view, pos, side) => {
|
|
1947
|
-
const syntax =
|
|
2155
|
+
const syntax = syntaxTree6(view.state).resolveInner(pos, side);
|
|
1948
2156
|
let link2 = null;
|
|
1949
2157
|
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1950
2158
|
link2 = node.name === "Link" ? node : null;
|
|
@@ -2021,27 +2229,27 @@ var LinkText = class extends WidgetType5 {
|
|
|
2021
2229
|
}
|
|
2022
2230
|
};
|
|
2023
2231
|
var buildDecorations5 = (view, options) => {
|
|
2024
|
-
const builder = new
|
|
2232
|
+
const builder = new RangeSetBuilder5();
|
|
2025
2233
|
const { state } = view;
|
|
2026
2234
|
const cursor = state.selection.main.head;
|
|
2027
2235
|
for (const { from, to } of view.visibleRanges) {
|
|
2028
|
-
|
|
2236
|
+
syntaxTree6(state).iterate({
|
|
2029
2237
|
enter: (node) => {
|
|
2030
2238
|
if (node.name === "Link") {
|
|
2031
|
-
const
|
|
2032
|
-
const text =
|
|
2239
|
+
const marks = node.node.getChildren("LinkMark");
|
|
2240
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
2033
2241
|
const urlNode = node.node.getChild("URL");
|
|
2034
2242
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2035
2243
|
if (!url) {
|
|
2036
2244
|
return false;
|
|
2037
2245
|
}
|
|
2038
2246
|
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
2039
|
-
builder.add(node.from, node.to,
|
|
2247
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
|
2040
2248
|
widget: new LinkText(text, options.link ? url : void 0)
|
|
2041
2249
|
}));
|
|
2042
2250
|
}
|
|
2043
2251
|
if (options.onRender) {
|
|
2044
|
-
builder.add(node.to, node.to,
|
|
2252
|
+
builder.add(node.to, node.to, Decoration8.replace({
|
|
2045
2253
|
widget: new LinkButton(url, options.onRender)
|
|
2046
2254
|
}));
|
|
2047
2255
|
}
|
|
@@ -2056,9 +2264,9 @@ var buildDecorations5 = (view, options) => {
|
|
|
2056
2264
|
};
|
|
2057
2265
|
|
|
2058
2266
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2059
|
-
import { syntaxTree as
|
|
2060
|
-
import { RangeSetBuilder as
|
|
2061
|
-
import { Decoration as
|
|
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";
|
|
2062
2270
|
var table = (options = {}) => {
|
|
2063
2271
|
return StateField4.define({
|
|
2064
2272
|
create: (state) => update(state, options),
|
|
@@ -2067,7 +2275,7 @@ var table = (options = {}) => {
|
|
|
2067
2275
|
});
|
|
2068
2276
|
};
|
|
2069
2277
|
var update = (state, options) => {
|
|
2070
|
-
const builder = new
|
|
2278
|
+
const builder = new RangeSetBuilder6();
|
|
2071
2279
|
const cursor = state.selection.main.head;
|
|
2072
2280
|
const tables = [];
|
|
2073
2281
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -2075,7 +2283,7 @@ var update = (state, options) => {
|
|
|
2075
2283
|
const table2 = getTable();
|
|
2076
2284
|
return table2.rows?.[table2.rows.length - 1];
|
|
2077
2285
|
};
|
|
2078
|
-
|
|
2286
|
+
syntaxTree7(state).iterate({
|
|
2079
2287
|
enter: (node) => {
|
|
2080
2288
|
switch (node.name) {
|
|
2081
2289
|
case "Table": {
|
|
@@ -2107,10 +2315,10 @@ var update = (state, options) => {
|
|
|
2107
2315
|
});
|
|
2108
2316
|
tables.forEach((table2) => {
|
|
2109
2317
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2110
|
-
hide && builder.add(table2.from, table2.to,
|
|
2318
|
+
hide && builder.add(table2.from, table2.to, Decoration9.replace({
|
|
2111
2319
|
widget: new TableWidget(table2)
|
|
2112
2320
|
}));
|
|
2113
|
-
builder.add(table2.from, table2.to,
|
|
2321
|
+
builder.add(table2.from, table2.to, Decoration9.mark({
|
|
2114
2322
|
class: "cm-table"
|
|
2115
2323
|
}));
|
|
2116
2324
|
});
|
|
@@ -2154,9 +2362,9 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2154
2362
|
};
|
|
2155
2363
|
|
|
2156
2364
|
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
2157
|
-
import { syntaxTree as
|
|
2158
|
-
import { RangeSetBuilder as
|
|
2159
|
-
import { EditorView as EditorView12, Decoration as
|
|
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";
|
|
2160
2368
|
var styles5 = EditorView12.baseTheme({
|
|
2161
2369
|
"& .cm-task": {
|
|
2162
2370
|
color: getToken("extend.colors.blue.500")
|
|
@@ -2203,23 +2411,23 @@ var CheckboxWidget = class extends WidgetType7 {
|
|
|
2203
2411
|
return false;
|
|
2204
2412
|
}
|
|
2205
2413
|
};
|
|
2206
|
-
var checkedDecoration =
|
|
2414
|
+
var checkedDecoration = Decoration10.replace({
|
|
2207
2415
|
widget: new CheckboxWidget(true)
|
|
2208
2416
|
});
|
|
2209
|
-
var uncheckedDecoration =
|
|
2417
|
+
var uncheckedDecoration = Decoration10.replace({
|
|
2210
2418
|
widget: new CheckboxWidget(false)
|
|
2211
2419
|
});
|
|
2212
2420
|
var buildDecorations6 = (view) => {
|
|
2213
|
-
const builder = new
|
|
2421
|
+
const builder = new RangeSetBuilder7();
|
|
2214
2422
|
const { state } = view;
|
|
2215
2423
|
const cursor = state.selection.main.head;
|
|
2216
2424
|
for (const { from, to } of view.visibleRanges) {
|
|
2217
|
-
|
|
2425
|
+
syntaxTree8(state).iterate({
|
|
2218
2426
|
enter: (node) => {
|
|
2219
2427
|
if (node.name === "TaskMarker") {
|
|
2220
2428
|
if (cursor < node.from || cursor > node.to) {
|
|
2221
2429
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2222
|
-
builder.add(node.from - 2, node.from - 1,
|
|
2430
|
+
builder.add(node.from - 2, node.from - 1, Decoration10.mark({
|
|
2223
2431
|
class: "cm-task"
|
|
2224
2432
|
}));
|
|
2225
2433
|
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
@@ -2234,7 +2442,7 @@ var buildDecorations6 = (view) => {
|
|
|
2234
2442
|
};
|
|
2235
2443
|
var tasklist = (options = {}) => {
|
|
2236
2444
|
return [
|
|
2237
|
-
|
|
2445
|
+
ViewPlugin8.fromClass(class {
|
|
2238
2446
|
constructor(view) {
|
|
2239
2447
|
this.decorations = buildDecorations6(view);
|
|
2240
2448
|
}
|
|
@@ -2285,7 +2493,7 @@ var outliner = (options = {}) => {
|
|
|
2285
2493
|
};
|
|
2286
2494
|
|
|
2287
2495
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
2288
|
-
import { keymap as
|
|
2496
|
+
import { keymap as keymap6 } from "@codemirror/view";
|
|
2289
2497
|
var defaultItems = [
|
|
2290
2498
|
"hello world!",
|
|
2291
2499
|
"this is a test.",
|
|
@@ -2295,7 +2503,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2295
2503
|
let t;
|
|
2296
2504
|
let idx = 0;
|
|
2297
2505
|
return [
|
|
2298
|
-
|
|
2506
|
+
keymap6.of([
|
|
2299
2507
|
{
|
|
2300
2508
|
// Reset.
|
|
2301
2509
|
key: "alt-meta-'",
|
|
@@ -2372,8 +2580,9 @@ var defaultTheme = {
|
|
|
2372
2580
|
outline: "none"
|
|
2373
2581
|
},
|
|
2374
2582
|
".cm-scroller": {
|
|
2375
|
-
overflow:
|
|
2376
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2583
|
+
// overflow: 'visible',
|
|
2584
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2585
|
+
lineHeight: 1.4
|
|
2377
2586
|
},
|
|
2378
2587
|
".cm-content": {
|
|
2379
2588
|
padding: 0,
|
|
@@ -2407,7 +2616,7 @@ var defaultTheme = {
|
|
|
2407
2616
|
paddingInline: 0
|
|
2408
2617
|
},
|
|
2409
2618
|
".cm-activeLine": {
|
|
2410
|
-
background: "
|
|
2619
|
+
background: "transparent"
|
|
2411
2620
|
},
|
|
2412
2621
|
//
|
|
2413
2622
|
// Selection
|
|
@@ -2578,15 +2787,12 @@ var codeTheme = {
|
|
|
2578
2787
|
};
|
|
2579
2788
|
|
|
2580
2789
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2581
|
-
var
|
|
2790
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2582
2791
|
var EditorModes = [
|
|
2583
2792
|
"default",
|
|
2584
2793
|
"vim"
|
|
2585
2794
|
];
|
|
2586
2795
|
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2587
|
-
const tabsterDOMAttribute = useFocusableGroup({
|
|
2588
|
-
tabBehavior: "limited"
|
|
2589
|
-
});
|
|
2590
2796
|
const { themeMode } = useThemeContext();
|
|
2591
2797
|
const rootRef = useRef(null);
|
|
2592
2798
|
const [view, setView] = useState(null);
|
|
@@ -2594,7 +2800,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2594
2800
|
view
|
|
2595
2801
|
]);
|
|
2596
2802
|
useEffect2(() => {
|
|
2597
|
-
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
|
+
}
|
|
2598
2812
|
view?.focus();
|
|
2599
2813
|
}
|
|
2600
2814
|
}, [
|
|
@@ -2612,8 +2826,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2612
2826
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2613
2827
|
EditorView13.exceptionSink.of((err) => {
|
|
2614
2828
|
log2.catch(err, void 0, {
|
|
2615
|
-
F:
|
|
2616
|
-
L:
|
|
2829
|
+
F: __dxlog_file3,
|
|
2830
|
+
L: 134,
|
|
2617
2831
|
S: void 0,
|
|
2618
2832
|
C: (f, a) => f(...a)
|
|
2619
2833
|
});
|
|
@@ -2630,15 +2844,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2630
2844
|
class: slots.content?.className ?? ""
|
|
2631
2845
|
}),
|
|
2632
2846
|
// State.
|
|
2847
|
+
EditorView13.editable.of(!readonly),
|
|
2633
2848
|
EditorState2.readOnly.of(!!readonly),
|
|
2634
2849
|
// Storage and replication.
|
|
2635
2850
|
// NOTE: This must come before user extensions.
|
|
2636
2851
|
model.extension,
|
|
2637
|
-
// TODO(burdon): Factor out (
|
|
2852
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2638
2853
|
editorMode === "vim" && vim(),
|
|
2639
2854
|
// Custom.
|
|
2640
2855
|
...extensions
|
|
2641
|
-
].filter(
|
|
2856
|
+
].filter(isNotFalsy3)
|
|
2642
2857
|
});
|
|
2643
2858
|
const newView = new EditorView13({
|
|
2644
2859
|
state,
|
|
@@ -2675,7 +2890,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2675
2890
|
}
|
|
2676
2891
|
case "Escape": {
|
|
2677
2892
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2678
|
-
|
|
2893
|
+
view?.focus();
|
|
2679
2894
|
}
|
|
2680
2895
|
break;
|
|
2681
2896
|
}
|
|
@@ -2688,9 +2903,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2688
2903
|
key: model.id,
|
|
2689
2904
|
role: "none",
|
|
2690
2905
|
tabIndex: 0,
|
|
2691
|
-
onKeyUp: handleKeyUp,
|
|
2692
2906
|
...slots.root,
|
|
2693
|
-
...editorMode !==
|
|
2907
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2908
|
+
onKeyUp: handleKeyUp,
|
|
2694
2909
|
ref: rootRef
|
|
2695
2910
|
});
|
|
2696
2911
|
});
|
|
@@ -2701,7 +2916,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2701
2916
|
ref: forwardedRef,
|
|
2702
2917
|
readonly,
|
|
2703
2918
|
extensions: [
|
|
2704
|
-
|
|
2919
|
+
createBasicBundle({
|
|
2705
2920
|
themeMode,
|
|
2706
2921
|
placeholder: placeholder3,
|
|
2707
2922
|
lineWrapping
|
|
@@ -2720,7 +2935,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2720
2935
|
ref: forwardedRef,
|
|
2721
2936
|
readonly,
|
|
2722
2937
|
extensions: [
|
|
2723
|
-
|
|
2938
|
+
createMarkdownExtensions({
|
|
2724
2939
|
themeMode,
|
|
2725
2940
|
placeholder: placeholder3
|
|
2726
2941
|
}),
|
|
@@ -2747,12 +2962,173 @@ var defaultMarkdownSlots = {
|
|
|
2747
2962
|
...defaultSlots
|
|
2748
2963
|
};
|
|
2749
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
|
+
|
|
2750
3126
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2751
3127
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2752
3128
|
import { Context as Context2 } from "@dxos/context";
|
|
2753
|
-
import { invariant as
|
|
3129
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2754
3130
|
import { log as log3 } from "@dxos/log";
|
|
2755
|
-
var
|
|
3131
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2756
3132
|
var DEBOUNCE_INTERVAL = 100;
|
|
2757
3133
|
var SpaceAwarenessProvider = class {
|
|
2758
3134
|
constructor(params) {
|
|
@@ -2792,7 +3168,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2792
3168
|
log3.debug("failed to query awareness", {
|
|
2793
3169
|
err
|
|
2794
3170
|
}, {
|
|
2795
|
-
F:
|
|
3171
|
+
F: __dxlog_file4,
|
|
2796
3172
|
L: 89,
|
|
2797
3173
|
S: this,
|
|
2798
3174
|
C: (f, a) => f(...a)
|
|
@@ -2808,8 +3184,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2808
3184
|
return Array.from(this._remoteStates.values());
|
|
2809
3185
|
}
|
|
2810
3186
|
update(position) {
|
|
2811
|
-
|
|
2812
|
-
F:
|
|
3187
|
+
invariant2(this._postTask, void 0, {
|
|
3188
|
+
F: __dxlog_file4,
|
|
2813
3189
|
L: 104,
|
|
2814
3190
|
S: this,
|
|
2815
3191
|
A: [
|
|
@@ -2825,8 +3201,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2825
3201
|
this._postTask.schedule();
|
|
2826
3202
|
}
|
|
2827
3203
|
_handleQueryMessage() {
|
|
2828
|
-
|
|
2829
|
-
F:
|
|
3204
|
+
invariant2(this._postTask, void 0, {
|
|
3205
|
+
F: __dxlog_file4,
|
|
2830
3206
|
L: 115,
|
|
2831
3207
|
S: this,
|
|
2832
3208
|
A: [
|
|
@@ -2837,8 +3213,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2837
3213
|
this._postTask.schedule();
|
|
2838
3214
|
}
|
|
2839
3215
|
_handlePostMessage(message) {
|
|
2840
|
-
|
|
2841
|
-
F:
|
|
3216
|
+
invariant2(message.kind === "post", void 0, {
|
|
3217
|
+
F: __dxlog_file4,
|
|
2842
3218
|
L: 120,
|
|
2843
3219
|
S: this,
|
|
2844
3220
|
A: [
|
|
@@ -2858,9 +3234,50 @@ var modelState = StateField5.define({
|
|
|
2858
3234
|
update: (model) => model
|
|
2859
3235
|
});
|
|
2860
3236
|
|
|
2861
|
-
// 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
|
|
2862
3279
|
import { useState as useState2 } from "react";
|
|
2863
|
-
var
|
|
3280
|
+
var useEditorView = () => {
|
|
2864
3281
|
const [view, setView] = useState2(null);
|
|
2865
3282
|
return [
|
|
2866
3283
|
(ref) => {
|
|
@@ -2870,19 +3287,125 @@ var useTextEditor = () => {
|
|
|
2870
3287
|
];
|
|
2871
3288
|
};
|
|
2872
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
|
+
|
|
2873
3397
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
2874
3398
|
import get4 from "lodash.get";
|
|
2875
|
-
import { useEffect as
|
|
3399
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2876
3400
|
import { generateName } from "@dxos/display-name";
|
|
2877
3401
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
2878
|
-
import { invariant as
|
|
3402
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2879
3403
|
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
2880
|
-
|
|
2881
|
-
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";
|
|
2882
3405
|
var useTextModel = (props) => {
|
|
2883
3406
|
const { identity, space, text } = props;
|
|
2884
|
-
const [model, setModel] =
|
|
2885
|
-
|
|
3407
|
+
const [model, setModel] = useState4();
|
|
3408
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
2886
3409
|
identity,
|
|
2887
3410
|
space,
|
|
2888
3411
|
text
|
|
@@ -2890,9 +3413,9 @@ var useTextModel = (props) => {
|
|
|
2890
3413
|
return model;
|
|
2891
3414
|
};
|
|
2892
3415
|
var createModel = ({ space, identity, text }) => {
|
|
2893
|
-
|
|
2894
|
-
F:
|
|
2895
|
-
L:
|
|
3416
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3417
|
+
F: __dxlog_file6,
|
|
3418
|
+
L: 34,
|
|
2896
3419
|
S: void 0,
|
|
2897
3420
|
A: [
|
|
2898
3421
|
"isAutomergeObject(text)",
|
|
@@ -2903,7 +3426,7 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2903
3426
|
const doc = getRawDoc(obj, [
|
|
2904
3427
|
obj.field
|
|
2905
3428
|
]);
|
|
2906
|
-
const
|
|
3429
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
2907
3430
|
space,
|
|
2908
3431
|
channel: `automerge.awareness.${obj.id}`,
|
|
2909
3432
|
info: {
|
|
@@ -2913,19 +3436,22 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2913
3436
|
},
|
|
2914
3437
|
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
2915
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
|
+
}
|
|
2916
3450
|
const model = {
|
|
2917
3451
|
id: obj.id,
|
|
2918
3452
|
content: doc,
|
|
2919
3453
|
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2920
|
-
extension:
|
|
2921
|
-
modelState.init(() => model),
|
|
2922
|
-
automerge3({
|
|
2923
|
-
handle: doc.handle,
|
|
2924
|
-
path: doc.path
|
|
2925
|
-
}),
|
|
2926
|
-
awarenessProvider && AwarenessProvider.of(awarenessProvider),
|
|
2927
|
-
awareness()
|
|
2928
|
-
].filter(isNotNullOrUndefined),
|
|
3454
|
+
extension: extensions,
|
|
2929
3455
|
peer: identity ? {
|
|
2930
3456
|
id: identity.identityKey.toHex(),
|
|
2931
3457
|
name: identity.profile?.displayName
|
|
@@ -2934,7 +3460,6 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2934
3460
|
return model;
|
|
2935
3461
|
};
|
|
2936
3462
|
export {
|
|
2937
|
-
AwarenessProvider,
|
|
2938
3463
|
BaseTextEditor,
|
|
2939
3464
|
Cursor,
|
|
2940
3465
|
Doc,
|
|
@@ -2944,30 +3469,39 @@ export {
|
|
|
2944
3469
|
SpaceAwarenessProvider,
|
|
2945
3470
|
TextEditor,
|
|
2946
3471
|
TextKind,
|
|
3472
|
+
Toolbar,
|
|
2947
3473
|
YText,
|
|
2948
3474
|
YXmlFragment,
|
|
2949
3475
|
autocomplete,
|
|
2950
|
-
|
|
3476
|
+
automerge,
|
|
2951
3477
|
awareness,
|
|
2952
|
-
|
|
3478
|
+
awarenessProvider,
|
|
2953
3479
|
blast,
|
|
2954
3480
|
callbackWrapper,
|
|
2955
3481
|
code2 as code,
|
|
2956
3482
|
codeTheme,
|
|
2957
3483
|
comments,
|
|
3484
|
+
createBasicBundle,
|
|
3485
|
+
createComment,
|
|
3486
|
+
createDataExtensions,
|
|
3487
|
+
createMarkdownExtensions,
|
|
3488
|
+
createThemeExtensions,
|
|
2958
3489
|
defaultMarkdownSlots,
|
|
2959
3490
|
defaultOptions,
|
|
2960
3491
|
defaultSlots,
|
|
2961
3492
|
defaultTextSlots,
|
|
2962
3493
|
defaultTheme,
|
|
3494
|
+
focusComment,
|
|
3495
|
+
formatting,
|
|
2963
3496
|
getToken,
|
|
2964
3497
|
heading2 as heading,
|
|
2965
3498
|
hr,
|
|
2966
3499
|
image,
|
|
3500
|
+
insertCodeblock,
|
|
3501
|
+
insertTable,
|
|
2967
3502
|
link,
|
|
2968
3503
|
listener,
|
|
2969
3504
|
logChanges,
|
|
2970
|
-
markdownBundle,
|
|
2971
3505
|
markdownHighlightStyle,
|
|
2972
3506
|
markdownTags,
|
|
2973
3507
|
markdownTagsExtensions,
|
|
@@ -2976,15 +3510,23 @@ export {
|
|
|
2976
3510
|
modelState,
|
|
2977
3511
|
outliner,
|
|
2978
3512
|
setComments,
|
|
2979
|
-
|
|
3513
|
+
setHeading,
|
|
2980
3514
|
setSelection,
|
|
2981
3515
|
table,
|
|
2982
3516
|
tags2 as tags,
|
|
2983
3517
|
tasklist,
|
|
2984
3518
|
textTheme,
|
|
3519
|
+
toggleBold,
|
|
3520
|
+
toggleItalic,
|
|
3521
|
+
toggleList,
|
|
3522
|
+
toggleStrikethrough,
|
|
3523
|
+
toggleStyle,
|
|
2985
3524
|
typewriter,
|
|
3525
|
+
useActionHandler,
|
|
2986
3526
|
useComments,
|
|
3527
|
+
useEditorView,
|
|
2987
3528
|
useTextEditor,
|
|
2988
|
-
useTextModel
|
|
3529
|
+
useTextModel,
|
|
3530
|
+
useToolbarContext
|
|
2989
3531
|
};
|
|
2990
3532
|
//# sourceMappingURL=index.mjs.map
|