@dxos/react-ui-editor 0.3.11-main.1690b50 → 0.3.11-main.17ae201
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 +808 -252
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +1 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/{comments.stories.d.ts → hooks.stories.d.ts} +9 -12
- 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 +12 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.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 +27 -16
- package/src/components/TextEditor/automerge.stories.tsx +1 -2
- 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 +7 -4
- package/src/extensions/basic.ts +15 -13
- package/src/extensions/blast.ts +4 -1
- 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 +12 -2
- 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 +28 -9
- package/src/index.ts +1 -1
- package/src/themes/default.ts +9 -4
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +0 -1
- package/src/components/TextEditor/comments.stories.tsx +0 -357
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// packages/ui/react-ui-editor/src/index.ts
|
|
2
2
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
3
3
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
4
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
4
5
|
|
|
5
6
|
// packages/ui/react-ui-editor/src/components/TextEditor/index.ts
|
|
6
7
|
import { tags as tags2 } from "@lezer/highlight";
|
|
@@ -8,13 +9,13 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
9
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
9
10
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
10
11
|
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
11
|
-
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
12
|
import { vim } from "@replit/codemirror-vim";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
14
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
15
15
|
import { log as log2 } from "@dxos/log";
|
|
16
16
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
|
-
import {
|
|
17
|
+
import { focusRing, mx as mx3 } from "@dxos/react-ui-theme";
|
|
18
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
18
19
|
|
|
19
20
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
20
21
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
@@ -53,14 +54,14 @@ var autocomplete = ({ onSearch }) => {
|
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
57
|
+
import { invertedEffects } from "@codemirror/commands";
|
|
56
58
|
import { StateField } from "@codemirror/state";
|
|
57
59
|
import { EditorView, ViewPlugin } from "@codemirror/view";
|
|
58
|
-
import { next as
|
|
59
|
-
import { invariant } from "@dxos/invariant";
|
|
60
|
+
import { next as A4 } from "@dxos/automerge/automerge";
|
|
60
61
|
|
|
61
62
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
|
62
63
|
import get from "lodash.get";
|
|
63
|
-
import { next as
|
|
64
|
+
import { next as A } from "@dxos/automerge/automerge";
|
|
64
65
|
var cursorConverter = (handle, path) => ({
|
|
65
66
|
// TODO(burdon): Handle assoc to associate with a previous character.
|
|
66
67
|
toCursor: (pos) => {
|
|
@@ -72,7 +73,7 @@ var cursorConverter = (handle, path) => ({
|
|
|
72
73
|
if (typeof value === "string" && value.length <= pos) {
|
|
73
74
|
return "end";
|
|
74
75
|
}
|
|
75
|
-
return
|
|
76
|
+
return A.getCursor(doc, path.slice(), pos);
|
|
76
77
|
},
|
|
77
78
|
fromCursor: (cursor) => {
|
|
78
79
|
if (cursor === "") {
|
|
@@ -90,26 +91,28 @@ var cursorConverter = (handle, path) => ({
|
|
|
90
91
|
return 0;
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
|
-
return
|
|
94
|
+
return A.getCursorPosition(doc, path.slice(), cursor);
|
|
94
95
|
}
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
98
99
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
99
|
-
var effectType = StateEffect.define({});
|
|
100
|
-
var reconcileAnnotationType = Annotation.define();
|
|
101
100
|
var getPath = (state, field) => state.field(field).path;
|
|
102
101
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
103
|
-
var
|
|
102
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
103
|
+
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
104
104
|
newHeads
|
|
105
105
|
});
|
|
106
|
-
var
|
|
106
|
+
var reconcileAnnotation = Annotation.define();
|
|
107
|
+
var isReconcile = (tr) => {
|
|
108
|
+
return !!tr.annotation(reconcileAnnotation);
|
|
109
|
+
};
|
|
107
110
|
|
|
108
111
|
// packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
|
|
109
|
-
import { next as
|
|
112
|
+
import { next as A3 } from "@dxos/automerge/automerge";
|
|
110
113
|
|
|
111
114
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
|
112
|
-
import { next as
|
|
115
|
+
import { next as A2 } from "@dxos/automerge/automerge";
|
|
113
116
|
var updateAutomerge = (field, handle, transactions, state) => {
|
|
114
117
|
const { lastHeads, path } = state.field(field);
|
|
115
118
|
let hasChanges = false;
|
|
@@ -122,11 +125,19 @@ var updateAutomerge = (field, handle, transactions, state) => {
|
|
|
122
125
|
return void 0;
|
|
123
126
|
}
|
|
124
127
|
const newHeads = handle.changeAt(lastHeads, (doc) => {
|
|
128
|
+
const invertedTransactions = [];
|
|
125
129
|
for (const tr of transactions) {
|
|
126
|
-
tr.changes.iterChanges((fromA, toA, _fromB, _toB,
|
|
127
|
-
|
|
130
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
131
|
+
invertedTransactions.push({
|
|
132
|
+
from: fromA,
|
|
133
|
+
del: toA - fromA,
|
|
134
|
+
insert
|
|
135
|
+
});
|
|
128
136
|
});
|
|
129
137
|
}
|
|
138
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
139
|
+
A2.splice(doc, path.slice(), from, del, insert.toString());
|
|
140
|
+
});
|
|
130
141
|
});
|
|
131
142
|
return newHeads ?? void 0;
|
|
132
143
|
};
|
|
@@ -141,13 +152,13 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
141
152
|
selection = selection.map(changeSet, 1);
|
|
142
153
|
view.dispatch({
|
|
143
154
|
changes: changeSet,
|
|
144
|
-
annotations:
|
|
155
|
+
annotations: reconcileAnnotation.of(false)
|
|
145
156
|
});
|
|
146
157
|
}
|
|
147
158
|
}
|
|
148
159
|
view.dispatch({
|
|
149
160
|
selection,
|
|
150
|
-
annotations:
|
|
161
|
+
annotations: reconcileAnnotation.of(false)
|
|
151
162
|
});
|
|
152
163
|
};
|
|
153
164
|
var handlePatch = (patch, target, state) => {
|
|
@@ -168,7 +179,7 @@ var handleInsert = (target, patch) => {
|
|
|
168
179
|
if (index == null) {
|
|
169
180
|
return [];
|
|
170
181
|
}
|
|
171
|
-
const text = patch.values.map((
|
|
182
|
+
const text = patch.values.map((value) => value ? value.toString() : "").join("");
|
|
172
183
|
return [
|
|
173
184
|
{
|
|
174
185
|
from: index,
|
|
@@ -246,36 +257,37 @@ var PatchSemaphore = class {
|
|
|
246
257
|
this._state = _state;
|
|
247
258
|
this._inReconcile = false;
|
|
248
259
|
}
|
|
249
|
-
// NOTE: Cannot destruct view.state.
|
|
250
260
|
reconcile(view) {
|
|
251
|
-
if (this._inReconcile) {
|
|
252
|
-
|
|
261
|
+
if (!this._inReconcile) {
|
|
262
|
+
this._inReconcile = true;
|
|
263
|
+
this.doReconcile(view);
|
|
264
|
+
this._inReconcile = false;
|
|
253
265
|
}
|
|
254
|
-
|
|
266
|
+
}
|
|
267
|
+
doReconcile(view) {
|
|
255
268
|
const path = getPath(view.state, this._state);
|
|
256
269
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
257
270
|
let selection = view.state.selection;
|
|
258
|
-
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !
|
|
271
|
+
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
259
272
|
const toInvert = transactions.slice().reverse();
|
|
260
|
-
for (const
|
|
261
|
-
const inverted =
|
|
273
|
+
for (const tr of toInvert) {
|
|
274
|
+
const inverted = tr.changes.invert(tr.startState.doc);
|
|
262
275
|
selection = selection.map(inverted);
|
|
263
276
|
view.dispatch({
|
|
264
277
|
changes: inverted,
|
|
265
|
-
annotations:
|
|
278
|
+
annotations: reconcileAnnotation.of(true)
|
|
266
279
|
});
|
|
267
280
|
}
|
|
268
281
|
let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
269
282
|
if (newHeads === null || newHeads === void 0) {
|
|
270
|
-
newHeads =
|
|
283
|
+
newHeads = A3.getHeads(this._handle.docSync());
|
|
271
284
|
}
|
|
272
|
-
const diff =
|
|
285
|
+
const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
|
|
273
286
|
updateCodeMirror(view, selection, path, diff);
|
|
274
287
|
view.dispatch({
|
|
275
288
|
effects: updateHeads(newHeads),
|
|
276
|
-
annotations:
|
|
289
|
+
annotations: reconcileAnnotation.of(false)
|
|
277
290
|
});
|
|
278
|
-
this._inReconcile = false;
|
|
279
291
|
}
|
|
280
292
|
};
|
|
281
293
|
|
|
@@ -317,12 +329,11 @@ var Cursor = class _Cursor {
|
|
|
317
329
|
};
|
|
318
330
|
|
|
319
331
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
320
|
-
var
|
|
321
|
-
|
|
322
|
-
const state = StateField.define({
|
|
332
|
+
var automerge = ({ handle, path }) => {
|
|
333
|
+
const syncState = StateField.define({
|
|
323
334
|
create: () => ({
|
|
324
335
|
path: path.slice(),
|
|
325
|
-
lastHeads:
|
|
336
|
+
lastHeads: A4.getHeads(handle.docSync()),
|
|
326
337
|
unreconciledTransactions: []
|
|
327
338
|
}),
|
|
328
339
|
update: (value, tr) => {
|
|
@@ -333,7 +344,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
333
344
|
};
|
|
334
345
|
let clearUnreconciled = false;
|
|
335
346
|
for (const effect of tr.effects) {
|
|
336
|
-
if (effect.is(
|
|
347
|
+
if (effect.is(updateHeadsEffect)) {
|
|
337
348
|
result.lastHeads = effect.value.newHeads;
|
|
338
349
|
clearUnreconciled = true;
|
|
339
350
|
}
|
|
@@ -341,29 +352,21 @@ var automerge3 = ({ handle, path }) => {
|
|
|
341
352
|
if (clearUnreconciled) {
|
|
342
353
|
result.unreconciledTransactions = [];
|
|
343
354
|
} else {
|
|
344
|
-
if (!
|
|
355
|
+
if (!isReconcile(tr)) {
|
|
345
356
|
result.unreconciledTransactions.push(tr);
|
|
346
357
|
}
|
|
347
358
|
}
|
|
348
359
|
return result;
|
|
349
360
|
}
|
|
350
361
|
});
|
|
351
|
-
const semaphore = new PatchSemaphore(handle,
|
|
362
|
+
const semaphore = new PatchSemaphore(handle, syncState);
|
|
352
363
|
return [
|
|
353
364
|
Cursor.converter.of(cursorConverter(handle, path)),
|
|
365
|
+
syncState,
|
|
354
366
|
// Reconcile external updates.
|
|
355
367
|
ViewPlugin.fromClass(class {
|
|
356
368
|
constructor(_view) {
|
|
357
369
|
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
370
|
handle.addListener("change", this._handleChange.bind(this));
|
|
368
371
|
}
|
|
369
372
|
destroy() {
|
|
@@ -379,7 +382,17 @@ var automerge3 = ({ handle, path }) => {
|
|
|
379
382
|
semaphore.reconcile(view);
|
|
380
383
|
}
|
|
381
384
|
}),
|
|
382
|
-
|
|
385
|
+
// TODO(burdon): Record undo transactions.
|
|
386
|
+
// See https://github.com/yjs/y-codemirror.next/tree/main
|
|
387
|
+
// https://codemirror.net/examples/inverted-effect
|
|
388
|
+
invertedEffects.of((tr) => {
|
|
389
|
+
const effects = [];
|
|
390
|
+
if (!tr.changes.empty) {
|
|
391
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return effects;
|
|
395
|
+
})
|
|
383
396
|
];
|
|
384
397
|
};
|
|
385
398
|
|
|
@@ -398,13 +411,13 @@ var dummyProvider = {
|
|
|
398
411
|
update: () => {
|
|
399
412
|
}
|
|
400
413
|
};
|
|
401
|
-
var
|
|
414
|
+
var awarenessProvider = Facet2.define({
|
|
402
415
|
combine: (providers) => providers[0] ?? dummyProvider
|
|
403
416
|
});
|
|
404
417
|
var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
405
418
|
var awareness = (provider = dummyProvider) => {
|
|
406
419
|
return [
|
|
407
|
-
|
|
420
|
+
awarenessProvider.of(provider),
|
|
408
421
|
ViewPlugin2.fromClass(RemoteSelectionsDecorator, {
|
|
409
422
|
decorations: (value) => value.decorations
|
|
410
423
|
}),
|
|
@@ -418,7 +431,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
418
431
|
this._lastAnchor = void 0;
|
|
419
432
|
this._lastHead = void 0;
|
|
420
433
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
421
|
-
this._provider = view.state.facet(
|
|
434
|
+
this._provider = view.state.facet(awarenessProvider);
|
|
422
435
|
this._provider.open();
|
|
423
436
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
424
437
|
view.dispatch({
|
|
@@ -624,24 +637,25 @@ import { history } from "@codemirror/commands";
|
|
|
624
637
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
625
638
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
626
639
|
import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
627
|
-
|
|
628
|
-
|
|
640
|
+
import { isNotFalsy } from "@dxos/util";
|
|
641
|
+
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
|
|
642
|
+
lineWrapping && EditorView3.lineWrapping,
|
|
629
643
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
630
644
|
bracketMatching(),
|
|
631
645
|
closeBrackets(),
|
|
632
646
|
drawSelection(),
|
|
633
647
|
highlightActiveLine(),
|
|
634
648
|
history(),
|
|
635
|
-
_placeholder
|
|
649
|
+
_placeholder && placeholder(_placeholder),
|
|
636
650
|
// https://github.com/codemirror/theme-one-dark
|
|
637
651
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
638
|
-
];
|
|
652
|
+
].filter(isNotFalsy);
|
|
639
653
|
|
|
640
654
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
641
655
|
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
642
656
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
643
|
-
import { invariant
|
|
644
|
-
var
|
|
657
|
+
import { invariant } from "@dxos/invariant";
|
|
658
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
645
659
|
var defaultOptions = {
|
|
646
660
|
effect: 2,
|
|
647
661
|
maxParticles: 200,
|
|
@@ -767,9 +781,9 @@ var Blaster = class {
|
|
|
767
781
|
return this._node;
|
|
768
782
|
}
|
|
769
783
|
initialize() {
|
|
770
|
-
|
|
771
|
-
F:
|
|
772
|
-
L:
|
|
784
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
785
|
+
F: __dxlog_file,
|
|
786
|
+
L: 141,
|
|
773
787
|
S: this,
|
|
774
788
|
A: [
|
|
775
789
|
"!this._canvas && !this._ctx",
|
|
@@ -804,9 +818,9 @@ var Blaster = class {
|
|
|
804
818
|
}
|
|
805
819
|
}
|
|
806
820
|
start() {
|
|
807
|
-
|
|
808
|
-
F:
|
|
809
|
-
L:
|
|
821
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
822
|
+
F: __dxlog_file,
|
|
823
|
+
L: 180,
|
|
810
824
|
S: this,
|
|
811
825
|
A: [
|
|
812
826
|
"this._canvas && this._ctx",
|
|
@@ -948,12 +962,12 @@ var random = (min, max) => {
|
|
|
948
962
|
};
|
|
949
963
|
|
|
950
964
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
951
|
-
import {
|
|
965
|
+
import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
|
|
966
|
+
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
952
967
|
import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
|
|
953
968
|
import sortBy from "lodash.sortby";
|
|
954
969
|
import { useEffect } from "react";
|
|
955
970
|
import { debounce } from "@dxos/async";
|
|
956
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
957
971
|
import { nonNullable } from "@dxos/util";
|
|
958
972
|
|
|
959
973
|
// packages/ui/react-ui-editor/src/styles/cursors.ts
|
|
@@ -1025,13 +1039,13 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
|
|
|
1025
1039
|
|
|
1026
1040
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1027
1041
|
import { log } from "@dxos/log";
|
|
1028
|
-
var
|
|
1042
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1029
1043
|
var callbackWrapper = (fn) => (...args) => {
|
|
1030
1044
|
try {
|
|
1031
1045
|
return fn(...args);
|
|
1032
1046
|
} catch (err) {
|
|
1033
1047
|
log.catch(err, void 0, {
|
|
1034
|
-
F:
|
|
1048
|
+
F: __dxlog_file2,
|
|
1035
1049
|
L: 18,
|
|
1036
1050
|
S: void 0,
|
|
1037
1051
|
C: (f, a) => f(...a)
|
|
@@ -1059,7 +1073,6 @@ var logChanges = (trs) => {
|
|
|
1059
1073
|
};
|
|
1060
1074
|
|
|
1061
1075
|
// 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
1076
|
var styles2 = EditorView5.baseTheme({
|
|
1064
1077
|
"& .cm-comment": {
|
|
1065
1078
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
@@ -1068,15 +1081,13 @@ var styles2 = EditorView5.baseTheme({
|
|
|
1068
1081
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1069
1082
|
}
|
|
1070
1083
|
});
|
|
1071
|
-
var
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
};
|
|
1079
|
-
var setFocus = (view, id, center = true) => {
|
|
1084
|
+
var commentMark = Decoration2.mark({
|
|
1085
|
+
class: "cm-comment"
|
|
1086
|
+
});
|
|
1087
|
+
var commentCurrentMark = Decoration2.mark({
|
|
1088
|
+
class: "cm-comment-current"
|
|
1089
|
+
});
|
|
1090
|
+
var focusComment = (view, id, center = true) => {
|
|
1080
1091
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
1081
1092
|
if (!comment?.comment.cursor) {
|
|
1082
1093
|
return;
|
|
@@ -1138,7 +1149,7 @@ var commentsState = StateField2.define({
|
|
|
1138
1149
|
return value;
|
|
1139
1150
|
}
|
|
1140
1151
|
});
|
|
1141
|
-
var
|
|
1152
|
+
var commentsDecorations = EditorView5.decorations.compute([
|
|
1142
1153
|
commentsState
|
|
1143
1154
|
], (state) => {
|
|
1144
1155
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1149,9 +1160,9 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1149
1160
|
return void 0;
|
|
1150
1161
|
}
|
|
1151
1162
|
if (comment.comment.id === current) {
|
|
1152
|
-
return
|
|
1163
|
+
return commentCurrentMark.range(range.from, range.to);
|
|
1153
1164
|
} else {
|
|
1154
|
-
return
|
|
1165
|
+
return commentMark.range(range.from, range.to);
|
|
1155
1166
|
}
|
|
1156
1167
|
}).filter(nonNullable);
|
|
1157
1168
|
return Decoration2.set(decorations);
|
|
@@ -1180,84 +1191,124 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1180
1191
|
cut: handleTrack,
|
|
1181
1192
|
copy: handleTrack
|
|
1182
1193
|
}),
|
|
1183
|
-
//
|
|
1184
|
-
|
|
1194
|
+
// Track deleted comments.
|
|
1195
|
+
invertedEffects2.of((tr) => {
|
|
1196
|
+
const { comments: comments2 } = tr.startState.field(commentsState);
|
|
1197
|
+
const effects = [];
|
|
1198
|
+
tr.changes.iterChangedRanges((fromA, toA) => {
|
|
1199
|
+
for (const { comment: { id }, range: { from, to } } of comments2) {
|
|
1200
|
+
if (from < to && from >= fromA && to <= toA) {
|
|
1201
|
+
effects.push(restoreCommentEffect.of({
|
|
1202
|
+
id,
|
|
1203
|
+
from,
|
|
1204
|
+
to
|
|
1205
|
+
}));
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
});
|
|
1209
|
+
return effects;
|
|
1210
|
+
}),
|
|
1211
|
+
// Handle paste or the undo of comment deletion.
|
|
1212
|
+
EditorView5.updateListener.of((update2) => {
|
|
1213
|
+
const restore = [];
|
|
1214
|
+
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1215
|
+
const tr = update2.transactions[i];
|
|
1216
|
+
for (let j = 0; j < restore.length; j++) {
|
|
1217
|
+
restore[j] = mapTrackedComment(restore[j], tr.changes);
|
|
1218
|
+
}
|
|
1219
|
+
for (const effect of tr.effects) {
|
|
1220
|
+
if (effect.is(restoreCommentEffect)) {
|
|
1221
|
+
restore.push(effect.value);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1185
1225
|
if (tracked) {
|
|
1186
|
-
const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1226
|
+
const paste = update2.transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1187
1227
|
if (paste) {
|
|
1188
1228
|
let found = -1;
|
|
1189
1229
|
paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
1190
1230
|
if (text.eq(tracked.text)) {
|
|
1191
|
-
for (let i = transactions.indexOf(paste) + 1; i < transactions.length; i++) {
|
|
1192
|
-
fromB = transactions[i].changes.mapPos(fromB);
|
|
1231
|
+
for (let i = update2.transactions.indexOf(paste) + 1; i < update2.transactions.length; i++) {
|
|
1232
|
+
fromB = update2.transactions[i].changes.mapPos(fromB);
|
|
1193
1233
|
}
|
|
1194
1234
|
found = fromB;
|
|
1195
1235
|
}
|
|
1196
1236
|
});
|
|
1197
1237
|
if (found > -1) {
|
|
1198
1238
|
for (const moved of tracked.comments) {
|
|
1199
|
-
|
|
1239
|
+
restore.push({
|
|
1240
|
+
id: moved.id,
|
|
1200
1241
|
from: found + moved.from,
|
|
1201
1242
|
to: found + moved.to
|
|
1202
|
-
};
|
|
1203
|
-
const cursor = Cursor.getCursorFromRange(state, range);
|
|
1204
|
-
onUpdate(moved.id, cursor);
|
|
1243
|
+
});
|
|
1205
1244
|
}
|
|
1206
1245
|
}
|
|
1207
1246
|
tracked = null;
|
|
1208
1247
|
}
|
|
1209
1248
|
}
|
|
1249
|
+
for (const comment of restore) {
|
|
1250
|
+
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
1251
|
+
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
1252
|
+
if (!exists) {
|
|
1253
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
1254
|
+
onUpdate(comment.id, cursor);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1210
1257
|
})
|
|
1211
1258
|
];
|
|
1212
1259
|
};
|
|
1213
|
-
var
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1260
|
+
var mapTrackedComment = (comment, changes) => ({
|
|
1261
|
+
id: comment.id,
|
|
1262
|
+
from: changes.mapPos(comment.from, 1),
|
|
1263
|
+
to: changes.mapPos(comment.to, 1)
|
|
1264
|
+
});
|
|
1265
|
+
var restoreCommentEffect = StateEffect2.define({
|
|
1266
|
+
map: mapTrackedComment
|
|
1267
|
+
});
|
|
1268
|
+
var optionsFacet = Facet3.define({
|
|
1269
|
+
combine: (providers) => providers[0]
|
|
1270
|
+
});
|
|
1271
|
+
var createComment = (view) => {
|
|
1272
|
+
const options = view.state.facet(optionsFacet);
|
|
1273
|
+
const { from, to } = view.state.selection.main;
|
|
1274
|
+
if (from === to) {
|
|
1275
|
+
return false;
|
|
1276
|
+
}
|
|
1277
|
+
if (to === view.state.doc.length) {
|
|
1278
|
+
view.dispatch({
|
|
1279
|
+
changes: {
|
|
1280
|
+
from: to,
|
|
1281
|
+
insert: "\n"
|
|
1282
|
+
}
|
|
1225
1283
|
});
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1284
|
+
}
|
|
1285
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
1286
|
+
from,
|
|
1287
|
+
to
|
|
1288
|
+
});
|
|
1289
|
+
if (cursor) {
|
|
1290
|
+
const id = options.onCreate?.(cursor, view.coordsAtPos(from));
|
|
1291
|
+
if (id) {
|
|
1231
1292
|
view.dispatch({
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1293
|
+
effects: setSelection.of({
|
|
1294
|
+
current: id
|
|
1295
|
+
}),
|
|
1296
|
+
selection: {
|
|
1297
|
+
anchor: to
|
|
1235
1298
|
}
|
|
1236
1299
|
});
|
|
1300
|
+
return true;
|
|
1237
1301
|
}
|
|
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
|
-
};
|
|
1302
|
+
}
|
|
1303
|
+
return false;
|
|
1304
|
+
};
|
|
1305
|
+
var comments = (options = {}) => {
|
|
1306
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1307
|
+
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1258
1308
|
return [
|
|
1309
|
+
optionsFacet.of(options),
|
|
1259
1310
|
commentsState,
|
|
1260
|
-
|
|
1311
|
+
commentsDecorations,
|
|
1261
1312
|
styles2,
|
|
1262
1313
|
//
|
|
1263
1314
|
// Keymap.
|
|
@@ -1265,7 +1316,7 @@ var comments = (options = {}) => {
|
|
|
1265
1316
|
options.onCreate ? keymap3.of([
|
|
1266
1317
|
{
|
|
1267
1318
|
key: shortcut,
|
|
1268
|
-
run: callbackWrapper(
|
|
1319
|
+
run: callbackWrapper(createComment)
|
|
1269
1320
|
}
|
|
1270
1321
|
]) : [],
|
|
1271
1322
|
//
|
|
@@ -1403,6 +1454,7 @@ import { searchKeymap } from "@codemirror/search";
|
|
|
1403
1454
|
import { EditorState } from "@codemirror/state";
|
|
1404
1455
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1405
1456
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1457
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1406
1458
|
|
|
1407
1459
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1408
1460
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1593,11 +1645,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1593
1645
|
};
|
|
1594
1646
|
|
|
1595
1647
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1596
|
-
var
|
|
1648
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1597
1649
|
return [
|
|
1650
|
+
lineWrapping && EditorView7.lineWrapping,
|
|
1598
1651
|
EditorState.allowMultipleSelections.of(true),
|
|
1599
1652
|
EditorState.tabSize.of(2),
|
|
1600
|
-
EditorView7.lineWrapping,
|
|
1601
1653
|
// https://github.com/codemirror/basic-setup
|
|
1602
1654
|
bracketMatching2(),
|
|
1603
1655
|
closeBrackets2(),
|
|
@@ -1607,7 +1659,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1607
1659
|
highlightActiveLine2(),
|
|
1608
1660
|
history2(),
|
|
1609
1661
|
indentOnInput(),
|
|
1610
|
-
_placeholder
|
|
1662
|
+
_placeholder && placeholder2(_placeholder),
|
|
1611
1663
|
// Main extension.
|
|
1612
1664
|
// https://github.com/codemirror/lang-markdown
|
|
1613
1665
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1642,7 +1694,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1642
1694
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1643
1695
|
...standardKeymap
|
|
1644
1696
|
])
|
|
1645
|
-
];
|
|
1697
|
+
].filter(isNotFalsy2);
|
|
1646
1698
|
};
|
|
1647
1699
|
|
|
1648
1700
|
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
@@ -1652,26 +1704,43 @@ import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Dec
|
|
|
1652
1704
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1653
1705
|
var styles3 = EditorView8.baseTheme({
|
|
1654
1706
|
"& .cm-code": {
|
|
1655
|
-
paddingInline: "1rem !important",
|
|
1656
1707
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1657
1708
|
},
|
|
1658
1709
|
"& .cm-codeblock": {
|
|
1659
|
-
|
|
1660
|
-
|
|
1710
|
+
width: "100%",
|
|
1711
|
+
paddingInline: "1rem !important",
|
|
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
|
+
display: "inline-block",
|
|
1733
|
+
"&::after": {
|
|
1734
|
+
borderTopLeftRadius: ".5rem",
|
|
1735
|
+
borderTopRightRadius: ".5rem"
|
|
1736
|
+
}
|
|
1671
1737
|
},
|
|
1672
1738
|
"& .cm-codeblock-last": {
|
|
1673
|
-
|
|
1674
|
-
|
|
1739
|
+
display: "inline-block",
|
|
1740
|
+
"&::after": {
|
|
1741
|
+
borderBottomLeftRadius: ".5rem",
|
|
1742
|
+
borderBottomRightRadius: ".5rem"
|
|
1743
|
+
}
|
|
1675
1744
|
}
|
|
1676
1745
|
});
|
|
1677
1746
|
var getLineRange = (lines, from, to) => {
|
|
@@ -1715,7 +1784,7 @@ var buildDecorations = (view) => {
|
|
|
1715
1784
|
}));
|
|
1716
1785
|
} else {
|
|
1717
1786
|
builder.add(block.from, block.from, Decoration3.line({
|
|
1718
|
-
class: mx2("cm-code cm-codeblock")
|
|
1787
|
+
class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1719
1788
|
}));
|
|
1720
1789
|
}
|
|
1721
1790
|
}
|
|
@@ -1743,16 +1812,156 @@ var code2 = () => {
|
|
|
1743
1812
|
];
|
|
1744
1813
|
};
|
|
1745
1814
|
|
|
1746
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
1815
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1816
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1747
1817
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1748
1818
|
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1749
|
-
import { Decoration as Decoration4, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1819
|
+
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1820
|
+
var setHeading = (level) => (view) => {
|
|
1821
|
+
const { selection: { ranges }, doc } = view.state;
|
|
1822
|
+
const changes = [];
|
|
1823
|
+
for (const range of ranges) {
|
|
1824
|
+
const { number } = doc.lineAt(range.anchor);
|
|
1825
|
+
const { from, to } = doc.line(number);
|
|
1826
|
+
const line = doc.sliceString(from, to);
|
|
1827
|
+
const [_, marks, spaces] = line.match(/(#+)(\s+)/) ?? [];
|
|
1828
|
+
const current = marks?.length ?? 0;
|
|
1829
|
+
if (level !== current) {
|
|
1830
|
+
changes.push({
|
|
1831
|
+
from,
|
|
1832
|
+
to: from + current + (spaces?.length ?? 0),
|
|
1833
|
+
insert: "#".repeat(level) + (level > 0 ? " " : "")
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
if (changes.length) {
|
|
1838
|
+
view.dispatch({
|
|
1839
|
+
changes
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
return true;
|
|
1843
|
+
};
|
|
1844
|
+
var toggleStyle = (mark2) => (view) => {
|
|
1845
|
+
const { ranges } = view.state.selection;
|
|
1846
|
+
for (const range of ranges) {
|
|
1847
|
+
if (range.from === range.to) {
|
|
1848
|
+
return false;
|
|
1849
|
+
}
|
|
1850
|
+
view.dispatch({
|
|
1851
|
+
changes: [
|
|
1852
|
+
{
|
|
1853
|
+
from: range.from,
|
|
1854
|
+
insert: mark2
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
from: range.to,
|
|
1858
|
+
insert: mark2
|
|
1859
|
+
}
|
|
1860
|
+
]
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
return true;
|
|
1864
|
+
};
|
|
1865
|
+
var snippets = {
|
|
1866
|
+
codeblock: snippet([
|
|
1867
|
+
"```#{lang}",
|
|
1868
|
+
" #{}",
|
|
1869
|
+
"```"
|
|
1870
|
+
].join("\n")),
|
|
1871
|
+
table: snippet([
|
|
1872
|
+
"| #{col1} | #{col2} |",
|
|
1873
|
+
"| ---- | ---- |",
|
|
1874
|
+
"| #{val1} | #{val2} |",
|
|
1875
|
+
"| #{val3} | #{val4} |"
|
|
1876
|
+
].join("\n"))
|
|
1877
|
+
};
|
|
1878
|
+
var insertCodeblock = (view) => {
|
|
1879
|
+
const { selection: { main }, doc } = view.state;
|
|
1880
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1881
|
+
const { from } = doc.line(number);
|
|
1882
|
+
snippets.codeblock(view, null, from, from);
|
|
1883
|
+
};
|
|
1884
|
+
var insertTable = (view) => {
|
|
1885
|
+
const { selection: { main }, doc } = view.state;
|
|
1886
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1887
|
+
const { from } = doc.line(number);
|
|
1888
|
+
snippets.table(view, null, from, from);
|
|
1889
|
+
};
|
|
1890
|
+
var toggleBold = toggleStyle("**");
|
|
1891
|
+
var toggleItalic = toggleStyle("_");
|
|
1892
|
+
var toggleStrikethrough = toggleStyle("~~");
|
|
1893
|
+
var toggleList = (view) => {
|
|
1894
|
+
};
|
|
1895
|
+
var formatting = (options = {}) => {
|
|
1896
|
+
return [
|
|
1897
|
+
keymap5.of([
|
|
1898
|
+
{
|
|
1899
|
+
key: "meta-b",
|
|
1900
|
+
run: toggleBold
|
|
1901
|
+
}
|
|
1902
|
+
]),
|
|
1903
|
+
styling()
|
|
1904
|
+
];
|
|
1905
|
+
};
|
|
1906
|
+
var styling = () => {
|
|
1907
|
+
const buildDecorations7 = (view) => {
|
|
1908
|
+
const builder = new RangeSetBuilder2();
|
|
1909
|
+
const { state } = view;
|
|
1910
|
+
const cursor = state.selection.main.head;
|
|
1911
|
+
const replace = (node, marks) => {
|
|
1912
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
1913
|
+
for (const mark2 of marks) {
|
|
1914
|
+
builder.add(mark2.from, mark2.to, Decoration4.replace({}));
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
};
|
|
1918
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1919
|
+
syntaxTree2(state).iterate({
|
|
1920
|
+
enter: (node) => {
|
|
1921
|
+
switch (node.name) {
|
|
1922
|
+
case "Emphasis":
|
|
1923
|
+
case "StrongEmphasis": {
|
|
1924
|
+
const marks = node.node.getChildren("EmphasisMark");
|
|
1925
|
+
replace(node, marks);
|
|
1926
|
+
break;
|
|
1927
|
+
}
|
|
1928
|
+
case "Strikethrough": {
|
|
1929
|
+
const marks = node.node.getChildren("StrikethroughMark");
|
|
1930
|
+
replace(node, marks);
|
|
1931
|
+
break;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
},
|
|
1935
|
+
from,
|
|
1936
|
+
to
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
return builder.finish();
|
|
1940
|
+
};
|
|
1941
|
+
return [
|
|
1942
|
+
ViewPlugin4.fromClass(class {
|
|
1943
|
+
constructor(view) {
|
|
1944
|
+
this.decorations = buildDecorations7(view);
|
|
1945
|
+
}
|
|
1946
|
+
update(update2) {
|
|
1947
|
+
this.decorations = buildDecorations7(update2.view);
|
|
1948
|
+
}
|
|
1949
|
+
}, {
|
|
1950
|
+
decorations: (value) => value.decorations
|
|
1951
|
+
})
|
|
1952
|
+
];
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1956
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1957
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1958
|
+
import { Decoration as Decoration5, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1750
1959
|
var buildDecorations2 = (view) => {
|
|
1751
|
-
const builder = new
|
|
1960
|
+
const builder = new RangeSetBuilder3();
|
|
1752
1961
|
const { state } = view;
|
|
1753
1962
|
const cursor = state.selection.main.head;
|
|
1754
1963
|
for (const { from, to } of view.visibleRanges) {
|
|
1755
|
-
|
|
1964
|
+
syntaxTree3(state).iterate({
|
|
1756
1965
|
enter: (node) => {
|
|
1757
1966
|
switch (node.name) {
|
|
1758
1967
|
case "ATXHeading1":
|
|
@@ -1763,8 +1972,8 @@ var buildDecorations2 = (view) => {
|
|
|
1763
1972
|
case "ATXHeading6": {
|
|
1764
1973
|
const mark2 = node.node.getChild("HeaderMark");
|
|
1765
1974
|
if (mark2) {
|
|
1766
|
-
if (view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1767
|
-
builder.add(mark2.from, mark2.to + 1,
|
|
1975
|
+
if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1976
|
+
builder.add(mark2.from, mark2.to + 1, Decoration5.replace({}));
|
|
1768
1977
|
}
|
|
1769
1978
|
}
|
|
1770
1979
|
}
|
|
@@ -1778,7 +1987,7 @@ var buildDecorations2 = (view) => {
|
|
|
1778
1987
|
};
|
|
1779
1988
|
var heading2 = () => {
|
|
1780
1989
|
return [
|
|
1781
|
-
|
|
1990
|
+
ViewPlugin5.fromClass(class {
|
|
1782
1991
|
constructor(view) {
|
|
1783
1992
|
this.decorations = buildDecorations2(view);
|
|
1784
1993
|
}
|
|
@@ -1792,9 +2001,9 @@ var heading2 = () => {
|
|
|
1792
2001
|
};
|
|
1793
2002
|
|
|
1794
2003
|
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
1795
|
-
import { syntaxTree as
|
|
1796
|
-
import { RangeSetBuilder as
|
|
1797
|
-
import { Decoration as
|
|
2004
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2005
|
+
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
2006
|
+
import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1798
2007
|
var styles4 = EditorView9.baseTheme({
|
|
1799
2008
|
"& .cm-hr": {
|
|
1800
2009
|
// Note that block-level decorations should not have vertical margins,
|
|
@@ -1808,15 +2017,15 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1808
2017
|
return el;
|
|
1809
2018
|
}
|
|
1810
2019
|
};
|
|
1811
|
-
var decoration =
|
|
2020
|
+
var decoration = Decoration6.replace({
|
|
1812
2021
|
widget: new HorizontalRuleWidget()
|
|
1813
2022
|
});
|
|
1814
2023
|
var buildDecorations3 = (view) => {
|
|
1815
|
-
const builder = new
|
|
2024
|
+
const builder = new RangeSetBuilder4();
|
|
1816
2025
|
const { state } = view;
|
|
1817
2026
|
const cursor = state.selection.main.head;
|
|
1818
2027
|
for (const { from, to } of view.visibleRanges) {
|
|
1819
|
-
|
|
2028
|
+
syntaxTree4(state).iterate({
|
|
1820
2029
|
enter: (node) => {
|
|
1821
2030
|
if (node.name === "HorizontalRule") {
|
|
1822
2031
|
if (cursor <= node.from || cursor >= node.to) {
|
|
@@ -1832,7 +2041,7 @@ var buildDecorations3 = (view) => {
|
|
|
1832
2041
|
};
|
|
1833
2042
|
var hr = () => {
|
|
1834
2043
|
return [
|
|
1835
|
-
|
|
2044
|
+
ViewPlugin6.fromClass(class {
|
|
1836
2045
|
constructor(view) {
|
|
1837
2046
|
this.decorations = buildDecorations3(view);
|
|
1838
2047
|
}
|
|
@@ -1847,13 +2056,13 @@ var hr = () => {
|
|
|
1847
2056
|
};
|
|
1848
2057
|
|
|
1849
2058
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
1850
|
-
import { syntaxTree as
|
|
2059
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
1851
2060
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1852
|
-
import { Decoration as
|
|
2061
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1853
2062
|
var image = (options = {}) => {
|
|
1854
2063
|
return StateField3.define({
|
|
1855
2064
|
create: (state) => {
|
|
1856
|
-
return
|
|
2065
|
+
return Decoration7.set(buildDecorations4(0, state.doc.length, state));
|
|
1857
2066
|
},
|
|
1858
2067
|
update: (value, tr) => {
|
|
1859
2068
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -1882,14 +2091,14 @@ var image = (options = {}) => {
|
|
|
1882
2091
|
var buildDecorations4 = (from, to, state) => {
|
|
1883
2092
|
const decorations = [];
|
|
1884
2093
|
const cursor = state.selection.main.head;
|
|
1885
|
-
|
|
2094
|
+
syntaxTree5(state).iterate({
|
|
1886
2095
|
enter: (node) => {
|
|
1887
2096
|
if (node.name === "Image") {
|
|
1888
2097
|
const urlNode = node.node.getChild("URL");
|
|
1889
2098
|
if (urlNode) {
|
|
1890
2099
|
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1891
2100
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1892
|
-
decorations.push(
|
|
2101
|
+
decorations.push(Decoration7.replace({
|
|
1893
2102
|
block: true,
|
|
1894
2103
|
widget: new ImageWidget(url)
|
|
1895
2104
|
}).range(hide ? node.from : node.to, node.to));
|
|
@@ -1919,13 +2128,13 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1919
2128
|
};
|
|
1920
2129
|
|
|
1921
2130
|
// 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
|
|
2131
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
2132
|
+
import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
|
|
2133
|
+
import { hoverTooltip as hoverTooltip2, Decoration as Decoration8, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1925
2134
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1926
2135
|
var link = (options = {}) => {
|
|
1927
2136
|
const extensions = [
|
|
1928
|
-
|
|
2137
|
+
ViewPlugin7.fromClass(class {
|
|
1929
2138
|
constructor(view) {
|
|
1930
2139
|
this.decorations = buildDecorations5(view, options);
|
|
1931
2140
|
}
|
|
@@ -1944,7 +2153,7 @@ var link = (options = {}) => {
|
|
|
1944
2153
|
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1945
2154
|
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1946
2155
|
hoverTooltip2((view, pos, side) => {
|
|
1947
|
-
const syntax =
|
|
2156
|
+
const syntax = syntaxTree6(view.state).resolveInner(pos, side);
|
|
1948
2157
|
let link2 = null;
|
|
1949
2158
|
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1950
2159
|
link2 = node.name === "Link" ? node : null;
|
|
@@ -2021,27 +2230,27 @@ var LinkText = class extends WidgetType5 {
|
|
|
2021
2230
|
}
|
|
2022
2231
|
};
|
|
2023
2232
|
var buildDecorations5 = (view, options) => {
|
|
2024
|
-
const builder = new
|
|
2233
|
+
const builder = new RangeSetBuilder5();
|
|
2025
2234
|
const { state } = view;
|
|
2026
2235
|
const cursor = state.selection.main.head;
|
|
2027
2236
|
for (const { from, to } of view.visibleRanges) {
|
|
2028
|
-
|
|
2237
|
+
syntaxTree6(state).iterate({
|
|
2029
2238
|
enter: (node) => {
|
|
2030
2239
|
if (node.name === "Link") {
|
|
2031
|
-
const
|
|
2032
|
-
const text =
|
|
2240
|
+
const marks = node.node.getChildren("LinkMark");
|
|
2241
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
2033
2242
|
const urlNode = node.node.getChild("URL");
|
|
2034
2243
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2035
2244
|
if (!url) {
|
|
2036
2245
|
return false;
|
|
2037
2246
|
}
|
|
2038
2247
|
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
2039
|
-
builder.add(node.from, node.to,
|
|
2248
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
|
2040
2249
|
widget: new LinkText(text, options.link ? url : void 0)
|
|
2041
2250
|
}));
|
|
2042
2251
|
}
|
|
2043
2252
|
if (options.onRender) {
|
|
2044
|
-
builder.add(node.to, node.to,
|
|
2253
|
+
builder.add(node.to, node.to, Decoration8.replace({
|
|
2045
2254
|
widget: new LinkButton(url, options.onRender)
|
|
2046
2255
|
}));
|
|
2047
2256
|
}
|
|
@@ -2056,9 +2265,9 @@ var buildDecorations5 = (view, options) => {
|
|
|
2056
2265
|
};
|
|
2057
2266
|
|
|
2058
2267
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2059
|
-
import { syntaxTree as
|
|
2060
|
-
import { RangeSetBuilder as
|
|
2061
|
-
import { Decoration as
|
|
2268
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2269
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
|
|
2270
|
+
import { Decoration as Decoration9, EditorView as EditorView11, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2062
2271
|
var table = (options = {}) => {
|
|
2063
2272
|
return StateField4.define({
|
|
2064
2273
|
create: (state) => update(state, options),
|
|
@@ -2067,7 +2276,7 @@ var table = (options = {}) => {
|
|
|
2067
2276
|
});
|
|
2068
2277
|
};
|
|
2069
2278
|
var update = (state, options) => {
|
|
2070
|
-
const builder = new
|
|
2279
|
+
const builder = new RangeSetBuilder6();
|
|
2071
2280
|
const cursor = state.selection.main.head;
|
|
2072
2281
|
const tables = [];
|
|
2073
2282
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -2075,7 +2284,7 @@ var update = (state, options) => {
|
|
|
2075
2284
|
const table2 = getTable();
|
|
2076
2285
|
return table2.rows?.[table2.rows.length - 1];
|
|
2077
2286
|
};
|
|
2078
|
-
|
|
2287
|
+
syntaxTree7(state).iterate({
|
|
2079
2288
|
enter: (node) => {
|
|
2080
2289
|
switch (node.name) {
|
|
2081
2290
|
case "Table": {
|
|
@@ -2107,10 +2316,10 @@ var update = (state, options) => {
|
|
|
2107
2316
|
});
|
|
2108
2317
|
tables.forEach((table2) => {
|
|
2109
2318
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2110
|
-
hide && builder.add(table2.from, table2.to,
|
|
2319
|
+
hide && builder.add(table2.from, table2.to, Decoration9.replace({
|
|
2111
2320
|
widget: new TableWidget(table2)
|
|
2112
2321
|
}));
|
|
2113
|
-
builder.add(table2.from, table2.to,
|
|
2322
|
+
builder.add(table2.from, table2.to, Decoration9.mark({
|
|
2114
2323
|
class: "cm-table"
|
|
2115
2324
|
}));
|
|
2116
2325
|
});
|
|
@@ -2154,9 +2363,9 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2154
2363
|
};
|
|
2155
2364
|
|
|
2156
2365
|
// 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
|
|
2366
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
2367
|
+
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
2368
|
+
import { EditorView as EditorView12, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
2160
2369
|
var styles5 = EditorView12.baseTheme({
|
|
2161
2370
|
"& .cm-task": {
|
|
2162
2371
|
color: getToken("extend.colors.blue.500")
|
|
@@ -2203,23 +2412,23 @@ var CheckboxWidget = class extends WidgetType7 {
|
|
|
2203
2412
|
return false;
|
|
2204
2413
|
}
|
|
2205
2414
|
};
|
|
2206
|
-
var checkedDecoration =
|
|
2415
|
+
var checkedDecoration = Decoration10.replace({
|
|
2207
2416
|
widget: new CheckboxWidget(true)
|
|
2208
2417
|
});
|
|
2209
|
-
var uncheckedDecoration =
|
|
2418
|
+
var uncheckedDecoration = Decoration10.replace({
|
|
2210
2419
|
widget: new CheckboxWidget(false)
|
|
2211
2420
|
});
|
|
2212
2421
|
var buildDecorations6 = (view) => {
|
|
2213
|
-
const builder = new
|
|
2422
|
+
const builder = new RangeSetBuilder7();
|
|
2214
2423
|
const { state } = view;
|
|
2215
2424
|
const cursor = state.selection.main.head;
|
|
2216
2425
|
for (const { from, to } of view.visibleRanges) {
|
|
2217
|
-
|
|
2426
|
+
syntaxTree8(state).iterate({
|
|
2218
2427
|
enter: (node) => {
|
|
2219
2428
|
if (node.name === "TaskMarker") {
|
|
2220
2429
|
if (cursor < node.from || cursor > node.to) {
|
|
2221
2430
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2222
|
-
builder.add(node.from - 2, node.from - 1,
|
|
2431
|
+
builder.add(node.from - 2, node.from - 1, Decoration10.mark({
|
|
2223
2432
|
class: "cm-task"
|
|
2224
2433
|
}));
|
|
2225
2434
|
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
@@ -2234,7 +2443,7 @@ var buildDecorations6 = (view) => {
|
|
|
2234
2443
|
};
|
|
2235
2444
|
var tasklist = (options = {}) => {
|
|
2236
2445
|
return [
|
|
2237
|
-
|
|
2446
|
+
ViewPlugin8.fromClass(class {
|
|
2238
2447
|
constructor(view) {
|
|
2239
2448
|
this.decorations = buildDecorations6(view);
|
|
2240
2449
|
}
|
|
@@ -2285,7 +2494,7 @@ var outliner = (options = {}) => {
|
|
|
2285
2494
|
};
|
|
2286
2495
|
|
|
2287
2496
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
2288
|
-
import { keymap as
|
|
2497
|
+
import { keymap as keymap6 } from "@codemirror/view";
|
|
2289
2498
|
var defaultItems = [
|
|
2290
2499
|
"hello world!",
|
|
2291
2500
|
"this is a test.",
|
|
@@ -2295,7 +2504,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2295
2504
|
let t;
|
|
2296
2505
|
let idx = 0;
|
|
2297
2506
|
return [
|
|
2298
|
-
|
|
2507
|
+
keymap6.of([
|
|
2299
2508
|
{
|
|
2300
2509
|
// Reset.
|
|
2301
2510
|
key: "alt-meta-'",
|
|
@@ -2372,8 +2581,9 @@ var defaultTheme = {
|
|
|
2372
2581
|
outline: "none"
|
|
2373
2582
|
},
|
|
2374
2583
|
".cm-scroller": {
|
|
2375
|
-
overflow:
|
|
2376
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2584
|
+
// overflow: 'visible',
|
|
2585
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2586
|
+
lineHeight: 1.4
|
|
2377
2587
|
},
|
|
2378
2588
|
".cm-content": {
|
|
2379
2589
|
padding: 0,
|
|
@@ -2397,8 +2607,11 @@ var defaultTheme = {
|
|
|
2397
2607
|
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
2398
2608
|
borderLeft: "2px solid white"
|
|
2399
2609
|
},
|
|
2400
|
-
".cm-placeholder": {
|
|
2401
|
-
|
|
2610
|
+
"&light .cm-placeholder": {
|
|
2611
|
+
color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
2612
|
+
},
|
|
2613
|
+
"&dark .cm-placeholder": {
|
|
2614
|
+
color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
2402
2615
|
},
|
|
2403
2616
|
//
|
|
2404
2617
|
// line
|
|
@@ -2407,7 +2620,7 @@ var defaultTheme = {
|
|
|
2407
2620
|
paddingInline: 0
|
|
2408
2621
|
},
|
|
2409
2622
|
".cm-activeLine": {
|
|
2410
|
-
background: "
|
|
2623
|
+
background: "transparent"
|
|
2411
2624
|
},
|
|
2412
2625
|
//
|
|
2413
2626
|
// Selection
|
|
@@ -2578,15 +2791,12 @@ var codeTheme = {
|
|
|
2578
2791
|
};
|
|
2579
2792
|
|
|
2580
2793
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2581
|
-
var
|
|
2794
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2582
2795
|
var EditorModes = [
|
|
2583
2796
|
"default",
|
|
2584
2797
|
"vim"
|
|
2585
2798
|
];
|
|
2586
2799
|
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
2800
|
const { themeMode } = useThemeContext();
|
|
2591
2801
|
const rootRef = useRef(null);
|
|
2592
2802
|
const [view, setView] = useState(null);
|
|
@@ -2594,7 +2804,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2594
2804
|
view
|
|
2595
2805
|
]);
|
|
2596
2806
|
useEffect2(() => {
|
|
2597
|
-
if (autoFocus) {
|
|
2807
|
+
if (autoFocus && !view?.hasFocus) {
|
|
2808
|
+
if (view?.state.selection.main?.from === 0) {
|
|
2809
|
+
const { to } = view.state.doc.lineAt(0);
|
|
2810
|
+
view?.dispatch({
|
|
2811
|
+
selection: {
|
|
2812
|
+
anchor: to
|
|
2813
|
+
}
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2598
2816
|
view?.focus();
|
|
2599
2817
|
}
|
|
2600
2818
|
}, [
|
|
@@ -2612,8 +2830,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2612
2830
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2613
2831
|
EditorView13.exceptionSink.of((err) => {
|
|
2614
2832
|
log2.catch(err, void 0, {
|
|
2615
|
-
F:
|
|
2616
|
-
L:
|
|
2833
|
+
F: __dxlog_file3,
|
|
2834
|
+
L: 134,
|
|
2617
2835
|
S: void 0,
|
|
2618
2836
|
C: (f, a) => f(...a)
|
|
2619
2837
|
});
|
|
@@ -2630,15 +2848,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2630
2848
|
class: slots.content?.className ?? ""
|
|
2631
2849
|
}),
|
|
2632
2850
|
// State.
|
|
2851
|
+
EditorView13.editable.of(!readonly),
|
|
2633
2852
|
EditorState2.readOnly.of(!!readonly),
|
|
2634
2853
|
// Storage and replication.
|
|
2635
2854
|
// NOTE: This must come before user extensions.
|
|
2636
2855
|
model.extension,
|
|
2637
|
-
// TODO(burdon): Factor out (
|
|
2856
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2638
2857
|
editorMode === "vim" && vim(),
|
|
2639
2858
|
// Custom.
|
|
2640
2859
|
...extensions
|
|
2641
|
-
].filter(
|
|
2860
|
+
].filter(isNotFalsy3)
|
|
2642
2861
|
});
|
|
2643
2862
|
const newView = new EditorView13({
|
|
2644
2863
|
state,
|
|
@@ -2675,7 +2894,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2675
2894
|
}
|
|
2676
2895
|
case "Escape": {
|
|
2677
2896
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2678
|
-
|
|
2897
|
+
view?.focus();
|
|
2679
2898
|
}
|
|
2680
2899
|
break;
|
|
2681
2900
|
}
|
|
@@ -2688,9 +2907,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2688
2907
|
key: model.id,
|
|
2689
2908
|
role: "none",
|
|
2690
2909
|
tabIndex: 0,
|
|
2691
|
-
onKeyUp: handleKeyUp,
|
|
2692
2910
|
...slots.root,
|
|
2693
|
-
...editorMode !==
|
|
2911
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2912
|
+
onKeyUp: handleKeyUp,
|
|
2694
2913
|
ref: rootRef
|
|
2695
2914
|
});
|
|
2696
2915
|
});
|
|
@@ -2701,7 +2920,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2701
2920
|
ref: forwardedRef,
|
|
2702
2921
|
readonly,
|
|
2703
2922
|
extensions: [
|
|
2704
|
-
|
|
2923
|
+
createBasicBundle({
|
|
2705
2924
|
themeMode,
|
|
2706
2925
|
placeholder: placeholder3,
|
|
2707
2926
|
lineWrapping
|
|
@@ -2720,7 +2939,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2720
2939
|
ref: forwardedRef,
|
|
2721
2940
|
readonly,
|
|
2722
2941
|
extensions: [
|
|
2723
|
-
|
|
2942
|
+
createMarkdownExtensions({
|
|
2724
2943
|
themeMode,
|
|
2725
2944
|
placeholder: placeholder3
|
|
2726
2945
|
}),
|
|
@@ -2733,11 +2952,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2733
2952
|
});
|
|
2734
2953
|
var defaultSlots = {
|
|
2735
2954
|
root: {
|
|
2736
|
-
|
|
2737
|
-
className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
|
|
2955
|
+
className: mx3("grow", focusRing)
|
|
2738
2956
|
},
|
|
2739
2957
|
editor: {
|
|
2740
|
-
className: "
|
|
2958
|
+
className: "bs-full"
|
|
2741
2959
|
}
|
|
2742
2960
|
};
|
|
2743
2961
|
var defaultTextSlots = {
|
|
@@ -2747,12 +2965,173 @@ var defaultMarkdownSlots = {
|
|
|
2747
2965
|
...defaultSlots
|
|
2748
2966
|
};
|
|
2749
2967
|
|
|
2968
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
2969
|
+
import { At, CaretRight, ChatText, Code, Image, Link, ListBullets, ListChecks, ListNumbers, TextStrikethrough, Table as Table2, TextB, TextItalic } from "@phosphor-icons/react";
|
|
2970
|
+
import { createContext } from "@radix-ui/react-context";
|
|
2971
|
+
import React2 from "react";
|
|
2972
|
+
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
2973
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
2974
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
2975
|
+
var ToolbarRoot = ({ children, onAction }) => {
|
|
2976
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
2977
|
+
onAction
|
|
2978
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
2979
|
+
density: "fine"
|
|
2980
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
2981
|
+
role: "toolbar",
|
|
2982
|
+
className: "flex w-full shrink-0 p-2 gap-4 items-center whitespace-nowrap overflow-hidden"
|
|
2983
|
+
}, children)));
|
|
2984
|
+
};
|
|
2985
|
+
var ToolbarButton = ({ Icon, onClick, title }) => {
|
|
2986
|
+
const { onAction } = useToolbarContext("ToolbarButton");
|
|
2987
|
+
const handleClick = () => {
|
|
2988
|
+
const action = onClick();
|
|
2989
|
+
if (action) {
|
|
2990
|
+
onAction?.(action);
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
return /* @__PURE__ */ React2.createElement(Button, {
|
|
2994
|
+
variant: "ghost",
|
|
2995
|
+
classNames: "p-2",
|
|
2996
|
+
onClick: handleClick,
|
|
2997
|
+
title
|
|
2998
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
2999
|
+
className: getSize(5)
|
|
3000
|
+
}));
|
|
3001
|
+
};
|
|
3002
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3003
|
+
className: "grow"
|
|
3004
|
+
});
|
|
3005
|
+
var MarkdownHeading = () => {
|
|
3006
|
+
const { onAction } = useToolbarContext("MarkdownFormatting");
|
|
3007
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3008
|
+
defaultValue: "0",
|
|
3009
|
+
onValueChange: (value) => onAction?.({
|
|
3010
|
+
type: "heading",
|
|
3011
|
+
data: parseInt(value)
|
|
3012
|
+
})
|
|
3013
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
3014
|
+
classNames: "w-[8rem]"
|
|
3015
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3016
|
+
value: "0"
|
|
3017
|
+
}, "Paragraph"), [
|
|
3018
|
+
1,
|
|
3019
|
+
2,
|
|
3020
|
+
3,
|
|
3021
|
+
4,
|
|
3022
|
+
5,
|
|
3023
|
+
6
|
|
3024
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3025
|
+
key: level,
|
|
3026
|
+
value: String(level)
|
|
3027
|
+
}, "Heading ", level))))));
|
|
3028
|
+
};
|
|
3029
|
+
var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3030
|
+
role: "none"
|
|
3031
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3032
|
+
Icon: TextB,
|
|
3033
|
+
title: "Bold",
|
|
3034
|
+
onClick: () => ({
|
|
3035
|
+
type: "bold"
|
|
3036
|
+
})
|
|
3037
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3038
|
+
Icon: TextItalic,
|
|
3039
|
+
title: "Italic",
|
|
3040
|
+
onClick: () => ({
|
|
3041
|
+
type: "italic"
|
|
3042
|
+
})
|
|
3043
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3044
|
+
Icon: TextStrikethrough,
|
|
3045
|
+
title: "Strike-through",
|
|
3046
|
+
onClick: () => ({
|
|
3047
|
+
type: "strikethrough"
|
|
3048
|
+
})
|
|
3049
|
+
}));
|
|
3050
|
+
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3051
|
+
role: "none"
|
|
3052
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3053
|
+
Icon: ListBullets,
|
|
3054
|
+
title: "Bullet list",
|
|
3055
|
+
onClick: () => ({
|
|
3056
|
+
type: "list"
|
|
3057
|
+
})
|
|
3058
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3059
|
+
Icon: ListNumbers,
|
|
3060
|
+
title: "Numbered list",
|
|
3061
|
+
onClick: () => ({
|
|
3062
|
+
type: "list-ordered"
|
|
3063
|
+
})
|
|
3064
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3065
|
+
Icon: ListChecks,
|
|
3066
|
+
title: "Task list",
|
|
3067
|
+
onClick: () => ({
|
|
3068
|
+
type: "list-tasks"
|
|
3069
|
+
})
|
|
3070
|
+
}));
|
|
3071
|
+
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3072
|
+
role: "none"
|
|
3073
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3074
|
+
Icon: CaretRight,
|
|
3075
|
+
title: "Block quite",
|
|
3076
|
+
onClick: () => ({
|
|
3077
|
+
type: "blockquote"
|
|
3078
|
+
})
|
|
3079
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3080
|
+
Icon: Code,
|
|
3081
|
+
title: "Code block",
|
|
3082
|
+
onClick: () => ({
|
|
3083
|
+
type: "codeblock"
|
|
3084
|
+
})
|
|
3085
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3086
|
+
Icon: Table2,
|
|
3087
|
+
title: "Table",
|
|
3088
|
+
onClick: () => ({
|
|
3089
|
+
type: "table"
|
|
3090
|
+
})
|
|
3091
|
+
}));
|
|
3092
|
+
var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3093
|
+
role: "none"
|
|
3094
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3095
|
+
Icon: Link,
|
|
3096
|
+
title: "Link",
|
|
3097
|
+
onClick: () => ({
|
|
3098
|
+
type: "link"
|
|
3099
|
+
})
|
|
3100
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3101
|
+
Icon: At,
|
|
3102
|
+
title: "Mention",
|
|
3103
|
+
onClick: () => ({
|
|
3104
|
+
type: "mention"
|
|
3105
|
+
})
|
|
3106
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3107
|
+
Icon: Image,
|
|
3108
|
+
title: "Image",
|
|
3109
|
+
onClick: () => ({
|
|
3110
|
+
type: "image"
|
|
3111
|
+
})
|
|
3112
|
+
}));
|
|
3113
|
+
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));
|
|
3114
|
+
var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
|
|
3115
|
+
Icon: ChatText,
|
|
3116
|
+
title: "Create comment",
|
|
3117
|
+
onClick: () => ({
|
|
3118
|
+
type: "comment"
|
|
3119
|
+
})
|
|
3120
|
+
});
|
|
3121
|
+
var Toolbar = {
|
|
3122
|
+
Root: ToolbarRoot,
|
|
3123
|
+
Button: ToolbarButton,
|
|
3124
|
+
Separator: ToolbarSeparator,
|
|
3125
|
+
Markdown: MarkdownStandard,
|
|
3126
|
+
Extended: MarkdownExtended
|
|
3127
|
+
};
|
|
3128
|
+
|
|
2750
3129
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2751
3130
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2752
3131
|
import { Context as Context2 } from "@dxos/context";
|
|
2753
|
-
import { invariant as
|
|
3132
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2754
3133
|
import { log as log3 } from "@dxos/log";
|
|
2755
|
-
var
|
|
3134
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2756
3135
|
var DEBOUNCE_INTERVAL = 100;
|
|
2757
3136
|
var SpaceAwarenessProvider = class {
|
|
2758
3137
|
constructor(params) {
|
|
@@ -2792,7 +3171,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2792
3171
|
log3.debug("failed to query awareness", {
|
|
2793
3172
|
err
|
|
2794
3173
|
}, {
|
|
2795
|
-
F:
|
|
3174
|
+
F: __dxlog_file4,
|
|
2796
3175
|
L: 89,
|
|
2797
3176
|
S: this,
|
|
2798
3177
|
C: (f, a) => f(...a)
|
|
@@ -2808,8 +3187,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2808
3187
|
return Array.from(this._remoteStates.values());
|
|
2809
3188
|
}
|
|
2810
3189
|
update(position) {
|
|
2811
|
-
|
|
2812
|
-
F:
|
|
3190
|
+
invariant2(this._postTask, void 0, {
|
|
3191
|
+
F: __dxlog_file4,
|
|
2813
3192
|
L: 104,
|
|
2814
3193
|
S: this,
|
|
2815
3194
|
A: [
|
|
@@ -2825,8 +3204,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2825
3204
|
this._postTask.schedule();
|
|
2826
3205
|
}
|
|
2827
3206
|
_handleQueryMessage() {
|
|
2828
|
-
|
|
2829
|
-
F:
|
|
3207
|
+
invariant2(this._postTask, void 0, {
|
|
3208
|
+
F: __dxlog_file4,
|
|
2830
3209
|
L: 115,
|
|
2831
3210
|
S: this,
|
|
2832
3211
|
A: [
|
|
@@ -2837,8 +3216,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2837
3216
|
this._postTask.schedule();
|
|
2838
3217
|
}
|
|
2839
3218
|
_handlePostMessage(message) {
|
|
2840
|
-
|
|
2841
|
-
F:
|
|
3219
|
+
invariant2(message.kind === "post", void 0, {
|
|
3220
|
+
F: __dxlog_file4,
|
|
2842
3221
|
L: 120,
|
|
2843
3222
|
S: this,
|
|
2844
3223
|
A: [
|
|
@@ -2858,9 +3237,50 @@ var modelState = StateField5.define({
|
|
|
2858
3237
|
update: (model) => model
|
|
2859
3238
|
});
|
|
2860
3239
|
|
|
2861
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
3240
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3241
|
+
var useActionHandler = (view) => {
|
|
3242
|
+
return (action) => {
|
|
3243
|
+
if (!view) {
|
|
3244
|
+
return;
|
|
3245
|
+
}
|
|
3246
|
+
switch (action.type) {
|
|
3247
|
+
case "heading":
|
|
3248
|
+
setHeading(parseInt(action.data))(view);
|
|
3249
|
+
break;
|
|
3250
|
+
case "bold":
|
|
3251
|
+
toggleBold(view);
|
|
3252
|
+
break;
|
|
3253
|
+
case "italic":
|
|
3254
|
+
toggleItalic(view);
|
|
3255
|
+
break;
|
|
3256
|
+
case "strikethrough":
|
|
3257
|
+
toggleStrikethrough(view);
|
|
3258
|
+
break;
|
|
3259
|
+
case "list":
|
|
3260
|
+
toggleList(view);
|
|
3261
|
+
break;
|
|
3262
|
+
case "codeblock":
|
|
3263
|
+
insertCodeblock(view);
|
|
3264
|
+
break;
|
|
3265
|
+
case "table":
|
|
3266
|
+
insertTable(view);
|
|
3267
|
+
break;
|
|
3268
|
+
case "comment":
|
|
3269
|
+
createComment(view);
|
|
3270
|
+
break;
|
|
3271
|
+
}
|
|
3272
|
+
setTimeout(() => {
|
|
3273
|
+
view.focus();
|
|
3274
|
+
view.dispatch({
|
|
3275
|
+
selection: view.state.selection
|
|
3276
|
+
});
|
|
3277
|
+
});
|
|
3278
|
+
};
|
|
3279
|
+
};
|
|
3280
|
+
|
|
3281
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
2862
3282
|
import { useState as useState2 } from "react";
|
|
2863
|
-
var
|
|
3283
|
+
var useEditorView = () => {
|
|
2864
3284
|
const [view, setView] = useState2(null);
|
|
2865
3285
|
return [
|
|
2866
3286
|
(ref) => {
|
|
@@ -2870,29 +3290,144 @@ var useTextEditor = () => {
|
|
|
2870
3290
|
];
|
|
2871
3291
|
};
|
|
2872
3292
|
|
|
3293
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3294
|
+
import { EditorSelection, EditorState as EditorState3 } from "@codemirror/state";
|
|
3295
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
3296
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
3297
|
+
import { log as log4 } from "@dxos/log";
|
|
3298
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
3299
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
3300
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
3301
|
+
const onUpdate = useRef2();
|
|
3302
|
+
const [view, setView] = useState3();
|
|
3303
|
+
const parentRef = useRef2(null);
|
|
3304
|
+
useEffect3(() => {
|
|
3305
|
+
if (parentRef.current) {
|
|
3306
|
+
const state = EditorState3.create({
|
|
3307
|
+
doc,
|
|
3308
|
+
selection,
|
|
3309
|
+
extensions: [
|
|
3310
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3311
|
+
EditorView14.exceptionSink.of((err) => {
|
|
3312
|
+
log4.catch(err, void 0, {
|
|
3313
|
+
F: __dxlog_file5,
|
|
3314
|
+
L: 57,
|
|
3315
|
+
S: void 0,
|
|
3316
|
+
C: (f, a) => f(...a)
|
|
3317
|
+
});
|
|
3318
|
+
}),
|
|
3319
|
+
extensions,
|
|
3320
|
+
EditorView14.updateListener.of(() => {
|
|
3321
|
+
onUpdate.current?.();
|
|
3322
|
+
})
|
|
3323
|
+
].filter(isNotFalsy4)
|
|
3324
|
+
});
|
|
3325
|
+
const view2 = new EditorView14({
|
|
3326
|
+
parent: parentRef.current,
|
|
3327
|
+
scrollTo,
|
|
3328
|
+
state,
|
|
3329
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3330
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3331
|
+
dispatchTransactions: (trs, view3) => {
|
|
3332
|
+
if (debug) {
|
|
3333
|
+
logChanges(trs);
|
|
3334
|
+
}
|
|
3335
|
+
view3.update(trs);
|
|
3336
|
+
}
|
|
3337
|
+
});
|
|
3338
|
+
setView(view2);
|
|
3339
|
+
}
|
|
3340
|
+
return () => {
|
|
3341
|
+
view?.destroy();
|
|
3342
|
+
};
|
|
3343
|
+
}, [
|
|
3344
|
+
parentRef
|
|
3345
|
+
]);
|
|
3346
|
+
useEffect3(() => {
|
|
3347
|
+
if (view) {
|
|
3348
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
3349
|
+
selection = EditorSelection.single(view.state.doc.line(1).to);
|
|
3350
|
+
}
|
|
3351
|
+
if (selection || scrollTo) {
|
|
3352
|
+
onUpdate.current = () => {
|
|
3353
|
+
onUpdate.current = void 0;
|
|
3354
|
+
view.dispatch({
|
|
3355
|
+
selection,
|
|
3356
|
+
effects: scrollTo && [
|
|
3357
|
+
scrollTo
|
|
3358
|
+
],
|
|
3359
|
+
scrollIntoView: !scrollTo
|
|
3360
|
+
});
|
|
3361
|
+
};
|
|
3362
|
+
}
|
|
3363
|
+
if (autoFocus) {
|
|
3364
|
+
view.focus();
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
}, [
|
|
3368
|
+
view,
|
|
3369
|
+
autoFocus,
|
|
3370
|
+
selection,
|
|
3371
|
+
scrollTo
|
|
3372
|
+
]);
|
|
3373
|
+
return {
|
|
3374
|
+
parentRef,
|
|
3375
|
+
view
|
|
3376
|
+
};
|
|
3377
|
+
};
|
|
3378
|
+
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
3379
|
+
return [
|
|
3380
|
+
//
|
|
3381
|
+
EditorState3.readOnly.of(readonly),
|
|
3382
|
+
EditorView14.editable.of(!readonly)
|
|
3383
|
+
];
|
|
3384
|
+
};
|
|
3385
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
3386
|
+
return [
|
|
3387
|
+
//
|
|
3388
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3389
|
+
theme && EditorView14.theme(theme),
|
|
3390
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3391
|
+
EditorView14.editorAttributes.of({
|
|
3392
|
+
class: slots?.editor?.className ?? ""
|
|
3393
|
+
}),
|
|
3394
|
+
EditorView14.contentAttributes.of({
|
|
3395
|
+
class: slots?.content?.className ?? ""
|
|
3396
|
+
})
|
|
3397
|
+
].filter(isNotFalsy4);
|
|
3398
|
+
};
|
|
3399
|
+
|
|
2873
3400
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
2874
3401
|
import get4 from "lodash.get";
|
|
2875
|
-
import { useEffect as
|
|
3402
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2876
3403
|
import { generateName } from "@dxos/display-name";
|
|
2877
3404
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
2878
|
-
import { invariant as
|
|
3405
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2879
3406
|
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";
|
|
3407
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
2882
3408
|
var useTextModel = (props) => {
|
|
2883
3409
|
const { identity, space, text } = props;
|
|
2884
|
-
const [model, setModel] =
|
|
2885
|
-
|
|
3410
|
+
const [model, setModel] = useState4();
|
|
3411
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
2886
3412
|
identity,
|
|
2887
3413
|
space,
|
|
2888
3414
|
text
|
|
2889
3415
|
]);
|
|
2890
3416
|
return model;
|
|
2891
3417
|
};
|
|
3418
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
3419
|
+
const [content, setContent] = useState4(defaultContent ?? "");
|
|
3420
|
+
return {
|
|
3421
|
+
id,
|
|
3422
|
+
content,
|
|
3423
|
+
setContent,
|
|
3424
|
+
text: () => content
|
|
3425
|
+
};
|
|
3426
|
+
};
|
|
2892
3427
|
var createModel = ({ space, identity, text }) => {
|
|
2893
|
-
|
|
2894
|
-
F:
|
|
2895
|
-
L:
|
|
3428
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3429
|
+
F: __dxlog_file6,
|
|
3430
|
+
L: 50,
|
|
2896
3431
|
S: void 0,
|
|
2897
3432
|
A: [
|
|
2898
3433
|
"isAutomergeObject(text)",
|
|
@@ -2903,7 +3438,7 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2903
3438
|
const doc = getRawDoc(obj, [
|
|
2904
3439
|
obj.field
|
|
2905
3440
|
]);
|
|
2906
|
-
const
|
|
3441
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
2907
3442
|
space,
|
|
2908
3443
|
channel: `automerge.awareness.${obj.id}`,
|
|
2909
3444
|
info: {
|
|
@@ -2913,19 +3448,22 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2913
3448
|
},
|
|
2914
3449
|
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
2915
3450
|
});
|
|
3451
|
+
const extensions = [
|
|
3452
|
+
//
|
|
3453
|
+
modelState.init(() => model),
|
|
3454
|
+
automerge({
|
|
3455
|
+
handle: doc.handle,
|
|
3456
|
+
path: doc.path
|
|
3457
|
+
})
|
|
3458
|
+
];
|
|
3459
|
+
if (awarenessProvider2) {
|
|
3460
|
+
extensions.push(awareness(awarenessProvider2));
|
|
3461
|
+
}
|
|
2916
3462
|
const model = {
|
|
2917
3463
|
id: obj.id,
|
|
2918
3464
|
content: doc,
|
|
2919
3465
|
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),
|
|
3466
|
+
extension: extensions,
|
|
2929
3467
|
peer: identity ? {
|
|
2930
3468
|
id: identity.identityKey.toHex(),
|
|
2931
3469
|
name: identity.profile?.displayName
|
|
@@ -2934,7 +3472,6 @@ var createModel = ({ space, identity, text }) => {
|
|
|
2934
3472
|
return model;
|
|
2935
3473
|
};
|
|
2936
3474
|
export {
|
|
2937
|
-
AwarenessProvider,
|
|
2938
3475
|
BaseTextEditor,
|
|
2939
3476
|
Cursor,
|
|
2940
3477
|
Doc,
|
|
@@ -2944,30 +3481,40 @@ export {
|
|
|
2944
3481
|
SpaceAwarenessProvider,
|
|
2945
3482
|
TextEditor,
|
|
2946
3483
|
TextKind,
|
|
3484
|
+
Toolbar,
|
|
2947
3485
|
YText,
|
|
2948
3486
|
YXmlFragment,
|
|
2949
3487
|
autocomplete,
|
|
2950
|
-
|
|
3488
|
+
automerge,
|
|
2951
3489
|
awareness,
|
|
2952
|
-
|
|
3490
|
+
awarenessProvider,
|
|
2953
3491
|
blast,
|
|
2954
3492
|
callbackWrapper,
|
|
2955
3493
|
code2 as code,
|
|
2956
3494
|
codeTheme,
|
|
2957
3495
|
comments,
|
|
3496
|
+
createBasicBundle,
|
|
3497
|
+
createComment,
|
|
3498
|
+
createDataExtensions,
|
|
3499
|
+
createMarkdownExtensions,
|
|
3500
|
+
createThemeExtensions,
|
|
2958
3501
|
defaultMarkdownSlots,
|
|
2959
3502
|
defaultOptions,
|
|
2960
3503
|
defaultSlots,
|
|
2961
3504
|
defaultTextSlots,
|
|
2962
3505
|
defaultTheme,
|
|
3506
|
+
focusComment,
|
|
3507
|
+
formatting,
|
|
2963
3508
|
getToken,
|
|
2964
3509
|
heading2 as heading,
|
|
2965
3510
|
hr,
|
|
2966
3511
|
image,
|
|
3512
|
+
insertCodeblock,
|
|
3513
|
+
insertTable,
|
|
3514
|
+
keymap7 as keymap,
|
|
2967
3515
|
link,
|
|
2968
3516
|
listener,
|
|
2969
3517
|
logChanges,
|
|
2970
|
-
markdownBundle,
|
|
2971
3518
|
markdownHighlightStyle,
|
|
2972
3519
|
markdownTags,
|
|
2973
3520
|
markdownTagsExtensions,
|
|
@@ -2976,15 +3523,24 @@ export {
|
|
|
2976
3523
|
modelState,
|
|
2977
3524
|
outliner,
|
|
2978
3525
|
setComments,
|
|
2979
|
-
|
|
3526
|
+
setHeading,
|
|
2980
3527
|
setSelection,
|
|
2981
3528
|
table,
|
|
2982
3529
|
tags2 as tags,
|
|
2983
3530
|
tasklist,
|
|
2984
3531
|
textTheme,
|
|
3532
|
+
toggleBold,
|
|
3533
|
+
toggleItalic,
|
|
3534
|
+
toggleList,
|
|
3535
|
+
toggleStrikethrough,
|
|
3536
|
+
toggleStyle,
|
|
2985
3537
|
typewriter,
|
|
3538
|
+
useActionHandler,
|
|
2986
3539
|
useComments,
|
|
3540
|
+
useEditorView,
|
|
3541
|
+
useInMemoryTextModel,
|
|
2987
3542
|
useTextEditor,
|
|
2988
|
-
useTextModel
|
|
3543
|
+
useTextModel,
|
|
3544
|
+
useToolbarContext
|
|
2989
3545
|
};
|
|
2990
3546
|
//# sourceMappingURL=index.mjs.map
|