@dxos/react-ui-editor 0.3.11-main.73ee990 → 0.3.11-main.764a9c1
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 +1649 -234
- 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 +27 -7
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +12 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- 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 +55 -8
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- 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 +39 -26
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +5 -6
- package/src/components/TextEditor/TextEditor.tsx +26 -16
- package/src/components/TextEditor/automerge.stories.tsx +1 -2
- package/src/components/TextEditor/hooks.stories.tsx +111 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +22 -6
- package/src/components/Toolbar/Toolbar.tsx +224 -75
- 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 +27 -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 +9 -9
- 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 +84 -30
- package/src/extensions/markdown/bundle.ts +10 -5
- package/src/extensions/markdown/code.ts +12 -4
- package/src/extensions/markdown/formatting.test.ts +482 -0
- package/src/extensions/markdown/formatting.ts +1133 -55
- package/src/extensions/markdown/link.ts +8 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useActionHandler.ts +61 -13
- 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 +10 -5
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +0 -1
- package/src/components/TextEditor/comments.stories.tsx +0 -357
|
@@ -1,20 +1,21 @@
|
|
|
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";
|
|
7
8
|
|
|
8
9
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
9
10
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
10
|
-
import { EditorView as
|
|
11
|
-
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
11
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
12
12
|
import { vim } from "@replit/codemirror-vim";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
|
-
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } 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,18 +125,18 @@ var updateAutomerge = (field, handle, transactions, state) => {
|
|
|
122
125
|
return void 0;
|
|
123
126
|
}
|
|
124
127
|
const newHeads = handle.changeAt(lastHeads, (doc) => {
|
|
125
|
-
const
|
|
128
|
+
const invertedTransactions = [];
|
|
126
129
|
for (const tr of transactions) {
|
|
127
130
|
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
128
|
-
|
|
129
|
-
fromA,
|
|
130
|
-
toA,
|
|
131
|
+
invertedTransactions.push({
|
|
132
|
+
from: fromA,
|
|
133
|
+
del: toA - fromA,
|
|
131
134
|
insert
|
|
132
135
|
});
|
|
133
136
|
});
|
|
134
137
|
}
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
139
|
+
A2.splice(doc, path.slice(), from, del, insert.toString());
|
|
137
140
|
});
|
|
138
141
|
});
|
|
139
142
|
return newHeads ?? void 0;
|
|
@@ -149,13 +152,13 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
149
152
|
selection = selection.map(changeSet, 1);
|
|
150
153
|
view.dispatch({
|
|
151
154
|
changes: changeSet,
|
|
152
|
-
annotations:
|
|
155
|
+
annotations: reconcileAnnotation.of(false)
|
|
153
156
|
});
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
view.dispatch({
|
|
157
160
|
selection,
|
|
158
|
-
annotations:
|
|
161
|
+
annotations: reconcileAnnotation.of(false)
|
|
159
162
|
});
|
|
160
163
|
};
|
|
161
164
|
var handlePatch = (patch, target, state) => {
|
|
@@ -176,7 +179,7 @@ var handleInsert = (target, patch) => {
|
|
|
176
179
|
if (index == null) {
|
|
177
180
|
return [];
|
|
178
181
|
}
|
|
179
|
-
const text = patch.values.map((
|
|
182
|
+
const text = patch.values.map((value) => value ? value.toString() : "").join("");
|
|
180
183
|
return [
|
|
181
184
|
{
|
|
182
185
|
from: index,
|
|
@@ -254,36 +257,37 @@ var PatchSemaphore = class {
|
|
|
254
257
|
this._state = _state;
|
|
255
258
|
this._inReconcile = false;
|
|
256
259
|
}
|
|
257
|
-
// NOTE: Cannot destruct view.state.
|
|
258
260
|
reconcile(view) {
|
|
259
|
-
if (this._inReconcile) {
|
|
260
|
-
|
|
261
|
+
if (!this._inReconcile) {
|
|
262
|
+
this._inReconcile = true;
|
|
263
|
+
this.doReconcile(view);
|
|
264
|
+
this._inReconcile = false;
|
|
261
265
|
}
|
|
262
|
-
|
|
266
|
+
}
|
|
267
|
+
doReconcile(view) {
|
|
263
268
|
const path = getPath(view.state, this._state);
|
|
264
269
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
265
270
|
let selection = view.state.selection;
|
|
266
|
-
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !
|
|
271
|
+
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
267
272
|
const toInvert = transactions.slice().reverse();
|
|
268
|
-
for (const
|
|
269
|
-
const inverted =
|
|
273
|
+
for (const tr of toInvert) {
|
|
274
|
+
const inverted = tr.changes.invert(tr.startState.doc);
|
|
270
275
|
selection = selection.map(inverted);
|
|
271
276
|
view.dispatch({
|
|
272
277
|
changes: inverted,
|
|
273
|
-
annotations:
|
|
278
|
+
annotations: reconcileAnnotation.of(true)
|
|
274
279
|
});
|
|
275
280
|
}
|
|
276
281
|
let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
277
282
|
if (newHeads === null || newHeads === void 0) {
|
|
278
|
-
newHeads =
|
|
283
|
+
newHeads = A3.getHeads(this._handle.docSync());
|
|
279
284
|
}
|
|
280
|
-
const diff =
|
|
285
|
+
const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
|
|
281
286
|
updateCodeMirror(view, selection, path, diff);
|
|
282
287
|
view.dispatch({
|
|
283
288
|
effects: updateHeads(newHeads),
|
|
284
|
-
annotations:
|
|
289
|
+
annotations: reconcileAnnotation.of(false)
|
|
285
290
|
});
|
|
286
|
-
this._inReconcile = false;
|
|
287
291
|
}
|
|
288
292
|
};
|
|
289
293
|
|
|
@@ -325,12 +329,11 @@ var Cursor = class _Cursor {
|
|
|
325
329
|
};
|
|
326
330
|
|
|
327
331
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
328
|
-
var
|
|
329
|
-
|
|
330
|
-
const state = StateField.define({
|
|
332
|
+
var automerge = ({ handle, path }) => {
|
|
333
|
+
const syncState = StateField.define({
|
|
331
334
|
create: () => ({
|
|
332
335
|
path: path.slice(),
|
|
333
|
-
lastHeads:
|
|
336
|
+
lastHeads: A4.getHeads(handle.docSync()),
|
|
334
337
|
unreconciledTransactions: []
|
|
335
338
|
}),
|
|
336
339
|
update: (value, tr) => {
|
|
@@ -341,7 +344,7 @@ var automerge4 = ({ handle, path }) => {
|
|
|
341
344
|
};
|
|
342
345
|
let clearUnreconciled = false;
|
|
343
346
|
for (const effect of tr.effects) {
|
|
344
|
-
if (effect.is(
|
|
347
|
+
if (effect.is(updateHeadsEffect)) {
|
|
345
348
|
result.lastHeads = effect.value.newHeads;
|
|
346
349
|
clearUnreconciled = true;
|
|
347
350
|
}
|
|
@@ -349,29 +352,21 @@ var automerge4 = ({ handle, path }) => {
|
|
|
349
352
|
if (clearUnreconciled) {
|
|
350
353
|
result.unreconciledTransactions = [];
|
|
351
354
|
} else {
|
|
352
|
-
if (!
|
|
355
|
+
if (!isReconcile(tr)) {
|
|
353
356
|
result.unreconciledTransactions.push(tr);
|
|
354
357
|
}
|
|
355
358
|
}
|
|
356
359
|
return result;
|
|
357
360
|
}
|
|
358
361
|
});
|
|
359
|
-
const semaphore = new PatchSemaphore(handle,
|
|
362
|
+
const semaphore = new PatchSemaphore(handle, syncState);
|
|
360
363
|
return [
|
|
361
364
|
Cursor.converter.of(cursorConverter(handle, path)),
|
|
365
|
+
syncState,
|
|
362
366
|
// Reconcile external updates.
|
|
363
367
|
ViewPlugin.fromClass(class {
|
|
364
368
|
constructor(_view) {
|
|
365
369
|
this._view = _view;
|
|
366
|
-
invariant(this._view, void 0, {
|
|
367
|
-
F: __dxlog_file,
|
|
368
|
-
L: 66,
|
|
369
|
-
S: this,
|
|
370
|
-
A: [
|
|
371
|
-
"this._view",
|
|
372
|
-
""
|
|
373
|
-
]
|
|
374
|
-
});
|
|
375
370
|
handle.addListener("change", this._handleChange.bind(this));
|
|
376
371
|
}
|
|
377
372
|
destroy() {
|
|
@@ -387,7 +382,17 @@ var automerge4 = ({ handle, path }) => {
|
|
|
387
382
|
semaphore.reconcile(view);
|
|
388
383
|
}
|
|
389
384
|
}),
|
|
390
|
-
|
|
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
|
+
})
|
|
391
396
|
];
|
|
392
397
|
};
|
|
393
398
|
|
|
@@ -406,13 +411,13 @@ var dummyProvider = {
|
|
|
406
411
|
update: () => {
|
|
407
412
|
}
|
|
408
413
|
};
|
|
409
|
-
var
|
|
414
|
+
var awarenessProvider = Facet2.define({
|
|
410
415
|
combine: (providers) => providers[0] ?? dummyProvider
|
|
411
416
|
});
|
|
412
417
|
var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
413
418
|
var awareness = (provider = dummyProvider) => {
|
|
414
419
|
return [
|
|
415
|
-
|
|
420
|
+
awarenessProvider.of(provider),
|
|
416
421
|
ViewPlugin2.fromClass(RemoteSelectionsDecorator, {
|
|
417
422
|
decorations: (value) => value.decorations
|
|
418
423
|
}),
|
|
@@ -426,7 +431,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
426
431
|
this._lastAnchor = void 0;
|
|
427
432
|
this._lastHead = void 0;
|
|
428
433
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
429
|
-
this._provider = view.state.facet(
|
|
434
|
+
this._provider = view.state.facet(awarenessProvider);
|
|
430
435
|
this._provider.open();
|
|
431
436
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
432
437
|
view.dispatch({
|
|
@@ -632,24 +637,25 @@ import { history } from "@codemirror/commands";
|
|
|
632
637
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
633
638
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
634
639
|
import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
635
|
-
|
|
636
|
-
|
|
640
|
+
import { isNotFalsy } from "@dxos/util";
|
|
641
|
+
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
|
|
642
|
+
lineWrapping && EditorView3.lineWrapping,
|
|
637
643
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
638
644
|
bracketMatching(),
|
|
639
645
|
closeBrackets(),
|
|
640
646
|
drawSelection(),
|
|
641
647
|
highlightActiveLine(),
|
|
642
648
|
history(),
|
|
643
|
-
_placeholder
|
|
649
|
+
_placeholder && placeholder(_placeholder),
|
|
644
650
|
// https://github.com/codemirror/theme-one-dark
|
|
645
651
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
646
|
-
];
|
|
652
|
+
].filter(isNotFalsy);
|
|
647
653
|
|
|
648
654
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
649
655
|
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
650
656
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
651
|
-
import { invariant
|
|
652
|
-
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";
|
|
653
659
|
var defaultOptions = {
|
|
654
660
|
effect: 2,
|
|
655
661
|
maxParticles: 200,
|
|
@@ -775,9 +781,9 @@ var Blaster = class {
|
|
|
775
781
|
return this._node;
|
|
776
782
|
}
|
|
777
783
|
initialize() {
|
|
778
|
-
|
|
779
|
-
F:
|
|
780
|
-
L:
|
|
784
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
785
|
+
F: __dxlog_file,
|
|
786
|
+
L: 141,
|
|
781
787
|
S: this,
|
|
782
788
|
A: [
|
|
783
789
|
"!this._canvas && !this._ctx",
|
|
@@ -812,9 +818,9 @@ var Blaster = class {
|
|
|
812
818
|
}
|
|
813
819
|
}
|
|
814
820
|
start() {
|
|
815
|
-
|
|
816
|
-
F:
|
|
817
|
-
L:
|
|
821
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
822
|
+
F: __dxlog_file,
|
|
823
|
+
L: 180,
|
|
818
824
|
S: this,
|
|
819
825
|
A: [
|
|
820
826
|
"this._canvas && this._ctx",
|
|
@@ -956,6 +962,7 @@ var random = (min, max) => {
|
|
|
956
962
|
};
|
|
957
963
|
|
|
958
964
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
965
|
+
import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
|
|
959
966
|
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
960
967
|
import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
|
|
961
968
|
import sortBy from "lodash.sortby";
|
|
@@ -1032,13 +1039,13 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
|
|
|
1032
1039
|
|
|
1033
1040
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1034
1041
|
import { log } from "@dxos/log";
|
|
1035
|
-
var
|
|
1042
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1036
1043
|
var callbackWrapper = (fn) => (...args) => {
|
|
1037
1044
|
try {
|
|
1038
1045
|
return fn(...args);
|
|
1039
1046
|
} catch (err) {
|
|
1040
1047
|
log.catch(err, void 0, {
|
|
1041
|
-
F:
|
|
1048
|
+
F: __dxlog_file2,
|
|
1042
1049
|
L: 18,
|
|
1043
1050
|
S: void 0,
|
|
1044
1051
|
C: (f, a) => f(...a)
|
|
@@ -1067,22 +1074,34 @@ var logChanges = (trs) => {
|
|
|
1067
1074
|
|
|
1068
1075
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1069
1076
|
var styles2 = EditorView5.baseTheme({
|
|
1070
|
-
"& .cm-comment": {
|
|
1077
|
+
"&light .cm-comment, &light .cm-comment-current": {
|
|
1078
|
+
mixBlendMode: "darken"
|
|
1079
|
+
},
|
|
1080
|
+
"&dark .cm-comment, &dark .cm-comment-current": {
|
|
1081
|
+
mixBlendMode: "plus-lighter"
|
|
1082
|
+
},
|
|
1083
|
+
"&light .cm-comment": {
|
|
1071
1084
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1072
1085
|
},
|
|
1073
|
-
"& .cm-comment-current": {
|
|
1086
|
+
"&light .cm-comment-current": {
|
|
1074
1087
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1088
|
+
},
|
|
1089
|
+
"&dark .cm-comment": {
|
|
1090
|
+
color: getToken("extend.colors.yellow.50"),
|
|
1091
|
+
backgroundColor: getToken("extend.colors.yellow.900")
|
|
1092
|
+
},
|
|
1093
|
+
"&dark .cm-comment-current": {
|
|
1094
|
+
color: getToken("extend.colors.yellow.100"),
|
|
1095
|
+
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1075
1096
|
}
|
|
1076
1097
|
});
|
|
1077
|
-
var
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
};
|
|
1085
|
-
var setFocus = (view, id, center = true) => {
|
|
1098
|
+
var commentMark = Decoration2.mark({
|
|
1099
|
+
class: "cm-comment"
|
|
1100
|
+
});
|
|
1101
|
+
var commentCurrentMark = Decoration2.mark({
|
|
1102
|
+
class: "cm-comment-current"
|
|
1103
|
+
});
|
|
1104
|
+
var focusComment = (view, id, center = true) => {
|
|
1086
1105
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
1087
1106
|
if (!comment?.comment.cursor) {
|
|
1088
1107
|
return;
|
|
@@ -1144,7 +1163,7 @@ var commentsState = StateField2.define({
|
|
|
1144
1163
|
return value;
|
|
1145
1164
|
}
|
|
1146
1165
|
});
|
|
1147
|
-
var
|
|
1166
|
+
var commentsDecorations = EditorView5.decorations.compute([
|
|
1148
1167
|
commentsState
|
|
1149
1168
|
], (state) => {
|
|
1150
1169
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1155,9 +1174,9 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1155
1174
|
return void 0;
|
|
1156
1175
|
}
|
|
1157
1176
|
if (comment.comment.id === current) {
|
|
1158
|
-
return
|
|
1177
|
+
return commentCurrentMark.range(range.from, range.to);
|
|
1159
1178
|
} else {
|
|
1160
|
-
return
|
|
1179
|
+
return commentMark.range(range.from, range.to);
|
|
1161
1180
|
}
|
|
1162
1181
|
}).filter(nonNullable);
|
|
1163
1182
|
return Decoration2.set(decorations);
|
|
@@ -1186,36 +1205,80 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1186
1205
|
cut: handleTrack,
|
|
1187
1206
|
copy: handleTrack
|
|
1188
1207
|
}),
|
|
1189
|
-
//
|
|
1190
|
-
|
|
1208
|
+
// Track deleted comments.
|
|
1209
|
+
invertedEffects2.of((tr) => {
|
|
1210
|
+
const { comments: comments2 } = tr.startState.field(commentsState);
|
|
1211
|
+
const effects = [];
|
|
1212
|
+
tr.changes.iterChangedRanges((fromA, toA) => {
|
|
1213
|
+
for (const { comment: { id }, range: { from, to } } of comments2) {
|
|
1214
|
+
if (from < to && from >= fromA && to <= toA) {
|
|
1215
|
+
effects.push(restoreCommentEffect.of({
|
|
1216
|
+
id,
|
|
1217
|
+
from,
|
|
1218
|
+
to
|
|
1219
|
+
}));
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
return effects;
|
|
1224
|
+
}),
|
|
1225
|
+
// Handle paste or the undo of comment deletion.
|
|
1226
|
+
EditorView5.updateListener.of((update2) => {
|
|
1227
|
+
const restore = [];
|
|
1228
|
+
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1229
|
+
const tr = update2.transactions[i];
|
|
1230
|
+
for (let j = 0; j < restore.length; j++) {
|
|
1231
|
+
restore[j] = mapTrackedComment(restore[j], tr.changes);
|
|
1232
|
+
}
|
|
1233
|
+
for (const effect of tr.effects) {
|
|
1234
|
+
if (effect.is(restoreCommentEffect)) {
|
|
1235
|
+
restore.push(effect.value);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1191
1239
|
if (tracked) {
|
|
1192
|
-
const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1240
|
+
const paste = update2.transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1193
1241
|
if (paste) {
|
|
1194
1242
|
let found = -1;
|
|
1195
1243
|
paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
1196
1244
|
if (text.eq(tracked.text)) {
|
|
1197
|
-
for (let i = transactions.indexOf(paste) + 1; i < transactions.length; i++) {
|
|
1198
|
-
fromB = transactions[i].changes.mapPos(fromB);
|
|
1245
|
+
for (let i = update2.transactions.indexOf(paste) + 1; i < update2.transactions.length; i++) {
|
|
1246
|
+
fromB = update2.transactions[i].changes.mapPos(fromB);
|
|
1199
1247
|
}
|
|
1200
1248
|
found = fromB;
|
|
1201
1249
|
}
|
|
1202
1250
|
});
|
|
1203
1251
|
if (found > -1) {
|
|
1204
1252
|
for (const moved of tracked.comments) {
|
|
1205
|
-
|
|
1253
|
+
restore.push({
|
|
1254
|
+
id: moved.id,
|
|
1206
1255
|
from: found + moved.from,
|
|
1207
1256
|
to: found + moved.to
|
|
1208
|
-
};
|
|
1209
|
-
const cursor = Cursor.getCursorFromRange(state, range);
|
|
1210
|
-
onUpdate(moved.id, cursor);
|
|
1257
|
+
});
|
|
1211
1258
|
}
|
|
1212
1259
|
}
|
|
1213
1260
|
tracked = null;
|
|
1214
1261
|
}
|
|
1215
1262
|
}
|
|
1263
|
+
for (const comment of restore) {
|
|
1264
|
+
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
1265
|
+
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
1266
|
+
if (!exists) {
|
|
1267
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
1268
|
+
onUpdate(comment.id, cursor);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1216
1271
|
})
|
|
1217
1272
|
];
|
|
1218
1273
|
};
|
|
1274
|
+
var mapTrackedComment = (comment, changes) => ({
|
|
1275
|
+
id: comment.id,
|
|
1276
|
+
from: changes.mapPos(comment.from, 1),
|
|
1277
|
+
to: changes.mapPos(comment.to, 1)
|
|
1278
|
+
});
|
|
1279
|
+
var restoreCommentEffect = StateEffect2.define({
|
|
1280
|
+
map: mapTrackedComment
|
|
1281
|
+
});
|
|
1219
1282
|
var optionsFacet = Facet3.define({
|
|
1220
1283
|
combine: (providers) => providers[0]
|
|
1221
1284
|
});
|
|
@@ -1238,14 +1301,18 @@ var createComment = (view) => {
|
|
|
1238
1301
|
to
|
|
1239
1302
|
});
|
|
1240
1303
|
if (cursor) {
|
|
1241
|
-
const id = options.onCreate?.(
|
|
1304
|
+
const id = options.onCreate?.({
|
|
1305
|
+
cursor,
|
|
1306
|
+
from,
|
|
1307
|
+
location: view.coordsAtPos(from)
|
|
1308
|
+
});
|
|
1242
1309
|
if (id) {
|
|
1243
1310
|
view.dispatch({
|
|
1244
1311
|
effects: setSelection.of({
|
|
1245
1312
|
current: id
|
|
1246
1313
|
}),
|
|
1247
1314
|
selection: {
|
|
1248
|
-
anchor:
|
|
1315
|
+
anchor: to
|
|
1249
1316
|
}
|
|
1250
1317
|
});
|
|
1251
1318
|
return true;
|
|
@@ -1259,7 +1326,7 @@ var comments = (options = {}) => {
|
|
|
1259
1326
|
return [
|
|
1260
1327
|
optionsFacet.of(options),
|
|
1261
1328
|
commentsState,
|
|
1262
|
-
|
|
1329
|
+
commentsDecorations,
|
|
1263
1330
|
styles2,
|
|
1264
1331
|
//
|
|
1265
1332
|
// Keymap.
|
|
@@ -1405,6 +1472,7 @@ import { searchKeymap } from "@codemirror/search";
|
|
|
1405
1472
|
import { EditorState } from "@codemirror/state";
|
|
1406
1473
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1407
1474
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1475
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1408
1476
|
|
|
1409
1477
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1410
1478
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1595,11 +1663,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1595
1663
|
};
|
|
1596
1664
|
|
|
1597
1665
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1598
|
-
var
|
|
1666
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1599
1667
|
return [
|
|
1668
|
+
lineWrapping && EditorView7.lineWrapping,
|
|
1600
1669
|
EditorState.allowMultipleSelections.of(true),
|
|
1601
1670
|
EditorState.tabSize.of(2),
|
|
1602
|
-
EditorView7.lineWrapping,
|
|
1603
1671
|
// https://github.com/codemirror/basic-setup
|
|
1604
1672
|
bracketMatching2(),
|
|
1605
1673
|
closeBrackets2(),
|
|
@@ -1609,7 +1677,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1609
1677
|
highlightActiveLine2(),
|
|
1610
1678
|
history2(),
|
|
1611
1679
|
indentOnInput(),
|
|
1612
|
-
_placeholder
|
|
1680
|
+
_placeholder && placeholder2(_placeholder),
|
|
1613
1681
|
// Main extension.
|
|
1614
1682
|
// https://github.com/codemirror/lang-markdown
|
|
1615
1683
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1644,7 +1712,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1644
1712
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1645
1713
|
...standardKeymap
|
|
1646
1714
|
])
|
|
1647
|
-
];
|
|
1715
|
+
].filter(isNotFalsy2);
|
|
1648
1716
|
};
|
|
1649
1717
|
|
|
1650
1718
|
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
@@ -1654,12 +1722,11 @@ import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Dec
|
|
|
1654
1722
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1655
1723
|
var styles3 = EditorView8.baseTheme({
|
|
1656
1724
|
"& .cm-code": {
|
|
1657
|
-
paddingInline: "1rem !important",
|
|
1658
1725
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1659
1726
|
},
|
|
1660
1727
|
"& .cm-codeblock": {
|
|
1661
|
-
display: "inline-block",
|
|
1662
1728
|
width: "100%",
|
|
1729
|
+
paddingInline: "1rem !important",
|
|
1663
1730
|
position: "relative",
|
|
1664
1731
|
"&::after": {
|
|
1665
1732
|
content: '""',
|
|
@@ -1680,12 +1747,14 @@ var styles3 = EditorView8.baseTheme({
|
|
|
1680
1747
|
}
|
|
1681
1748
|
},
|
|
1682
1749
|
"& .cm-codeblock-first": {
|
|
1750
|
+
display: "inline-block",
|
|
1683
1751
|
"&::after": {
|
|
1684
1752
|
borderTopLeftRadius: ".5rem",
|
|
1685
1753
|
borderTopRightRadius: ".5rem"
|
|
1686
1754
|
}
|
|
1687
1755
|
},
|
|
1688
1756
|
"& .cm-codeblock-last": {
|
|
1757
|
+
display: "inline-block",
|
|
1689
1758
|
"&::after": {
|
|
1690
1759
|
borderBottomLeftRadius: ".5rem",
|
|
1691
1760
|
borderBottomRightRadius: ".5rem"
|
|
@@ -1733,7 +1802,7 @@ var buildDecorations = (view) => {
|
|
|
1733
1802
|
}));
|
|
1734
1803
|
} else {
|
|
1735
1804
|
builder.add(block.from, block.from, Decoration3.line({
|
|
1736
|
-
class: mx2("cm-code cm-codeblock")
|
|
1805
|
+
class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1737
1806
|
}));
|
|
1738
1807
|
}
|
|
1739
1808
|
}
|
|
@@ -1762,65 +1831,838 @@ var code2 = () => {
|
|
|
1762
1831
|
};
|
|
1763
1832
|
|
|
1764
1833
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1834
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1765
1835
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1766
|
-
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1767
|
-
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1768
|
-
|
|
1769
|
-
|
|
1836
|
+
import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
|
|
1837
|
+
import { Decoration as Decoration4, EditorView as EditorView9, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1838
|
+
import { useState, useMemo } from "react";
|
|
1839
|
+
var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
1840
|
+
var Inline;
|
|
1841
|
+
(function(Inline2) {
|
|
1842
|
+
Inline2[Inline2["Strong"] = 0] = "Strong";
|
|
1843
|
+
Inline2[Inline2["Emphasis"] = 1] = "Emphasis";
|
|
1844
|
+
Inline2[Inline2["Strikethrough"] = 2] = "Strikethrough";
|
|
1845
|
+
Inline2[Inline2["Code"] = 3] = "Code";
|
|
1846
|
+
})(Inline || (Inline = {}));
|
|
1847
|
+
var List;
|
|
1848
|
+
(function(List2) {
|
|
1849
|
+
List2[List2["Ordered"] = 0] = "Ordered";
|
|
1850
|
+
List2[List2["Bullet"] = 1] = "Bullet";
|
|
1851
|
+
List2[List2["Task"] = 2] = "Task";
|
|
1852
|
+
})(List || (List = {}));
|
|
1853
|
+
var setHeading = (level) => ({ state, dispatch }) => {
|
|
1854
|
+
const { selection: { ranges }, doc } = state;
|
|
1770
1855
|
const changes = [];
|
|
1856
|
+
let prevBlock = -1;
|
|
1771
1857
|
for (const range of ranges) {
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1858
|
+
syntaxTree2(state).iterate({
|
|
1859
|
+
from: range.from,
|
|
1860
|
+
to: range.to,
|
|
1861
|
+
enter: (node) => {
|
|
1862
|
+
if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
prevBlock = node.from;
|
|
1866
|
+
const blockType = Textblocks[node.name];
|
|
1867
|
+
const isHeading = /heading(\d)/.exec(blockType);
|
|
1868
|
+
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
1869
|
+
if (curLevel < 0 || curLevel === level) {
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
if (curLevel === 0) {
|
|
1873
|
+
changes.push({
|
|
1874
|
+
from: node.from,
|
|
1875
|
+
insert: "#".repeat(level) + " "
|
|
1876
|
+
});
|
|
1877
|
+
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
1878
|
+
const nextLine = doc.lineAt(node.to);
|
|
1879
|
+
if (level) {
|
|
1880
|
+
changes.push({
|
|
1881
|
+
from: node.from,
|
|
1882
|
+
insert: "#".repeat(level) + " "
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
changes.push({
|
|
1886
|
+
from: nextLine.from - 1,
|
|
1887
|
+
to: nextLine.to
|
|
1888
|
+
});
|
|
1889
|
+
} else {
|
|
1890
|
+
if (level === 0) {
|
|
1891
|
+
changes.push({
|
|
1892
|
+
from: node.from,
|
|
1893
|
+
to: Math.min(node.to, node.from + curLevel + 1)
|
|
1894
|
+
});
|
|
1895
|
+
} else if (level < curLevel) {
|
|
1896
|
+
changes.push({
|
|
1897
|
+
from: node.from,
|
|
1898
|
+
to: node.from + (curLevel - level)
|
|
1899
|
+
});
|
|
1900
|
+
} else {
|
|
1901
|
+
changes.push({
|
|
1902
|
+
from: node.from,
|
|
1903
|
+
insert: "#".repeat(level - curLevel)
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
});
|
|
1909
|
+
}
|
|
1910
|
+
if (!changes.length) {
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
dispatch(state.update({
|
|
1914
|
+
changes,
|
|
1915
|
+
userEvent: "format.setHeading",
|
|
1916
|
+
scrollIntoView: true
|
|
1917
|
+
}));
|
|
1918
|
+
return true;
|
|
1919
|
+
};
|
|
1920
|
+
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
1921
|
+
const marker = inlineMarkerText(type);
|
|
1922
|
+
const changes = state.changeByRange((range) => {
|
|
1923
|
+
if (!enable && range.empty) {
|
|
1924
|
+
const after = state.doc.sliceString(range.head, range.head + 6);
|
|
1925
|
+
const found = after.indexOf(marker);
|
|
1926
|
+
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
1927
|
+
const before = state.doc.sliceString(range.head - 6, range.head);
|
|
1928
|
+
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
1929
|
+
...before.slice(before.length - found)
|
|
1930
|
+
].reverse().join("") === after.slice(0, found)) {
|
|
1931
|
+
return {
|
|
1932
|
+
changes: [
|
|
1933
|
+
{
|
|
1934
|
+
from: range.head - marker.length - found,
|
|
1935
|
+
to: range.head - found
|
|
1936
|
+
},
|
|
1937
|
+
{
|
|
1938
|
+
from: range.head + found,
|
|
1939
|
+
to: range.head + found + marker.length
|
|
1940
|
+
}
|
|
1941
|
+
],
|
|
1942
|
+
range: EditorSelection.cursor(range.from - marker.length)
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
const changes2 = [];
|
|
1948
|
+
const changesAtEnd = [];
|
|
1949
|
+
let blockStart = -1;
|
|
1950
|
+
let blockEnd = -1;
|
|
1951
|
+
let startCovered = false;
|
|
1952
|
+
let endCovered = false;
|
|
1953
|
+
let { from, to } = range;
|
|
1954
|
+
syntaxTree2(state).iterate({
|
|
1955
|
+
from,
|
|
1956
|
+
to,
|
|
1957
|
+
enter: (node) => {
|
|
1958
|
+
const { name } = node;
|
|
1959
|
+
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
1960
|
+
blockStart = blockContentStart(node);
|
|
1961
|
+
blockEnd = blockContentEnd(node, state.doc);
|
|
1962
|
+
startCovered = endCovered = false;
|
|
1963
|
+
} else if (name === "Link" || name === "Image" && enable) {
|
|
1964
|
+
if (from < node.from && to > node.from && to <= node.to) {
|
|
1965
|
+
to = node.to;
|
|
1966
|
+
} else if (to > node.to && from >= node.from && from < node.to) {
|
|
1967
|
+
from = node.from;
|
|
1968
|
+
}
|
|
1969
|
+
} else if (IgnoreInline.has(name) && enable) {
|
|
1970
|
+
if (node.from < from && node.to > from) {
|
|
1971
|
+
if (to === from) {
|
|
1972
|
+
to = node.to;
|
|
1973
|
+
}
|
|
1974
|
+
from = node.to;
|
|
1975
|
+
}
|
|
1976
|
+
if (node.from < to && node.to > to) {
|
|
1977
|
+
to = node.from;
|
|
1978
|
+
}
|
|
1979
|
+
} else if (Object.hasOwn(InlineMarker, name)) {
|
|
1980
|
+
const markType = InlineMarker[name];
|
|
1981
|
+
const size = inlineMarkerText(markType).length;
|
|
1982
|
+
const openEnd = node.from + size;
|
|
1983
|
+
const closeStart = node.to - size;
|
|
1984
|
+
if (markType === type) {
|
|
1985
|
+
if (openEnd <= from && closeStart >= from) {
|
|
1986
|
+
startCovered = openEnd === from ? "adjacent" : true;
|
|
1987
|
+
}
|
|
1988
|
+
if (openEnd <= to && closeStart >= to) {
|
|
1989
|
+
endCovered = closeStart === to ? "adjacent" : true;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
if (markType === type || type === 3 && enable) {
|
|
1993
|
+
if (node.from >= from && openEnd <= to) {
|
|
1994
|
+
changes2.push({
|
|
1995
|
+
from: node.from,
|
|
1996
|
+
to: openEnd
|
|
1997
|
+
});
|
|
1998
|
+
if (markType !== type && closeStart >= to) {
|
|
1999
|
+
changesAtEnd.push({
|
|
2000
|
+
from: skipSpaces(Math.min(to, blockEnd), state.doc, 1, blockEnd),
|
|
2001
|
+
insert: inlineMarkerText(markType)
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (closeStart >= from && node.to <= to) {
|
|
2006
|
+
changes2.push({
|
|
2007
|
+
from: closeStart,
|
|
2008
|
+
to: node.to
|
|
2009
|
+
});
|
|
2010
|
+
if (markType !== type && openEnd <= from) {
|
|
2011
|
+
changes2.push({
|
|
2012
|
+
from: skipSpaces(Math.max(from, blockStart), state.doc, -1, blockStart),
|
|
2013
|
+
insert: inlineMarkerText(markType)
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
},
|
|
2020
|
+
leave: (node) => {
|
|
2021
|
+
if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== "codeblock") {
|
|
2022
|
+
const rangeStart = Math.max(from, blockStart);
|
|
2023
|
+
const rangeEnd = Math.min(to, blockEnd);
|
|
2024
|
+
if (enable) {
|
|
2025
|
+
if (!startCovered) {
|
|
2026
|
+
changes2.push({
|
|
2027
|
+
from: rangeStart,
|
|
2028
|
+
insert: marker
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
if (!endCovered) {
|
|
2032
|
+
changes2.push({
|
|
2033
|
+
from: rangeEnd,
|
|
2034
|
+
insert: marker
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
} else {
|
|
2038
|
+
if (startCovered === "adjacent") {
|
|
2039
|
+
changes2.push({
|
|
2040
|
+
from: from - marker.length,
|
|
2041
|
+
to: from
|
|
2042
|
+
});
|
|
2043
|
+
} else if (startCovered) {
|
|
2044
|
+
changes2.push({
|
|
2045
|
+
from: skipSpaces(rangeStart, state.doc, -1, blockStart),
|
|
2046
|
+
insert: marker
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
if (endCovered === "adjacent") {
|
|
2050
|
+
changes2.push({
|
|
2051
|
+
from: to,
|
|
2052
|
+
to: to + marker.length
|
|
2053
|
+
});
|
|
2054
|
+
} else if (endCovered) {
|
|
2055
|
+
changes2.push({
|
|
2056
|
+
from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
|
|
2057
|
+
insert: marker
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
});
|
|
2064
|
+
const changeSet = state.changes(changes2.concat(changesAtEnd));
|
|
2065
|
+
return {
|
|
2066
|
+
changes: changeSet,
|
|
2067
|
+
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
2068
|
+
};
|
|
2069
|
+
});
|
|
2070
|
+
dispatch(state.update(changes, {
|
|
2071
|
+
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
2072
|
+
scrollIntoView: true
|
|
2073
|
+
}));
|
|
2074
|
+
return true;
|
|
2075
|
+
};
|
|
2076
|
+
var addStyle = (style) => setStyle(style, true);
|
|
2077
|
+
var removeStyle = (style) => setStyle(style, false);
|
|
2078
|
+
var toggleStyle = (style) => (arg) => {
|
|
2079
|
+
const form = getFormatting(arg.state);
|
|
2080
|
+
return setStyle(style, style === 0 ? !form.strong : style === 1 ? !form.emphasis : style === 2 ? !form.strikethrough : !form.code)(arg);
|
|
2081
|
+
};
|
|
2082
|
+
var toggleStrong = toggleStyle(0);
|
|
2083
|
+
var toggleEmphasis = toggleStyle(1);
|
|
2084
|
+
var toggleStrikethrough = toggleStyle(2);
|
|
2085
|
+
var toggleInlineCode = toggleStyle(3);
|
|
2086
|
+
var inlineMarkerText = (type) => type === 0 ? "**" : type === 2 ? "~~" : type === 1 ? "*" : "`";
|
|
2087
|
+
var blockContentStart = (node) => {
|
|
2088
|
+
const atx = /^ATXHeading(\d)/.exec(node.name);
|
|
2089
|
+
if (atx) {
|
|
2090
|
+
return Math.min(node.to, node.from + +atx[1] + 1);
|
|
2091
|
+
}
|
|
2092
|
+
return node.from;
|
|
2093
|
+
};
|
|
2094
|
+
var blockContentEnd = (node, doc) => {
|
|
2095
|
+
const setext = /^SetextHeading(\d)/.exec(node.name);
|
|
2096
|
+
const lastLine = doc.lineAt(node.to);
|
|
2097
|
+
if (setext || /^[\s>]*$/.exec(lastLine.text)) {
|
|
2098
|
+
return lastLine.from - 1;
|
|
2099
|
+
}
|
|
2100
|
+
return node.to;
|
|
2101
|
+
};
|
|
2102
|
+
var skipSpaces = (pos, doc, dir, limit) => {
|
|
2103
|
+
const line = doc.lineAt(pos);
|
|
2104
|
+
while (pos !== limit && line.text[pos - line.from - (dir < 0 ? 1 : 0)] === " ") {
|
|
2105
|
+
pos += dir;
|
|
2106
|
+
}
|
|
2107
|
+
return pos;
|
|
2108
|
+
};
|
|
2109
|
+
var snippets = {
|
|
2110
|
+
codeblock: snippet([
|
|
2111
|
+
//
|
|
2112
|
+
"```#{}",
|
|
2113
|
+
"#{}",
|
|
2114
|
+
"```"
|
|
2115
|
+
].join("\n")),
|
|
2116
|
+
table: snippet([
|
|
2117
|
+
//
|
|
2118
|
+
"| #{col1} | #{col2} |",
|
|
2119
|
+
"| ---- | ---- |",
|
|
2120
|
+
"| #{val1} | #{val2} |",
|
|
2121
|
+
"| #{val3} | #{val4} |",
|
|
2122
|
+
""
|
|
2123
|
+
].join("\n"))
|
|
2124
|
+
};
|
|
2125
|
+
var insertTable = (view) => {
|
|
2126
|
+
const { selection: { main }, doc } = view.state;
|
|
2127
|
+
const { number } = doc.lineAt(main.anchor);
|
|
2128
|
+
const { from } = doc.line(number);
|
|
2129
|
+
snippets.table(view, null, from, from);
|
|
2130
|
+
};
|
|
2131
|
+
var removeLinkInner = (from, to, changes, state) => {
|
|
2132
|
+
syntaxTree2(state).iterate({
|
|
2133
|
+
from,
|
|
2134
|
+
to,
|
|
2135
|
+
enter: (node) => {
|
|
2136
|
+
if (node.name === "Link" && node.from < to && node.to > from) {
|
|
2137
|
+
node.node.cursor().iterate((node2) => {
|
|
2138
|
+
const { name } = node2;
|
|
2139
|
+
if (name === "LinkMark" || name === "LinkLabel") {
|
|
2140
|
+
changes.push({
|
|
2141
|
+
from: node2.from,
|
|
2142
|
+
to: node2.to
|
|
2143
|
+
});
|
|
2144
|
+
} else if (name === "LinkTitle" || name === "URL") {
|
|
2145
|
+
changes.push({
|
|
2146
|
+
from: skipSpaces(node2.from, state.doc, -1),
|
|
2147
|
+
to: skipSpaces(node2.to, state.doc, 1)
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
});
|
|
2151
|
+
return false;
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
});
|
|
2155
|
+
};
|
|
2156
|
+
var removeLink = ({ state, dispatch }) => {
|
|
2157
|
+
const changes = [];
|
|
2158
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2159
|
+
removeLinkInner(from, to, changes, state);
|
|
2160
|
+
}
|
|
2161
|
+
if (!changes) {
|
|
2162
|
+
return false;
|
|
2163
|
+
}
|
|
2164
|
+
dispatch(state.update({
|
|
2165
|
+
changes,
|
|
2166
|
+
userEvent: "format.link.remove",
|
|
2167
|
+
scrollIntoView: true
|
|
2168
|
+
}));
|
|
2169
|
+
return true;
|
|
2170
|
+
};
|
|
2171
|
+
var addLink = ({ state, dispatch }) => {
|
|
2172
|
+
const changes = state.changeByRange((range) => {
|
|
2173
|
+
let { from, to } = range;
|
|
2174
|
+
const cutStyles = [];
|
|
2175
|
+
let okay = null;
|
|
2176
|
+
syntaxTree2(state).iterate({
|
|
2177
|
+
from,
|
|
2178
|
+
to,
|
|
2179
|
+
enter: (node) => {
|
|
2180
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
2181
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state.doc);
|
|
2182
|
+
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
2183
|
+
const sNode = node.node;
|
|
2184
|
+
if (node.from < from && node.to <= to) {
|
|
2185
|
+
if (sNode.firstChild.to === from) {
|
|
2186
|
+
from = node.from;
|
|
2187
|
+
} else {
|
|
2188
|
+
cutStyles.push(sNode);
|
|
2189
|
+
}
|
|
2190
|
+
} else if (node.from >= from && node.to > to) {
|
|
2191
|
+
if (sNode.lastChild.from === to) {
|
|
2192
|
+
to = node.to;
|
|
2193
|
+
} else {
|
|
2194
|
+
cutStyles.push(sNode);
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
2200
|
+
if (okay === null) {
|
|
2201
|
+
const line = state.doc.lineAt(from);
|
|
2202
|
+
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
2203
|
+
}
|
|
2204
|
+
if (!okay) {
|
|
2205
|
+
return {
|
|
2206
|
+
range
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
const changes2 = [];
|
|
2210
|
+
const changesAfter = [];
|
|
2211
|
+
removeLinkInner(from, to, changesAfter, state);
|
|
2212
|
+
let cursorOffset = 1;
|
|
2213
|
+
for (const style of cutStyles) {
|
|
2214
|
+
const type = InlineMarker[style.name];
|
|
2215
|
+
const mark2 = inlineMarkerText(type);
|
|
2216
|
+
if (style.from < from) {
|
|
2217
|
+
changes2.push({
|
|
2218
|
+
from: skipSpaces(from, state.doc, -1),
|
|
2219
|
+
insert: mark2
|
|
2220
|
+
});
|
|
2221
|
+
changesAfter.push({
|
|
2222
|
+
from: skipSpaces(from, state.doc, 1, to),
|
|
2223
|
+
insert: mark2
|
|
2224
|
+
});
|
|
2225
|
+
} else {
|
|
2226
|
+
changes2.push({
|
|
2227
|
+
from: skipSpaces(to, state.doc, -1, from),
|
|
2228
|
+
insert: mark2
|
|
2229
|
+
});
|
|
2230
|
+
const after = skipSpaces(to, state.doc, 1);
|
|
2231
|
+
if (after === to) {
|
|
2232
|
+
cursorOffset += mark2.length;
|
|
2233
|
+
}
|
|
2234
|
+
changesAfter.push({
|
|
2235
|
+
from: after,
|
|
2236
|
+
insert: mark2
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
changes2.push({
|
|
2241
|
+
from,
|
|
2242
|
+
insert: "["
|
|
2243
|
+
}, {
|
|
2244
|
+
from: to,
|
|
2245
|
+
insert: "]()"
|
|
2246
|
+
});
|
|
2247
|
+
const changeSet = state.changes(changes2.concat(changesAfter));
|
|
2248
|
+
return {
|
|
2249
|
+
changes: changeSet,
|
|
2250
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
2251
|
+
};
|
|
2252
|
+
});
|
|
2253
|
+
if (changes.changes.empty) {
|
|
2254
|
+
return false;
|
|
2255
|
+
}
|
|
2256
|
+
dispatch(state.update(changes, {
|
|
2257
|
+
userEvent: "format.link.add",
|
|
2258
|
+
scrollIntoView: true
|
|
2259
|
+
}));
|
|
2260
|
+
return true;
|
|
2261
|
+
};
|
|
2262
|
+
var addList = (type) => ({ state, dispatch }) => {
|
|
2263
|
+
let lastBlock = -1;
|
|
2264
|
+
let counter = 1;
|
|
2265
|
+
let first = true;
|
|
2266
|
+
let parentColumn = null;
|
|
2267
|
+
const blocks = [];
|
|
2268
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2269
|
+
syntaxTree2(state).iterate({
|
|
2270
|
+
from,
|
|
2271
|
+
to,
|
|
2272
|
+
enter: (node) => {
|
|
2273
|
+
if (Object.hasOwn(Textblocks, node.name) && node.name !== "TableCell" || node.name === "Table") {
|
|
2274
|
+
if (first) {
|
|
2275
|
+
let before = node.node.prevSibling;
|
|
2276
|
+
while (before && /Mark$/.test(before.name)) {
|
|
2277
|
+
before = before.prevSibling;
|
|
2278
|
+
}
|
|
2279
|
+
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
2280
|
+
const item = before.lastChild;
|
|
2281
|
+
const itemLine = state.doc.lineAt(item.from);
|
|
2282
|
+
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
2283
|
+
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
2284
|
+
if (type === 0) {
|
|
2285
|
+
const mark2 = /^\s*(\d+)[.)]/.exec(itemText);
|
|
2286
|
+
if (mark2) {
|
|
2287
|
+
parentColumn += mark2[1].length;
|
|
2288
|
+
counter = +mark2[1] + 1;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
first = false;
|
|
2293
|
+
}
|
|
2294
|
+
if (node.from === lastBlock) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
lastBlock = node.from;
|
|
2298
|
+
blocks.push({
|
|
2299
|
+
node: node.node,
|
|
2300
|
+
counter,
|
|
2301
|
+
parentColumn
|
|
2302
|
+
});
|
|
2303
|
+
counter++;
|
|
2304
|
+
return false;
|
|
2305
|
+
}
|
|
2306
|
+
},
|
|
2307
|
+
leave: (node) => {
|
|
2308
|
+
if (node.name === "BulletList" || node.name === "OrderedList" || node.name === "Blockquote") {
|
|
2309
|
+
counter = 1;
|
|
2310
|
+
parentColumn = null;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
if (!blocks.length) {
|
|
2316
|
+
const { from, to } = state.doc.lineAt(state.selection.main.anchor);
|
|
2317
|
+
if (from === to) {
|
|
2318
|
+
dispatch(state.update({
|
|
2319
|
+
changes: [
|
|
2320
|
+
{
|
|
2321
|
+
from,
|
|
2322
|
+
insert: type === 1 ? "- " : type === 0 ? "1. " : "- [ ] "
|
|
2323
|
+
}
|
|
2324
|
+
],
|
|
2325
|
+
userEvent: "format.list.add",
|
|
2326
|
+
scrollIntoView: true
|
|
2327
|
+
}));
|
|
2328
|
+
return true;
|
|
2329
|
+
}
|
|
2330
|
+
return false;
|
|
2331
|
+
}
|
|
2332
|
+
const changes = [];
|
|
2333
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
2334
|
+
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
2335
|
+
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
2336
|
+
let padding = nodeFrom > 0 && !/\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
2337
|
+
if (type === 0) {
|
|
2338
|
+
padding += String(counter2).length;
|
|
2339
|
+
}
|
|
2340
|
+
let line = state.doc.lineAt(nodeFrom);
|
|
2341
|
+
const column = nodeFrom - line.from;
|
|
2342
|
+
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
2343
|
+
padding = Math.max(padding, parentColumn2 - column);
|
|
2344
|
+
}
|
|
2345
|
+
let mark2;
|
|
2346
|
+
if (type === 0) {
|
|
2347
|
+
let max = counter2;
|
|
2348
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
2349
|
+
if (blocks[j].counter !== max + 1) {
|
|
2350
|
+
break;
|
|
2351
|
+
}
|
|
2352
|
+
max++;
|
|
2353
|
+
}
|
|
2354
|
+
const num = String(counter2);
|
|
2355
|
+
padding = Math.max(String(max).length, padding);
|
|
2356
|
+
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
2357
|
+
} else {
|
|
2358
|
+
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
2359
|
+
}
|
|
2360
|
+
changes.push({
|
|
2361
|
+
from: nodeFrom,
|
|
2362
|
+
insert: mark2
|
|
2363
|
+
});
|
|
2364
|
+
while (line.to < node.to) {
|
|
2365
|
+
line = state.doc.lineAt(line.to + 1);
|
|
2366
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
1778
2367
|
changes.push({
|
|
1779
|
-
from,
|
|
1780
|
-
|
|
1781
|
-
insert: "#".repeat(level) + (level > 0 ? " " : "")
|
|
2368
|
+
from: line.from + Math.min(open, column),
|
|
2369
|
+
insert: " ".repeat(mark2.length)
|
|
1782
2370
|
});
|
|
1783
2371
|
}
|
|
1784
2372
|
}
|
|
1785
|
-
if (
|
|
1786
|
-
|
|
1787
|
-
|
|
2373
|
+
if (type === 0) {
|
|
2374
|
+
const last = blocks[blocks.length - 1];
|
|
2375
|
+
let next = last.node.nextSibling;
|
|
2376
|
+
while (next && /Mark$/.test(next.name)) {
|
|
2377
|
+
next = next.nextSibling;
|
|
2378
|
+
}
|
|
2379
|
+
if (next?.name === "OrderedList") {
|
|
2380
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
dispatch(state.update({
|
|
2384
|
+
changes,
|
|
2385
|
+
userEvent: "format.list.add",
|
|
2386
|
+
scrollIntoView: true
|
|
2387
|
+
}));
|
|
2388
|
+
return true;
|
|
2389
|
+
};
|
|
2390
|
+
var removeList = (type) => ({ state, dispatch }) => {
|
|
2391
|
+
let lastBlock = -1;
|
|
2392
|
+
const changes = [];
|
|
2393
|
+
const stack = [];
|
|
2394
|
+
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
2395
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2396
|
+
syntaxTree2(state).iterate({
|
|
2397
|
+
from,
|
|
2398
|
+
to,
|
|
2399
|
+
enter: (node) => {
|
|
2400
|
+
const { name } = node;
|
|
2401
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2402
|
+
stack.push(name);
|
|
2403
|
+
} else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2404
|
+
stack[stack.length - 1] = "TaskList";
|
|
2405
|
+
}
|
|
2406
|
+
},
|
|
2407
|
+
leave: (node) => {
|
|
2408
|
+
const { name } = node;
|
|
2409
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2410
|
+
stack.pop();
|
|
2411
|
+
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
2412
|
+
lastBlock = node.from;
|
|
2413
|
+
let line = state.doc.lineAt(node.from);
|
|
2414
|
+
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
2415
|
+
if (!mark2) {
|
|
2416
|
+
return false;
|
|
2417
|
+
}
|
|
2418
|
+
const column = node.from - line.from;
|
|
2419
|
+
changes.push({
|
|
2420
|
+
from: node.from,
|
|
2421
|
+
to: node.from + mark2[0].length
|
|
2422
|
+
});
|
|
2423
|
+
while (line.to < node.to) {
|
|
2424
|
+
line = state.doc.lineAt(line.to + 1);
|
|
2425
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2426
|
+
if (open > column) {
|
|
2427
|
+
changes.push({
|
|
2428
|
+
from: line.from + column,
|
|
2429
|
+
to: line.from + Math.min(column + mark2[0].length, open)
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
if (node.to >= to) {
|
|
2434
|
+
renumberListItems(node.node.nextSibling, 1, changes, state.doc);
|
|
2435
|
+
}
|
|
2436
|
+
return false;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
1788
2439
|
});
|
|
1789
2440
|
}
|
|
2441
|
+
if (!changes.length) {
|
|
2442
|
+
return false;
|
|
2443
|
+
}
|
|
2444
|
+
dispatch(state.update({
|
|
2445
|
+
changes,
|
|
2446
|
+
userEvent: "format.list.remove",
|
|
2447
|
+
scrollIntoView: true
|
|
2448
|
+
}));
|
|
1790
2449
|
return true;
|
|
1791
2450
|
};
|
|
1792
|
-
var
|
|
1793
|
-
const
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
2451
|
+
var toggleList = (type) => (target) => {
|
|
2452
|
+
const formatting2 = getFormatting(target.state);
|
|
2453
|
+
const active = formatting2.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
2454
|
+
return (active ? removeList(type) : addList(type))(target);
|
|
2455
|
+
};
|
|
2456
|
+
var renumberListItems = (item, counter, changes, doc) => {
|
|
2457
|
+
for (; item; item = item.nextSibling) {
|
|
2458
|
+
if (item.name === "ListItem") {
|
|
2459
|
+
const number = /(\s*)(\d+)[.)]/.exec(doc.sliceString(item.from, item.from + 10));
|
|
2460
|
+
if (!number || +number[2] === counter) {
|
|
2461
|
+
break;
|
|
2462
|
+
}
|
|
2463
|
+
const size = number[1].length + number[2].length;
|
|
2464
|
+
const newNum = String(counter);
|
|
2465
|
+
changes.push({
|
|
2466
|
+
from: item.from + Math.max(0, size - newNum.length),
|
|
2467
|
+
to: item.from + size,
|
|
2468
|
+
insert: newNum
|
|
2469
|
+
});
|
|
2470
|
+
counter++;
|
|
1797
2471
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
2475
|
+
const lines = [];
|
|
2476
|
+
let lastBlock = -1;
|
|
2477
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2478
|
+
syntaxTree2(state).iterate({
|
|
2479
|
+
from,
|
|
2480
|
+
to,
|
|
2481
|
+
enter: (node) => {
|
|
2482
|
+
if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
|
|
2483
|
+
if (node.from === lastBlock) {
|
|
2484
|
+
return false;
|
|
2485
|
+
}
|
|
2486
|
+
lastBlock = node.from;
|
|
2487
|
+
let line = state.doc.lineAt(node.from);
|
|
2488
|
+
if (line.number > 1) {
|
|
2489
|
+
const prevLine = state.doc.line(line.number - 1);
|
|
2490
|
+
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
2491
|
+
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
2492
|
+
lines.push(prevLine);
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
for (; ; ) {
|
|
2497
|
+
lines.push(line);
|
|
2498
|
+
if (line.to >= node.to) {
|
|
2499
|
+
break;
|
|
2500
|
+
}
|
|
2501
|
+
line = state.doc.line(line.number + 1);
|
|
2502
|
+
}
|
|
2503
|
+
if (!enable && line.number < state.doc.lines) {
|
|
2504
|
+
const nextLine = state.doc.line(line.number + 1);
|
|
2505
|
+
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
2506
|
+
lines.push(nextLine);
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
return false;
|
|
1807
2510
|
}
|
|
1808
|
-
|
|
2511
|
+
}
|
|
1809
2512
|
});
|
|
1810
2513
|
}
|
|
2514
|
+
const changes = [];
|
|
2515
|
+
for (const line of lines) {
|
|
2516
|
+
if (enable) {
|
|
2517
|
+
changes.push({
|
|
2518
|
+
from: line.from,
|
|
2519
|
+
insert: /\S/.test(line.text) ? "> " : ">"
|
|
2520
|
+
});
|
|
2521
|
+
} else {
|
|
2522
|
+
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
2523
|
+
if (quote) {
|
|
2524
|
+
changes.push({
|
|
2525
|
+
from: line.from + quote[1].length,
|
|
2526
|
+
to: line.from + quote[0].length
|
|
2527
|
+
});
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
if (!changes.length) {
|
|
2532
|
+
return false;
|
|
2533
|
+
}
|
|
2534
|
+
dispatch(state.update({
|
|
2535
|
+
changes,
|
|
2536
|
+
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
2537
|
+
scrollIntoView: true
|
|
2538
|
+
}));
|
|
1811
2539
|
return true;
|
|
1812
2540
|
};
|
|
1813
|
-
var
|
|
1814
|
-
var
|
|
1815
|
-
var
|
|
1816
|
-
|
|
2541
|
+
var addBlockquote = setBlockquote(true);
|
|
2542
|
+
var removeBlockquote = setBlockquote(false);
|
|
2543
|
+
var toggleBlockquote = (target) => {
|
|
2544
|
+
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
2545
|
+
};
|
|
2546
|
+
var addCodeblock = (target) => {
|
|
2547
|
+
const { state, dispatch } = target;
|
|
2548
|
+
const { selection } = state;
|
|
2549
|
+
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
2550
|
+
const { head } = selection.main;
|
|
2551
|
+
const line = state.doc.lineAt(head);
|
|
2552
|
+
if (!/\S/.test(line.text) && head === line.from) {
|
|
2553
|
+
snippets.codeblock(target, null, line.from, line.to);
|
|
2554
|
+
return true;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
const ranges = [];
|
|
2558
|
+
for (const { from, to } of selection.ranges) {
|
|
2559
|
+
let blockFrom = from;
|
|
2560
|
+
let blockTo = to;
|
|
2561
|
+
syntaxTree2(state).iterate({
|
|
2562
|
+
from,
|
|
2563
|
+
to,
|
|
2564
|
+
enter: (node) => {
|
|
2565
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
2566
|
+
if (from >= node.from && to <= node.to) {
|
|
2567
|
+
blockFrom = node.from;
|
|
2568
|
+
blockTo = node.to;
|
|
2569
|
+
} else {
|
|
2570
|
+
blockFrom = Math.min(blockFrom, state.doc.lineAt(node.from).from);
|
|
2571
|
+
blockTo = Math.max(blockTo, state.doc.lineAt(node.to).to);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
});
|
|
2576
|
+
if (ranges.length && ranges[ranges.length - 1].to >= blockFrom - 1) {
|
|
2577
|
+
ranges[ranges.length - 1].to = blockTo;
|
|
2578
|
+
} else {
|
|
2579
|
+
ranges.push({
|
|
2580
|
+
from: blockFrom,
|
|
2581
|
+
to: blockTo
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
if (!ranges.length) {
|
|
2586
|
+
return false;
|
|
2587
|
+
}
|
|
2588
|
+
const changes = ranges.map(({ from, to }) => {
|
|
2589
|
+
const column = from - state.doc.lineAt(from).from;
|
|
2590
|
+
return [
|
|
2591
|
+
{
|
|
2592
|
+
from,
|
|
2593
|
+
insert: "```\n" + " ".repeat(column)
|
|
2594
|
+
},
|
|
2595
|
+
{
|
|
2596
|
+
from: to,
|
|
2597
|
+
insert: "\n" + " ".repeat(column) + "```"
|
|
2598
|
+
}
|
|
2599
|
+
];
|
|
2600
|
+
});
|
|
2601
|
+
dispatch(state.update({
|
|
2602
|
+
changes,
|
|
2603
|
+
userEvent: "format.codeblock.add",
|
|
2604
|
+
scrollIntoView: true
|
|
2605
|
+
}));
|
|
2606
|
+
return true;
|
|
2607
|
+
};
|
|
2608
|
+
var removeCodeblock = ({ state, dispatch }) => {
|
|
2609
|
+
const changes = [];
|
|
2610
|
+
let lastBlock = -1;
|
|
2611
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2612
|
+
syntaxTree2(state).iterate({
|
|
2613
|
+
from,
|
|
2614
|
+
to,
|
|
2615
|
+
enter: (node) => {
|
|
2616
|
+
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
2617
|
+
lastBlock = node.from;
|
|
2618
|
+
const firstLine = state.doc.lineAt(node.from);
|
|
2619
|
+
if (node.name === "FencedCode") {
|
|
2620
|
+
changes.push({
|
|
2621
|
+
from: node.from,
|
|
2622
|
+
to: firstLine.to + 1 + node.from - firstLine.from
|
|
2623
|
+
});
|
|
2624
|
+
const lastLine = state.doc.lineAt(node.to);
|
|
2625
|
+
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
2626
|
+
changes.push({
|
|
2627
|
+
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
2628
|
+
to: lastLine.to
|
|
2629
|
+
});
|
|
2630
|
+
}
|
|
2631
|
+
} else {
|
|
2632
|
+
const column = node.from - firstLine.from;
|
|
2633
|
+
for (let line = firstLine; ; line = state.doc.line(line.number + 1)) {
|
|
2634
|
+
changes.push({
|
|
2635
|
+
from: line.from + column - 4,
|
|
2636
|
+
to: line.from + column
|
|
2637
|
+
});
|
|
2638
|
+
if (line.to >= node.to) {
|
|
2639
|
+
break;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
});
|
|
2646
|
+
}
|
|
2647
|
+
if (!changes.length) {
|
|
2648
|
+
return false;
|
|
2649
|
+
}
|
|
2650
|
+
dispatch(state.update({
|
|
2651
|
+
changes,
|
|
2652
|
+
userEvent: "format.codeblock.remove",
|
|
2653
|
+
scrollIntoView: true
|
|
2654
|
+
}));
|
|
2655
|
+
return true;
|
|
2656
|
+
};
|
|
2657
|
+
var toggleCodeblock = (target) => {
|
|
2658
|
+
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
1817
2659
|
};
|
|
1818
2660
|
var formatting = (options = {}) => {
|
|
1819
2661
|
return [
|
|
1820
2662
|
keymap5.of([
|
|
1821
2663
|
{
|
|
1822
2664
|
key: "meta-b",
|
|
1823
|
-
run:
|
|
2665
|
+
run: toggleStrong
|
|
1824
2666
|
}
|
|
1825
2667
|
]),
|
|
1826
2668
|
styling()
|
|
@@ -1831,9 +2673,9 @@ var styling = () => {
|
|
|
1831
2673
|
const builder = new RangeSetBuilder2();
|
|
1832
2674
|
const { state } = view;
|
|
1833
2675
|
const cursor = state.selection.main.head;
|
|
1834
|
-
const replace = (node,
|
|
2676
|
+
const replace = (node, marks) => {
|
|
1835
2677
|
if (cursor <= node.from || cursor >= node.to) {
|
|
1836
|
-
for (const mark2 of
|
|
2678
|
+
for (const mark2 of marks) {
|
|
1837
2679
|
builder.add(mark2.from, mark2.to, Decoration4.replace({}));
|
|
1838
2680
|
}
|
|
1839
2681
|
}
|
|
@@ -1844,13 +2686,13 @@ var styling = () => {
|
|
|
1844
2686
|
switch (node.name) {
|
|
1845
2687
|
case "Emphasis":
|
|
1846
2688
|
case "StrongEmphasis": {
|
|
1847
|
-
const
|
|
1848
|
-
replace(node,
|
|
2689
|
+
const marks = node.node.getChildren("EmphasisMark");
|
|
2690
|
+
replace(node, marks);
|
|
1849
2691
|
break;
|
|
1850
2692
|
}
|
|
1851
2693
|
case "Strikethrough": {
|
|
1852
|
-
const
|
|
1853
|
-
replace(node,
|
|
2694
|
+
const marks = node.node.getChildren("StrikethroughMark");
|
|
2695
|
+
replace(node, marks);
|
|
1854
2696
|
break;
|
|
1855
2697
|
}
|
|
1856
2698
|
}
|
|
@@ -1874,6 +2716,209 @@ var styling = () => {
|
|
|
1874
2716
|
})
|
|
1875
2717
|
];
|
|
1876
2718
|
};
|
|
2719
|
+
var InlineMarker = {
|
|
2720
|
+
Emphasis: 1,
|
|
2721
|
+
StrongEmphasis: 0,
|
|
2722
|
+
InlineCode: 3,
|
|
2723
|
+
Strikethrough: 2
|
|
2724
|
+
};
|
|
2725
|
+
var IgnoreInline = /* @__PURE__ */ new Set([
|
|
2726
|
+
"Autolink",
|
|
2727
|
+
"CodeMark",
|
|
2728
|
+
"CodeText",
|
|
2729
|
+
"Comment",
|
|
2730
|
+
"EmphasisMark",
|
|
2731
|
+
"Hardbreak",
|
|
2732
|
+
"HeaderMark",
|
|
2733
|
+
"HTMLTag",
|
|
2734
|
+
"LinkMark",
|
|
2735
|
+
"ListMark",
|
|
2736
|
+
"ProcessingInstruction",
|
|
2737
|
+
"QuoteMark",
|
|
2738
|
+
"StrikethroughMark",
|
|
2739
|
+
"SubscriptMark",
|
|
2740
|
+
"SuperscriptMark",
|
|
2741
|
+
"TaskMarker"
|
|
2742
|
+
]);
|
|
2743
|
+
var Textblocks = {
|
|
2744
|
+
ATXHeading1: "heading1",
|
|
2745
|
+
ATXHeading2: "heading2",
|
|
2746
|
+
ATXHeading3: "heading3",
|
|
2747
|
+
ATXHeading4: "heading4",
|
|
2748
|
+
ATXHeading5: "heading5",
|
|
2749
|
+
ATXHeading6: "heading6",
|
|
2750
|
+
CodeBlock: "codeblock",
|
|
2751
|
+
FencedCode: "codeblock",
|
|
2752
|
+
Paragraph: "paragraph",
|
|
2753
|
+
SetextHeading1: "heading1",
|
|
2754
|
+
SetextHeading2: "heading2",
|
|
2755
|
+
TableCell: "tablecell",
|
|
2756
|
+
Task: "paragraph"
|
|
2757
|
+
};
|
|
2758
|
+
var getFormatting = (state) => {
|
|
2759
|
+
let blockType = null;
|
|
2760
|
+
const inline = [
|
|
2761
|
+
null,
|
|
2762
|
+
null,
|
|
2763
|
+
null,
|
|
2764
|
+
null
|
|
2765
|
+
];
|
|
2766
|
+
let link2 = false;
|
|
2767
|
+
let blockQuote = null;
|
|
2768
|
+
let listStyle = null;
|
|
2769
|
+
const stack = [];
|
|
2770
|
+
let currentBlock = null;
|
|
2771
|
+
const advanceInline = (upto) => {
|
|
2772
|
+
if (!currentBlock) {
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
upto = Math.min(upto, currentBlock.end);
|
|
2776
|
+
if (upto <= currentBlock.pos) {
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
for (let i = 0; i < currentBlock.active.length; i++) {
|
|
2780
|
+
if (inline[i] === false) {
|
|
2781
|
+
continue;
|
|
2782
|
+
} else if (currentBlock.active[i]) {
|
|
2783
|
+
inline[i] = true;
|
|
2784
|
+
} else if (/\S/.test(state.doc.sliceString(currentBlock.pos, upto))) {
|
|
2785
|
+
inline[i] = false;
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
currentBlock.pos = upto;
|
|
2789
|
+
};
|
|
2790
|
+
const skipInline = (upto) => {
|
|
2791
|
+
if (currentBlock && upto > currentBlock.pos) {
|
|
2792
|
+
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
2793
|
+
}
|
|
2794
|
+
};
|
|
2795
|
+
const { selection } = state;
|
|
2796
|
+
for (const range of selection.ranges) {
|
|
2797
|
+
if (range.empty && inline.some((v) => v === null)) {
|
|
2798
|
+
const contextSize = Math.min(range.head, 6);
|
|
2799
|
+
const contextBefore = state.doc.sliceString(range.head - contextSize, range.head);
|
|
2800
|
+
let contextAfter = state.doc.sliceString(range.head, range.head + contextSize);
|
|
2801
|
+
for (let i = 0; i < contextSize; i++) {
|
|
2802
|
+
const ch = contextAfter[i];
|
|
2803
|
+
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
2804
|
+
contextAfter = contextAfter.slice(0, i);
|
|
2805
|
+
break;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
for (let i = 0; i < inline.length; i++) {
|
|
2809
|
+
const mark2 = inlineMarkerText(i);
|
|
2810
|
+
const found = contextAfter.indexOf(mark2);
|
|
2811
|
+
if (found > -1) {
|
|
2812
|
+
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark2.length);
|
|
2813
|
+
if (inline[i] === null) {
|
|
2814
|
+
inline[i] = true;
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
syntaxTree2(state).iterate({
|
|
2820
|
+
from: range.from,
|
|
2821
|
+
to: range.to,
|
|
2822
|
+
enter: (node) => {
|
|
2823
|
+
advanceInline(node.from);
|
|
2824
|
+
const { name } = node;
|
|
2825
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2826
|
+
stack.push(name);
|
|
2827
|
+
} else if (name === "Link") {
|
|
2828
|
+
link2 = true;
|
|
2829
|
+
} else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
|
|
2830
|
+
if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2831
|
+
stack[stack.length - 1] = "TaskList";
|
|
2832
|
+
}
|
|
2833
|
+
const blockCode = Textblocks[name];
|
|
2834
|
+
if (blockType === null) {
|
|
2835
|
+
blockType = blockCode;
|
|
2836
|
+
} else if (blockType !== blockCode) {
|
|
2837
|
+
blockType = false;
|
|
2838
|
+
}
|
|
2839
|
+
if (blockCode !== "codeblock" && inline.some((i) => i !== false)) {
|
|
2840
|
+
currentBlock = {
|
|
2841
|
+
pos: Math.max(range.from, node.from),
|
|
2842
|
+
end: Math.min(range.to, node.to),
|
|
2843
|
+
active: [
|
|
2844
|
+
false,
|
|
2845
|
+
false,
|
|
2846
|
+
false,
|
|
2847
|
+
false
|
|
2848
|
+
]
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
2852
|
+
const index = InlineMarker[name];
|
|
2853
|
+
if (range.empty && inline[index] === null) {
|
|
2854
|
+
inline[index] = true;
|
|
2855
|
+
}
|
|
2856
|
+
currentBlock.active[index] = true;
|
|
2857
|
+
} else if (IgnoreInline.has(name)) {
|
|
2858
|
+
skipInline(node.to);
|
|
2859
|
+
}
|
|
2860
|
+
},
|
|
2861
|
+
leave: (node) => {
|
|
2862
|
+
advanceInline(node.to);
|
|
2863
|
+
const { name } = node;
|
|
2864
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2865
|
+
stack.pop();
|
|
2866
|
+
} else if (Object.hasOwn(Textblocks, name)) {
|
|
2867
|
+
let hasList = false;
|
|
2868
|
+
let hasQuote = false;
|
|
2869
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
2870
|
+
if (stack[i] === "Blockquote") {
|
|
2871
|
+
hasQuote = true;
|
|
2872
|
+
} else if (!hasList) {
|
|
2873
|
+
hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
if (blockQuote === null) {
|
|
2877
|
+
blockQuote = hasQuote;
|
|
2878
|
+
} else if (!hasQuote && blockQuote) {
|
|
2879
|
+
blockQuote = false;
|
|
2880
|
+
}
|
|
2881
|
+
if (listStyle === null) {
|
|
2882
|
+
listStyle = hasList;
|
|
2883
|
+
} else if (listStyle !== hasList) {
|
|
2884
|
+
listStyle = false;
|
|
2885
|
+
}
|
|
2886
|
+
currentBlock = null;
|
|
2887
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
2888
|
+
currentBlock.active[InlineMarker[name]] = false;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
const { from, to } = state.doc.lineAt(selection.main.anchor);
|
|
2894
|
+
const blankLine = from === to;
|
|
2895
|
+
return {
|
|
2896
|
+
blankLine,
|
|
2897
|
+
blockType: blockType || null,
|
|
2898
|
+
blockQuote: blockQuote ?? false,
|
|
2899
|
+
code: inline[3] ?? false,
|
|
2900
|
+
emphasis: inline[1] ?? false,
|
|
2901
|
+
strong: inline[0] ?? false,
|
|
2902
|
+
strikethrough: inline[2] ?? false,
|
|
2903
|
+
link: link2,
|
|
2904
|
+
listStyle: listStyle || null
|
|
2905
|
+
};
|
|
2906
|
+
};
|
|
2907
|
+
var useFormattingState = () => {
|
|
2908
|
+
const [state, setState] = useState(null);
|
|
2909
|
+
const observer = useMemo(() => EditorView9.updateListener.of((update2) => {
|
|
2910
|
+
if (update2.docChanged || update2.selectionSet) {
|
|
2911
|
+
const newState = getFormatting(update2.state);
|
|
2912
|
+
if (!state || !compareFormatting(state, newState)) {
|
|
2913
|
+
setState(newState);
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
}), []);
|
|
2917
|
+
return [
|
|
2918
|
+
state,
|
|
2919
|
+
observer
|
|
2920
|
+
];
|
|
2921
|
+
};
|
|
1877
2922
|
|
|
1878
2923
|
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1879
2924
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
@@ -1926,8 +2971,8 @@ var heading2 = () => {
|
|
|
1926
2971
|
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
1927
2972
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
1928
2973
|
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
1929
|
-
import { Decoration as Decoration6, EditorView as
|
|
1930
|
-
var styles4 =
|
|
2974
|
+
import { Decoration as Decoration6, EditorView as EditorView10, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
2975
|
+
var styles4 = EditorView10.baseTheme({
|
|
1931
2976
|
"& .cm-hr": {
|
|
1932
2977
|
// Note that block-level decorations should not have vertical margins,
|
|
1933
2978
|
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
@@ -1981,7 +3026,7 @@ var hr = () => {
|
|
|
1981
3026
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
1982
3027
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
1983
3028
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1984
|
-
import { Decoration as Decoration7, EditorView as
|
|
3029
|
+
import { Decoration as Decoration7, EditorView as EditorView11, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1985
3030
|
var image = (options = {}) => {
|
|
1986
3031
|
return StateField3.define({
|
|
1987
3032
|
create: (state) => {
|
|
@@ -2008,7 +3053,7 @@ var image = (options = {}) => {
|
|
|
2008
3053
|
add: buildDecorations4(from, to, tr.state)
|
|
2009
3054
|
});
|
|
2010
3055
|
},
|
|
2011
|
-
provide: (field) =>
|
|
3056
|
+
provide: (field) => EditorView11.decorations.from(field)
|
|
2012
3057
|
});
|
|
2013
3058
|
};
|
|
2014
3059
|
var buildDecorations4 = (from, to, state) => {
|
|
@@ -2160,8 +3205,8 @@ var buildDecorations5 = (view, options) => {
|
|
|
2160
3205
|
syntaxTree6(state).iterate({
|
|
2161
3206
|
enter: (node) => {
|
|
2162
3207
|
if (node.name === "Link") {
|
|
2163
|
-
const
|
|
2164
|
-
const text =
|
|
3208
|
+
const marks = node.node.getChildren("LinkMark");
|
|
3209
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
2165
3210
|
const urlNode = node.node.getChild("URL");
|
|
2166
3211
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2167
3212
|
if (!url) {
|
|
@@ -2190,12 +3235,12 @@ var buildDecorations5 = (view, options) => {
|
|
|
2190
3235
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2191
3236
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2192
3237
|
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
|
|
2193
|
-
import { Decoration as Decoration9, EditorView as
|
|
3238
|
+
import { Decoration as Decoration9, EditorView as EditorView12, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2194
3239
|
var table = (options = {}) => {
|
|
2195
3240
|
return StateField4.define({
|
|
2196
3241
|
create: (state) => update(state, options),
|
|
2197
3242
|
update: (_, tr) => update(tr.state, options),
|
|
2198
|
-
provide: (field) =>
|
|
3243
|
+
provide: (field) => EditorView12.decorations.from(field)
|
|
2199
3244
|
});
|
|
2200
3245
|
};
|
|
2201
3246
|
var update = (state, options) => {
|
|
@@ -2288,8 +3333,8 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2288
3333
|
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
2289
3334
|
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
2290
3335
|
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
2291
|
-
import { EditorView as
|
|
2292
|
-
var styles5 =
|
|
3336
|
+
import { EditorView as EditorView13, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
3337
|
+
var styles5 = EditorView13.baseTheme({
|
|
2293
3338
|
"& .cm-task": {
|
|
2294
3339
|
color: getToken("extend.colors.blue.500")
|
|
2295
3340
|
},
|
|
@@ -2504,8 +3549,9 @@ var defaultTheme = {
|
|
|
2504
3549
|
outline: "none"
|
|
2505
3550
|
},
|
|
2506
3551
|
".cm-scroller": {
|
|
2507
|
-
overflow:
|
|
2508
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
3552
|
+
// overflow: 'visible',
|
|
3553
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
3554
|
+
lineHeight: 1.4
|
|
2509
3555
|
},
|
|
2510
3556
|
".cm-content": {
|
|
2511
3557
|
padding: 0,
|
|
@@ -2513,11 +3559,11 @@ var defaultTheme = {
|
|
|
2513
3559
|
fontSize: "16px"
|
|
2514
3560
|
},
|
|
2515
3561
|
"&light .cm-content": {
|
|
2516
|
-
color: get3(tokens, "extend.
|
|
3562
|
+
color: get3(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
2517
3563
|
caretColor: "black"
|
|
2518
3564
|
},
|
|
2519
3565
|
"&dark .cm-content": {
|
|
2520
|
-
color: get3(tokens, "extend.
|
|
3566
|
+
color: get3(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
2521
3567
|
caretColor: "white"
|
|
2522
3568
|
},
|
|
2523
3569
|
//
|
|
@@ -2529,8 +3575,11 @@ var defaultTheme = {
|
|
|
2529
3575
|
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
2530
3576
|
borderLeft: "2px solid white"
|
|
2531
3577
|
},
|
|
2532
|
-
".cm-placeholder": {
|
|
2533
|
-
|
|
3578
|
+
"&light .cm-placeholder": {
|
|
3579
|
+
color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
3580
|
+
},
|
|
3581
|
+
"&dark .cm-placeholder": {
|
|
3582
|
+
color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
2534
3583
|
},
|
|
2535
3584
|
//
|
|
2536
3585
|
// line
|
|
@@ -2710,23 +3759,28 @@ var codeTheme = {
|
|
|
2710
3759
|
};
|
|
2711
3760
|
|
|
2712
3761
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
2713
|
-
var
|
|
3762
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
2714
3763
|
var EditorModes = [
|
|
2715
3764
|
"default",
|
|
2716
3765
|
"vim"
|
|
2717
3766
|
];
|
|
2718
3767
|
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2719
|
-
const tabsterDOMAttribute = useFocusableGroup({
|
|
2720
|
-
tabBehavior: "limited"
|
|
2721
|
-
});
|
|
2722
3768
|
const { themeMode } = useThemeContext();
|
|
2723
3769
|
const rootRef = useRef(null);
|
|
2724
|
-
const [view, setView] =
|
|
3770
|
+
const [view, setView] = useState2(null);
|
|
2725
3771
|
useImperativeHandle(forwardedRef, () => view, [
|
|
2726
3772
|
view
|
|
2727
3773
|
]);
|
|
2728
3774
|
useEffect2(() => {
|
|
2729
|
-
if (autoFocus) {
|
|
3775
|
+
if (autoFocus && !view?.hasFocus) {
|
|
3776
|
+
if (view?.state.selection.main?.from === 0) {
|
|
3777
|
+
const { to } = view.state.doc.lineAt(0);
|
|
3778
|
+
view?.dispatch({
|
|
3779
|
+
selection: {
|
|
3780
|
+
anchor: to
|
|
3781
|
+
}
|
|
3782
|
+
});
|
|
3783
|
+
}
|
|
2730
3784
|
view?.focus();
|
|
2731
3785
|
}
|
|
2732
3786
|
}, [
|
|
@@ -2742,38 +3796,38 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2742
3796
|
selection,
|
|
2743
3797
|
extensions: [
|
|
2744
3798
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2745
|
-
|
|
3799
|
+
EditorView14.exceptionSink.of((err) => {
|
|
2746
3800
|
log2.catch(err, void 0, {
|
|
2747
|
-
F:
|
|
2748
|
-
L:
|
|
3801
|
+
F: __dxlog_file3,
|
|
3802
|
+
L: 134,
|
|
2749
3803
|
S: void 0,
|
|
2750
3804
|
C: (f, a) => f(...a)
|
|
2751
3805
|
});
|
|
2752
3806
|
}),
|
|
2753
3807
|
// Theme.
|
|
2754
3808
|
// TODO(burdon): Make configurable.
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
3809
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3810
|
+
EditorView14.theme(theme ?? {}),
|
|
3811
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3812
|
+
EditorView14.editorAttributes.of({
|
|
2759
3813
|
class: slots.editor?.className ?? ""
|
|
2760
3814
|
}),
|
|
2761
|
-
|
|
3815
|
+
EditorView14.contentAttributes.of({
|
|
2762
3816
|
class: slots.content?.className ?? ""
|
|
2763
3817
|
}),
|
|
2764
3818
|
// State.
|
|
2765
|
-
|
|
3819
|
+
EditorView14.editable.of(!readonly),
|
|
2766
3820
|
EditorState2.readOnly.of(!!readonly),
|
|
2767
3821
|
// Storage and replication.
|
|
2768
3822
|
// NOTE: This must come before user extensions.
|
|
2769
3823
|
model.extension,
|
|
2770
|
-
// TODO(burdon): Factor out (
|
|
3824
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2771
3825
|
editorMode === "vim" && vim(),
|
|
2772
3826
|
// Custom.
|
|
2773
3827
|
...extensions
|
|
2774
|
-
].filter(
|
|
3828
|
+
].filter(isNotFalsy3)
|
|
2775
3829
|
});
|
|
2776
|
-
const newView = new
|
|
3830
|
+
const newView = new EditorView14({
|
|
2777
3831
|
state,
|
|
2778
3832
|
parent: rootRef.current,
|
|
2779
3833
|
scrollTo,
|
|
@@ -2808,7 +3862,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2808
3862
|
}
|
|
2809
3863
|
case "Escape": {
|
|
2810
3864
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2811
|
-
|
|
3865
|
+
view?.focus();
|
|
2812
3866
|
}
|
|
2813
3867
|
break;
|
|
2814
3868
|
}
|
|
@@ -2821,9 +3875,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2821
3875
|
key: model.id,
|
|
2822
3876
|
role: "none",
|
|
2823
3877
|
tabIndex: 0,
|
|
2824
|
-
onKeyUp: handleKeyUp,
|
|
2825
3878
|
...slots.root,
|
|
2826
|
-
...editorMode !==
|
|
3879
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
3880
|
+
onKeyUp: handleKeyUp,
|
|
2827
3881
|
ref: rootRef
|
|
2828
3882
|
});
|
|
2829
3883
|
});
|
|
@@ -2834,7 +3888,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2834
3888
|
ref: forwardedRef,
|
|
2835
3889
|
readonly,
|
|
2836
3890
|
extensions: [
|
|
2837
|
-
|
|
3891
|
+
createBasicBundle({
|
|
2838
3892
|
themeMode,
|
|
2839
3893
|
placeholder: placeholder3,
|
|
2840
3894
|
lineWrapping
|
|
@@ -2853,7 +3907,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2853
3907
|
ref: forwardedRef,
|
|
2854
3908
|
readonly,
|
|
2855
3909
|
extensions: [
|
|
2856
|
-
|
|
3910
|
+
createMarkdownExtensions({
|
|
2857
3911
|
themeMode,
|
|
2858
3912
|
placeholder: placeholder3
|
|
2859
3913
|
}),
|
|
@@ -2866,11 +3920,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2866
3920
|
});
|
|
2867
3921
|
var defaultSlots = {
|
|
2868
3922
|
root: {
|
|
2869
|
-
|
|
2870
|
-
className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
|
|
3923
|
+
className: mx3("grow", focusRing)
|
|
2871
3924
|
},
|
|
2872
3925
|
editor: {
|
|
2873
|
-
className: "
|
|
3926
|
+
className: "bs-full"
|
|
2874
3927
|
}
|
|
2875
3928
|
};
|
|
2876
3929
|
var defaultTextSlots = {
|
|
@@ -2880,12 +3933,212 @@ var defaultMarkdownSlots = {
|
|
|
2880
3933
|
...defaultSlots
|
|
2881
3934
|
};
|
|
2882
3935
|
|
|
3936
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
3937
|
+
import { CaretRight, ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
|
|
3938
|
+
import { createContext } from "@radix-ui/react-context";
|
|
3939
|
+
import React2 from "react";
|
|
3940
|
+
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
3941
|
+
import { getSize, mx as mx4 } from "@dxos/react-ui-theme";
|
|
3942
|
+
var HeadingIcons = {
|
|
3943
|
+
"0": Paragraph,
|
|
3944
|
+
"1": TextHOne,
|
|
3945
|
+
"2": TextHTwo,
|
|
3946
|
+
"3": TextHThree,
|
|
3947
|
+
"4": TextHFour,
|
|
3948
|
+
"5": TextHFive,
|
|
3949
|
+
"6": TextHSix
|
|
3950
|
+
};
|
|
3951
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
3952
|
+
var ToolbarRoot = ({ children, onAction, state }) => {
|
|
3953
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
3954
|
+
onAction,
|
|
3955
|
+
state
|
|
3956
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
3957
|
+
density: "fine"
|
|
3958
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
3959
|
+
role: "toolbar",
|
|
3960
|
+
className: "flex w-full shrink-0 p-1 gap-4 items-center whitespace-nowrap overflow-hidden"
|
|
3961
|
+
}, children)));
|
|
3962
|
+
};
|
|
3963
|
+
var ToolbarButton = ({ Icon, onClick, title, getState, disable }) => {
|
|
3964
|
+
const { onAction, state } = useToolbarContext("ToolbarButton");
|
|
3965
|
+
const active = getState && state ? getState(state) : false;
|
|
3966
|
+
const disabled = disable && state ? disable(state) : false;
|
|
3967
|
+
const handleClick = (event) => {
|
|
3968
|
+
const action = onClick(state);
|
|
3969
|
+
if (action) {
|
|
3970
|
+
onAction?.(action);
|
|
3971
|
+
event.preventDefault();
|
|
3972
|
+
}
|
|
3973
|
+
};
|
|
3974
|
+
return /* @__PURE__ */ React2.createElement(Button, {
|
|
3975
|
+
variant: "ghost",
|
|
3976
|
+
classNames: mx4("p-2", active && "ring-[1px]"),
|
|
3977
|
+
onMouseDown: handleClick,
|
|
3978
|
+
title,
|
|
3979
|
+
disabled
|
|
3980
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
3981
|
+
className: getSize(5)
|
|
3982
|
+
}));
|
|
3983
|
+
};
|
|
3984
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3985
|
+
className: "grow"
|
|
3986
|
+
});
|
|
3987
|
+
var MarkdownHeading = () => {
|
|
3988
|
+
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
3989
|
+
const blockType = state ? state.blockType : "paragraph";
|
|
3990
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
|
3991
|
+
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
3992
|
+
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
3993
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3994
|
+
disabled: value === null,
|
|
3995
|
+
value: value ?? "0",
|
|
3996
|
+
onValueChange: (value2) => onAction?.({
|
|
3997
|
+
type: "heading",
|
|
3998
|
+
data: parseInt(value2)
|
|
3999
|
+
})
|
|
4000
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(HeadingIcon, {
|
|
4001
|
+
className: getSize(5)
|
|
4002
|
+
})), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4003
|
+
value: "0"
|
|
4004
|
+
}, "Paragraph"), [
|
|
4005
|
+
1,
|
|
4006
|
+
2,
|
|
4007
|
+
3,
|
|
4008
|
+
4,
|
|
4009
|
+
5,
|
|
4010
|
+
6
|
|
4011
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4012
|
+
key: level,
|
|
4013
|
+
value: String(level)
|
|
4014
|
+
}, "Heading ", level))))));
|
|
4015
|
+
};
|
|
4016
|
+
var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4017
|
+
role: "none"
|
|
4018
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4019
|
+
Icon: TextB,
|
|
4020
|
+
title: "String",
|
|
4021
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4022
|
+
getState: (s) => s.strong,
|
|
4023
|
+
onClick: (s) => ({
|
|
4024
|
+
type: "strong",
|
|
4025
|
+
data: s ? !s.strong : null
|
|
4026
|
+
})
|
|
4027
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4028
|
+
Icon: TextItalic,
|
|
4029
|
+
title: "Emphasis",
|
|
4030
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4031
|
+
getState: (s) => s.emphasis,
|
|
4032
|
+
onClick: (s) => ({
|
|
4033
|
+
type: "emphasis",
|
|
4034
|
+
data: s ? !s.emphasis : null
|
|
4035
|
+
})
|
|
4036
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4037
|
+
Icon: TextStrikethrough,
|
|
4038
|
+
title: "Strike-through",
|
|
4039
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4040
|
+
getState: (s) => s.strikethrough,
|
|
4041
|
+
onClick: (s) => ({
|
|
4042
|
+
type: "strikethrough",
|
|
4043
|
+
data: s ? !s.strikethrough : null
|
|
4044
|
+
})
|
|
4045
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4046
|
+
Icon: Code,
|
|
4047
|
+
title: "Inline code",
|
|
4048
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4049
|
+
getState: (s) => s.code,
|
|
4050
|
+
onClick: (s) => ({
|
|
4051
|
+
type: "code",
|
|
4052
|
+
data: s ? !s.code : null
|
|
4053
|
+
})
|
|
4054
|
+
}));
|
|
4055
|
+
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4056
|
+
role: "none"
|
|
4057
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4058
|
+
Icon: ListBullets,
|
|
4059
|
+
title: "Bullet list",
|
|
4060
|
+
getState: (s) => s.listStyle === "bullet",
|
|
4061
|
+
onClick: (s) => ({
|
|
4062
|
+
type: "list-bullet",
|
|
4063
|
+
data: s ? s.listStyle !== "bullet" : null
|
|
4064
|
+
})
|
|
4065
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4066
|
+
Icon: ListNumbers,
|
|
4067
|
+
title: "Numbered list",
|
|
4068
|
+
getState: (s) => s.listStyle === "ordered",
|
|
4069
|
+
onClick: (s) => ({
|
|
4070
|
+
type: "list-ordered",
|
|
4071
|
+
data: s ? s.listStyle !== "ordered" : null
|
|
4072
|
+
})
|
|
4073
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4074
|
+
Icon: ListChecks,
|
|
4075
|
+
title: "Task list",
|
|
4076
|
+
getState: (s) => s.listStyle === "task",
|
|
4077
|
+
onClick: (s) => ({
|
|
4078
|
+
type: "list-tasks",
|
|
4079
|
+
data: s ? s.listStyle !== "task" : null
|
|
4080
|
+
})
|
|
4081
|
+
}));
|
|
4082
|
+
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4083
|
+
role: "none"
|
|
4084
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4085
|
+
Icon: CaretRight,
|
|
4086
|
+
title: "Block quote",
|
|
4087
|
+
getState: (s) => s.blockQuote,
|
|
4088
|
+
onClick: (s) => ({
|
|
4089
|
+
type: "blockquote",
|
|
4090
|
+
data: s ? !s.blockQuote : null
|
|
4091
|
+
})
|
|
4092
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4093
|
+
Icon: CodeBlock,
|
|
4094
|
+
title: "Code block",
|
|
4095
|
+
disable: (s) => !s.blankLine,
|
|
4096
|
+
getState: (s) => s.blockType === "codeblock",
|
|
4097
|
+
onClick: (s) => ({
|
|
4098
|
+
type: "codeblock",
|
|
4099
|
+
data: s ? s.blockType !== "codeblock" : null
|
|
4100
|
+
})
|
|
4101
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4102
|
+
Icon: Table2,
|
|
4103
|
+
title: "Table",
|
|
4104
|
+
disable: (s) => !s.blankLine,
|
|
4105
|
+
onClick: () => ({
|
|
4106
|
+
type: "table"
|
|
4107
|
+
})
|
|
4108
|
+
}));
|
|
4109
|
+
var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4110
|
+
role: "none"
|
|
4111
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4112
|
+
Icon: Link,
|
|
4113
|
+
title: "Link",
|
|
4114
|
+
getState: (s) => s.link,
|
|
4115
|
+
onClick: (s) => ({
|
|
4116
|
+
type: "link",
|
|
4117
|
+
data: s ? !s.link : null
|
|
4118
|
+
})
|
|
4119
|
+
}));
|
|
4120
|
+
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));
|
|
4121
|
+
var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
|
|
4122
|
+
Icon: ChatText,
|
|
4123
|
+
title: "Create comment",
|
|
4124
|
+
onClick: () => ({
|
|
4125
|
+
type: "comment"
|
|
4126
|
+
})
|
|
4127
|
+
});
|
|
4128
|
+
var Toolbar = {
|
|
4129
|
+
Root: ToolbarRoot,
|
|
4130
|
+
Button: ToolbarButton,
|
|
4131
|
+
Separator: ToolbarSeparator,
|
|
4132
|
+
Markdown: MarkdownStandard,
|
|
4133
|
+
Extended: MarkdownExtended
|
|
4134
|
+
};
|
|
4135
|
+
|
|
2883
4136
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2884
4137
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2885
4138
|
import { Context as Context2 } from "@dxos/context";
|
|
2886
|
-
import { invariant as
|
|
4139
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2887
4140
|
import { log as log3 } from "@dxos/log";
|
|
2888
|
-
var
|
|
4141
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
2889
4142
|
var DEBOUNCE_INTERVAL = 100;
|
|
2890
4143
|
var SpaceAwarenessProvider = class {
|
|
2891
4144
|
constructor(params) {
|
|
@@ -2925,7 +4178,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2925
4178
|
log3.debug("failed to query awareness", {
|
|
2926
4179
|
err
|
|
2927
4180
|
}, {
|
|
2928
|
-
F:
|
|
4181
|
+
F: __dxlog_file4,
|
|
2929
4182
|
L: 89,
|
|
2930
4183
|
S: this,
|
|
2931
4184
|
C: (f, a) => f(...a)
|
|
@@ -2941,8 +4194,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2941
4194
|
return Array.from(this._remoteStates.values());
|
|
2942
4195
|
}
|
|
2943
4196
|
update(position) {
|
|
2944
|
-
|
|
2945
|
-
F:
|
|
4197
|
+
invariant2(this._postTask, void 0, {
|
|
4198
|
+
F: __dxlog_file4,
|
|
2946
4199
|
L: 104,
|
|
2947
4200
|
S: this,
|
|
2948
4201
|
A: [
|
|
@@ -2958,8 +4211,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2958
4211
|
this._postTask.schedule();
|
|
2959
4212
|
}
|
|
2960
4213
|
_handleQueryMessage() {
|
|
2961
|
-
|
|
2962
|
-
F:
|
|
4214
|
+
invariant2(this._postTask, void 0, {
|
|
4215
|
+
F: __dxlog_file4,
|
|
2963
4216
|
L: 115,
|
|
2964
4217
|
S: this,
|
|
2965
4218
|
A: [
|
|
@@ -2970,8 +4223,8 @@ var SpaceAwarenessProvider = class {
|
|
|
2970
4223
|
this._postTask.schedule();
|
|
2971
4224
|
}
|
|
2972
4225
|
_handlePostMessage(message) {
|
|
2973
|
-
|
|
2974
|
-
F:
|
|
4226
|
+
invariant2(message.kind === "post", void 0, {
|
|
4227
|
+
F: __dxlog_file4,
|
|
2975
4228
|
L: 120,
|
|
2976
4229
|
S: this,
|
|
2977
4230
|
A: [
|
|
@@ -2997,36 +4250,52 @@ var useActionHandler = (view) => {
|
|
|
2997
4250
|
if (!view) {
|
|
2998
4251
|
return;
|
|
2999
4252
|
}
|
|
4253
|
+
let inlineType, listType;
|
|
3000
4254
|
switch (action.type) {
|
|
3001
4255
|
case "heading":
|
|
3002
4256
|
setHeading(parseInt(action.data))(view);
|
|
3003
4257
|
break;
|
|
3004
|
-
case "
|
|
3005
|
-
|
|
4258
|
+
case "strong":
|
|
4259
|
+
case "emphasis":
|
|
4260
|
+
case "strikethrough":
|
|
4261
|
+
case "code":
|
|
4262
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4263
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3006
4264
|
break;
|
|
3007
|
-
case "
|
|
3008
|
-
|
|
4265
|
+
case "list-ordered":
|
|
4266
|
+
case "list-bullet":
|
|
4267
|
+
case "list-tasks":
|
|
4268
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4269
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3009
4270
|
break;
|
|
3010
|
-
case "
|
|
3011
|
-
|
|
4271
|
+
case "blockquote":
|
|
4272
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4273
|
+
break;
|
|
4274
|
+
case "codeblock":
|
|
4275
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3012
4276
|
break;
|
|
3013
|
-
case "
|
|
3014
|
-
|
|
4277
|
+
case "table":
|
|
4278
|
+
insertTable(view);
|
|
4279
|
+
break;
|
|
4280
|
+
case "link":
|
|
4281
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
3015
4282
|
break;
|
|
3016
4283
|
case "comment":
|
|
3017
4284
|
createComment(view);
|
|
3018
4285
|
break;
|
|
3019
4286
|
}
|
|
3020
4287
|
setTimeout(() => {
|
|
3021
|
-
view.
|
|
4288
|
+
if (!view.hasFocus) {
|
|
4289
|
+
view.focus();
|
|
4290
|
+
}
|
|
3022
4291
|
});
|
|
3023
4292
|
};
|
|
3024
4293
|
};
|
|
3025
4294
|
|
|
3026
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
3027
|
-
import { useState as
|
|
3028
|
-
var
|
|
3029
|
-
const [view, setView] =
|
|
4295
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4296
|
+
import { useState as useState3 } from "react";
|
|
4297
|
+
var useEditorView = () => {
|
|
4298
|
+
const [view, setView] = useState3(null);
|
|
3030
4299
|
return [
|
|
3031
4300
|
(ref) => {
|
|
3032
4301
|
setView(ref);
|
|
@@ -3035,29 +4304,144 @@ var useTextEditor = () => {
|
|
|
3035
4304
|
];
|
|
3036
4305
|
};
|
|
3037
4306
|
|
|
4307
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4308
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4309
|
+
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4310
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
4311
|
+
import { log as log4 } from "@dxos/log";
|
|
4312
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
4313
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4314
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
4315
|
+
const onUpdate = useRef2();
|
|
4316
|
+
const [view, setView] = useState4();
|
|
4317
|
+
const parentRef = useRef2(null);
|
|
4318
|
+
useEffect3(() => {
|
|
4319
|
+
if (parentRef.current) {
|
|
4320
|
+
const state = EditorState3.create({
|
|
4321
|
+
doc,
|
|
4322
|
+
selection,
|
|
4323
|
+
extensions: [
|
|
4324
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4325
|
+
EditorView15.exceptionSink.of((err) => {
|
|
4326
|
+
log4.catch(err, void 0, {
|
|
4327
|
+
F: __dxlog_file5,
|
|
4328
|
+
L: 57,
|
|
4329
|
+
S: void 0,
|
|
4330
|
+
C: (f, a) => f(...a)
|
|
4331
|
+
});
|
|
4332
|
+
}),
|
|
4333
|
+
extensions,
|
|
4334
|
+
EditorView15.updateListener.of(() => {
|
|
4335
|
+
onUpdate.current?.();
|
|
4336
|
+
})
|
|
4337
|
+
].filter(isNotFalsy4)
|
|
4338
|
+
});
|
|
4339
|
+
const view2 = new EditorView15({
|
|
4340
|
+
parent: parentRef.current,
|
|
4341
|
+
scrollTo,
|
|
4342
|
+
state,
|
|
4343
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4344
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4345
|
+
dispatchTransactions: (trs, view3) => {
|
|
4346
|
+
if (debug) {
|
|
4347
|
+
logChanges(trs);
|
|
4348
|
+
}
|
|
4349
|
+
view3.update(trs);
|
|
4350
|
+
}
|
|
4351
|
+
});
|
|
4352
|
+
setView(view2);
|
|
4353
|
+
}
|
|
4354
|
+
return () => {
|
|
4355
|
+
view?.destroy();
|
|
4356
|
+
};
|
|
4357
|
+
}, [
|
|
4358
|
+
parentRef
|
|
4359
|
+
]);
|
|
4360
|
+
useEffect3(() => {
|
|
4361
|
+
if (view) {
|
|
4362
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4363
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4364
|
+
}
|
|
4365
|
+
if (selection || scrollTo) {
|
|
4366
|
+
onUpdate.current = () => {
|
|
4367
|
+
onUpdate.current = void 0;
|
|
4368
|
+
view.dispatch({
|
|
4369
|
+
selection,
|
|
4370
|
+
effects: scrollTo && [
|
|
4371
|
+
scrollTo
|
|
4372
|
+
],
|
|
4373
|
+
scrollIntoView: !scrollTo
|
|
4374
|
+
});
|
|
4375
|
+
};
|
|
4376
|
+
}
|
|
4377
|
+
if (autoFocus) {
|
|
4378
|
+
view.focus();
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
}, [
|
|
4382
|
+
view,
|
|
4383
|
+
autoFocus,
|
|
4384
|
+
selection,
|
|
4385
|
+
scrollTo
|
|
4386
|
+
]);
|
|
4387
|
+
return {
|
|
4388
|
+
parentRef,
|
|
4389
|
+
view
|
|
4390
|
+
};
|
|
4391
|
+
};
|
|
4392
|
+
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4393
|
+
return [
|
|
4394
|
+
//
|
|
4395
|
+
EditorState3.readOnly.of(readonly),
|
|
4396
|
+
EditorView15.editable.of(!readonly)
|
|
4397
|
+
];
|
|
4398
|
+
};
|
|
4399
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4400
|
+
return [
|
|
4401
|
+
//
|
|
4402
|
+
EditorView15.baseTheme(defaultTheme),
|
|
4403
|
+
theme && EditorView15.theme(theme),
|
|
4404
|
+
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4405
|
+
EditorView15.editorAttributes.of({
|
|
4406
|
+
class: slots?.editor?.className ?? ""
|
|
4407
|
+
}),
|
|
4408
|
+
EditorView15.contentAttributes.of({
|
|
4409
|
+
class: slots?.content?.className ?? ""
|
|
4410
|
+
})
|
|
4411
|
+
].filter(isNotFalsy4);
|
|
4412
|
+
};
|
|
4413
|
+
|
|
3038
4414
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
3039
4415
|
import get4 from "lodash.get";
|
|
3040
|
-
import { useEffect as
|
|
4416
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
3041
4417
|
import { generateName } from "@dxos/display-name";
|
|
3042
4418
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
3043
|
-
import { invariant as
|
|
4419
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
3044
4420
|
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
3045
|
-
import { isNotNullOrUndefined } from "@dxos/util";
|
|
3046
4421
|
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
3047
4422
|
var useTextModel = (props) => {
|
|
3048
4423
|
const { identity, space, text } = props;
|
|
3049
|
-
const [model, setModel] =
|
|
3050
|
-
|
|
4424
|
+
const [model, setModel] = useState5();
|
|
4425
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
3051
4426
|
identity,
|
|
3052
4427
|
space,
|
|
3053
4428
|
text
|
|
3054
4429
|
]);
|
|
3055
4430
|
return model;
|
|
3056
4431
|
};
|
|
4432
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4433
|
+
const [content, setContent] = useState5(defaultContent ?? "");
|
|
4434
|
+
return {
|
|
4435
|
+
id,
|
|
4436
|
+
content,
|
|
4437
|
+
setContent,
|
|
4438
|
+
text: () => content
|
|
4439
|
+
};
|
|
4440
|
+
};
|
|
3057
4441
|
var createModel = ({ space, identity, text }) => {
|
|
3058
|
-
|
|
4442
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
3059
4443
|
F: __dxlog_file6,
|
|
3060
|
-
L:
|
|
4444
|
+
L: 50,
|
|
3061
4445
|
S: void 0,
|
|
3062
4446
|
A: [
|
|
3063
4447
|
"isAutomergeObject(text)",
|
|
@@ -3068,7 +4452,7 @@ var createModel = ({ space, identity, text }) => {
|
|
|
3068
4452
|
const doc = getRawDoc(obj, [
|
|
3069
4453
|
obj.field
|
|
3070
4454
|
]);
|
|
3071
|
-
const
|
|
4455
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
3072
4456
|
space,
|
|
3073
4457
|
channel: `automerge.awareness.${obj.id}`,
|
|
3074
4458
|
info: {
|
|
@@ -3078,19 +4462,22 @@ var createModel = ({ space, identity, text }) => {
|
|
|
3078
4462
|
},
|
|
3079
4463
|
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
3080
4464
|
});
|
|
4465
|
+
const extensions = [
|
|
4466
|
+
//
|
|
4467
|
+
modelState.init(() => model),
|
|
4468
|
+
automerge({
|
|
4469
|
+
handle: doc.handle,
|
|
4470
|
+
path: doc.path
|
|
4471
|
+
})
|
|
4472
|
+
];
|
|
4473
|
+
if (awarenessProvider2) {
|
|
4474
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4475
|
+
}
|
|
3081
4476
|
const model = {
|
|
3082
4477
|
id: obj.id,
|
|
3083
4478
|
content: doc,
|
|
3084
4479
|
text: () => get4(doc.handle.docSync(), doc.path),
|
|
3085
|
-
extension:
|
|
3086
|
-
modelState.init(() => model),
|
|
3087
|
-
automerge4({
|
|
3088
|
-
handle: doc.handle,
|
|
3089
|
-
path: doc.path
|
|
3090
|
-
}),
|
|
3091
|
-
awarenessProvider && AwarenessProvider.of(awarenessProvider),
|
|
3092
|
-
awareness()
|
|
3093
|
-
].filter(isNotNullOrUndefined),
|
|
4480
|
+
extension: extensions,
|
|
3094
4481
|
peer: identity ? {
|
|
3095
4482
|
id: identity.identityKey.toHex(),
|
|
3096
4483
|
name: identity.profile?.displayName
|
|
@@ -3099,42 +4486,57 @@ var createModel = ({ space, identity, text }) => {
|
|
|
3099
4486
|
return model;
|
|
3100
4487
|
};
|
|
3101
4488
|
export {
|
|
3102
|
-
AwarenessProvider,
|
|
3103
4489
|
BaseTextEditor,
|
|
3104
4490
|
Cursor,
|
|
3105
4491
|
Doc,
|
|
3106
4492
|
EditorModes,
|
|
4493
|
+
Inline,
|
|
4494
|
+
List,
|
|
3107
4495
|
MarkdownEditor,
|
|
3108
4496
|
RemoteSelectionsDecorator,
|
|
3109
4497
|
SpaceAwarenessProvider,
|
|
3110
4498
|
TextEditor,
|
|
3111
4499
|
TextKind,
|
|
4500
|
+
Toolbar,
|
|
3112
4501
|
YText,
|
|
3113
4502
|
YXmlFragment,
|
|
4503
|
+
addBlockquote,
|
|
4504
|
+
addCodeblock,
|
|
4505
|
+
addLink,
|
|
4506
|
+
addList,
|
|
4507
|
+
addStyle,
|
|
3114
4508
|
autocomplete,
|
|
3115
|
-
|
|
4509
|
+
automerge,
|
|
3116
4510
|
awareness,
|
|
3117
|
-
|
|
4511
|
+
awarenessProvider,
|
|
3118
4512
|
blast,
|
|
3119
4513
|
callbackWrapper,
|
|
3120
4514
|
code2 as code,
|
|
3121
4515
|
codeTheme,
|
|
3122
4516
|
comments,
|
|
4517
|
+
compareFormatting,
|
|
4518
|
+
createBasicBundle,
|
|
3123
4519
|
createComment,
|
|
4520
|
+
createDataExtensions,
|
|
4521
|
+
createMarkdownExtensions,
|
|
4522
|
+
createThemeExtensions,
|
|
3124
4523
|
defaultMarkdownSlots,
|
|
3125
4524
|
defaultOptions,
|
|
3126
4525
|
defaultSlots,
|
|
3127
4526
|
defaultTextSlots,
|
|
3128
4527
|
defaultTheme,
|
|
4528
|
+
focusComment,
|
|
3129
4529
|
formatting,
|
|
4530
|
+
getFormatting,
|
|
3130
4531
|
getToken,
|
|
3131
4532
|
heading2 as heading,
|
|
3132
4533
|
hr,
|
|
3133
4534
|
image,
|
|
4535
|
+
insertTable,
|
|
4536
|
+
keymap7 as keymap,
|
|
3134
4537
|
link,
|
|
3135
4538
|
listener,
|
|
3136
4539
|
logChanges,
|
|
3137
|
-
markdownBundle,
|
|
3138
4540
|
markdownHighlightStyle,
|
|
3139
4541
|
markdownTags,
|
|
3140
4542
|
markdownTagsExtensions,
|
|
@@ -3142,23 +4544,36 @@ export {
|
|
|
3142
4544
|
mention,
|
|
3143
4545
|
modelState,
|
|
3144
4546
|
outliner,
|
|
4547
|
+
removeBlockquote,
|
|
4548
|
+
removeCodeblock,
|
|
4549
|
+
removeLink,
|
|
4550
|
+
removeList,
|
|
4551
|
+
removeStyle,
|
|
4552
|
+
setBlockquote,
|
|
3145
4553
|
setComments,
|
|
3146
|
-
setFocus,
|
|
3147
4554
|
setHeading,
|
|
3148
4555
|
setSelection,
|
|
4556
|
+
setStyle,
|
|
3149
4557
|
table,
|
|
3150
4558
|
tags2 as tags,
|
|
3151
4559
|
tasklist,
|
|
3152
4560
|
textTheme,
|
|
3153
|
-
|
|
3154
|
-
|
|
4561
|
+
toggleBlockquote,
|
|
4562
|
+
toggleCodeblock,
|
|
4563
|
+
toggleEmphasis,
|
|
4564
|
+
toggleInlineCode,
|
|
3155
4565
|
toggleList,
|
|
3156
4566
|
toggleStrikethrough,
|
|
4567
|
+
toggleStrong,
|
|
3157
4568
|
toggleStyle,
|
|
3158
4569
|
typewriter,
|
|
3159
4570
|
useActionHandler,
|
|
3160
4571
|
useComments,
|
|
4572
|
+
useEditorView,
|
|
4573
|
+
useFormattingState,
|
|
4574
|
+
useInMemoryTextModel,
|
|
3161
4575
|
useTextEditor,
|
|
3162
|
-
useTextModel
|
|
4576
|
+
useTextModel,
|
|
4577
|
+
useToolbarContext
|
|
3163
4578
|
};
|
|
3164
4579
|
//# sourceMappingURL=index.mjs.map
|