@dxos/react-ui-editor 0.3.11-main.cc2fe2c → 0.3.11-main.ccc0ca3
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 +782 -241
- 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 +39 -26
- 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 +24 -9
- 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
|
|
@@ -1657,21 +1708,37 @@ var styles3 = EditorView8.baseTheme({
|
|
|
1657
1708
|
},
|
|
1658
1709
|
"& .cm-codeblock": {
|
|
1659
1710
|
display: "inline-block",
|
|
1660
|
-
width: "100%"
|
|
1711
|
+
width: "100%",
|
|
1712
|
+
position: "relative",
|
|
1713
|
+
"&::after": {
|
|
1714
|
+
content: '""',
|
|
1715
|
+
position: "absolute",
|
|
1716
|
+
inset: 0
|
|
1717
|
+
}
|
|
1661
1718
|
},
|
|
1662
|
-
"&light .cm-codeblock
|
|
1663
|
-
|
|
1719
|
+
"&light .cm-codeblock": {
|
|
1720
|
+
"&::after": {
|
|
1721
|
+
background: getToken("extend.semanticColors.input.light"),
|
|
1722
|
+
mixBlendMode: "darken"
|
|
1723
|
+
}
|
|
1664
1724
|
},
|
|
1665
|
-
"&dark .cm-codeblock
|
|
1666
|
-
|
|
1725
|
+
"&dark .cm-codeblock": {
|
|
1726
|
+
"&::after": {
|
|
1727
|
+
background: getToken("extend.semanticColors.input.dark"),
|
|
1728
|
+
mixBlendMode: "lighten"
|
|
1729
|
+
}
|
|
1667
1730
|
},
|
|
1668
1731
|
"& .cm-codeblock-first": {
|
|
1669
|
-
|
|
1670
|
-
|
|
1732
|
+
"&::after": {
|
|
1733
|
+
borderTopLeftRadius: ".5rem",
|
|
1734
|
+
borderTopRightRadius: ".5rem"
|
|
1735
|
+
}
|
|
1671
1736
|
},
|
|
1672
1737
|
"& .cm-codeblock-last": {
|
|
1673
|
-
|
|
1674
|
-
|
|
1738
|
+
"&::after": {
|
|
1739
|
+
borderBottomLeftRadius: ".5rem",
|
|
1740
|
+
borderBottomRightRadius: ".5rem"
|
|
1741
|
+
}
|
|
1675
1742
|
}
|
|
1676
1743
|
});
|
|
1677
1744
|
var getLineRange = (lines, from, to) => {
|
|
@@ -1743,16 +1810,156 @@ var code2 = () => {
|
|
|
1743
1810
|
];
|
|
1744
1811
|
};
|
|
1745
1812
|
|
|
1746
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
1813
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1814
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1747
1815
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1748
1816
|
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1749
|
-
import { Decoration as Decoration4, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1817
|
+
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1818
|
+
var setHeading = (level) => (view) => {
|
|
1819
|
+
const { selection: { ranges }, doc } = view.state;
|
|
1820
|
+
const changes = [];
|
|
1821
|
+
for (const range of ranges) {
|
|
1822
|
+
const { number } = doc.lineAt(range.anchor);
|
|
1823
|
+
const { from, to } = doc.line(number);
|
|
1824
|
+
const line = doc.sliceString(from, to);
|
|
1825
|
+
const [_, marks, spaces] = line.match(/(#+)(\s+)/) ?? [];
|
|
1826
|
+
const current = marks?.length ?? 0;
|
|
1827
|
+
if (level !== current) {
|
|
1828
|
+
changes.push({
|
|
1829
|
+
from,
|
|
1830
|
+
to: from + current + (spaces?.length ?? 0),
|
|
1831
|
+
insert: "#".repeat(level) + (level > 0 ? " " : "")
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
if (changes.length) {
|
|
1836
|
+
view.dispatch({
|
|
1837
|
+
changes
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
return true;
|
|
1841
|
+
};
|
|
1842
|
+
var toggleStyle = (mark2) => (view) => {
|
|
1843
|
+
const { ranges } = view.state.selection;
|
|
1844
|
+
for (const range of ranges) {
|
|
1845
|
+
if (range.from === range.to) {
|
|
1846
|
+
return false;
|
|
1847
|
+
}
|
|
1848
|
+
view.dispatch({
|
|
1849
|
+
changes: [
|
|
1850
|
+
{
|
|
1851
|
+
from: range.from,
|
|
1852
|
+
insert: mark2
|
|
1853
|
+
},
|
|
1854
|
+
{
|
|
1855
|
+
from: range.to,
|
|
1856
|
+
insert: mark2
|
|
1857
|
+
}
|
|
1858
|
+
]
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
return true;
|
|
1862
|
+
};
|
|
1863
|
+
var snippets = {
|
|
1864
|
+
codeblock: snippet([
|
|
1865
|
+
"```#{lang}",
|
|
1866
|
+
" #{}",
|
|
1867
|
+
"```"
|
|
1868
|
+
].join("\n")),
|
|
1869
|
+
table: snippet([
|
|
1870
|
+
"| #{col1} | #{col2} |",
|
|
1871
|
+
"| ---- | ---- |",
|
|
1872
|
+
"| #{val1} | #{val2} |",
|
|
1873
|
+
"| #{val3} | #{val4} |"
|
|
1874
|
+
].join("\n"))
|
|
1875
|
+
};
|
|
1876
|
+
var insertCodeblock = (view) => {
|
|
1877
|
+
const { selection: { main }, doc } = view.state;
|
|
1878
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1879
|
+
const { from } = doc.line(number);
|
|
1880
|
+
snippets.codeblock(view, null, from, from);
|
|
1881
|
+
};
|
|
1882
|
+
var insertTable = (view) => {
|
|
1883
|
+
const { selection: { main }, doc } = view.state;
|
|
1884
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1885
|
+
const { from } = doc.line(number);
|
|
1886
|
+
snippets.table(view, null, from, from);
|
|
1887
|
+
};
|
|
1888
|
+
var toggleBold = toggleStyle("**");
|
|
1889
|
+
var toggleItalic = toggleStyle("_");
|
|
1890
|
+
var toggleStrikethrough = toggleStyle("~~");
|
|
1891
|
+
var toggleList = (view) => {
|
|
1892
|
+
};
|
|
1893
|
+
var formatting = (options = {}) => {
|
|
1894
|
+
return [
|
|
1895
|
+
keymap5.of([
|
|
1896
|
+
{
|
|
1897
|
+
key: "meta-b",
|
|
1898
|
+
run: toggleBold
|
|
1899
|
+
}
|
|
1900
|
+
]),
|
|
1901
|
+
styling()
|
|
1902
|
+
];
|
|
1903
|
+
};
|
|
1904
|
+
var styling = () => {
|
|
1905
|
+
const buildDecorations7 = (view) => {
|
|
1906
|
+
const builder = new RangeSetBuilder2();
|
|
1907
|
+
const { state } = view;
|
|
1908
|
+
const cursor = state.selection.main.head;
|
|
1909
|
+
const replace = (node, marks) => {
|
|
1910
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
1911
|
+
for (const mark2 of marks) {
|
|
1912
|
+
builder.add(mark2.from, mark2.to, Decoration4.replace({}));
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
};
|
|
1916
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1917
|
+
syntaxTree2(state).iterate({
|
|
1918
|
+
enter: (node) => {
|
|
1919
|
+
switch (node.name) {
|
|
1920
|
+
case "Emphasis":
|
|
1921
|
+
case "StrongEmphasis": {
|
|
1922
|
+
const marks = node.node.getChildren("EmphasisMark");
|
|
1923
|
+
replace(node, marks);
|
|
1924
|
+
break;
|
|
1925
|
+
}
|
|
1926
|
+
case "Strikethrough": {
|
|
1927
|
+
const marks = node.node.getChildren("StrikethroughMark");
|
|
1928
|
+
replace(node, marks);
|
|
1929
|
+
break;
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
},
|
|
1933
|
+
from,
|
|
1934
|
+
to
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
return builder.finish();
|
|
1938
|
+
};
|
|
1939
|
+
return [
|
|
1940
|
+
ViewPlugin4.fromClass(class {
|
|
1941
|
+
constructor(view) {
|
|
1942
|
+
this.decorations = buildDecorations7(view);
|
|
1943
|
+
}
|
|
1944
|
+
update(update2) {
|
|
1945
|
+
this.decorations = buildDecorations7(update2.view);
|
|
1946
|
+
}
|
|
1947
|
+
}, {
|
|
1948
|
+
decorations: (value) => value.decorations
|
|
1949
|
+
})
|
|
1950
|
+
];
|
|
1951
|
+
};
|
|
1952
|
+
|
|
1953
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1954
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1955
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1956
|
+
import { Decoration as Decoration5, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1750
1957
|
var buildDecorations2 = (view) => {
|
|
1751
|
-
const builder = new
|
|
1958
|
+
const builder = new RangeSetBuilder3();
|
|
1752
1959
|
const { state } = view;
|
|
1753
1960
|
const cursor = state.selection.main.head;
|
|
1754
1961
|
for (const { from, to } of view.visibleRanges) {
|
|
1755
|
-
|
|
1962
|
+
syntaxTree3(state).iterate({
|
|
1756
1963
|
enter: (node) => {
|
|
1757
1964
|
switch (node.name) {
|
|
1758
1965
|
case "ATXHeading1":
|
|
@@ -1763,8 +1970,8 @@ var buildDecorations2 = (view) => {
|
|
|
1763
1970
|
case "ATXHeading6": {
|
|
1764
1971
|
const mark2 = node.node.getChild("HeaderMark");
|
|
1765
1972
|
if (mark2) {
|
|
1766
|
-
if (view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1767
|
-
builder.add(mark2.from, mark2.to + 1,
|
|
1973
|
+
if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1974
|
+
builder.add(mark2.from, mark2.to + 1, Decoration5.replace({}));
|
|
1768
1975
|
}
|
|
1769
1976
|
}
|
|
1770
1977
|
}
|
|
@@ -1778,7 +1985,7 @@ var buildDecorations2 = (view) => {
|
|
|
1778
1985
|
};
|
|
1779
1986
|
var heading2 = () => {
|
|
1780
1987
|
return [
|
|
1781
|
-
|
|
1988
|
+
ViewPlugin5.fromClass(class {
|
|
1782
1989
|
constructor(view) {
|
|
1783
1990
|
this.decorations = buildDecorations2(view);
|
|
1784
1991
|
}
|
|
@@ -1792,9 +1999,9 @@ var heading2 = () => {
|
|
|
1792
1999
|
};
|
|
1793
2000
|
|
|
1794
2001
|
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
1795
|
-
import { syntaxTree as
|
|
1796
|
-
import { RangeSetBuilder as
|
|
1797
|
-
import { Decoration as
|
|
2002
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2003
|
+
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
2004
|
+
import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1798
2005
|
var styles4 = EditorView9.baseTheme({
|
|
1799
2006
|
"& .cm-hr": {
|
|
1800
2007
|
// Note that block-level decorations should not have vertical margins,
|
|
@@ -1808,15 +2015,15 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1808
2015
|
return el;
|
|
1809
2016
|
}
|
|
1810
2017
|
};
|
|
1811
|
-
var decoration =
|
|
2018
|
+
var decoration = Decoration6.replace({
|
|
1812
2019
|
widget: new HorizontalRuleWidget()
|
|
1813
2020
|
});
|
|
1814
2021
|
var buildDecorations3 = (view) => {
|
|
1815
|
-
const builder = new
|
|
2022
|
+
const builder = new RangeSetBuilder4();
|
|
1816
2023
|
const { state } = view;
|
|
1817
2024
|
const cursor = state.selection.main.head;
|
|
1818
2025
|
for (const { from, to } of view.visibleRanges) {
|
|
1819
|
-
|
|
2026
|
+
syntaxTree4(state).iterate({
|
|
1820
2027
|
enter: (node) => {
|
|
1821
2028
|
if (node.name === "HorizontalRule") {
|
|
1822
2029
|
if (cursor <= node.from || cursor >= node.to) {
|
|
@@ -1832,7 +2039,7 @@ var buildDecorations3 = (view) => {
|
|
|
1832
2039
|
};
|
|
1833
2040
|
var hr = () => {
|
|
1834
2041
|
return [
|
|
1835
|
-
|
|
2042
|
+
ViewPlugin6.fromClass(class {
|
|
1836
2043
|
constructor(view) {
|
|
1837
2044
|
this.decorations = buildDecorations3(view);
|
|
1838
2045
|
}
|
|
@@ -1847,13 +2054,13 @@ var hr = () => {
|
|
|
1847
2054
|
};
|
|
1848
2055
|
|
|
1849
2056
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
1850
|
-
import { syntaxTree as
|
|
2057
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
1851
2058
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1852
|
-
import { Decoration as
|
|
2059
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1853
2060
|
var image = (options = {}) => {
|
|
1854
2061
|
return StateField3.define({
|
|
1855
2062
|
create: (state) => {
|
|
1856
|
-
return
|
|
2063
|
+
return Decoration7.set(buildDecorations4(0, state.doc.length, state));
|
|
1857
2064
|
},
|
|
1858
2065
|
update: (value, tr) => {
|
|
1859
2066
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -1882,14 +2089,14 @@ var image = (options = {}) => {
|
|
|
1882
2089
|
var buildDecorations4 = (from, to, state) => {
|
|
1883
2090
|
const decorations = [];
|
|
1884
2091
|
const cursor = state.selection.main.head;
|
|
1885
|
-
|
|
2092
|
+
syntaxTree5(state).iterate({
|
|
1886
2093
|
enter: (node) => {
|
|
1887
2094
|
if (node.name === "Image") {
|
|
1888
2095
|
const urlNode = node.node.getChild("URL");
|
|
1889
2096
|
if (urlNode) {
|
|
1890
2097
|
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1891
2098
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1892
|
-
decorations.push(
|
|
2099
|
+
decorations.push(Decoration7.replace({
|
|
1893
2100
|
block: true,
|
|
1894
2101
|
widget: new ImageWidget(url)
|
|
1895
2102
|
}).range(hide ? node.from : node.to, node.to));
|
|
@@ -1919,13 +2126,13 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1919
2126
|
};
|
|
1920
2127
|
|
|
1921
2128
|
// 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
|
|
2129
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
2130
|
+
import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
|
|
2131
|
+
import { hoverTooltip as hoverTooltip2, Decoration as Decoration8, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1925
2132
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1926
2133
|
var link = (options = {}) => {
|
|
1927
2134
|
const extensions = [
|
|
1928
|
-
|
|
2135
|
+
ViewPlugin7.fromClass(class {
|
|
1929
2136
|
constructor(view) {
|
|
1930
2137
|
this.decorations = buildDecorations5(view, options);
|
|
1931
2138
|
}
|
|
@@ -1944,7 +2151,7 @@ var link = (options = {}) => {
|
|
|
1944
2151
|
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1945
2152
|
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1946
2153
|
hoverTooltip2((view, pos, side) => {
|
|
1947
|
-
const syntax =
|
|
2154
|
+
const syntax = syntaxTree6(view.state).resolveInner(pos, side);
|
|
1948
2155
|
let link2 = null;
|
|
1949
2156
|
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1950
2157
|
link2 = node.name === "Link" ? node : null;
|
|
@@ -2021,27 +2228,27 @@ var LinkText = class extends WidgetType5 {
|
|
|
2021
2228
|
}
|
|
2022
2229
|
};
|
|
2023
2230
|
var buildDecorations5 = (view, options) => {
|
|
2024
|
-
const builder = new
|
|
2231
|
+
const builder = new RangeSetBuilder5();
|
|
2025
2232
|
const { state } = view;
|
|
2026
2233
|
const cursor = state.selection.main.head;
|
|
2027
2234
|
for (const { from, to } of view.visibleRanges) {
|
|
2028
|
-
|
|
2235
|
+
syntaxTree6(state).iterate({
|
|
2029
2236
|
enter: (node) => {
|
|
2030
2237
|
if (node.name === "Link") {
|
|
2031
|
-
const
|
|
2032
|
-
const text =
|
|
2238
|
+
const marks = node.node.getChildren("LinkMark");
|
|
2239
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
2033
2240
|
const urlNode = node.node.getChild("URL");
|
|
2034
2241
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2035
2242
|
if (!url) {
|
|
2036
2243
|
return false;
|
|
2037
2244
|
}
|
|
2038
2245
|
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
2039
|
-
builder.add(node.from, node.to,
|
|
2246
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
|
2040
2247
|
widget: new LinkText(text, options.link ? url : void 0)
|
|
2041
2248
|
}));
|
|
2042
2249
|
}
|
|
2043
2250
|
if (options.onRender) {
|
|
2044
|
-
builder.add(node.to, node.to,
|
|
2251
|
+
builder.add(node.to, node.to, Decoration8.replace({
|
|
2045
2252
|
widget: new LinkButton(url, options.onRender)
|
|
2046
2253
|
}));
|
|
2047
2254
|
}
|
|
@@ -2056,9 +2263,9 @@ var buildDecorations5 = (view, options) => {
|
|
|
2056
2263
|
};
|
|
2057
2264
|
|
|
2058
2265
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2059
|
-
import { syntaxTree as
|
|
2060
|
-
import { RangeSetBuilder as
|
|
2061
|
-
import { Decoration as
|
|
2266
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2267
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
|
|
2268
|
+
import { Decoration as Decoration9, EditorView as EditorView11, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2062
2269
|
var table = (options = {}) => {
|
|
2063
2270
|
return StateField4.define({
|
|
2064
2271
|
create: (state) => update(state, options),
|
|
@@ -2067,7 +2274,7 @@ var table = (options = {}) => {
|
|
|
2067
2274
|
});
|
|
2068
2275
|
};
|
|
2069
2276
|
var update = (state, options) => {
|
|
2070
|
-
const builder = new
|
|
2277
|
+
const builder = new RangeSetBuilder6();
|
|
2071
2278
|
const cursor = state.selection.main.head;
|
|
2072
2279
|
const tables = [];
|
|
2073
2280
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -2075,7 +2282,7 @@ var update = (state, options) => {
|
|
|
2075
2282
|
const table2 = getTable();
|
|
2076
2283
|
return table2.rows?.[table2.rows.length - 1];
|
|
2077
2284
|
};
|
|
2078
|
-
|
|
2285
|
+
syntaxTree7(state).iterate({
|
|
2079
2286
|
enter: (node) => {
|
|
2080
2287
|
switch (node.name) {
|
|
2081
2288
|
case "Table": {
|
|
@@ -2107,10 +2314,10 @@ var update = (state, options) => {
|
|
|
2107
2314
|
});
|
|
2108
2315
|
tables.forEach((table2) => {
|
|
2109
2316
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2110
|
-
hide && builder.add(table2.from, table2.to,
|
|
2317
|
+
hide && builder.add(table2.from, table2.to, Decoration9.replace({
|
|
2111
2318
|
widget: new TableWidget(table2)
|
|
2112
2319
|
}));
|
|
2113
|
-
builder.add(table2.from, table2.to,
|
|
2320
|
+
builder.add(table2.from, table2.to, Decoration9.mark({
|
|
2114
2321
|
class: "cm-table"
|
|
2115
2322
|
}));
|
|
2116
2323
|
});
|
|
@@ -2154,9 +2361,9 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2154
2361
|
};
|
|
2155
2362
|
|
|
2156
2363
|
// 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
|
|
2364
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
2365
|
+
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
2366
|
+
import { EditorView as EditorView12, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
2160
2367
|
var styles5 = EditorView12.baseTheme({
|
|
2161
2368
|
"& .cm-task": {
|
|
2162
2369
|
color: getToken("extend.colors.blue.500")
|
|
@@ -2203,23 +2410,23 @@ var CheckboxWidget = class extends WidgetType7 {
|
|
|
2203
2410
|
return false;
|
|
2204
2411
|
}
|
|
2205
2412
|
};
|
|
2206
|
-
var checkedDecoration =
|
|
2413
|
+
var checkedDecoration = Decoration10.replace({
|
|
2207
2414
|
widget: new CheckboxWidget(true)
|
|
2208
2415
|
});
|
|
2209
|
-
var uncheckedDecoration =
|
|
2416
|
+
var uncheckedDecoration = Decoration10.replace({
|
|
2210
2417
|
widget: new CheckboxWidget(false)
|
|
2211
2418
|
});
|
|
2212
2419
|
var buildDecorations6 = (view) => {
|
|
2213
|
-
const builder = new
|
|
2420
|
+
const builder = new RangeSetBuilder7();
|
|
2214
2421
|
const { state } = view;
|
|
2215
2422
|
const cursor = state.selection.main.head;
|
|
2216
2423
|
for (const { from, to } of view.visibleRanges) {
|
|
2217
|
-
|
|
2424
|
+
syntaxTree8(state).iterate({
|
|
2218
2425
|
enter: (node) => {
|
|
2219
2426
|
if (node.name === "TaskMarker") {
|
|
2220
2427
|
if (cursor < node.from || cursor > node.to) {
|
|
2221
2428
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2222
|
-
builder.add(node.from - 2, node.from - 1,
|
|
2429
|
+
builder.add(node.from - 2, node.from - 1, Decoration10.mark({
|
|
2223
2430
|
class: "cm-task"
|
|
2224
2431
|
}));
|
|
2225
2432
|
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
@@ -2234,7 +2441,7 @@ var buildDecorations6 = (view) => {
|
|
|
2234
2441
|
};
|
|
2235
2442
|
var tasklist = (options = {}) => {
|
|
2236
2443
|
return [
|
|
2237
|
-
|
|
2444
|
+
ViewPlugin8.fromClass(class {
|
|
2238
2445
|
constructor(view) {
|
|
2239
2446
|
this.decorations = buildDecorations6(view);
|
|
2240
2447
|
}
|
|
@@ -2285,7 +2492,7 @@ var outliner = (options = {}) => {
|
|
|
2285
2492
|
};
|
|
2286
2493
|
|
|
2287
2494
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
2288
|
-
import { keymap as
|
|
2495
|
+
import { keymap as keymap6 } from "@codemirror/view";
|
|
2289
2496
|
var defaultItems = [
|
|
2290
2497
|
"hello world!",
|
|
2291
2498
|
"this is a test.",
|
|
@@ -2295,7 +2502,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2295
2502
|
let t;
|
|
2296
2503
|
let idx = 0;
|
|
2297
2504
|
return [
|
|
2298
|
-
|
|
2505
|
+
keymap6.of([
|
|
2299
2506
|
{
|
|
2300
2507
|
// Reset.
|
|
2301
2508
|
key: "alt-meta-'",
|
|
@@ -2372,8 +2579,9 @@ var defaultTheme = {
|
|
|
2372
2579
|
outline: "none"
|
|
2373
2580
|
},
|
|
2374
2581
|
".cm-scroller": {
|
|
2375
|
-
overflow:
|
|
2376
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2582
|
+
// overflow: 'visible',
|
|
2583
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2584
|
+
lineHeight: 1.4
|
|
2377
2585
|
},
|
|
2378
2586
|
".cm-content": {
|
|
2379
2587
|
padding: 0,
|
|
@@ -2407,7 +2615,7 @@ var defaultTheme = {
|
|
|
2407
2615
|
paddingInline: 0
|
|
2408
2616
|
},
|
|
2409
2617
|
".cm-activeLine": {
|
|
2410
|
-
background: "
|
|
2618
|
+
background: "transparent"
|
|
2411
2619
|
},
|
|
2412
2620
|
//
|
|
2413
2621
|
// Selection
|
|
@@ -2578,15 +2786,12 @@ var codeTheme = {
|
|
|
2578
2786
|
};
|
|
2579
2787
|
|
|
2580
2788
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2581
|
-
var
|
|
2789
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2582
2790
|
var EditorModes = [
|
|
2583
2791
|
"default",
|
|
2584
2792
|
"vim"
|
|
2585
2793
|
];
|
|
2586
2794
|
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
2795
|
const { themeMode } = useThemeContext();
|
|
2591
2796
|
const rootRef = useRef(null);
|
|
2592
2797
|
const [view, setView] = useState(null);
|
|
@@ -2594,7 +2799,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2594
2799
|
view
|
|
2595
2800
|
]);
|
|
2596
2801
|
useEffect2(() => {
|
|
2597
|
-
if (autoFocus) {
|
|
2802
|
+
if (autoFocus && !view?.hasFocus) {
|
|
2803
|
+
if (view?.state.selection.main?.from === 0) {
|
|
2804
|
+
const { to } = view.state.doc.lineAt(0);
|
|
2805
|
+
view?.dispatch({
|
|
2806
|
+
selection: {
|
|
2807
|
+
anchor: to
|
|
2808
|
+
}
|
|
2809
|
+
});
|
|
2810
|
+
}
|
|
2598
2811
|
view?.focus();
|
|
2599
2812
|
}
|
|
2600
2813
|
}, [
|
|
@@ -2612,8 +2825,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2612
2825
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2613
2826
|
EditorView13.exceptionSink.of((err) => {
|
|
2614
2827
|
log2.catch(err, void 0, {
|
|
2615
|
-
F:
|
|
2616
|
-
L:
|
|
2828
|
+
F: __dxlog_file3,
|
|
2829
|
+
L: 134,
|
|
2617
2830
|
S: void 0,
|
|
2618
2831
|
C: (f, a) => f(...a)
|
|
2619
2832
|
});
|
|
@@ -2630,15 +2843,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2630
2843
|
class: slots.content?.className ?? ""
|
|
2631
2844
|
}),
|
|
2632
2845
|
// State.
|
|
2846
|
+
EditorView13.editable.of(!readonly),
|
|
2633
2847
|
EditorState2.readOnly.of(!!readonly),
|
|
2634
2848
|
// Storage and replication.
|
|
2635
2849
|
// NOTE: This must come before user extensions.
|
|
2636
2850
|
model.extension,
|
|
2637
|
-
// TODO(burdon): Factor out (
|
|
2851
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2638
2852
|
editorMode === "vim" && vim(),
|
|
2639
2853
|
// Custom.
|
|
2640
2854
|
...extensions
|
|
2641
|
-
].filter(
|
|
2855
|
+
].filter(isNotFalsy3)
|
|
2642
2856
|
});
|
|
2643
2857
|
const newView = new EditorView13({
|
|
2644
2858
|
state,
|
|
@@ -2675,7 +2889,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2675
2889
|
}
|
|
2676
2890
|
case "Escape": {
|
|
2677
2891
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2678
|
-
|
|
2892
|
+
view?.focus();
|
|
2679
2893
|
}
|
|
2680
2894
|
break;
|
|
2681
2895
|
}
|
|
@@ -2688,9 +2902,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2688
2902
|
key: model.id,
|
|
2689
2903
|
role: "none",
|
|
2690
2904
|
tabIndex: 0,
|
|
2691
|
-
onKeyUp: handleKeyUp,
|
|
2692
2905
|
...slots.root,
|
|
2693
|
-
...editorMode !==
|
|
2906
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2907
|
+
onKeyUp: handleKeyUp,
|
|
2694
2908
|
ref: rootRef
|
|
2695
2909
|
});
|
|
2696
2910
|
});
|
|
@@ -2701,7 +2915,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2701
2915
|
ref: forwardedRef,
|
|
2702
2916
|
readonly,
|
|
2703
2917
|
extensions: [
|
|
2704
|
-
|
|
2918
|
+
createBasicBundle({
|
|
2705
2919
|
themeMode,
|
|
2706
2920
|
placeholder: placeholder3,
|
|
2707
2921
|
lineWrapping
|
|
@@ -2720,7 +2934,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2720
2934
|
ref: forwardedRef,
|
|
2721
2935
|
readonly,
|
|
2722
2936
|
extensions: [
|
|
2723
|
-
|
|
2937
|
+
createMarkdownExtensions({
|
|
2724
2938
|
themeMode,
|
|
2725
2939
|
placeholder: placeholder3
|
|
2726
2940
|
}),
|
|
@@ -2747,12 +2961,173 @@ var defaultMarkdownSlots = {
|
|
|
2747
2961
|
...defaultSlots
|
|
2748
2962
|
};
|
|
2749
2963
|
|
|
2964
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
2965
|
+
import { At, CaretRight, ChatText, Code, Image, Link, ListBullets, ListChecks, ListNumbers, TextStrikethrough, Table as Table2, TextB, TextItalic } from "@phosphor-icons/react";
|
|
2966
|
+
import { createContext } from "@radix-ui/react-context";
|
|
2967
|
+
import React2 from "react";
|
|
2968
|
+
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
2969
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
2970
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
2971
|
+
var ToolbarRoot = ({ children, onAction }) => {
|
|
2972
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
2973
|
+
onAction
|
|
2974
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
2975
|
+
density: "fine"
|
|
2976
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
2977
|
+
role: "toolbar",
|
|
2978
|
+
className: "flex w-full shrink-0 p-2 gap-4 items-center whitespace-nowrap overflow-hidden"
|
|
2979
|
+
}, children)));
|
|
2980
|
+
};
|
|
2981
|
+
var ToolbarButton = ({ Icon, onClick, title }) => {
|
|
2982
|
+
const { onAction } = useToolbarContext("ToolbarButton");
|
|
2983
|
+
const handleClick = () => {
|
|
2984
|
+
const action = onClick();
|
|
2985
|
+
if (action) {
|
|
2986
|
+
onAction?.(action);
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
return /* @__PURE__ */ React2.createElement(Button, {
|
|
2990
|
+
variant: "ghost",
|
|
2991
|
+
classNames: "p-2",
|
|
2992
|
+
onClick: handleClick,
|
|
2993
|
+
title
|
|
2994
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
2995
|
+
className: getSize(5)
|
|
2996
|
+
}));
|
|
2997
|
+
};
|
|
2998
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
2999
|
+
className: "grow"
|
|
3000
|
+
});
|
|
3001
|
+
var MarkdownHeading = () => {
|
|
3002
|
+
const { onAction } = useToolbarContext("MarkdownFormatting");
|
|
3003
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3004
|
+
defaultValue: "0",
|
|
3005
|
+
onValueChange: (value) => onAction?.({
|
|
3006
|
+
type: "heading",
|
|
3007
|
+
data: parseInt(value)
|
|
3008
|
+
})
|
|
3009
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
3010
|
+
classNames: "w-[8rem]"
|
|
3011
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3012
|
+
value: "0"
|
|
3013
|
+
}, "Paragraph"), [
|
|
3014
|
+
1,
|
|
3015
|
+
2,
|
|
3016
|
+
3,
|
|
3017
|
+
4,
|
|
3018
|
+
5,
|
|
3019
|
+
6
|
|
3020
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3021
|
+
key: level,
|
|
3022
|
+
value: String(level)
|
|
3023
|
+
}, "Heading ", level))))));
|
|
3024
|
+
};
|
|
3025
|
+
var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3026
|
+
role: "none"
|
|
3027
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3028
|
+
Icon: TextB,
|
|
3029
|
+
title: "Bold",
|
|
3030
|
+
onClick: () => ({
|
|
3031
|
+
type: "bold"
|
|
3032
|
+
})
|
|
3033
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3034
|
+
Icon: TextItalic,
|
|
3035
|
+
title: "Italic",
|
|
3036
|
+
onClick: () => ({
|
|
3037
|
+
type: "italic"
|
|
3038
|
+
})
|
|
3039
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3040
|
+
Icon: TextStrikethrough,
|
|
3041
|
+
title: "Strike-through",
|
|
3042
|
+
onClick: () => ({
|
|
3043
|
+
type: "strikethrough"
|
|
3044
|
+
})
|
|
3045
|
+
}));
|
|
3046
|
+
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3047
|
+
role: "none"
|
|
3048
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3049
|
+
Icon: ListBullets,
|
|
3050
|
+
title: "Bullet list",
|
|
3051
|
+
onClick: () => ({
|
|
3052
|
+
type: "list"
|
|
3053
|
+
})
|
|
3054
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3055
|
+
Icon: ListNumbers,
|
|
3056
|
+
title: "Numbered list",
|
|
3057
|
+
onClick: () => ({
|
|
3058
|
+
type: "list-ordered"
|
|
3059
|
+
})
|
|
3060
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3061
|
+
Icon: ListChecks,
|
|
3062
|
+
title: "Task list",
|
|
3063
|
+
onClick: () => ({
|
|
3064
|
+
type: "list-tasks"
|
|
3065
|
+
})
|
|
3066
|
+
}));
|
|
3067
|
+
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3068
|
+
role: "none"
|
|
3069
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3070
|
+
Icon: CaretRight,
|
|
3071
|
+
title: "Block quite",
|
|
3072
|
+
onClick: () => ({
|
|
3073
|
+
type: "blockquote"
|
|
3074
|
+
})
|
|
3075
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3076
|
+
Icon: Code,
|
|
3077
|
+
title: "Code block",
|
|
3078
|
+
onClick: () => ({
|
|
3079
|
+
type: "codeblock"
|
|
3080
|
+
})
|
|
3081
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3082
|
+
Icon: Table2,
|
|
3083
|
+
title: "Table",
|
|
3084
|
+
onClick: () => ({
|
|
3085
|
+
type: "table"
|
|
3086
|
+
})
|
|
3087
|
+
}));
|
|
3088
|
+
var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3089
|
+
role: "none"
|
|
3090
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3091
|
+
Icon: Link,
|
|
3092
|
+
title: "Link",
|
|
3093
|
+
onClick: () => ({
|
|
3094
|
+
type: "link"
|
|
3095
|
+
})
|
|
3096
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3097
|
+
Icon: At,
|
|
3098
|
+
title: "Mention",
|
|
3099
|
+
onClick: () => ({
|
|
3100
|
+
type: "mention"
|
|
3101
|
+
})
|
|
3102
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3103
|
+
Icon: Image,
|
|
3104
|
+
title: "Image",
|
|
3105
|
+
onClick: () => ({
|
|
3106
|
+
type: "image"
|
|
3107
|
+
})
|
|
3108
|
+
}));
|
|
3109
|
+
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));
|
|
3110
|
+
var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
|
|
3111
|
+
Icon: ChatText,
|
|
3112
|
+
title: "Create comment",
|
|
3113
|
+
onClick: () => ({
|
|
3114
|
+
type: "comment"
|
|
3115
|
+
})
|
|
3116
|
+
});
|
|
3117
|
+
var Toolbar = {
|
|
3118
|
+
Root: ToolbarRoot,
|
|
3119
|
+
Button: ToolbarButton,
|
|
3120
|
+
Separator: ToolbarSeparator,
|
|
3121
|
+
Markdown: MarkdownStandard,
|
|
3122
|
+
Extended: MarkdownExtended
|
|
3123
|
+
};
|
|
3124
|
+
|
|
2750
3125
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2751
3126
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2752
3127
|
import { Context as Context2 } from "@dxos/context";
|
|
2753
|
-
import { invariant as
|
|
3128
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2754
3129
|
import { log as log3 } from "@dxos/log";
|
|
2755
|
-
var
|
|
3130
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2756
3131
|
var DEBOUNCE_INTERVAL = 100;
|
|
2757
3132
|
var SpaceAwarenessProvider = class {
|
|
2758
3133
|
constructor(params) {
|
|
@@ -2792,7 +3167,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2792
3167
|
log3.debug("failed to query awareness", {
|
|
2793
3168
|
err
|
|
2794
3169
|
}, {
|
|
2795
|
-
F:
|
|
3170
|
+
F: __dxlog_file4,
|
|
2796
3171
|
L: 89,
|
|
2797
3172
|
S: this,
|
|
2798
3173
|
C: (f, a) => f(...a)
|
|
@@ -2808,8 +3183,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2808
3183
|
return Array.from(this._remoteStates.values());
|
|
2809
3184
|
}
|
|
2810
3185
|
update(position) {
|
|
2811
|
-
|
|
2812
|
-
F:
|
|
3186
|
+
invariant2(this._postTask, void 0, {
|
|
3187
|
+
F: __dxlog_file4,
|
|
2813
3188
|
L: 104,
|
|
2814
3189
|
S: this,
|
|
2815
3190
|
A: [
|
|
@@ -2825,8 +3200,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2825
3200
|
this._postTask.schedule();
|
|
2826
3201
|
}
|
|
2827
3202
|
_handleQueryMessage() {
|
|
2828
|
-
|
|
2829
|
-
F:
|
|
3203
|
+
invariant2(this._postTask, void 0, {
|
|
3204
|
+
F: __dxlog_file4,
|
|
2830
3205
|
L: 115,
|
|
2831
3206
|
S: this,
|
|
2832
3207
|
A: [
|
|
@@ -2837,8 +3212,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2837
3212
|
this._postTask.schedule();
|
|
2838
3213
|
}
|
|
2839
3214
|
_handlePostMessage(message) {
|
|
2840
|
-
|
|
2841
|
-
F:
|
|
3215
|
+
invariant2(message.kind === "post", void 0, {
|
|
3216
|
+
F: __dxlog_file4,
|
|
2842
3217
|
L: 120,
|
|
2843
3218
|
S: this,
|
|
2844
3219
|
A: [
|
|
@@ -2858,9 +3233,50 @@ var modelState = StateField5.define({
|
|
|
2858
3233
|
update: (model) => model
|
|
2859
3234
|
});
|
|
2860
3235
|
|
|
2861
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
3236
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3237
|
+
var useActionHandler = (view) => {
|
|
3238
|
+
return (action) => {
|
|
3239
|
+
if (!view) {
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
switch (action.type) {
|
|
3243
|
+
case "heading":
|
|
3244
|
+
setHeading(parseInt(action.data))(view);
|
|
3245
|
+
break;
|
|
3246
|
+
case "bold":
|
|
3247
|
+
toggleBold(view);
|
|
3248
|
+
break;
|
|
3249
|
+
case "italic":
|
|
3250
|
+
toggleItalic(view);
|
|
3251
|
+
break;
|
|
3252
|
+
case "strikethrough":
|
|
3253
|
+
toggleStrikethrough(view);
|
|
3254
|
+
break;
|
|
3255
|
+
case "list":
|
|
3256
|
+
toggleList(view);
|
|
3257
|
+
break;
|
|
3258
|
+
case "codeblock":
|
|
3259
|
+
insertCodeblock(view);
|
|
3260
|
+
break;
|
|
3261
|
+
case "table":
|
|
3262
|
+
insertTable(view);
|
|
3263
|
+
break;
|
|
3264
|
+
case "comment":
|
|
3265
|
+
createComment(view);
|
|
3266
|
+
break;
|
|
3267
|
+
}
|
|
3268
|
+
setTimeout(() => {
|
|
3269
|
+
view.focus();
|
|
3270
|
+
view.dispatch({
|
|
3271
|
+
selection: view.state.selection
|
|
3272
|
+
});
|
|
3273
|
+
});
|
|
3274
|
+
};
|
|
3275
|
+
};
|
|
3276
|
+
|
|
3277
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
2862
3278
|
import { useState as useState2 } from "react";
|
|
2863
|
-
var
|
|
3279
|
+
var useEditorView = () => {
|
|
2864
3280
|
const [view, setView] = useState2(null);
|
|
2865
3281
|
return [
|
|
2866
3282
|
(ref) => {
|
|
@@ -2870,19 +3286,125 @@ var useTextEditor = () => {
|
|
|
2870
3286
|
];
|
|
2871
3287
|
};
|
|
2872
3288
|
|
|
3289
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3290
|
+
import { EditorSelection, EditorState as EditorState3 } from "@codemirror/state";
|
|
3291
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
3292
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
3293
|
+
import { log as log4 } from "@dxos/log";
|
|
3294
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
3295
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
3296
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
3297
|
+
const onUpdate = useRef2();
|
|
3298
|
+
const [view, setView] = useState3();
|
|
3299
|
+
const parentRef = useRef2(null);
|
|
3300
|
+
useEffect3(() => {
|
|
3301
|
+
if (parentRef.current) {
|
|
3302
|
+
const state = EditorState3.create({
|
|
3303
|
+
doc,
|
|
3304
|
+
selection,
|
|
3305
|
+
extensions: [
|
|
3306
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3307
|
+
EditorView14.exceptionSink.of((err) => {
|
|
3308
|
+
log4.catch(err, void 0, {
|
|
3309
|
+
F: __dxlog_file5,
|
|
3310
|
+
L: 57,
|
|
3311
|
+
S: void 0,
|
|
3312
|
+
C: (f, a) => f(...a)
|
|
3313
|
+
});
|
|
3314
|
+
}),
|
|
3315
|
+
extensions,
|
|
3316
|
+
EditorView14.updateListener.of(() => {
|
|
3317
|
+
onUpdate.current?.();
|
|
3318
|
+
})
|
|
3319
|
+
].filter(isNotFalsy4)
|
|
3320
|
+
});
|
|
3321
|
+
const view2 = new EditorView14({
|
|
3322
|
+
parent: parentRef.current,
|
|
3323
|
+
scrollTo,
|
|
3324
|
+
state,
|
|
3325
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3326
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3327
|
+
dispatchTransactions: (trs, view3) => {
|
|
3328
|
+
if (debug) {
|
|
3329
|
+
logChanges(trs);
|
|
3330
|
+
}
|
|
3331
|
+
view3.update(trs);
|
|
3332
|
+
}
|
|
3333
|
+
});
|
|
3334
|
+
setView(view2);
|
|
3335
|
+
}
|
|
3336
|
+
return () => {
|
|
3337
|
+
view?.destroy();
|
|
3338
|
+
};
|
|
3339
|
+
}, [
|
|
3340
|
+
parentRef
|
|
3341
|
+
]);
|
|
3342
|
+
useEffect3(() => {
|
|
3343
|
+
if (view) {
|
|
3344
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
3345
|
+
selection = EditorSelection.single(view.state.doc.line(1).to);
|
|
3346
|
+
}
|
|
3347
|
+
if (selection || scrollTo) {
|
|
3348
|
+
onUpdate.current = () => {
|
|
3349
|
+
onUpdate.current = void 0;
|
|
3350
|
+
view.dispatch({
|
|
3351
|
+
selection,
|
|
3352
|
+
effects: scrollTo && [
|
|
3353
|
+
scrollTo
|
|
3354
|
+
],
|
|
3355
|
+
scrollIntoView: !scrollTo
|
|
3356
|
+
});
|
|
3357
|
+
};
|
|
3358
|
+
}
|
|
3359
|
+
if (autoFocus) {
|
|
3360
|
+
view.focus();
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
}, [
|
|
3364
|
+
view,
|
|
3365
|
+
autoFocus,
|
|
3366
|
+
selection,
|
|
3367
|
+
scrollTo
|
|
3368
|
+
]);
|
|
3369
|
+
return {
|
|
3370
|
+
parentRef,
|
|
3371
|
+
view
|
|
3372
|
+
};
|
|
3373
|
+
};
|
|
3374
|
+
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
3375
|
+
return [
|
|
3376
|
+
//
|
|
3377
|
+
EditorState3.readOnly.of(readonly),
|
|
3378
|
+
EditorView14.editable.of(!readonly)
|
|
3379
|
+
];
|
|
3380
|
+
};
|
|
3381
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
3382
|
+
return [
|
|
3383
|
+
//
|
|
3384
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3385
|
+
theme && EditorView14.theme(theme),
|
|
3386
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3387
|
+
EditorView14.editorAttributes.of({
|
|
3388
|
+
class: slots?.editor?.className ?? ""
|
|
3389
|
+
}),
|
|
3390
|
+
EditorView14.contentAttributes.of({
|
|
3391
|
+
class: slots?.content?.className ?? ""
|
|
3392
|
+
})
|
|
3393
|
+
].filter(isNotFalsy4);
|
|
3394
|
+
};
|
|
3395
|
+
|
|
2873
3396
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
2874
3397
|
import get4 from "lodash.get";
|
|
2875
|
-
import { useEffect as
|
|
3398
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2876
3399
|
import { generateName } from "@dxos/display-name";
|
|
2877
3400
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
2878
|
-
import { invariant as
|
|
3401
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2879
3402
|
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";
|
|
3403
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
2882
3404
|
var useTextModel = (props) => {
|
|
2883
3405
|
const { identity, space, text } = props;
|
|
2884
|
-
const [model, setModel] =
|
|
2885
|
-
|
|
3406
|
+
const [model, setModel] = useState4();
|
|
3407
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
2886
3408
|
identity,
|
|
2887
3409
|
space,
|
|
2888
3410
|
text
|
|
@@ -2890,9 +3412,9 @@ var useTextModel = (props) => {
|
|
|
2890
3412
|
return model;
|
|
2891
3413
|
};
|
|
2892
3414
|
var createModel = ({ space, identity, text }) => {
|
|
2893
|
-
|
|
2894
|
-
F:
|
|
2895
|
-
L:
|
|
3415
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3416
|
+
F: __dxlog_file6,
|
|
3417
|
+
L: 34,
|
|
2896
3418
|
S: void 0,
|
|
2897
3419
|
A: [
|
|
2898
3420
|
"isAutomergeObject(text)",
|
|
@@ -2903,7 +3425,7 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2903
3425
|
const doc = getRawDoc(obj, [
|
|
2904
3426
|
obj.field
|
|
2905
3427
|
]);
|
|
2906
|
-
const
|
|
3428
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
2907
3429
|
space,
|
|
2908
3430
|
channel: `automerge.awareness.${obj.id}`,
|
|
2909
3431
|
info: {
|
|
@@ -2913,19 +3435,22 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2913
3435
|
},
|
|
2914
3436
|
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
2915
3437
|
});
|
|
3438
|
+
const extensions = [
|
|
3439
|
+
//
|
|
3440
|
+
modelState.init(() => model),
|
|
3441
|
+
automerge({
|
|
3442
|
+
handle: doc.handle,
|
|
3443
|
+
path: doc.path
|
|
3444
|
+
})
|
|
3445
|
+
];
|
|
3446
|
+
if (awarenessProvider2) {
|
|
3447
|
+
extensions.push(awareness(awarenessProvider2));
|
|
3448
|
+
}
|
|
2916
3449
|
const model = {
|
|
2917
3450
|
id: obj.id,
|
|
2918
3451
|
content: doc,
|
|
2919
3452
|
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),
|
|
3453
|
+
extension: extensions,
|
|
2929
3454
|
peer: identity ? {
|
|
2930
3455
|
id: identity.identityKey.toHex(),
|
|
2931
3456
|
name: identity.profile?.displayName
|
|
@@ -2934,7 +3459,6 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2934
3459
|
return model;
|
|
2935
3460
|
};
|
|
2936
3461
|
export {
|
|
2937
|
-
AwarenessProvider,
|
|
2938
3462
|
BaseTextEditor,
|
|
2939
3463
|
Cursor,
|
|
2940
3464
|
Doc,
|
|
@@ -2944,30 +3468,39 @@ export {
|
|
|
2944
3468
|
SpaceAwarenessProvider,
|
|
2945
3469
|
TextEditor,
|
|
2946
3470
|
TextKind,
|
|
3471
|
+
Toolbar,
|
|
2947
3472
|
YText,
|
|
2948
3473
|
YXmlFragment,
|
|
2949
3474
|
autocomplete,
|
|
2950
|
-
|
|
3475
|
+
automerge,
|
|
2951
3476
|
awareness,
|
|
2952
|
-
|
|
3477
|
+
awarenessProvider,
|
|
2953
3478
|
blast,
|
|
2954
3479
|
callbackWrapper,
|
|
2955
3480
|
code2 as code,
|
|
2956
3481
|
codeTheme,
|
|
2957
3482
|
comments,
|
|
3483
|
+
createBasicBundle,
|
|
3484
|
+
createComment,
|
|
3485
|
+
createDataExtensions,
|
|
3486
|
+
createMarkdownExtensions,
|
|
3487
|
+
createThemeExtensions,
|
|
2958
3488
|
defaultMarkdownSlots,
|
|
2959
3489
|
defaultOptions,
|
|
2960
3490
|
defaultSlots,
|
|
2961
3491
|
defaultTextSlots,
|
|
2962
3492
|
defaultTheme,
|
|
3493
|
+
focusComment,
|
|
3494
|
+
formatting,
|
|
2963
3495
|
getToken,
|
|
2964
3496
|
heading2 as heading,
|
|
2965
3497
|
hr,
|
|
2966
3498
|
image,
|
|
3499
|
+
insertCodeblock,
|
|
3500
|
+
insertTable,
|
|
2967
3501
|
link,
|
|
2968
3502
|
listener,
|
|
2969
3503
|
logChanges,
|
|
2970
|
-
markdownBundle,
|
|
2971
3504
|
markdownHighlightStyle,
|
|
2972
3505
|
markdownTags,
|
|
2973
3506
|
markdownTagsExtensions,
|
|
@@ -2976,15 +3509,23 @@ export {
|
|
|
2976
3509
|
modelState,
|
|
2977
3510
|
outliner,
|
|
2978
3511
|
setComments,
|
|
2979
|
-
|
|
3512
|
+
setHeading,
|
|
2980
3513
|
setSelection,
|
|
2981
3514
|
table,
|
|
2982
3515
|
tags2 as tags,
|
|
2983
3516
|
tasklist,
|
|
2984
3517
|
textTheme,
|
|
3518
|
+
toggleBold,
|
|
3519
|
+
toggleItalic,
|
|
3520
|
+
toggleList,
|
|
3521
|
+
toggleStrikethrough,
|
|
3522
|
+
toggleStyle,
|
|
2985
3523
|
typewriter,
|
|
3524
|
+
useActionHandler,
|
|
2986
3525
|
useComments,
|
|
3526
|
+
useEditorView,
|
|
2987
3527
|
useTextEditor,
|
|
2988
|
-
useTextModel
|
|
3528
|
+
useTextModel,
|
|
3529
|
+
useToolbarContext
|
|
2989
3530
|
};
|
|
2990
3531
|
//# sourceMappingURL=index.mjs.map
|