@dxos/react-ui-editor 0.4.8-main.8cb190e → 0.4.8-main.8ec301e
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 +527 -305
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -2
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +2 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +11 -5
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +4 -2
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -0
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +3 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +7 -4
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts +6 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +2 -1
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/state.d.ts +20 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useDocAccessor.d.ts +4 -2
- package/dist/types/src/hooks/useDocAccessor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.stories.d.ts +1 -0
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +26 -24
- package/src/components/TextEditor/TextEditor.stories.tsx +16 -4
- package/src/components/TextEditor/TextEditor.tsx +13 -12
- package/src/components/Toolbar/Toolbar.stories.tsx +23 -24
- package/src/components/Toolbar/Toolbar.tsx +101 -35
- package/src/extensions/automerge/automerge.ts +4 -4
- package/src/extensions/comments.ts +2 -2
- package/src/extensions/factories.ts +30 -7
- package/src/extensions/index.ts +1 -0
- package/src/extensions/markdown/bundle.ts +8 -11
- package/src/extensions/markdown/formatting.test.ts +13 -13
- package/src/extensions/markdown/formatting.ts +95 -87
- package/src/extensions/markdown/image.ts +6 -0
- package/src/extensions/modes.ts +11 -2
- package/src/extensions/state.ts +90 -0
- package/src/hooks/useActionHandler.ts +5 -1
- package/src/hooks/useDocAccessor.ts +8 -2
- package/src/hooks/useTextEditor.stories.tsx +3 -3
- package/src/hooks/useTextEditor.ts +3 -0
- package/src/themes/default.ts +24 -8
- package/src/translations.ts +1 -0
|
@@ -15,6 +15,7 @@ var translations_default = [
|
|
|
15
15
|
"blockquote label": "Block quote",
|
|
16
16
|
"codeblock label": "Code block",
|
|
17
17
|
"comment label": "Create comment",
|
|
18
|
+
"image label": "Insert image",
|
|
18
19
|
"heading label": "Heading level",
|
|
19
20
|
"table label": "Create table"
|
|
20
21
|
}
|
|
@@ -23,18 +24,18 @@ var translations_default = [
|
|
|
23
24
|
];
|
|
24
25
|
|
|
25
26
|
// packages/ui/react-ui-editor/src/index.ts
|
|
26
|
-
import { keymap as
|
|
27
|
+
import { keymap as keymap11 } from "@codemirror/view";
|
|
27
28
|
import { tags as tags2 } from "@lezer/highlight";
|
|
28
29
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
29
30
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
30
31
|
|
|
31
32
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
32
33
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
33
|
-
import { EditorView as
|
|
34
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
34
35
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
35
36
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
36
37
|
import { log as log9 } from "@dxos/log";
|
|
37
|
-
import { isNotFalsy as
|
|
38
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
38
39
|
|
|
39
40
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
40
41
|
import { StateField } from "@codemirror/state";
|
|
@@ -56,8 +57,8 @@ var Cursor = class _Cursor {
|
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
static {
|
|
59
|
-
this.getCursorFromRange = (
|
|
60
|
-
const cursorConverter2 =
|
|
60
|
+
this.getCursorFromRange = (state2, range) => {
|
|
61
|
+
const cursorConverter2 = state2.facet(_Cursor.converter);
|
|
61
62
|
const from = cursorConverter2.toCursor(range.from);
|
|
62
63
|
const to = cursorConverter2.toCursor(range.to, -1);
|
|
63
64
|
return [
|
|
@@ -67,8 +68,8 @@ var Cursor = class _Cursor {
|
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
static {
|
|
70
|
-
this.getRangeFromCursor = (
|
|
71
|
-
const cursorConverter2 =
|
|
71
|
+
this.getRangeFromCursor = (state2, cursor) => {
|
|
72
|
+
const cursorConverter2 = state2.facet(_Cursor.converter);
|
|
72
73
|
const parts = cursor.split(":");
|
|
73
74
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
74
75
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
@@ -85,15 +86,15 @@ var annotationMark = Decoration.mark({
|
|
|
85
86
|
class: "cm-annotation"
|
|
86
87
|
});
|
|
87
88
|
var annotations = (options = {}) => {
|
|
88
|
-
const match = (
|
|
89
|
+
const match = (state2) => {
|
|
89
90
|
const annotations2 = [];
|
|
90
|
-
const text =
|
|
91
|
+
const text = state2.doc.toString();
|
|
91
92
|
if (options.match) {
|
|
92
93
|
const matches = text.matchAll(options.match);
|
|
93
94
|
for (const match2 of matches) {
|
|
94
95
|
const from = match2.index;
|
|
95
96
|
const to = from + match2[0].length;
|
|
96
|
-
const cursor = Cursor.getCursorFromRange(
|
|
97
|
+
const cursor = Cursor.getCursorFromRange(state2, {
|
|
97
98
|
from,
|
|
98
99
|
to
|
|
99
100
|
});
|
|
@@ -105,8 +106,8 @@ var annotations = (options = {}) => {
|
|
|
105
106
|
return annotations2;
|
|
106
107
|
};
|
|
107
108
|
const annotationsState = StateField.define({
|
|
108
|
-
create: (
|
|
109
|
-
return match(
|
|
109
|
+
create: (state2) => {
|
|
110
|
+
return match(state2);
|
|
110
111
|
},
|
|
111
112
|
update: (value, tr) => {
|
|
112
113
|
if (!tr.changes.empty) {
|
|
@@ -119,10 +120,10 @@ var annotations = (options = {}) => {
|
|
|
119
120
|
annotationsState,
|
|
120
121
|
EditorView.decorations.compute([
|
|
121
122
|
annotationsState
|
|
122
|
-
], (
|
|
123
|
-
const annotations2 =
|
|
123
|
+
], (state2) => {
|
|
124
|
+
const annotations2 = state2.field(annotationsState);
|
|
124
125
|
const decorations = annotations2.map((annotation2) => {
|
|
125
|
-
const range = Cursor.getRangeFromCursor(
|
|
126
|
+
const range = Cursor.getRangeFromCursor(state2, annotation2.cursor);
|
|
126
127
|
return range && annotationMark.range(range.from, range.to);
|
|
127
128
|
}).filter(isNotFalsy);
|
|
128
129
|
return Decoration.set(decorations);
|
|
@@ -239,8 +240,8 @@ var cursorConverter = ({ handle, path }) => ({
|
|
|
239
240
|
|
|
240
241
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
241
242
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
242
|
-
var getPath = (
|
|
243
|
-
var getLastHeads = (
|
|
243
|
+
var getPath = (state2, field) => state2.field(field).path;
|
|
244
|
+
var getLastHeads = (state2, field) => state2.field(field).lastHeads;
|
|
244
245
|
var updateHeadsEffect = StateEffect.define({});
|
|
245
246
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
246
247
|
newHeads
|
|
@@ -255,8 +256,8 @@ import { next as A3 } from "@dxos/automerge/automerge";
|
|
|
255
256
|
|
|
256
257
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
|
257
258
|
import { next as A2 } from "@dxos/automerge/automerge";
|
|
258
|
-
var updateAutomerge = (field, handle, transactions,
|
|
259
|
-
const { lastHeads, path } =
|
|
259
|
+
var updateAutomerge = (field, handle, transactions, state2) => {
|
|
260
|
+
const { lastHeads, path } = state2.field(field);
|
|
260
261
|
let hasChanges = false;
|
|
261
262
|
for (const tr of transactions) {
|
|
262
263
|
tr.changes.iterChanges(() => {
|
|
@@ -303,7 +304,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
303
304
|
annotations: reconcileAnnotation.of(false)
|
|
304
305
|
});
|
|
305
306
|
};
|
|
306
|
-
var handlePatch = (patch, target,
|
|
307
|
+
var handlePatch = (patch, target, state2) => {
|
|
307
308
|
if (patch.action === "insert") {
|
|
308
309
|
return handleInsert(target, patch);
|
|
309
310
|
} else if (patch.action === "splice") {
|
|
@@ -311,7 +312,7 @@ var handlePatch = (patch, target, state) => {
|
|
|
311
312
|
} else if (patch.action === "del") {
|
|
312
313
|
return handleDel(target, patch);
|
|
313
314
|
} else if (patch.action === "put") {
|
|
314
|
-
return handlePut(target, patch,
|
|
315
|
+
return handlePut(target, patch, state2);
|
|
315
316
|
} else {
|
|
316
317
|
return null;
|
|
317
318
|
}
|
|
@@ -355,7 +356,7 @@ var handleDel = (target, patch) => {
|
|
|
355
356
|
}
|
|
356
357
|
];
|
|
357
358
|
};
|
|
358
|
-
var handlePut = (target, patch,
|
|
359
|
+
var handlePut = (target, patch, state2) => {
|
|
359
360
|
const index = charPath(target, [
|
|
360
361
|
...patch.path,
|
|
361
362
|
0
|
|
@@ -363,7 +364,7 @@ var handlePut = (target, patch, state) => {
|
|
|
363
364
|
if (index == null) {
|
|
364
365
|
return [];
|
|
365
366
|
}
|
|
366
|
-
const length =
|
|
367
|
+
const length = state2.doc.length;
|
|
367
368
|
if (typeof patch.value !== "string") {
|
|
368
369
|
return [];
|
|
369
370
|
}
|
|
@@ -474,13 +475,13 @@ var automerge = (accessor) => {
|
|
|
474
475
|
ViewPlugin.fromClass(class {
|
|
475
476
|
constructor(_view) {
|
|
476
477
|
this._view = _view;
|
|
477
|
-
|
|
478
|
+
this._handleChange = () => {
|
|
479
|
+
syncer.reconcile(this._view, false);
|
|
480
|
+
};
|
|
481
|
+
accessor.handle.addListener("change", this._handleChange);
|
|
478
482
|
}
|
|
479
483
|
destroy() {
|
|
480
|
-
accessor.handle.removeListener("change", this._handleChange
|
|
481
|
-
}
|
|
482
|
-
_handleChange() {
|
|
483
|
-
syncer.reconcile(this._view, false);
|
|
484
|
+
accessor.handle.removeListener("change", this._handleChange);
|
|
484
485
|
}
|
|
485
486
|
}),
|
|
486
487
|
// Reconcile local updates.
|
|
@@ -561,9 +562,9 @@ var RemoteSelectionsDecorator = class {
|
|
|
561
562
|
_updateRemoteSelections(update2) {
|
|
562
563
|
const decorations = [];
|
|
563
564
|
const awarenessStates = this._provider.getRemoteStates();
|
|
564
|
-
for (const
|
|
565
|
-
const anchor =
|
|
566
|
-
const head =
|
|
565
|
+
for (const state2 of awarenessStates) {
|
|
566
|
+
const anchor = state2.position?.anchor ? this._cursorConverter.fromCursor(state2.position.anchor) : null;
|
|
567
|
+
const head = state2.position?.head ? this._cursorConverter.fromCursor(state2.position.head) : null;
|
|
567
568
|
if (anchor == null || head == null) {
|
|
568
569
|
continue;
|
|
569
570
|
}
|
|
@@ -571,8 +572,8 @@ var RemoteSelectionsDecorator = class {
|
|
|
571
572
|
const end = Math.min(Math.max(anchor, head), update2.view.state.doc.length);
|
|
572
573
|
const startLine = update2.view.state.doc.lineAt(start);
|
|
573
574
|
const endLine = update2.view.state.doc.lineAt(end);
|
|
574
|
-
const color =
|
|
575
|
-
const lightColor =
|
|
575
|
+
const color = state2.info.color ?? "#30bced";
|
|
576
|
+
const lightColor = state2.info.lightColor ?? color + "33";
|
|
576
577
|
if (startLine.number === endLine.number) {
|
|
577
578
|
decorations.push({
|
|
578
579
|
from: start,
|
|
@@ -625,7 +626,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
625
626
|
value: Decoration2.widget({
|
|
626
627
|
side: head - anchor > 0 ? -1 : 1,
|
|
627
628
|
block: false,
|
|
628
|
-
widget: new RemoteCaretWidget(
|
|
629
|
+
widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", color)
|
|
629
630
|
})
|
|
630
631
|
});
|
|
631
632
|
}
|
|
@@ -1156,7 +1157,7 @@ var commandConfig = Facet3.define({
|
|
|
1156
1157
|
});
|
|
1157
1158
|
var commandState = StateField3.define({
|
|
1158
1159
|
create: () => ({}),
|
|
1159
|
-
update: (
|
|
1160
|
+
update: (state2, tr) => {
|
|
1160
1161
|
for (const effect of tr.effects) {
|
|
1161
1162
|
if (effect.is(closeEffect)) {
|
|
1162
1163
|
return {};
|
|
@@ -1207,7 +1208,7 @@ var commandState = StateField3.define({
|
|
|
1207
1208
|
};
|
|
1208
1209
|
}
|
|
1209
1210
|
}
|
|
1210
|
-
return
|
|
1211
|
+
return state2;
|
|
1211
1212
|
},
|
|
1212
1213
|
provide: (field) => [
|
|
1213
1214
|
showTooltip.from(field, (value) => value.tooltip ?? null)
|
|
@@ -1453,8 +1454,8 @@ var setComments = StateEffect3.define();
|
|
|
1453
1454
|
var setSelection = StateEffect3.define();
|
|
1454
1455
|
var setCommentState = StateEffect3.define();
|
|
1455
1456
|
var commentsState = StateField4.define({
|
|
1456
|
-
create: (
|
|
1457
|
-
id:
|
|
1457
|
+
create: (state2) => ({
|
|
1458
|
+
id: state2.facet(documentId),
|
|
1458
1459
|
comments: [],
|
|
1459
1460
|
selection: {}
|
|
1460
1461
|
}),
|
|
@@ -1526,8 +1527,8 @@ var commentCurrentMark = Decoration4.mark({
|
|
|
1526
1527
|
});
|
|
1527
1528
|
var commentsDecorations = EditorView7.decorations.compute([
|
|
1528
1529
|
commentsState
|
|
1529
|
-
], (
|
|
1530
|
-
const { selection: { current }, comments: comments2 } =
|
|
1530
|
+
], (state2) => {
|
|
1531
|
+
const { selection: { current }, comments: comments2 } = state2.field(commentsState);
|
|
1531
1532
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1532
1533
|
const range = comment.range;
|
|
1533
1534
|
if (!range || range.from === range.to) {
|
|
@@ -1691,7 +1692,7 @@ var optionsFacet = Facet4.define({
|
|
|
1691
1692
|
});
|
|
1692
1693
|
var comments = (options = {}) => {
|
|
1693
1694
|
const { key: shortcut = "meta-'" } = options;
|
|
1694
|
-
const handleSelect = debounce((
|
|
1695
|
+
const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
|
|
1695
1696
|
return [
|
|
1696
1697
|
optionsFacet.of(options),
|
|
1697
1698
|
documentId.of(options.id),
|
|
@@ -1740,9 +1741,9 @@ var comments = (options = {}) => {
|
|
|
1740
1741
|
//
|
|
1741
1742
|
// Track deleted ranges and update ranges for decorations.
|
|
1742
1743
|
//
|
|
1743
|
-
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1744
|
+
EditorView7.updateListener.of(({ view, state: state2, changes }) => {
|
|
1744
1745
|
let mod = false;
|
|
1745
|
-
const { comments: comments2, ...value } =
|
|
1746
|
+
const { comments: comments2, ...value } = state2.field(commentsState);
|
|
1746
1747
|
changes.iterChanges((from, to, from2, to2) => {
|
|
1747
1748
|
comments2.forEach(({ comment, range }) => {
|
|
1748
1749
|
if (from2 === to2) {
|
|
@@ -1772,10 +1773,10 @@ var comments = (options = {}) => {
|
|
|
1772
1773
|
//
|
|
1773
1774
|
// Track selection/proximity.
|
|
1774
1775
|
//
|
|
1775
|
-
EditorView7.updateListener.of(({ view, state }) => {
|
|
1776
|
+
EditorView7.updateListener.of(({ view, state: state2 }) => {
|
|
1776
1777
|
let min = Infinity;
|
|
1777
|
-
const { selection: { current, closest }, comments: comments2 } =
|
|
1778
|
-
const { head } =
|
|
1778
|
+
const { selection: { current, closest }, comments: comments2 } = state2.field(commentsState);
|
|
1779
|
+
const { head } = state2.selection.main;
|
|
1779
1780
|
const selection = {};
|
|
1780
1781
|
comments2.forEach(({ comment, range }) => {
|
|
1781
1782
|
if (head >= range.from && head <= range.to) {
|
|
@@ -1796,7 +1797,7 @@ var comments = (options = {}) => {
|
|
|
1796
1797
|
});
|
|
1797
1798
|
handleSelect({
|
|
1798
1799
|
selection,
|
|
1799
|
-
id:
|
|
1800
|
+
id: state2.facet(documentId),
|
|
1800
1801
|
comments: comments2.map(({ comment, range }) => ({
|
|
1801
1802
|
comment,
|
|
1802
1803
|
range,
|
|
@@ -1831,14 +1832,14 @@ var focusComment = (view, id, center = true) => {
|
|
|
1831
1832
|
});
|
|
1832
1833
|
}
|
|
1833
1834
|
};
|
|
1834
|
-
var useComments = (view, id, comments2
|
|
1835
|
+
var useComments = (view, id, comments2) => {
|
|
1835
1836
|
useEffect(() => {
|
|
1836
1837
|
if (view) {
|
|
1837
1838
|
if (id === view.state.facet(documentId)) {
|
|
1838
1839
|
view.dispatch({
|
|
1839
1840
|
effects: setComments.of({
|
|
1840
1841
|
id,
|
|
1841
|
-
comments: comments2
|
|
1842
|
+
comments: comments2 ?? []
|
|
1842
1843
|
})
|
|
1843
1844
|
});
|
|
1844
1845
|
}
|
|
@@ -1864,11 +1865,11 @@ var cursorLineMargin = (options = {
|
|
|
1864
1865
|
if (!lines || lines <= 0) {
|
|
1865
1866
|
return [];
|
|
1866
1867
|
}
|
|
1867
|
-
return EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1868
|
+
return EditorView8.updateListener.of(({ transactions, state: state2, selectionSet, startState, view }) => {
|
|
1868
1869
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1869
1870
|
return;
|
|
1870
1871
|
}
|
|
1871
|
-
const s =
|
|
1872
|
+
const s = state2;
|
|
1872
1873
|
const { main } = s.selection;
|
|
1873
1874
|
const rect = view.dom.getBoundingClientRect();
|
|
1874
1875
|
const viewportTop = rect.top - view.documentTop;
|
|
@@ -1951,11 +1952,12 @@ var dnd = () => {
|
|
|
1951
1952
|
};
|
|
1952
1953
|
|
|
1953
1954
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
1954
|
-
import { closeBrackets } from "@codemirror/autocomplete";
|
|
1955
|
-
import { history } from "@codemirror/commands";
|
|
1955
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1956
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1956
1957
|
import { bracketMatching } from "@codemirror/language";
|
|
1958
|
+
import { searchKeymap } from "@codemirror/search";
|
|
1957
1959
|
import { EditorState } from "@codemirror/state";
|
|
1958
|
-
import { EditorView as EditorView10, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
|
1960
|
+
import { EditorView as EditorView10, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, highlightSpecialChars, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
|
1959
1961
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1960
1962
|
import { generateName } from "@dxos/display-name";
|
|
1961
1963
|
import { log as log7 } from "@dxos/log";
|
|
@@ -2163,41 +2165,59 @@ var defaultTheme = {
|
|
|
2163
2165
|
* </div>
|
|
2164
2166
|
* </div
|
|
2165
2167
|
*/
|
|
2166
|
-
".cm-panels": {
|
|
2167
|
-
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
|
|
2168
|
-
},
|
|
2168
|
+
".cm-panels": {},
|
|
2169
2169
|
".cm-panel": {
|
|
2170
|
-
background: get3(tokens, "extend.colors.neutral.50"),
|
|
2171
2170
|
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2172
2171
|
},
|
|
2172
|
+
".cm-panel input[type=checkbox]": {
|
|
2173
|
+
marginRight: "0.4rem !important"
|
|
2174
|
+
},
|
|
2175
|
+
"&light .cm-panel": {
|
|
2176
|
+
background: get3(tokens, "extend.colors.neutral.50")
|
|
2177
|
+
},
|
|
2178
|
+
"&dark .cm-panel": {
|
|
2179
|
+
background: get3(tokens, "extend.colors.neutral.850")
|
|
2180
|
+
},
|
|
2173
2181
|
".cm-button": {
|
|
2174
2182
|
margin: "4px",
|
|
2175
2183
|
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
2176
|
-
background: get3(tokens, "extend.colors.neutral.100"),
|
|
2177
2184
|
backgroundImage: "none",
|
|
2178
2185
|
border: "none",
|
|
2186
|
+
"&:active": {
|
|
2187
|
+
backgroundImage: "none"
|
|
2188
|
+
}
|
|
2189
|
+
},
|
|
2190
|
+
"&light .cm-button": {
|
|
2191
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
2179
2192
|
"&:hover": {
|
|
2180
2193
|
background: get3(tokens, "extend.colors.neutral.200")
|
|
2181
2194
|
},
|
|
2182
2195
|
"&:active": {
|
|
2183
|
-
background: get3(tokens, "extend.colors.neutral.300")
|
|
2184
|
-
backgroundImage: "none"
|
|
2196
|
+
background: get3(tokens, "extend.colors.neutral.300")
|
|
2185
2197
|
}
|
|
2186
2198
|
},
|
|
2187
|
-
".cm-
|
|
2188
|
-
|
|
2199
|
+
"&dark .cm-button": {
|
|
2200
|
+
background: get3(tokens, "extend.colors.neutral.800"),
|
|
2201
|
+
"&:hover": {
|
|
2202
|
+
background: get3(tokens, "extend.colors.neutral.700")
|
|
2203
|
+
},
|
|
2204
|
+
"&:active": {
|
|
2205
|
+
background: get3(tokens, "extend.colors.neutral.600")
|
|
2206
|
+
}
|
|
2189
2207
|
}
|
|
2190
2208
|
};
|
|
2191
2209
|
|
|
2192
2210
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2193
2211
|
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
|
2194
2212
|
var defaults = {
|
|
2213
|
+
allowMultipleSelections: true,
|
|
2195
2214
|
bracketMatching: true,
|
|
2196
2215
|
closeBrackets: true,
|
|
2197
2216
|
drawSelection: true,
|
|
2198
2217
|
editable: true,
|
|
2199
2218
|
history: true,
|
|
2200
|
-
lineWrapping: true
|
|
2219
|
+
lineWrapping: true,
|
|
2220
|
+
search: true
|
|
2201
2221
|
};
|
|
2202
2222
|
var createBasicExtensions = (_props) => {
|
|
2203
2223
|
const props = defaultsDeep2({}, _props, defaults);
|
|
@@ -2206,7 +2226,7 @@ var createBasicExtensions = (_props) => {
|
|
|
2206
2226
|
EditorView10.exceptionSink.of((err) => {
|
|
2207
2227
|
log7.catch(err, void 0, {
|
|
2208
2228
|
F: __dxlog_file9,
|
|
2209
|
-
L:
|
|
2229
|
+
L: 83,
|
|
2210
2230
|
S: void 0,
|
|
2211
2231
|
C: (f, a) => f(...a)
|
|
2212
2232
|
});
|
|
@@ -2218,6 +2238,7 @@ var createBasicExtensions = (_props) => {
|
|
|
2218
2238
|
props.dropCursor && dropCursor(),
|
|
2219
2239
|
props.drawSelection && drawSelection(),
|
|
2220
2240
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2241
|
+
highlightSpecialChars(),
|
|
2221
2242
|
props.history && history(),
|
|
2222
2243
|
props.lineNumbers && lineNumbers(),
|
|
2223
2244
|
props.lineWrapping && EditorView10.lineWrapping,
|
|
@@ -2227,7 +2248,20 @@ var createBasicExtensions = (_props) => {
|
|
|
2227
2248
|
EditorView10.editable.of(false)
|
|
2228
2249
|
],
|
|
2229
2250
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2230
|
-
props.tabSize && EditorState.tabSize.of(props.tabSize)
|
|
2251
|
+
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
2252
|
+
// https://codemirror.net/docs/ref/#view.KeyBinding
|
|
2253
|
+
keymap5.of([
|
|
2254
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2255
|
+
...standardKeymap,
|
|
2256
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2257
|
+
props.indentWithTab && indentWithTab,
|
|
2258
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
2259
|
+
...props.closeBrackets ? closeBracketsKeymap : [],
|
|
2260
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
2261
|
+
...props.history ? historyKeymap : [],
|
|
2262
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
2263
|
+
...props.search ? searchKeymap : []
|
|
2264
|
+
].filter(isNotFalsy2))
|
|
2231
2265
|
].filter(isNotFalsy2);
|
|
2232
2266
|
};
|
|
2233
2267
|
var defaultSlots = {
|
|
@@ -2286,14 +2320,14 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
2286
2320
|
};
|
|
2287
2321
|
|
|
2288
2322
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2289
|
-
import {
|
|
2290
|
-
import {
|
|
2323
|
+
import { completionKeymap as completionKeymap2 } from "@codemirror/autocomplete";
|
|
2324
|
+
import { defaultKeymap, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
2291
2325
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
2292
2326
|
import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
2293
2327
|
import { languages } from "@codemirror/language-data";
|
|
2294
|
-
import {
|
|
2328
|
+
import { lintKeymap } from "@codemirror/lint";
|
|
2295
2329
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
2296
|
-
import { keymap as
|
|
2330
|
+
import { keymap as keymap6 } from "@codemirror/view";
|
|
2297
2331
|
|
|
2298
2332
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
2299
2333
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -2508,17 +2542,13 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
2508
2542
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
2509
2543
|
// Custom styles.
|
|
2510
2544
|
syntaxHighlighting(markdownHighlightStyle()),
|
|
2511
|
-
|
|
2545
|
+
keymap6.of([
|
|
2512
2546
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2513
|
-
|
|
2514
|
-
// https://codemirror.net/docs/ref/#
|
|
2515
|
-
...
|
|
2516
|
-
|
|
2517
|
-
...
|
|
2518
|
-
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
2519
|
-
...searchKeymap,
|
|
2520
|
-
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2521
|
-
...standardKeymap
|
|
2547
|
+
indentWithTab2,
|
|
2548
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
2549
|
+
...defaultKeymap,
|
|
2550
|
+
...completionKeymap2,
|
|
2551
|
+
...lintKeymap
|
|
2522
2552
|
])
|
|
2523
2553
|
];
|
|
2524
2554
|
};
|
|
@@ -2606,8 +2636,8 @@ var checkedTask = Decoration5.replace({
|
|
|
2606
2636
|
var uncheckedTask = Decoration5.replace({
|
|
2607
2637
|
widget: new CheckboxWidget(false)
|
|
2608
2638
|
});
|
|
2609
|
-
var editingRange = (
|
|
2610
|
-
const { readOnly, selection: { main: { head } } } =
|
|
2639
|
+
var editingRange = (state2, range, focus) => {
|
|
2640
|
+
const { readOnly, selection: { main: { head } } } = state2;
|
|
2611
2641
|
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
2612
2642
|
};
|
|
2613
2643
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
@@ -2620,14 +2650,14 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
2620
2650
|
var buildDecorations = (view, options, focus) => {
|
|
2621
2651
|
const deco = new RangeSetBuilder2();
|
|
2622
2652
|
const atomicDeco = new RangeSetBuilder2();
|
|
2623
|
-
const { state } = view;
|
|
2653
|
+
const { state: state2 } = view;
|
|
2624
2654
|
for (const { from, to } of view.visibleRanges) {
|
|
2625
|
-
syntaxTree(
|
|
2655
|
+
syntaxTree(state2).iterate({
|
|
2626
2656
|
from,
|
|
2627
2657
|
to,
|
|
2628
2658
|
enter: (node) => {
|
|
2629
2659
|
if (node.name === "FencedCode") {
|
|
2630
|
-
const editing = editingRange(
|
|
2660
|
+
const editing = editingRange(state2, node, focus);
|
|
2631
2661
|
for (const block of view.viewportLineBlocks) {
|
|
2632
2662
|
if (block.to < node.from) {
|
|
2633
2663
|
continue;
|
|
@@ -2636,7 +2666,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2636
2666
|
break;
|
|
2637
2667
|
}
|
|
2638
2668
|
const first = block.from <= node.from;
|
|
2639
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(
|
|
2669
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
2640
2670
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2641
2671
|
if (!editing && (first || last)) {
|
|
2642
2672
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -2646,9 +2676,9 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2646
2676
|
} else if (node.name === "Link") {
|
|
2647
2677
|
const marks = node.node.getChildren("LinkMark");
|
|
2648
2678
|
const urlNode = node.node.getChild("URL");
|
|
2649
|
-
const editing = editingRange(
|
|
2679
|
+
const editing = editingRange(state2, node, focus);
|
|
2650
2680
|
if (urlNode && marks.length >= 2) {
|
|
2651
|
-
const url =
|
|
2681
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
2652
2682
|
if (!editing) {
|
|
2653
2683
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2654
2684
|
}
|
|
@@ -2669,24 +2699,24 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2669
2699
|
}
|
|
2670
2700
|
} else if (node.name === "HeaderMark") {
|
|
2671
2701
|
const parent = node.node.parent;
|
|
2672
|
-
if (/^ATX/.test(parent.name) && !editingRange(
|
|
2673
|
-
const next =
|
|
2702
|
+
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
2703
|
+
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
2674
2704
|
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2675
2705
|
}
|
|
2676
2706
|
} else if (node.name === "HorizontalRule") {
|
|
2677
|
-
if (!editingRange(
|
|
2707
|
+
if (!editingRange(state2, node, focus)) {
|
|
2678
2708
|
deco.add(node.from, node.to, horizontalRule);
|
|
2679
2709
|
}
|
|
2680
2710
|
} else if (node.name === "TaskMarker") {
|
|
2681
|
-
if (!editingRange(
|
|
2682
|
-
const checked =
|
|
2711
|
+
if (!editingRange(state2, node, focus)) {
|
|
2712
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2683
2713
|
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2684
2714
|
class: "cm-task"
|
|
2685
2715
|
}));
|
|
2686
2716
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2687
2717
|
}
|
|
2688
2718
|
} else if (MarksByParent.has(node.name)) {
|
|
2689
|
-
if (!editingRange(
|
|
2719
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
2690
2720
|
atomicDeco.add(node.from, node.to, hide);
|
|
2691
2721
|
}
|
|
2692
2722
|
}
|
|
@@ -2795,9 +2825,9 @@ var formattingStyles = EditorView12.baseTheme({
|
|
|
2795
2825
|
import { snippet } from "@codemirror/autocomplete";
|
|
2796
2826
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2797
2827
|
import { EditorSelection } from "@codemirror/state";
|
|
2798
|
-
import { EditorView as EditorView13, keymap as
|
|
2799
|
-
import {
|
|
2800
|
-
var
|
|
2828
|
+
import { EditorView as EditorView13, keymap as keymap7 } from "@codemirror/view";
|
|
2829
|
+
import { useMemo, useState } from "react";
|
|
2830
|
+
var formattingEquals = (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;
|
|
2801
2831
|
var Inline;
|
|
2802
2832
|
(function(Inline2) {
|
|
2803
2833
|
Inline2[Inline2["Strong"] = 0] = "Strong";
|
|
@@ -2811,13 +2841,13 @@ var List;
|
|
|
2811
2841
|
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2812
2842
|
List2[List2["Task"] = 2] = "Task";
|
|
2813
2843
|
})(List || (List = {}));
|
|
2814
|
-
var setHeading = (level) => ({ state, dispatch }) => {
|
|
2815
|
-
const { selection: { ranges }, doc } =
|
|
2844
|
+
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2845
|
+
const { selection: { ranges }, doc } = state2;
|
|
2816
2846
|
const changes = [];
|
|
2817
2847
|
let prevBlock = -1;
|
|
2818
2848
|
for (const range of ranges) {
|
|
2819
2849
|
let sawBlock = false;
|
|
2820
|
-
syntaxTree2(
|
|
2850
|
+
syntaxTree2(state2).iterate({
|
|
2821
2851
|
from: range.from,
|
|
2822
2852
|
to: range.to,
|
|
2823
2853
|
enter: (node) => {
|
|
@@ -2870,7 +2900,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2870
2900
|
}
|
|
2871
2901
|
});
|
|
2872
2902
|
let line;
|
|
2873
|
-
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line =
|
|
2903
|
+
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2874
2904
|
changes.push({
|
|
2875
2905
|
from: line.from,
|
|
2876
2906
|
to: line.to,
|
|
@@ -2881,23 +2911,23 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2881
2911
|
if (!changes.length) {
|
|
2882
2912
|
return false;
|
|
2883
2913
|
}
|
|
2884
|
-
const changeSet =
|
|
2885
|
-
dispatch(
|
|
2914
|
+
const changeSet = state2.changes(changes);
|
|
2915
|
+
dispatch(state2.update({
|
|
2886
2916
|
changes: changeSet,
|
|
2887
|
-
selection:
|
|
2917
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2888
2918
|
userEvent: "format.setHeading",
|
|
2889
2919
|
scrollIntoView: true
|
|
2890
2920
|
}));
|
|
2891
2921
|
return true;
|
|
2892
2922
|
};
|
|
2893
|
-
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
2923
|
+
var setStyle = (type, enable) => ({ state: state2, dispatch }) => {
|
|
2894
2924
|
const marker = inlineMarkerText(type);
|
|
2895
|
-
const changes =
|
|
2925
|
+
const changes = state2.changeByRange((range) => {
|
|
2896
2926
|
if (!enable && range.empty) {
|
|
2897
|
-
const after =
|
|
2927
|
+
const after = state2.doc.sliceString(range.head, range.head + 6);
|
|
2898
2928
|
const found = after.indexOf(marker);
|
|
2899
2929
|
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
2900
|
-
const before =
|
|
2930
|
+
const before = state2.doc.sliceString(range.head - 6, range.head);
|
|
2901
2931
|
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
2902
2932
|
...before.slice(before.length - found)
|
|
2903
2933
|
].reverse().join("") === after.slice(0, found)) {
|
|
@@ -2924,14 +2954,14 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2924
2954
|
let startCovered = false;
|
|
2925
2955
|
let endCovered = false;
|
|
2926
2956
|
let { from, to } = range;
|
|
2927
|
-
syntaxTree2(
|
|
2957
|
+
syntaxTree2(state2).iterate({
|
|
2928
2958
|
from,
|
|
2929
2959
|
to,
|
|
2930
2960
|
enter: (node) => {
|
|
2931
2961
|
const { name } = node;
|
|
2932
2962
|
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
2933
2963
|
blockStart = blockContentStart(node);
|
|
2934
|
-
blockEnd = blockContentEnd(node,
|
|
2964
|
+
blockEnd = blockContentEnd(node, state2.doc);
|
|
2935
2965
|
startCovered = endCovered = false;
|
|
2936
2966
|
} else if (name === "Link" || name === "Image" && enable) {
|
|
2937
2967
|
if (from < node.from && to > node.from && to <= node.to) {
|
|
@@ -2976,7 +3006,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2976
3006
|
});
|
|
2977
3007
|
if (markType !== type && closeStart >= to) {
|
|
2978
3008
|
changesAtEnd.push({
|
|
2979
|
-
from: skipSpaces(Math.min(to, blockEnd),
|
|
3009
|
+
from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
|
|
2980
3010
|
insert: inlineMarkerText(markType)
|
|
2981
3011
|
});
|
|
2982
3012
|
}
|
|
@@ -2988,7 +3018,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2988
3018
|
});
|
|
2989
3019
|
if (markType !== type && openEnd <= from) {
|
|
2990
3020
|
changes2.push({
|
|
2991
|
-
from: skipSpaces(Math.max(from, blockStart),
|
|
3021
|
+
from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
|
|
2992
3022
|
insert: inlineMarkerText(markType)
|
|
2993
3023
|
});
|
|
2994
3024
|
}
|
|
@@ -3018,7 +3048,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3018
3048
|
changes2.push(startCovered);
|
|
3019
3049
|
} else if (startCovered) {
|
|
3020
3050
|
changes2.push({
|
|
3021
|
-
from: skipSpaces(rangeStart,
|
|
3051
|
+
from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
|
|
3022
3052
|
insert: marker
|
|
3023
3053
|
});
|
|
3024
3054
|
}
|
|
@@ -3026,7 +3056,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3026
3056
|
changes2.push(endCovered);
|
|
3027
3057
|
} else if (endCovered) {
|
|
3028
3058
|
changes2.push({
|
|
3029
|
-
from: skipSpaces(rangeEnd,
|
|
3059
|
+
from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
|
|
3030
3060
|
insert: marker
|
|
3031
3061
|
});
|
|
3032
3062
|
}
|
|
@@ -3034,7 +3064,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3034
3064
|
}
|
|
3035
3065
|
}
|
|
3036
3066
|
});
|
|
3037
|
-
if (blockStart < 0 && range.empty && enable && !/\S/.test(
|
|
3067
|
+
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
3038
3068
|
return {
|
|
3039
3069
|
changes: {
|
|
3040
3070
|
from: range.head,
|
|
@@ -3043,13 +3073,13 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3043
3073
|
range: EditorSelection.cursor(range.head + marker.length)
|
|
3044
3074
|
};
|
|
3045
3075
|
}
|
|
3046
|
-
const changeSet =
|
|
3076
|
+
const changeSet = state2.changes(changes2.concat(changesAtEnd));
|
|
3047
3077
|
return {
|
|
3048
3078
|
changes: changeSet,
|
|
3049
3079
|
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
3050
3080
|
};
|
|
3051
3081
|
});
|
|
3052
|
-
dispatch(
|
|
3082
|
+
dispatch(state2.update(changes, {
|
|
3053
3083
|
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
3054
3084
|
scrollIntoView: true
|
|
3055
3085
|
}));
|
|
@@ -3123,8 +3153,8 @@ var insertTable = (view) => {
|
|
|
3123
3153
|
const { from } = doc.line(number);
|
|
3124
3154
|
snippets.table(view, null, from, from);
|
|
3125
3155
|
};
|
|
3126
|
-
var removeLinkInner = (from, to, changes,
|
|
3127
|
-
syntaxTree2(
|
|
3156
|
+
var removeLinkInner = (from, to, changes, state2) => {
|
|
3157
|
+
syntaxTree2(state2).iterate({
|
|
3128
3158
|
from,
|
|
3129
3159
|
to,
|
|
3130
3160
|
enter: (node) => {
|
|
@@ -3138,8 +3168,8 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3138
3168
|
});
|
|
3139
3169
|
} else if (name === "LinkTitle" || name === "URL") {
|
|
3140
3170
|
changes.push({
|
|
3141
|
-
from: skipSpaces(node2.from,
|
|
3142
|
-
to: skipSpaces(node2.to,
|
|
3171
|
+
from: skipSpaces(node2.from, state2.doc, -1),
|
|
3172
|
+
to: skipSpaces(node2.to, state2.doc, 1)
|
|
3143
3173
|
});
|
|
3144
3174
|
}
|
|
3145
3175
|
});
|
|
@@ -3148,32 +3178,32 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3148
3178
|
}
|
|
3149
3179
|
});
|
|
3150
3180
|
};
|
|
3151
|
-
var removeLink = ({ state, dispatch }) => {
|
|
3181
|
+
var removeLink = ({ state: state2, dispatch }) => {
|
|
3152
3182
|
const changes = [];
|
|
3153
|
-
for (const { from, to } of
|
|
3154
|
-
removeLinkInner(from, to, changes,
|
|
3183
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3184
|
+
removeLinkInner(from, to, changes, state2);
|
|
3155
3185
|
}
|
|
3156
3186
|
if (!changes) {
|
|
3157
3187
|
return false;
|
|
3158
3188
|
}
|
|
3159
|
-
dispatch(
|
|
3189
|
+
dispatch(state2.update({
|
|
3160
3190
|
changes,
|
|
3161
3191
|
userEvent: "format.link.remove",
|
|
3162
3192
|
scrollIntoView: true
|
|
3163
3193
|
}));
|
|
3164
3194
|
return true;
|
|
3165
3195
|
};
|
|
3166
|
-
var addLink = ({ state, dispatch }) => {
|
|
3167
|
-
const changes =
|
|
3196
|
+
var addLink = ({ url, image: image2 } = {}) => ({ state: state2, dispatch }) => {
|
|
3197
|
+
const changes = state2.changeByRange((range) => {
|
|
3168
3198
|
let { from, to } = range;
|
|
3169
3199
|
const cutStyles = [];
|
|
3170
3200
|
let okay = null;
|
|
3171
|
-
syntaxTree2(
|
|
3201
|
+
syntaxTree2(state2).iterate({
|
|
3172
3202
|
from,
|
|
3173
3203
|
to,
|
|
3174
3204
|
enter: (node) => {
|
|
3175
3205
|
if (Object.hasOwn(Textblocks, node.name)) {
|
|
3176
|
-
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node,
|
|
3206
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
|
|
3177
3207
|
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
3178
3208
|
const sNode = node.node;
|
|
3179
3209
|
if (node.from < from && node.to <= to) {
|
|
@@ -3193,7 +3223,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3193
3223
|
}
|
|
3194
3224
|
});
|
|
3195
3225
|
if (okay === null) {
|
|
3196
|
-
const line =
|
|
3226
|
+
const line = state2.doc.lineAt(from);
|
|
3197
3227
|
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
3198
3228
|
}
|
|
3199
3229
|
if (!okay) {
|
|
@@ -3203,26 +3233,26 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3203
3233
|
}
|
|
3204
3234
|
const changes2 = [];
|
|
3205
3235
|
const changesAfter = [];
|
|
3206
|
-
removeLinkInner(from, to, changesAfter,
|
|
3236
|
+
removeLinkInner(from, to, changesAfter, state2);
|
|
3207
3237
|
let cursorOffset = 1;
|
|
3208
3238
|
for (const style of cutStyles) {
|
|
3209
3239
|
const type = InlineMarker[style.name];
|
|
3210
3240
|
const mark2 = inlineMarkerText(type);
|
|
3211
3241
|
if (style.from < from) {
|
|
3212
3242
|
changes2.push({
|
|
3213
|
-
from: skipSpaces(from,
|
|
3243
|
+
from: skipSpaces(from, state2.doc, -1),
|
|
3214
3244
|
insert: mark2
|
|
3215
3245
|
});
|
|
3216
3246
|
changesAfter.push({
|
|
3217
|
-
from: skipSpaces(from,
|
|
3247
|
+
from: skipSpaces(from, state2.doc, 1, to),
|
|
3218
3248
|
insert: mark2
|
|
3219
3249
|
});
|
|
3220
3250
|
} else {
|
|
3221
3251
|
changes2.push({
|
|
3222
|
-
from: skipSpaces(to,
|
|
3252
|
+
from: skipSpaces(to, state2.doc, -1, from),
|
|
3223
3253
|
insert: mark2
|
|
3224
3254
|
});
|
|
3225
|
-
const after = skipSpaces(to,
|
|
3255
|
+
const after = skipSpaces(to, state2.doc, 1);
|
|
3226
3256
|
if (after === to) {
|
|
3227
3257
|
cursorOffset += mark2.length;
|
|
3228
3258
|
}
|
|
@@ -3234,34 +3264,34 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3234
3264
|
}
|
|
3235
3265
|
changes2.push({
|
|
3236
3266
|
from,
|
|
3237
|
-
insert: "["
|
|
3267
|
+
insert: image2 ? "`
|
|
3241
3271
|
});
|
|
3242
|
-
const changeSet =
|
|
3272
|
+
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
3243
3273
|
return {
|
|
3244
3274
|
changes: changeSet,
|
|
3245
|
-
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
3275
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
|
|
3246
3276
|
};
|
|
3247
3277
|
});
|
|
3248
3278
|
if (changes.changes.empty) {
|
|
3249
3279
|
return false;
|
|
3250
3280
|
}
|
|
3251
|
-
dispatch(
|
|
3281
|
+
dispatch(state2.update(changes, {
|
|
3252
3282
|
userEvent: "format.link.add",
|
|
3253
3283
|
scrollIntoView: true
|
|
3254
3284
|
}));
|
|
3255
3285
|
return true;
|
|
3256
3286
|
};
|
|
3257
|
-
var addList = (type) => ({ state, dispatch }) => {
|
|
3287
|
+
var addList = (type) => ({ state: state2, dispatch }) => {
|
|
3258
3288
|
let lastBlock = -1;
|
|
3259
3289
|
let counter = 1;
|
|
3260
3290
|
let first = true;
|
|
3261
3291
|
let parentColumn = null;
|
|
3262
3292
|
const blocks = [];
|
|
3263
|
-
for (const { from, to } of
|
|
3264
|
-
syntaxTree2(
|
|
3293
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3294
|
+
syntaxTree2(state2).iterate({
|
|
3265
3295
|
from,
|
|
3266
3296
|
to,
|
|
3267
3297
|
enter: (node) => {
|
|
@@ -3273,7 +3303,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3273
3303
|
}
|
|
3274
3304
|
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
3275
3305
|
const item = before.lastChild;
|
|
3276
|
-
const itemLine =
|
|
3306
|
+
const itemLine = state2.doc.lineAt(item.from);
|
|
3277
3307
|
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
3278
3308
|
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
3279
3309
|
if (type === 0) {
|
|
@@ -3308,10 +3338,10 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3308
3338
|
});
|
|
3309
3339
|
}
|
|
3310
3340
|
if (!blocks.length) {
|
|
3311
|
-
const { from, to } =
|
|
3341
|
+
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
3312
3342
|
if (from === to) {
|
|
3313
3343
|
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
3314
|
-
dispatch(
|
|
3344
|
+
dispatch(state2.update({
|
|
3315
3345
|
changes: [
|
|
3316
3346
|
{
|
|
3317
3347
|
from,
|
|
@@ -3332,11 +3362,11 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3332
3362
|
for (let i = 0; i < blocks.length; i++) {
|
|
3333
3363
|
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
3334
3364
|
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
3335
|
-
let padding = nodeFrom > 0 && !/\s/.test(
|
|
3365
|
+
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
3336
3366
|
if (type === 0) {
|
|
3337
3367
|
padding += String(counter2).length;
|
|
3338
3368
|
}
|
|
3339
|
-
let line =
|
|
3369
|
+
let line = state2.doc.lineAt(nodeFrom);
|
|
3340
3370
|
const column = nodeFrom - line.from;
|
|
3341
3371
|
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
3342
3372
|
padding = Math.max(padding, parentColumn2 - column);
|
|
@@ -3361,7 +3391,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3361
3391
|
insert: mark2
|
|
3362
3392
|
});
|
|
3363
3393
|
while (line.to < node.to) {
|
|
3364
|
-
line =
|
|
3394
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3365
3395
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3366
3396
|
changes.push({
|
|
3367
3397
|
from: line.from + Math.min(open, column),
|
|
@@ -3376,25 +3406,25 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3376
3406
|
next = next.nextSibling;
|
|
3377
3407
|
}
|
|
3378
3408
|
if (next?.name === "OrderedList") {
|
|
3379
|
-
renumberListItems(next.firstChild, last.counter + 1, changes,
|
|
3409
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
3380
3410
|
}
|
|
3381
3411
|
}
|
|
3382
|
-
const changeSet =
|
|
3383
|
-
dispatch(
|
|
3412
|
+
const changeSet = state2.changes(changes);
|
|
3413
|
+
dispatch(state2.update({
|
|
3384
3414
|
changes: changeSet,
|
|
3385
|
-
selection:
|
|
3415
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3386
3416
|
userEvent: "format.list.add",
|
|
3387
3417
|
scrollIntoView: true
|
|
3388
3418
|
}));
|
|
3389
3419
|
return true;
|
|
3390
3420
|
};
|
|
3391
|
-
var removeList = (type) => ({ state, dispatch }) => {
|
|
3421
|
+
var removeList = (type) => ({ state: state2, dispatch }) => {
|
|
3392
3422
|
let lastBlock = -1;
|
|
3393
3423
|
const changes = [];
|
|
3394
3424
|
const stack = [];
|
|
3395
3425
|
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
3396
|
-
for (const { from, to } of
|
|
3397
|
-
syntaxTree2(
|
|
3426
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3427
|
+
syntaxTree2(state2).iterate({
|
|
3398
3428
|
from,
|
|
3399
3429
|
to,
|
|
3400
3430
|
enter: (node) => {
|
|
@@ -3411,7 +3441,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3411
3441
|
stack.pop();
|
|
3412
3442
|
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
3413
3443
|
lastBlock = node.from;
|
|
3414
|
-
let line =
|
|
3444
|
+
let line = state2.doc.lineAt(node.from);
|
|
3415
3445
|
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
3416
3446
|
if (!mark2) {
|
|
3417
3447
|
return false;
|
|
@@ -3422,7 +3452,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3422
3452
|
to: node.from + mark2[0].length
|
|
3423
3453
|
});
|
|
3424
3454
|
while (line.to < node.to) {
|
|
3425
|
-
line =
|
|
3455
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3426
3456
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3427
3457
|
if (open > column) {
|
|
3428
3458
|
changes.push({
|
|
@@ -3432,7 +3462,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3432
3462
|
}
|
|
3433
3463
|
}
|
|
3434
3464
|
if (node.to >= to) {
|
|
3435
|
-
renumberListItems(node.node.nextSibling, 1, changes,
|
|
3465
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
3436
3466
|
}
|
|
3437
3467
|
return false;
|
|
3438
3468
|
}
|
|
@@ -3442,7 +3472,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3442
3472
|
if (!changes.length) {
|
|
3443
3473
|
return false;
|
|
3444
3474
|
}
|
|
3445
|
-
dispatch(
|
|
3475
|
+
dispatch(state2.update({
|
|
3446
3476
|
changes,
|
|
3447
3477
|
userEvent: "format.list.remove",
|
|
3448
3478
|
scrollIntoView: true
|
|
@@ -3472,12 +3502,12 @@ var renumberListItems = (item, counter, changes, doc) => {
|
|
|
3472
3502
|
}
|
|
3473
3503
|
}
|
|
3474
3504
|
};
|
|
3475
|
-
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
3505
|
+
var setBlockquote = (enable) => ({ state: state2, dispatch }) => {
|
|
3476
3506
|
const lines = [];
|
|
3477
3507
|
let lastBlock = -1;
|
|
3478
|
-
for (const { from, to } of
|
|
3508
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3479
3509
|
const sawBlock = false;
|
|
3480
|
-
syntaxTree2(
|
|
3510
|
+
syntaxTree2(state2).iterate({
|
|
3481
3511
|
from,
|
|
3482
3512
|
to,
|
|
3483
3513
|
enter: (node) => {
|
|
@@ -3486,9 +3516,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3486
3516
|
return false;
|
|
3487
3517
|
}
|
|
3488
3518
|
lastBlock = node.from;
|
|
3489
|
-
let line2 =
|
|
3519
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
3490
3520
|
if (line2.number > 1) {
|
|
3491
|
-
const prevLine =
|
|
3521
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
3492
3522
|
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
3493
3523
|
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
3494
3524
|
lines.push(prevLine);
|
|
@@ -3500,10 +3530,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3500
3530
|
if (line2.to >= node.to) {
|
|
3501
3531
|
break;
|
|
3502
3532
|
}
|
|
3503
|
-
line2 =
|
|
3533
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
3504
3534
|
}
|
|
3505
|
-
if (!enable && line2.number <
|
|
3506
|
-
const nextLine =
|
|
3535
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
3536
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
3507
3537
|
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
3508
3538
|
lines.push(nextLine);
|
|
3509
3539
|
}
|
|
@@ -3513,7 +3543,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3513
3543
|
}
|
|
3514
3544
|
});
|
|
3515
3545
|
let line;
|
|
3516
|
-
if (!sawBlock && enable && from === to && !/\S/.test((line =
|
|
3546
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3517
3547
|
lines.push(line);
|
|
3518
3548
|
}
|
|
3519
3549
|
}
|
|
@@ -3537,10 +3567,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3537
3567
|
if (!changes.length) {
|
|
3538
3568
|
return false;
|
|
3539
3569
|
}
|
|
3540
|
-
const changeSet =
|
|
3541
|
-
dispatch(
|
|
3570
|
+
const changeSet = state2.changes(changes);
|
|
3571
|
+
dispatch(state2.update({
|
|
3542
3572
|
changes: changeSet,
|
|
3543
|
-
selection:
|
|
3573
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3544
3574
|
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3545
3575
|
scrollIntoView: true
|
|
3546
3576
|
}));
|
|
@@ -3552,11 +3582,11 @@ var toggleBlockquote = (target) => {
|
|
|
3552
3582
|
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3553
3583
|
};
|
|
3554
3584
|
var addCodeblock = (target) => {
|
|
3555
|
-
const { state, dispatch } = target;
|
|
3556
|
-
const { selection } =
|
|
3585
|
+
const { state: state2, dispatch } = target;
|
|
3586
|
+
const { selection } = state2;
|
|
3557
3587
|
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
3558
3588
|
const { head } = selection.main;
|
|
3559
|
-
const line =
|
|
3589
|
+
const line = state2.doc.lineAt(head);
|
|
3560
3590
|
if (!/\S/.test(line.text) && head === line.from) {
|
|
3561
3591
|
snippets.codeblock(target, null, line.from, line.to);
|
|
3562
3592
|
return true;
|
|
@@ -3566,7 +3596,7 @@ var addCodeblock = (target) => {
|
|
|
3566
3596
|
for (const { from, to } of selection.ranges) {
|
|
3567
3597
|
let blockFrom = from;
|
|
3568
3598
|
let blockTo = to;
|
|
3569
|
-
syntaxTree2(
|
|
3599
|
+
syntaxTree2(state2).iterate({
|
|
3570
3600
|
from,
|
|
3571
3601
|
to,
|
|
3572
3602
|
enter: (node) => {
|
|
@@ -3575,8 +3605,8 @@ var addCodeblock = (target) => {
|
|
|
3575
3605
|
blockFrom = node.from;
|
|
3576
3606
|
blockTo = node.to;
|
|
3577
3607
|
} else {
|
|
3578
|
-
blockFrom = Math.min(blockFrom,
|
|
3579
|
-
blockTo = Math.max(blockTo,
|
|
3608
|
+
blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
|
|
3609
|
+
blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
|
|
3580
3610
|
}
|
|
3581
3611
|
}
|
|
3582
3612
|
}
|
|
@@ -3594,7 +3624,7 @@ var addCodeblock = (target) => {
|
|
|
3594
3624
|
return false;
|
|
3595
3625
|
}
|
|
3596
3626
|
const changes = ranges.map(({ from, to }) => {
|
|
3597
|
-
const column = from -
|
|
3627
|
+
const column = from - state2.doc.lineAt(from).from;
|
|
3598
3628
|
return [
|
|
3599
3629
|
{
|
|
3600
3630
|
from,
|
|
@@ -3606,30 +3636,30 @@ var addCodeblock = (target) => {
|
|
|
3606
3636
|
}
|
|
3607
3637
|
];
|
|
3608
3638
|
});
|
|
3609
|
-
dispatch(
|
|
3639
|
+
dispatch(state2.update({
|
|
3610
3640
|
changes,
|
|
3611
3641
|
userEvent: "format.codeblock.add",
|
|
3612
3642
|
scrollIntoView: true
|
|
3613
3643
|
}));
|
|
3614
3644
|
return true;
|
|
3615
3645
|
};
|
|
3616
|
-
var removeCodeblock = ({ state, dispatch }) => {
|
|
3646
|
+
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3617
3647
|
const changes = [];
|
|
3618
3648
|
let lastBlock = -1;
|
|
3619
|
-
for (const { from, to } of
|
|
3620
|
-
syntaxTree2(
|
|
3649
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3650
|
+
syntaxTree2(state2).iterate({
|
|
3621
3651
|
from,
|
|
3622
3652
|
to,
|
|
3623
3653
|
enter: (node) => {
|
|
3624
3654
|
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
3625
3655
|
lastBlock = node.from;
|
|
3626
|
-
const firstLine =
|
|
3656
|
+
const firstLine = state2.doc.lineAt(node.from);
|
|
3627
3657
|
if (node.name === "FencedCode") {
|
|
3628
3658
|
changes.push({
|
|
3629
3659
|
from: node.from,
|
|
3630
3660
|
to: firstLine.to + 1 + node.from - firstLine.from
|
|
3631
3661
|
});
|
|
3632
|
-
const lastLine =
|
|
3662
|
+
const lastLine = state2.doc.lineAt(node.to);
|
|
3633
3663
|
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
3634
3664
|
changes.push({
|
|
3635
3665
|
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
@@ -3638,7 +3668,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3638
3668
|
}
|
|
3639
3669
|
} else {
|
|
3640
3670
|
const column = node.from - firstLine.from;
|
|
3641
|
-
for (let line = firstLine; ; line =
|
|
3671
|
+
for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
|
|
3642
3672
|
changes.push({
|
|
3643
3673
|
from: line.from + column - 4,
|
|
3644
3674
|
to: line.from + column
|
|
@@ -3655,7 +3685,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3655
3685
|
if (!changes.length) {
|
|
3656
3686
|
return false;
|
|
3657
3687
|
}
|
|
3658
|
-
dispatch(
|
|
3688
|
+
dispatch(state2.update({
|
|
3659
3689
|
changes,
|
|
3660
3690
|
userEvent: "format.codeblock.remove",
|
|
3661
3691
|
scrollIntoView: true
|
|
@@ -3667,7 +3697,7 @@ var toggleCodeblock = (target) => {
|
|
|
3667
3697
|
};
|
|
3668
3698
|
var formattingKeymap = (options = {}) => {
|
|
3669
3699
|
return [
|
|
3670
|
-
|
|
3700
|
+
keymap7.of([
|
|
3671
3701
|
{
|
|
3672
3702
|
key: "meta-b",
|
|
3673
3703
|
run: toggleStrong
|
|
@@ -3714,7 +3744,7 @@ var Textblocks = {
|
|
|
3714
3744
|
TableCell: "tablecell",
|
|
3715
3745
|
Task: "paragraph"
|
|
3716
3746
|
};
|
|
3717
|
-
var getFormatting = (
|
|
3747
|
+
var getFormatting = (state2) => {
|
|
3718
3748
|
let blockType = null;
|
|
3719
3749
|
const inline = [
|
|
3720
3750
|
null,
|
|
@@ -3740,7 +3770,7 @@ var getFormatting = (state) => {
|
|
|
3740
3770
|
continue;
|
|
3741
3771
|
} else if (currentBlock.active[i]) {
|
|
3742
3772
|
inline[i] = true;
|
|
3743
|
-
} else if (/\S/.test(
|
|
3773
|
+
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3744
3774
|
inline[i] = false;
|
|
3745
3775
|
}
|
|
3746
3776
|
}
|
|
@@ -3751,12 +3781,12 @@ var getFormatting = (state) => {
|
|
|
3751
3781
|
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3752
3782
|
}
|
|
3753
3783
|
};
|
|
3754
|
-
const { selection } =
|
|
3784
|
+
const { selection } = state2;
|
|
3755
3785
|
for (const range of selection.ranges) {
|
|
3756
3786
|
if (range.empty && inline.some((v) => v === null)) {
|
|
3757
3787
|
const contextSize = Math.min(range.head, 6);
|
|
3758
|
-
const contextBefore =
|
|
3759
|
-
let contextAfter =
|
|
3788
|
+
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3789
|
+
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3760
3790
|
for (let i = 0; i < contextSize; i++) {
|
|
3761
3791
|
const ch = contextAfter[i];
|
|
3762
3792
|
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
@@ -3775,7 +3805,7 @@ var getFormatting = (state) => {
|
|
|
3775
3805
|
}
|
|
3776
3806
|
}
|
|
3777
3807
|
}
|
|
3778
|
-
syntaxTree2(
|
|
3808
|
+
syntaxTree2(state2).iterate({
|
|
3779
3809
|
from: range.from,
|
|
3780
3810
|
to: range.to,
|
|
3781
3811
|
enter: (node) => {
|
|
@@ -3849,7 +3879,7 @@ var getFormatting = (state) => {
|
|
|
3849
3879
|
}
|
|
3850
3880
|
});
|
|
3851
3881
|
}
|
|
3852
|
-
const { from, to } =
|
|
3882
|
+
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3853
3883
|
const blankLine = from === to;
|
|
3854
3884
|
return {
|
|
3855
3885
|
blankLine,
|
|
@@ -3864,17 +3894,22 @@ var getFormatting = (state) => {
|
|
|
3864
3894
|
};
|
|
3865
3895
|
};
|
|
3866
3896
|
var useFormattingState = () => {
|
|
3867
|
-
const [
|
|
3897
|
+
const [state2, setState] = useState();
|
|
3868
3898
|
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3869
3899
|
if (update2.docChanged || update2.selectionSet) {
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3900
|
+
setState((prevState) => {
|
|
3901
|
+
const newState = getFormatting(update2.state);
|
|
3902
|
+
if (!prevState || !formattingEquals(prevState, newState)) {
|
|
3903
|
+
return newState;
|
|
3904
|
+
}
|
|
3905
|
+
return prevState;
|
|
3906
|
+
});
|
|
3874
3907
|
}
|
|
3875
|
-
}), [
|
|
3908
|
+
}), [
|
|
3909
|
+
setState
|
|
3910
|
+
]);
|
|
3876
3911
|
return [
|
|
3877
|
-
|
|
3912
|
+
state2,
|
|
3878
3913
|
observer
|
|
3879
3914
|
];
|
|
3880
3915
|
};
|
|
@@ -3885,8 +3920,8 @@ import { StateField as StateField5 } from "@codemirror/state";
|
|
|
3885
3920
|
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3886
3921
|
var image = (options = {}) => {
|
|
3887
3922
|
return StateField5.define({
|
|
3888
|
-
create: (
|
|
3889
|
-
return Decoration6.set(buildDecorations2(0,
|
|
3923
|
+
create: (state2) => {
|
|
3924
|
+
return Decoration6.set(buildDecorations2(0, state2.doc.length, state2));
|
|
3890
3925
|
},
|
|
3891
3926
|
update: (value, tr) => {
|
|
3892
3927
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3920,16 +3955,16 @@ var preloadImage = (url) => {
|
|
|
3920
3955
|
preloaded.add(url);
|
|
3921
3956
|
}
|
|
3922
3957
|
};
|
|
3923
|
-
var buildDecorations2 = (from, to,
|
|
3958
|
+
var buildDecorations2 = (from, to, state2) => {
|
|
3924
3959
|
const decorations = [];
|
|
3925
|
-
const cursor =
|
|
3926
|
-
syntaxTree3(
|
|
3960
|
+
const cursor = state2.selection.main.head;
|
|
3961
|
+
syntaxTree3(state2).iterate({
|
|
3927
3962
|
enter: (node) => {
|
|
3928
3963
|
if (node.name === "Image") {
|
|
3929
3964
|
const urlNode = node.node.getChild("URL");
|
|
3930
3965
|
if (urlNode) {
|
|
3931
|
-
const hide2 =
|
|
3932
|
-
const url =
|
|
3966
|
+
const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
|
|
3967
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3933
3968
|
preloadImage(url);
|
|
3934
3969
|
decorations.push(Decoration6.replace({
|
|
3935
3970
|
block: true,
|
|
@@ -3959,6 +3994,8 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
3959
3994
|
return img;
|
|
3960
3995
|
}
|
|
3961
3996
|
};
|
|
3997
|
+
var imageUpload = (options = {}) => {
|
|
3998
|
+
};
|
|
3962
3999
|
|
|
3963
4000
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
3964
4001
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
@@ -4000,21 +4037,21 @@ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "
|
|
|
4000
4037
|
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4001
4038
|
var table = (options = {}) => {
|
|
4002
4039
|
return StateField6.define({
|
|
4003
|
-
create: (
|
|
4040
|
+
create: (state2) => update(state2, options),
|
|
4004
4041
|
update: (_, tr) => update(tr.state, options),
|
|
4005
4042
|
provide: (field) => EditorView15.decorations.from(field)
|
|
4006
4043
|
});
|
|
4007
4044
|
};
|
|
4008
|
-
var update = (
|
|
4045
|
+
var update = (state2, options) => {
|
|
4009
4046
|
const builder = new RangeSetBuilder3();
|
|
4010
|
-
const cursor =
|
|
4047
|
+
const cursor = state2.selection.main.head;
|
|
4011
4048
|
const tables = [];
|
|
4012
4049
|
const getTable = () => tables[tables.length - 1];
|
|
4013
4050
|
const getRow = () => {
|
|
4014
4051
|
const table2 = getTable();
|
|
4015
4052
|
return table2.rows?.[table2.rows.length - 1];
|
|
4016
4053
|
};
|
|
4017
|
-
syntaxTree5(
|
|
4054
|
+
syntaxTree5(state2).iterate({
|
|
4018
4055
|
enter: (node) => {
|
|
4019
4056
|
switch (node.name) {
|
|
4020
4057
|
case "Table": {
|
|
@@ -4035,9 +4072,9 @@ var update = (state, options) => {
|
|
|
4035
4072
|
case "TableCell": {
|
|
4036
4073
|
const row = getRow();
|
|
4037
4074
|
if (row) {
|
|
4038
|
-
row.push(
|
|
4075
|
+
row.push(state2.sliceDoc(node.from, node.to));
|
|
4039
4076
|
} else {
|
|
4040
|
-
getTable().header?.push(
|
|
4077
|
+
getTable().header?.push(state2.sliceDoc(node.from, node.to));
|
|
4041
4078
|
}
|
|
4042
4079
|
break;
|
|
4043
4080
|
}
|
|
@@ -4045,7 +4082,7 @@ var update = (state, options) => {
|
|
|
4045
4082
|
}
|
|
4046
4083
|
});
|
|
4047
4084
|
tables.forEach((table2) => {
|
|
4048
|
-
const hide2 =
|
|
4085
|
+
const hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4049
4086
|
if (hide2) {
|
|
4050
4087
|
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
4051
4088
|
widget: new TableWidget(table2)
|
|
@@ -4134,25 +4171,35 @@ var mention = ({ onSearch }) => {
|
|
|
4134
4171
|
|
|
4135
4172
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
4136
4173
|
import { Facet as Facet6 } from "@codemirror/state";
|
|
4137
|
-
import { keymap as
|
|
4174
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
4138
4175
|
import { vim } from "@replit/codemirror-vim";
|
|
4176
|
+
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
|
4177
|
+
var focusEvent = "focus.container";
|
|
4139
4178
|
var editorMode = Facet6.define({
|
|
4140
4179
|
combine: (modes) => modes[0] ?? {}
|
|
4141
4180
|
});
|
|
4142
4181
|
var EditorModes = {
|
|
4143
4182
|
default: [],
|
|
4183
|
+
vscode: [
|
|
4184
|
+
// https://github.com/replit/codemirror-vscode-keymap
|
|
4185
|
+
editorMode.of({
|
|
4186
|
+
type: "vscode"
|
|
4187
|
+
}),
|
|
4188
|
+
keymap8.of(vscodeKeymap)
|
|
4189
|
+
],
|
|
4144
4190
|
vim: [
|
|
4191
|
+
// https://github.com/replit/codemirror-vim
|
|
4145
4192
|
vim(),
|
|
4146
4193
|
editorMode.of({
|
|
4147
4194
|
type: "vim",
|
|
4148
4195
|
noTabster: true
|
|
4149
4196
|
}),
|
|
4150
|
-
|
|
4197
|
+
keymap8.of([
|
|
4151
4198
|
{
|
|
4152
4199
|
key: "Alt-Escape",
|
|
4153
4200
|
run: (view) => {
|
|
4154
4201
|
view.dispatch({
|
|
4155
|
-
userEvent:
|
|
4202
|
+
userEvent: focusEvent
|
|
4156
4203
|
});
|
|
4157
4204
|
return true;
|
|
4158
4205
|
}
|
|
@@ -4161,8 +4208,95 @@ var EditorModes = {
|
|
|
4161
4208
|
]
|
|
4162
4209
|
};
|
|
4163
4210
|
|
|
4211
|
+
// packages/ui/react-ui-editor/src/extensions/state.ts
|
|
4212
|
+
import { Transaction as Transaction2 } from "@codemirror/state";
|
|
4213
|
+
import { EditorView as EditorView16, keymap as keymap9 } from "@codemirror/view";
|
|
4214
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
4215
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4216
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4217
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
|
|
4218
|
+
var scrollAnnotation = "dxos.org/cm/scrolling";
|
|
4219
|
+
var keyPrefix = "dxos.org/react-ui-editor/state";
|
|
4220
|
+
var localStorageStateStoreAdapter = {
|
|
4221
|
+
setState: (id, state2) => {
|
|
4222
|
+
invariant4(id, void 0, {
|
|
4223
|
+
F: __dxlog_file11,
|
|
4224
|
+
L: 35,
|
|
4225
|
+
S: void 0,
|
|
4226
|
+
A: [
|
|
4227
|
+
"id",
|
|
4228
|
+
""
|
|
4229
|
+
]
|
|
4230
|
+
});
|
|
4231
|
+
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state2));
|
|
4232
|
+
},
|
|
4233
|
+
getState: (id) => {
|
|
4234
|
+
invariant4(id, void 0, {
|
|
4235
|
+
F: __dxlog_file11,
|
|
4236
|
+
L: 39,
|
|
4237
|
+
S: void 0,
|
|
4238
|
+
A: [
|
|
4239
|
+
"id",
|
|
4240
|
+
""
|
|
4241
|
+
]
|
|
4242
|
+
});
|
|
4243
|
+
const state2 = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
4244
|
+
return state2 ? JSON.parse(state2) : void 0;
|
|
4245
|
+
}
|
|
4246
|
+
};
|
|
4247
|
+
var state = ({ getState, setState } = {}) => {
|
|
4248
|
+
const setStateDebounced = debounce2(setState, 1e3);
|
|
4249
|
+
return [
|
|
4250
|
+
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
4251
|
+
EditorView16.updateListener.of(({ view, changes, transactions }) => {
|
|
4252
|
+
const id = view.state.facet(documentId2);
|
|
4253
|
+
if (!id || transactions.some((tr) => tr.isUserEvent(scrollAnnotation))) {
|
|
4254
|
+
return;
|
|
4255
|
+
}
|
|
4256
|
+
if (setState) {
|
|
4257
|
+
const { top } = view.dom.getBoundingClientRect();
|
|
4258
|
+
const pos = view.posAtCoords({
|
|
4259
|
+
x: 0,
|
|
4260
|
+
y: top
|
|
4261
|
+
});
|
|
4262
|
+
if (pos !== null) {
|
|
4263
|
+
const { anchor, head } = view.state.selection.main;
|
|
4264
|
+
setStateDebounced(id, {
|
|
4265
|
+
scrollTo: {
|
|
4266
|
+
from: pos,
|
|
4267
|
+
yMargin: 0
|
|
4268
|
+
},
|
|
4269
|
+
selection: {
|
|
4270
|
+
anchor,
|
|
4271
|
+
head
|
|
4272
|
+
}
|
|
4273
|
+
});
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
}),
|
|
4277
|
+
getState && keymap9.of([
|
|
4278
|
+
{
|
|
4279
|
+
key: "ctrl-r",
|
|
4280
|
+
run: (view) => {
|
|
4281
|
+
const state2 = getState(view.state.facet(documentId2));
|
|
4282
|
+
if (state2) {
|
|
4283
|
+
view.dispatch({
|
|
4284
|
+
effects: EditorView16.scrollIntoView(state2.scrollTo.from, {
|
|
4285
|
+
yMargin: 0
|
|
4286
|
+
}),
|
|
4287
|
+
selection: state2.selection,
|
|
4288
|
+
annotations: Transaction2.userEvent.of(scrollAnnotation)
|
|
4289
|
+
});
|
|
4290
|
+
}
|
|
4291
|
+
return true;
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
])
|
|
4295
|
+
].filter(isNotFalsy3);
|
|
4296
|
+
};
|
|
4297
|
+
|
|
4164
4298
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4165
|
-
import { keymap as
|
|
4299
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
|
4166
4300
|
var defaultItems = [
|
|
4167
4301
|
"hello world!",
|
|
4168
4302
|
"this is a test.",
|
|
@@ -4172,7 +4306,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4172
4306
|
let t;
|
|
4173
4307
|
let idx = 0;
|
|
4174
4308
|
return [
|
|
4175
|
-
|
|
4309
|
+
keymap10.of([
|
|
4176
4310
|
{
|
|
4177
4311
|
// Reset.
|
|
4178
4312
|
key: "alt-meta-'",
|
|
@@ -4219,9 +4353,11 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4219
4353
|
};
|
|
4220
4354
|
|
|
4221
4355
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4222
|
-
var
|
|
4356
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4223
4357
|
var instanceCount = 0;
|
|
4224
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo =
|
|
4358
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo = EditorView17.scrollIntoView(0, {
|
|
4359
|
+
yMargin: 0
|
|
4360
|
+
}), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4225
4361
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
4226
4362
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
4227
4363
|
tabBehavior: "limited"
|
|
@@ -4240,42 +4376,42 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4240
4376
|
autoFocus
|
|
4241
4377
|
]);
|
|
4242
4378
|
useEffect2(() => {
|
|
4243
|
-
log9("
|
|
4379
|
+
log9("create", {
|
|
4244
4380
|
id,
|
|
4245
4381
|
instanceId
|
|
4246
4382
|
}, {
|
|
4247
|
-
F:
|
|
4383
|
+
F: __dxlog_file12,
|
|
4248
4384
|
L: 88,
|
|
4249
4385
|
S: void 0,
|
|
4250
4386
|
C: (f, a) => f(...a)
|
|
4251
4387
|
});
|
|
4252
|
-
const
|
|
4388
|
+
const state2 = EditorState2.create({
|
|
4253
4389
|
doc,
|
|
4254
4390
|
selection,
|
|
4255
4391
|
extensions: [
|
|
4256
4392
|
id && documentId2.of(id),
|
|
4257
4393
|
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4258
|
-
|
|
4394
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4259
4395
|
log9.catch(err, void 0, {
|
|
4260
|
-
F:
|
|
4396
|
+
F: __dxlog_file12,
|
|
4261
4397
|
L: 101,
|
|
4262
4398
|
S: void 0,
|
|
4263
4399
|
C: (f, a) => f(...a)
|
|
4264
4400
|
});
|
|
4265
4401
|
}),
|
|
4266
4402
|
// Focus.
|
|
4267
|
-
|
|
4403
|
+
EditorView17.updateListener.of((update2) => {
|
|
4268
4404
|
update2.transactions.forEach((transaction) => {
|
|
4269
|
-
if (transaction.isUserEvent(
|
|
4405
|
+
if (transaction.isUserEvent(focusEvent)) {
|
|
4270
4406
|
rootRef.current?.focus();
|
|
4271
4407
|
}
|
|
4272
4408
|
});
|
|
4273
4409
|
}),
|
|
4274
4410
|
extensions
|
|
4275
|
-
].filter(
|
|
4411
|
+
].filter(isNotFalsy4)
|
|
4276
4412
|
});
|
|
4277
|
-
const view2 = new
|
|
4278
|
-
state,
|
|
4413
|
+
const view2 = new EditorView17({
|
|
4414
|
+
state: state2,
|
|
4279
4415
|
parent: rootRef.current,
|
|
4280
4416
|
scrollTo,
|
|
4281
4417
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
@@ -4287,21 +4423,29 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4287
4423
|
view3.update(trs);
|
|
4288
4424
|
}
|
|
4289
4425
|
});
|
|
4290
|
-
|
|
4291
|
-
if (moveToEndOfLine) {
|
|
4426
|
+
if (moveToEndOfLine && !(scrollTo || selection)) {
|
|
4292
4427
|
const { to } = view2.state.doc.lineAt(0);
|
|
4293
|
-
view2
|
|
4428
|
+
view2.dispatch({
|
|
4294
4429
|
selection: {
|
|
4295
4430
|
anchor: to
|
|
4296
4431
|
}
|
|
4297
4432
|
});
|
|
4298
4433
|
}
|
|
4299
|
-
if (
|
|
4434
|
+
if (state2.facet(editorMode).noTabster) {
|
|
4300
4435
|
rootRef.current?.removeAttribute("data-tabster");
|
|
4301
4436
|
}
|
|
4437
|
+
setView(view2);
|
|
4302
4438
|
return () => {
|
|
4439
|
+
log9("destroy", {
|
|
4440
|
+
id,
|
|
4441
|
+
instanceId
|
|
4442
|
+
}, {
|
|
4443
|
+
F: __dxlog_file12,
|
|
4444
|
+
L: 150,
|
|
4445
|
+
S: void 0,
|
|
4446
|
+
C: (f, a) => f(...a)
|
|
4447
|
+
});
|
|
4303
4448
|
view2?.destroy();
|
|
4304
|
-
setView(null);
|
|
4305
4449
|
};
|
|
4306
4450
|
}, [
|
|
4307
4451
|
doc,
|
|
@@ -4331,9 +4475,10 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4331
4475
|
});
|
|
4332
4476
|
|
|
4333
4477
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4334
|
-
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic
|
|
4478
|
+
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
|
|
4335
4479
|
import { createContext } from "@radix-ui/react-context";
|
|
4336
|
-
import React2, { useRef as useRef2, useState as useState3 } from "react";
|
|
4480
|
+
import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
4481
|
+
import { useDropzone } from "react-dropzone";
|
|
4337
4482
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4338
4483
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4339
4484
|
var tooltipProps = {
|
|
@@ -4350,10 +4495,10 @@ var HeadingIcons = {
|
|
|
4350
4495
|
"6": TextHSix
|
|
4351
4496
|
};
|
|
4352
4497
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4353
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
4498
|
+
var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
4354
4499
|
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
4355
4500
|
onAction,
|
|
4356
|
-
state
|
|
4501
|
+
state: state2
|
|
4357
4502
|
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
4358
4503
|
density: "fine"
|
|
4359
4504
|
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
@@ -4367,7 +4512,7 @@ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
|
4367
4512
|
};
|
|
4368
4513
|
var buttonStyles = "min-bs-0 p-2";
|
|
4369
4514
|
var iconStyles = getSize(5);
|
|
4370
|
-
var
|
|
4515
|
+
var ToolbarToggleButton = ({ Icon, children, ...props }) => {
|
|
4371
4516
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4372
4517
|
asChild: true
|
|
4373
4518
|
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
@@ -4380,14 +4525,27 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
|
4380
4525
|
className: "sr-only"
|
|
4381
4526
|
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4382
4527
|
};
|
|
4528
|
+
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4529
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4530
|
+
asChild: true
|
|
4531
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4532
|
+
variant: "ghost",
|
|
4533
|
+
...props,
|
|
4534
|
+
classNames: buttonStyles
|
|
4535
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
4536
|
+
className: iconStyles
|
|
4537
|
+
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4538
|
+
className: "sr-only"
|
|
4539
|
+
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4540
|
+
};
|
|
4383
4541
|
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4384
4542
|
role: "separator",
|
|
4385
4543
|
className: "grow"
|
|
4386
4544
|
});
|
|
4387
4545
|
var MarkdownHeading = () => {
|
|
4388
4546
|
const { t } = useTranslation(translationKey);
|
|
4389
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
4390
|
-
const blockType =
|
|
4547
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
|
|
4548
|
+
const blockType = state2 ? state2.blockType : "paragraph";
|
|
4391
4549
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4392
4550
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4393
4551
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
@@ -4461,43 +4619,43 @@ var markdownStyles = [
|
|
|
4461
4619
|
{
|
|
4462
4620
|
type: "strong",
|
|
4463
4621
|
Icon: TextB,
|
|
4464
|
-
getState: (
|
|
4622
|
+
getState: (state2) => state2.strong
|
|
4465
4623
|
},
|
|
4466
4624
|
{
|
|
4467
4625
|
type: "emphasis",
|
|
4468
4626
|
Icon: TextItalic,
|
|
4469
|
-
getState: (
|
|
4627
|
+
getState: (state2) => state2.emphasis
|
|
4470
4628
|
},
|
|
4471
4629
|
{
|
|
4472
4630
|
type: "strikethrough",
|
|
4473
4631
|
Icon: TextStrikethrough,
|
|
4474
|
-
getState: (
|
|
4632
|
+
getState: (state2) => state2.strikethrough
|
|
4475
4633
|
},
|
|
4476
4634
|
{
|
|
4477
4635
|
type: "code",
|
|
4478
4636
|
Icon: Code,
|
|
4479
|
-
getState: (
|
|
4637
|
+
getState: (state2) => state2.code
|
|
4480
4638
|
},
|
|
4481
4639
|
{
|
|
4482
4640
|
type: "link",
|
|
4483
4641
|
Icon: Link,
|
|
4484
|
-
getState: (
|
|
4642
|
+
getState: (state2) => state2.link
|
|
4485
4643
|
}
|
|
4486
4644
|
];
|
|
4487
4645
|
var MarkdownStyles = () => {
|
|
4488
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4646
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4489
4647
|
const { t } = useTranslation(translationKey);
|
|
4490
4648
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4491
4649
|
type: "multiple",
|
|
4492
|
-
value: markdownStyles.filter(({ getState }) =>
|
|
4493
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4650
|
+
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
4651
|
+
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4494
4652
|
key: type,
|
|
4495
4653
|
value: type,
|
|
4496
4654
|
Icon,
|
|
4497
|
-
disabled:
|
|
4498
|
-
onClick:
|
|
4655
|
+
disabled: state2?.blockType === "codeblock",
|
|
4656
|
+
onClick: state2 ? () => onAction?.({
|
|
4499
4657
|
type,
|
|
4500
|
-
data: !getState(
|
|
4658
|
+
data: !getState(state2)
|
|
4501
4659
|
}) : void 0
|
|
4502
4660
|
}, t(`${type} label`))));
|
|
4503
4661
|
};
|
|
@@ -4505,32 +4663,32 @@ var markdownLists = [
|
|
|
4505
4663
|
{
|
|
4506
4664
|
type: "list-bullet",
|
|
4507
4665
|
Icon: ListBullets,
|
|
4508
|
-
getState: (
|
|
4666
|
+
getState: (state2) => state2.listStyle === "bullet"
|
|
4509
4667
|
},
|
|
4510
4668
|
{
|
|
4511
4669
|
type: "list-ordered",
|
|
4512
4670
|
Icon: ListNumbers,
|
|
4513
|
-
getState: (
|
|
4671
|
+
getState: (state2) => state2.listStyle === "ordered"
|
|
4514
4672
|
},
|
|
4515
4673
|
{
|
|
4516
4674
|
type: "list-task",
|
|
4517
4675
|
Icon: ListChecks,
|
|
4518
|
-
getState: (
|
|
4676
|
+
getState: (state2) => state2.listStyle === "task"
|
|
4519
4677
|
}
|
|
4520
4678
|
];
|
|
4521
4679
|
var MarkdownLists = () => {
|
|
4522
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4680
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4523
4681
|
const { t } = useTranslation(translationKey);
|
|
4524
4682
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4525
4683
|
type: "single",
|
|
4526
|
-
value:
|
|
4527
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4684
|
+
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
4685
|
+
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4528
4686
|
key: type,
|
|
4529
4687
|
value: type,
|
|
4530
4688
|
Icon,
|
|
4531
|
-
onClick:
|
|
4689
|
+
onClick: state2 ? () => onAction?.({
|
|
4532
4690
|
type,
|
|
4533
|
-
data: !getState(
|
|
4691
|
+
data: !getState(state2)
|
|
4534
4692
|
}) : void 0
|
|
4535
4693
|
}, t(`${type} label`))));
|
|
4536
4694
|
};
|
|
@@ -4538,63 +4696,101 @@ var markdownBlocks = [
|
|
|
4538
4696
|
{
|
|
4539
4697
|
type: "blockquote",
|
|
4540
4698
|
Icon: Quotes,
|
|
4541
|
-
getState: (
|
|
4699
|
+
getState: (state2) => state2.blockQuote
|
|
4542
4700
|
},
|
|
4543
4701
|
{
|
|
4544
4702
|
type: "codeblock",
|
|
4545
4703
|
Icon: CodeBlock,
|
|
4546
|
-
getState: (
|
|
4704
|
+
getState: (state2) => state2.blockType === "codeblock"
|
|
4547
4705
|
},
|
|
4548
4706
|
{
|
|
4549
4707
|
type: "table",
|
|
4550
4708
|
Icon: Table2,
|
|
4551
|
-
getState: (
|
|
4552
|
-
disabled: (
|
|
4709
|
+
getState: (state2) => state2.blockType === "tablecell",
|
|
4710
|
+
disabled: (state2) => !state2.blankLine
|
|
4553
4711
|
}
|
|
4554
4712
|
];
|
|
4555
4713
|
var MarkdownBlocks = () => {
|
|
4556
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4714
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4557
4715
|
const { t } = useTranslation(translationKey);
|
|
4558
|
-
const value = markdownBlocks.find(({ getState }) =>
|
|
4716
|
+
const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
|
|
4559
4717
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4560
4718
|
type: "single",
|
|
4561
4719
|
value: value?.type ?? ""
|
|
4562
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4720
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4563
4721
|
key: type,
|
|
4564
4722
|
value: type,
|
|
4565
4723
|
Icon,
|
|
4566
|
-
disabled: !
|
|
4567
|
-
onClick:
|
|
4724
|
+
disabled: !state2 || disabled?.(state2),
|
|
4725
|
+
onClick: state2 ? () => onAction?.({
|
|
4568
4726
|
type,
|
|
4569
|
-
data: !getState(
|
|
4727
|
+
data: !getState(state2)
|
|
4570
4728
|
}) : void 0
|
|
4571
4729
|
}, t(`${type} label`))));
|
|
4572
4730
|
};
|
|
4573
4731
|
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));
|
|
4574
|
-
var
|
|
4732
|
+
var MarkdownCustom = ({ onUpload } = {}) => {
|
|
4575
4733
|
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4576
4734
|
const { t } = useTranslation(translationKey);
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4735
|
+
const { acceptedFiles, getInputProps, open } = useDropzone({
|
|
4736
|
+
multiple: false,
|
|
4737
|
+
noDrag: true,
|
|
4738
|
+
accept: {
|
|
4739
|
+
"image/*": [
|
|
4740
|
+
".jpg",
|
|
4741
|
+
".jpeg",
|
|
4742
|
+
".png",
|
|
4743
|
+
".gif"
|
|
4744
|
+
]
|
|
4745
|
+
}
|
|
4746
|
+
});
|
|
4747
|
+
useEffect3(() => {
|
|
4748
|
+
if (onUpload && acceptedFiles.length) {
|
|
4749
|
+
setTimeout(async () => {
|
|
4750
|
+
const f = acceptedFiles[0];
|
|
4751
|
+
const file = new File([
|
|
4752
|
+
f
|
|
4753
|
+
], f.name, {
|
|
4754
|
+
type: f.type,
|
|
4755
|
+
lastModified: f.lastModified
|
|
4756
|
+
});
|
|
4757
|
+
const { url } = await onUpload(file);
|
|
4758
|
+
if (url) {
|
|
4759
|
+
onAction?.({
|
|
4760
|
+
type: "image",
|
|
4761
|
+
data: url
|
|
4762
|
+
});
|
|
4763
|
+
}
|
|
4764
|
+
});
|
|
4765
|
+
}
|
|
4766
|
+
}, [
|
|
4767
|
+
acceptedFiles
|
|
4768
|
+
]);
|
|
4769
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("input", getInputProps()), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4770
|
+
value: "image",
|
|
4771
|
+
Icon: Image,
|
|
4772
|
+
onClick: () => open()
|
|
4773
|
+
}, t("image label")));
|
|
4774
|
+
};
|
|
4775
|
+
var MarkdownActions = () => {
|
|
4776
|
+
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4777
|
+
const { t } = useTranslation(translationKey);
|
|
4778
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4779
|
+
value: "comment",
|
|
4780
|
+
Icon: ChatText,
|
|
4581
4781
|
"data-testid": "editor.toolbar.comment",
|
|
4582
4782
|
onClick: () => onAction?.({
|
|
4583
4783
|
type: "comment"
|
|
4584
|
-
})
|
|
4585
|
-
|
|
4586
|
-
}, /* @__PURE__ */ React2.createElement(ChatText, {
|
|
4587
|
-
className: iconStyles
|
|
4588
|
-
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4589
|
-
className: "sr-only"
|
|
4590
|
-
}, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4784
|
+
})
|
|
4785
|
+
}, t("comment label")));
|
|
4591
4786
|
};
|
|
4592
4787
|
var Toolbar = {
|
|
4593
4788
|
Root: ToolbarRoot,
|
|
4594
|
-
Button:
|
|
4789
|
+
Button: ToolbarToggleButton,
|
|
4595
4790
|
Separator: ToolbarSeparator,
|
|
4596
4791
|
Markdown: MarkdownStandard,
|
|
4597
|
-
|
|
4792
|
+
Custom: MarkdownCustom,
|
|
4793
|
+
Actions: MarkdownActions
|
|
4598
4794
|
};
|
|
4599
4795
|
|
|
4600
4796
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
@@ -4631,7 +4827,13 @@ var useActionHandler = (view) => {
|
|
|
4631
4827
|
insertTable(view);
|
|
4632
4828
|
break;
|
|
4633
4829
|
case "link":
|
|
4634
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4830
|
+
(action.data === false ? removeLink : addLink())(view);
|
|
4831
|
+
break;
|
|
4832
|
+
case "image":
|
|
4833
|
+
addLink({
|
|
4834
|
+
url: action.data,
|
|
4835
|
+
image: true
|
|
4836
|
+
})(view);
|
|
4635
4837
|
break;
|
|
4636
4838
|
case "comment":
|
|
4637
4839
|
createComment(view);
|
|
@@ -4660,43 +4862,51 @@ var useDocAccessor = (text) => {
|
|
|
4660
4862
|
|
|
4661
4863
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4662
4864
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4663
|
-
import { EditorView as
|
|
4664
|
-
import { useEffect as
|
|
4865
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
4866
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4665
4867
|
import { log as log10 } from "@dxos/log";
|
|
4666
|
-
import { isNotFalsy as
|
|
4667
|
-
var
|
|
4868
|
+
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4869
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4668
4870
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4669
4871
|
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4670
4872
|
const onUpdate = useRef3();
|
|
4671
4873
|
const [view, setView] = useState4();
|
|
4672
4874
|
const parentRef = useRef3(null);
|
|
4673
|
-
|
|
4875
|
+
useEffect4(() => {
|
|
4674
4876
|
let view2;
|
|
4675
4877
|
if (parentRef.current) {
|
|
4676
|
-
|
|
4878
|
+
log10("create", {
|
|
4879
|
+
id
|
|
4880
|
+
}, {
|
|
4881
|
+
F: __dxlog_file13,
|
|
4882
|
+
L: 36,
|
|
4883
|
+
S: void 0,
|
|
4884
|
+
C: (f, a) => f(...a)
|
|
4885
|
+
});
|
|
4886
|
+
const state2 = EditorState3.create({
|
|
4677
4887
|
doc,
|
|
4678
4888
|
selection,
|
|
4679
4889
|
extensions: [
|
|
4680
4890
|
id && documentId2.of(id),
|
|
4681
4891
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4682
|
-
|
|
4892
|
+
EditorView18.exceptionSink.of((err) => {
|
|
4683
4893
|
log10.catch(err, void 0, {
|
|
4684
|
-
F:
|
|
4685
|
-
L:
|
|
4894
|
+
F: __dxlog_file13,
|
|
4895
|
+
L: 46,
|
|
4686
4896
|
S: void 0,
|
|
4687
4897
|
C: (f, a) => f(...a)
|
|
4688
4898
|
});
|
|
4689
4899
|
}),
|
|
4690
4900
|
extensions,
|
|
4691
|
-
|
|
4901
|
+
EditorView18.updateListener.of(() => {
|
|
4692
4902
|
onUpdate.current?.();
|
|
4693
4903
|
})
|
|
4694
|
-
].filter(
|
|
4904
|
+
].filter(isNotFalsy5)
|
|
4695
4905
|
});
|
|
4696
|
-
view2 = new
|
|
4906
|
+
view2 = new EditorView18({
|
|
4697
4907
|
parent: parentRef.current,
|
|
4698
4908
|
scrollTo,
|
|
4699
|
-
state,
|
|
4909
|
+
state: state2,
|
|
4700
4910
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4701
4911
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4702
4912
|
dispatchTransactions: (trs, view3) => {
|
|
@@ -4709,10 +4919,18 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
4709
4919
|
setView(view2);
|
|
4710
4920
|
}
|
|
4711
4921
|
return () => {
|
|
4922
|
+
log10("destroy", {
|
|
4923
|
+
id
|
|
4924
|
+
}, {
|
|
4925
|
+
F: __dxlog_file13,
|
|
4926
|
+
L: 74,
|
|
4927
|
+
S: void 0,
|
|
4928
|
+
C: (f, a) => f(...a)
|
|
4929
|
+
});
|
|
4712
4930
|
view2?.destroy();
|
|
4713
4931
|
};
|
|
4714
4932
|
}, deps);
|
|
4715
|
-
|
|
4933
|
+
useEffect4(() => {
|
|
4716
4934
|
if (view) {
|
|
4717
4935
|
if (!selection && !view.state.selection.main.anchor) {
|
|
4718
4936
|
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
@@ -4771,7 +4989,6 @@ export {
|
|
|
4771
4989
|
callbackWrapper,
|
|
4772
4990
|
command,
|
|
4773
4991
|
comments,
|
|
4774
|
-
compareFormatting,
|
|
4775
4992
|
createBasicExtensions,
|
|
4776
4993
|
createComment,
|
|
4777
4994
|
createDataExtensions,
|
|
@@ -4788,14 +5005,18 @@ export {
|
|
|
4788
5005
|
editorMode,
|
|
4789
5006
|
editorWithToolbarLayout,
|
|
4790
5007
|
focusComment,
|
|
5008
|
+
focusEvent,
|
|
5009
|
+
formattingEquals,
|
|
4791
5010
|
formattingKeymap,
|
|
4792
5011
|
getFormatting,
|
|
4793
5012
|
getToken,
|
|
4794
5013
|
image,
|
|
5014
|
+
imageUpload,
|
|
4795
5015
|
insertTable,
|
|
4796
|
-
|
|
5016
|
+
keymap11 as keymap,
|
|
4797
5017
|
linkTooltip,
|
|
4798
5018
|
listener,
|
|
5019
|
+
localStorageStateStoreAdapter,
|
|
4799
5020
|
logChanges,
|
|
4800
5021
|
markdownHighlightStyle,
|
|
4801
5022
|
markdownTags,
|
|
@@ -4811,6 +5032,7 @@ export {
|
|
|
4811
5032
|
setHeading,
|
|
4812
5033
|
setSelection,
|
|
4813
5034
|
setStyle,
|
|
5035
|
+
state,
|
|
4814
5036
|
table,
|
|
4815
5037
|
tags2 as tags,
|
|
4816
5038
|
toggleBlockquote,
|