@dxos/react-ui-editor 0.4.8-main.8cb190e → 0.4.8-main.932d824
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 +410 -256
- 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 +10 -4
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +3 -1
- 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/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +4 -1
- 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 +1 -0
- 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/useTextEditor.stories.d.ts +1 -0
- package/dist/types/src/hooks/useTextEditor.stories.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 +25 -24
- package/src/components/TextEditor/TextEditor.stories.tsx +16 -4
- package/src/components/TextEditor/TextEditor.tsx +11 -10
- package/src/components/Toolbar/Toolbar.stories.tsx +3 -2
- package/src/components/Toolbar/Toolbar.tsx +86 -32
- package/src/extensions/index.ts +1 -0
- package/src/extensions/markdown/formatting.test.ts +13 -13
- package/src/extensions/markdown/formatting.ts +80 -76
- package/src/extensions/markdown/image.ts +6 -0
- package/src/extensions/modes.ts +3 -1
- package/src/extensions/state.ts +90 -0
- package/src/hooks/useActionHandler.ts +5 -1
- package/src/hooks/useTextEditor.stories.tsx +3 -3
- 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 keymap10 } 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
|
}
|
|
@@ -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,
|
|
@@ -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;
|
|
@@ -2606,8 +2607,8 @@ var checkedTask = Decoration5.replace({
|
|
|
2606
2607
|
var uncheckedTask = Decoration5.replace({
|
|
2607
2608
|
widget: new CheckboxWidget(false)
|
|
2608
2609
|
});
|
|
2609
|
-
var editingRange = (
|
|
2610
|
-
const { readOnly, selection: { main: { head } } } =
|
|
2610
|
+
var editingRange = (state2, range, focus) => {
|
|
2611
|
+
const { readOnly, selection: { main: { head } } } = state2;
|
|
2611
2612
|
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
2612
2613
|
};
|
|
2613
2614
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
@@ -2620,14 +2621,14 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
2620
2621
|
var buildDecorations = (view, options, focus) => {
|
|
2621
2622
|
const deco = new RangeSetBuilder2();
|
|
2622
2623
|
const atomicDeco = new RangeSetBuilder2();
|
|
2623
|
-
const { state } = view;
|
|
2624
|
+
const { state: state2 } = view;
|
|
2624
2625
|
for (const { from, to } of view.visibleRanges) {
|
|
2625
|
-
syntaxTree(
|
|
2626
|
+
syntaxTree(state2).iterate({
|
|
2626
2627
|
from,
|
|
2627
2628
|
to,
|
|
2628
2629
|
enter: (node) => {
|
|
2629
2630
|
if (node.name === "FencedCode") {
|
|
2630
|
-
const editing = editingRange(
|
|
2631
|
+
const editing = editingRange(state2, node, focus);
|
|
2631
2632
|
for (const block of view.viewportLineBlocks) {
|
|
2632
2633
|
if (block.to < node.from) {
|
|
2633
2634
|
continue;
|
|
@@ -2636,7 +2637,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2636
2637
|
break;
|
|
2637
2638
|
}
|
|
2638
2639
|
const first = block.from <= node.from;
|
|
2639
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(
|
|
2640
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
2640
2641
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2641
2642
|
if (!editing && (first || last)) {
|
|
2642
2643
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -2646,9 +2647,9 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2646
2647
|
} else if (node.name === "Link") {
|
|
2647
2648
|
const marks = node.node.getChildren("LinkMark");
|
|
2648
2649
|
const urlNode = node.node.getChild("URL");
|
|
2649
|
-
const editing = editingRange(
|
|
2650
|
+
const editing = editingRange(state2, node, focus);
|
|
2650
2651
|
if (urlNode && marks.length >= 2) {
|
|
2651
|
-
const url =
|
|
2652
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
2652
2653
|
if (!editing) {
|
|
2653
2654
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2654
2655
|
}
|
|
@@ -2669,24 +2670,24 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2669
2670
|
}
|
|
2670
2671
|
} else if (node.name === "HeaderMark") {
|
|
2671
2672
|
const parent = node.node.parent;
|
|
2672
|
-
if (/^ATX/.test(parent.name) && !editingRange(
|
|
2673
|
-
const next =
|
|
2673
|
+
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
2674
|
+
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
2674
2675
|
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2675
2676
|
}
|
|
2676
2677
|
} else if (node.name === "HorizontalRule") {
|
|
2677
|
-
if (!editingRange(
|
|
2678
|
+
if (!editingRange(state2, node, focus)) {
|
|
2678
2679
|
deco.add(node.from, node.to, horizontalRule);
|
|
2679
2680
|
}
|
|
2680
2681
|
} else if (node.name === "TaskMarker") {
|
|
2681
|
-
if (!editingRange(
|
|
2682
|
-
const checked =
|
|
2682
|
+
if (!editingRange(state2, node, focus)) {
|
|
2683
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2683
2684
|
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2684
2685
|
class: "cm-task"
|
|
2685
2686
|
}));
|
|
2686
2687
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2687
2688
|
}
|
|
2688
2689
|
} else if (MarksByParent.has(node.name)) {
|
|
2689
|
-
if (!editingRange(
|
|
2690
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
2690
2691
|
atomicDeco.add(node.from, node.to, hide);
|
|
2691
2692
|
}
|
|
2692
2693
|
}
|
|
@@ -2811,13 +2812,13 @@ var List;
|
|
|
2811
2812
|
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2812
2813
|
List2[List2["Task"] = 2] = "Task";
|
|
2813
2814
|
})(List || (List = {}));
|
|
2814
|
-
var setHeading = (level) => ({ state, dispatch }) => {
|
|
2815
|
-
const { selection: { ranges }, doc } =
|
|
2815
|
+
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2816
|
+
const { selection: { ranges }, doc } = state2;
|
|
2816
2817
|
const changes = [];
|
|
2817
2818
|
let prevBlock = -1;
|
|
2818
2819
|
for (const range of ranges) {
|
|
2819
2820
|
let sawBlock = false;
|
|
2820
|
-
syntaxTree2(
|
|
2821
|
+
syntaxTree2(state2).iterate({
|
|
2821
2822
|
from: range.from,
|
|
2822
2823
|
to: range.to,
|
|
2823
2824
|
enter: (node) => {
|
|
@@ -2870,7 +2871,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2870
2871
|
}
|
|
2871
2872
|
});
|
|
2872
2873
|
let line;
|
|
2873
|
-
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line =
|
|
2874
|
+
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2874
2875
|
changes.push({
|
|
2875
2876
|
from: line.from,
|
|
2876
2877
|
to: line.to,
|
|
@@ -2881,23 +2882,23 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2881
2882
|
if (!changes.length) {
|
|
2882
2883
|
return false;
|
|
2883
2884
|
}
|
|
2884
|
-
const changeSet =
|
|
2885
|
-
dispatch(
|
|
2885
|
+
const changeSet = state2.changes(changes);
|
|
2886
|
+
dispatch(state2.update({
|
|
2886
2887
|
changes: changeSet,
|
|
2887
|
-
selection:
|
|
2888
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2888
2889
|
userEvent: "format.setHeading",
|
|
2889
2890
|
scrollIntoView: true
|
|
2890
2891
|
}));
|
|
2891
2892
|
return true;
|
|
2892
2893
|
};
|
|
2893
|
-
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
2894
|
+
var setStyle = (type, enable) => ({ state: state2, dispatch }) => {
|
|
2894
2895
|
const marker = inlineMarkerText(type);
|
|
2895
|
-
const changes =
|
|
2896
|
+
const changes = state2.changeByRange((range) => {
|
|
2896
2897
|
if (!enable && range.empty) {
|
|
2897
|
-
const after =
|
|
2898
|
+
const after = state2.doc.sliceString(range.head, range.head + 6);
|
|
2898
2899
|
const found = after.indexOf(marker);
|
|
2899
2900
|
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
2900
|
-
const before =
|
|
2901
|
+
const before = state2.doc.sliceString(range.head - 6, range.head);
|
|
2901
2902
|
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
2902
2903
|
...before.slice(before.length - found)
|
|
2903
2904
|
].reverse().join("") === after.slice(0, found)) {
|
|
@@ -2924,14 +2925,14 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2924
2925
|
let startCovered = false;
|
|
2925
2926
|
let endCovered = false;
|
|
2926
2927
|
let { from, to } = range;
|
|
2927
|
-
syntaxTree2(
|
|
2928
|
+
syntaxTree2(state2).iterate({
|
|
2928
2929
|
from,
|
|
2929
2930
|
to,
|
|
2930
2931
|
enter: (node) => {
|
|
2931
2932
|
const { name } = node;
|
|
2932
2933
|
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
2933
2934
|
blockStart = blockContentStart(node);
|
|
2934
|
-
blockEnd = blockContentEnd(node,
|
|
2935
|
+
blockEnd = blockContentEnd(node, state2.doc);
|
|
2935
2936
|
startCovered = endCovered = false;
|
|
2936
2937
|
} else if (name === "Link" || name === "Image" && enable) {
|
|
2937
2938
|
if (from < node.from && to > node.from && to <= node.to) {
|
|
@@ -2976,7 +2977,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2976
2977
|
});
|
|
2977
2978
|
if (markType !== type && closeStart >= to) {
|
|
2978
2979
|
changesAtEnd.push({
|
|
2979
|
-
from: skipSpaces(Math.min(to, blockEnd),
|
|
2980
|
+
from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
|
|
2980
2981
|
insert: inlineMarkerText(markType)
|
|
2981
2982
|
});
|
|
2982
2983
|
}
|
|
@@ -2988,7 +2989,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2988
2989
|
});
|
|
2989
2990
|
if (markType !== type && openEnd <= from) {
|
|
2990
2991
|
changes2.push({
|
|
2991
|
-
from: skipSpaces(Math.max(from, blockStart),
|
|
2992
|
+
from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
|
|
2992
2993
|
insert: inlineMarkerText(markType)
|
|
2993
2994
|
});
|
|
2994
2995
|
}
|
|
@@ -3018,7 +3019,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3018
3019
|
changes2.push(startCovered);
|
|
3019
3020
|
} else if (startCovered) {
|
|
3020
3021
|
changes2.push({
|
|
3021
|
-
from: skipSpaces(rangeStart,
|
|
3022
|
+
from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
|
|
3022
3023
|
insert: marker
|
|
3023
3024
|
});
|
|
3024
3025
|
}
|
|
@@ -3026,7 +3027,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3026
3027
|
changes2.push(endCovered);
|
|
3027
3028
|
} else if (endCovered) {
|
|
3028
3029
|
changes2.push({
|
|
3029
|
-
from: skipSpaces(rangeEnd,
|
|
3030
|
+
from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
|
|
3030
3031
|
insert: marker
|
|
3031
3032
|
});
|
|
3032
3033
|
}
|
|
@@ -3034,7 +3035,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3034
3035
|
}
|
|
3035
3036
|
}
|
|
3036
3037
|
});
|
|
3037
|
-
if (blockStart < 0 && range.empty && enable && !/\S/.test(
|
|
3038
|
+
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
3038
3039
|
return {
|
|
3039
3040
|
changes: {
|
|
3040
3041
|
from: range.head,
|
|
@@ -3043,13 +3044,13 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3043
3044
|
range: EditorSelection.cursor(range.head + marker.length)
|
|
3044
3045
|
};
|
|
3045
3046
|
}
|
|
3046
|
-
const changeSet =
|
|
3047
|
+
const changeSet = state2.changes(changes2.concat(changesAtEnd));
|
|
3047
3048
|
return {
|
|
3048
3049
|
changes: changeSet,
|
|
3049
3050
|
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
3050
3051
|
};
|
|
3051
3052
|
});
|
|
3052
|
-
dispatch(
|
|
3053
|
+
dispatch(state2.update(changes, {
|
|
3053
3054
|
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
3054
3055
|
scrollIntoView: true
|
|
3055
3056
|
}));
|
|
@@ -3123,8 +3124,8 @@ var insertTable = (view) => {
|
|
|
3123
3124
|
const { from } = doc.line(number);
|
|
3124
3125
|
snippets.table(view, null, from, from);
|
|
3125
3126
|
};
|
|
3126
|
-
var removeLinkInner = (from, to, changes,
|
|
3127
|
-
syntaxTree2(
|
|
3127
|
+
var removeLinkInner = (from, to, changes, state2) => {
|
|
3128
|
+
syntaxTree2(state2).iterate({
|
|
3128
3129
|
from,
|
|
3129
3130
|
to,
|
|
3130
3131
|
enter: (node) => {
|
|
@@ -3138,8 +3139,8 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3138
3139
|
});
|
|
3139
3140
|
} else if (name === "LinkTitle" || name === "URL") {
|
|
3140
3141
|
changes.push({
|
|
3141
|
-
from: skipSpaces(node2.from,
|
|
3142
|
-
to: skipSpaces(node2.to,
|
|
3142
|
+
from: skipSpaces(node2.from, state2.doc, -1),
|
|
3143
|
+
to: skipSpaces(node2.to, state2.doc, 1)
|
|
3143
3144
|
});
|
|
3144
3145
|
}
|
|
3145
3146
|
});
|
|
@@ -3148,32 +3149,32 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3148
3149
|
}
|
|
3149
3150
|
});
|
|
3150
3151
|
};
|
|
3151
|
-
var removeLink = ({ state, dispatch }) => {
|
|
3152
|
+
var removeLink = ({ state: state2, dispatch }) => {
|
|
3152
3153
|
const changes = [];
|
|
3153
|
-
for (const { from, to } of
|
|
3154
|
-
removeLinkInner(from, to, changes,
|
|
3154
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3155
|
+
removeLinkInner(from, to, changes, state2);
|
|
3155
3156
|
}
|
|
3156
3157
|
if (!changes) {
|
|
3157
3158
|
return false;
|
|
3158
3159
|
}
|
|
3159
|
-
dispatch(
|
|
3160
|
+
dispatch(state2.update({
|
|
3160
3161
|
changes,
|
|
3161
3162
|
userEvent: "format.link.remove",
|
|
3162
3163
|
scrollIntoView: true
|
|
3163
3164
|
}));
|
|
3164
3165
|
return true;
|
|
3165
3166
|
};
|
|
3166
|
-
var addLink = ({ state, dispatch }) => {
|
|
3167
|
-
const changes =
|
|
3167
|
+
var addLink = ({ url, image: image2 } = {}) => ({ state: state2, dispatch }) => {
|
|
3168
|
+
const changes = state2.changeByRange((range) => {
|
|
3168
3169
|
let { from, to } = range;
|
|
3169
3170
|
const cutStyles = [];
|
|
3170
3171
|
let okay = null;
|
|
3171
|
-
syntaxTree2(
|
|
3172
|
+
syntaxTree2(state2).iterate({
|
|
3172
3173
|
from,
|
|
3173
3174
|
to,
|
|
3174
3175
|
enter: (node) => {
|
|
3175
3176
|
if (Object.hasOwn(Textblocks, node.name)) {
|
|
3176
|
-
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node,
|
|
3177
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
|
|
3177
3178
|
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
3178
3179
|
const sNode = node.node;
|
|
3179
3180
|
if (node.from < from && node.to <= to) {
|
|
@@ -3193,7 +3194,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3193
3194
|
}
|
|
3194
3195
|
});
|
|
3195
3196
|
if (okay === null) {
|
|
3196
|
-
const line =
|
|
3197
|
+
const line = state2.doc.lineAt(from);
|
|
3197
3198
|
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
3198
3199
|
}
|
|
3199
3200
|
if (!okay) {
|
|
@@ -3203,26 +3204,26 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3203
3204
|
}
|
|
3204
3205
|
const changes2 = [];
|
|
3205
3206
|
const changesAfter = [];
|
|
3206
|
-
removeLinkInner(from, to, changesAfter,
|
|
3207
|
+
removeLinkInner(from, to, changesAfter, state2);
|
|
3207
3208
|
let cursorOffset = 1;
|
|
3208
3209
|
for (const style of cutStyles) {
|
|
3209
3210
|
const type = InlineMarker[style.name];
|
|
3210
3211
|
const mark2 = inlineMarkerText(type);
|
|
3211
3212
|
if (style.from < from) {
|
|
3212
3213
|
changes2.push({
|
|
3213
|
-
from: skipSpaces(from,
|
|
3214
|
+
from: skipSpaces(from, state2.doc, -1),
|
|
3214
3215
|
insert: mark2
|
|
3215
3216
|
});
|
|
3216
3217
|
changesAfter.push({
|
|
3217
|
-
from: skipSpaces(from,
|
|
3218
|
+
from: skipSpaces(from, state2.doc, 1, to),
|
|
3218
3219
|
insert: mark2
|
|
3219
3220
|
});
|
|
3220
3221
|
} else {
|
|
3221
3222
|
changes2.push({
|
|
3222
|
-
from: skipSpaces(to,
|
|
3223
|
+
from: skipSpaces(to, state2.doc, -1, from),
|
|
3223
3224
|
insert: mark2
|
|
3224
3225
|
});
|
|
3225
|
-
const after = skipSpaces(to,
|
|
3226
|
+
const after = skipSpaces(to, state2.doc, 1);
|
|
3226
3227
|
if (after === to) {
|
|
3227
3228
|
cursorOffset += mark2.length;
|
|
3228
3229
|
}
|
|
@@ -3234,34 +3235,34 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3234
3235
|
}
|
|
3235
3236
|
changes2.push({
|
|
3236
3237
|
from,
|
|
3237
|
-
insert: "["
|
|
3238
|
+
insert: image2 ? "`
|
|
3241
3242
|
});
|
|
3242
|
-
const changeSet =
|
|
3243
|
+
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
3243
3244
|
return {
|
|
3244
3245
|
changes: changeSet,
|
|
3245
|
-
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
3246
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
|
|
3246
3247
|
};
|
|
3247
3248
|
});
|
|
3248
3249
|
if (changes.changes.empty) {
|
|
3249
3250
|
return false;
|
|
3250
3251
|
}
|
|
3251
|
-
dispatch(
|
|
3252
|
+
dispatch(state2.update(changes, {
|
|
3252
3253
|
userEvent: "format.link.add",
|
|
3253
3254
|
scrollIntoView: true
|
|
3254
3255
|
}));
|
|
3255
3256
|
return true;
|
|
3256
3257
|
};
|
|
3257
|
-
var addList = (type) => ({ state, dispatch }) => {
|
|
3258
|
+
var addList = (type) => ({ state: state2, dispatch }) => {
|
|
3258
3259
|
let lastBlock = -1;
|
|
3259
3260
|
let counter = 1;
|
|
3260
3261
|
let first = true;
|
|
3261
3262
|
let parentColumn = null;
|
|
3262
3263
|
const blocks = [];
|
|
3263
|
-
for (const { from, to } of
|
|
3264
|
-
syntaxTree2(
|
|
3264
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3265
|
+
syntaxTree2(state2).iterate({
|
|
3265
3266
|
from,
|
|
3266
3267
|
to,
|
|
3267
3268
|
enter: (node) => {
|
|
@@ -3273,7 +3274,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3273
3274
|
}
|
|
3274
3275
|
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
3275
3276
|
const item = before.lastChild;
|
|
3276
|
-
const itemLine =
|
|
3277
|
+
const itemLine = state2.doc.lineAt(item.from);
|
|
3277
3278
|
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
3278
3279
|
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
3279
3280
|
if (type === 0) {
|
|
@@ -3308,10 +3309,10 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3308
3309
|
});
|
|
3309
3310
|
}
|
|
3310
3311
|
if (!blocks.length) {
|
|
3311
|
-
const { from, to } =
|
|
3312
|
+
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
3312
3313
|
if (from === to) {
|
|
3313
3314
|
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
3314
|
-
dispatch(
|
|
3315
|
+
dispatch(state2.update({
|
|
3315
3316
|
changes: [
|
|
3316
3317
|
{
|
|
3317
3318
|
from,
|
|
@@ -3332,11 +3333,11 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3332
3333
|
for (let i = 0; i < blocks.length; i++) {
|
|
3333
3334
|
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
3334
3335
|
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
3335
|
-
let padding = nodeFrom > 0 && !/\s/.test(
|
|
3336
|
+
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
3336
3337
|
if (type === 0) {
|
|
3337
3338
|
padding += String(counter2).length;
|
|
3338
3339
|
}
|
|
3339
|
-
let line =
|
|
3340
|
+
let line = state2.doc.lineAt(nodeFrom);
|
|
3340
3341
|
const column = nodeFrom - line.from;
|
|
3341
3342
|
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
3342
3343
|
padding = Math.max(padding, parentColumn2 - column);
|
|
@@ -3361,7 +3362,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3361
3362
|
insert: mark2
|
|
3362
3363
|
});
|
|
3363
3364
|
while (line.to < node.to) {
|
|
3364
|
-
line =
|
|
3365
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3365
3366
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3366
3367
|
changes.push({
|
|
3367
3368
|
from: line.from + Math.min(open, column),
|
|
@@ -3376,25 +3377,25 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3376
3377
|
next = next.nextSibling;
|
|
3377
3378
|
}
|
|
3378
3379
|
if (next?.name === "OrderedList") {
|
|
3379
|
-
renumberListItems(next.firstChild, last.counter + 1, changes,
|
|
3380
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
3380
3381
|
}
|
|
3381
3382
|
}
|
|
3382
|
-
const changeSet =
|
|
3383
|
-
dispatch(
|
|
3383
|
+
const changeSet = state2.changes(changes);
|
|
3384
|
+
dispatch(state2.update({
|
|
3384
3385
|
changes: changeSet,
|
|
3385
|
-
selection:
|
|
3386
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3386
3387
|
userEvent: "format.list.add",
|
|
3387
3388
|
scrollIntoView: true
|
|
3388
3389
|
}));
|
|
3389
3390
|
return true;
|
|
3390
3391
|
};
|
|
3391
|
-
var removeList = (type) => ({ state, dispatch }) => {
|
|
3392
|
+
var removeList = (type) => ({ state: state2, dispatch }) => {
|
|
3392
3393
|
let lastBlock = -1;
|
|
3393
3394
|
const changes = [];
|
|
3394
3395
|
const stack = [];
|
|
3395
3396
|
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
3396
|
-
for (const { from, to } of
|
|
3397
|
-
syntaxTree2(
|
|
3397
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3398
|
+
syntaxTree2(state2).iterate({
|
|
3398
3399
|
from,
|
|
3399
3400
|
to,
|
|
3400
3401
|
enter: (node) => {
|
|
@@ -3411,7 +3412,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3411
3412
|
stack.pop();
|
|
3412
3413
|
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
3413
3414
|
lastBlock = node.from;
|
|
3414
|
-
let line =
|
|
3415
|
+
let line = state2.doc.lineAt(node.from);
|
|
3415
3416
|
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
3416
3417
|
if (!mark2) {
|
|
3417
3418
|
return false;
|
|
@@ -3422,7 +3423,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3422
3423
|
to: node.from + mark2[0].length
|
|
3423
3424
|
});
|
|
3424
3425
|
while (line.to < node.to) {
|
|
3425
|
-
line =
|
|
3426
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3426
3427
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3427
3428
|
if (open > column) {
|
|
3428
3429
|
changes.push({
|
|
@@ -3432,7 +3433,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3432
3433
|
}
|
|
3433
3434
|
}
|
|
3434
3435
|
if (node.to >= to) {
|
|
3435
|
-
renumberListItems(node.node.nextSibling, 1, changes,
|
|
3436
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
3436
3437
|
}
|
|
3437
3438
|
return false;
|
|
3438
3439
|
}
|
|
@@ -3442,7 +3443,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3442
3443
|
if (!changes.length) {
|
|
3443
3444
|
return false;
|
|
3444
3445
|
}
|
|
3445
|
-
dispatch(
|
|
3446
|
+
dispatch(state2.update({
|
|
3446
3447
|
changes,
|
|
3447
3448
|
userEvent: "format.list.remove",
|
|
3448
3449
|
scrollIntoView: true
|
|
@@ -3472,12 +3473,12 @@ var renumberListItems = (item, counter, changes, doc) => {
|
|
|
3472
3473
|
}
|
|
3473
3474
|
}
|
|
3474
3475
|
};
|
|
3475
|
-
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
3476
|
+
var setBlockquote = (enable) => ({ state: state2, dispatch }) => {
|
|
3476
3477
|
const lines = [];
|
|
3477
3478
|
let lastBlock = -1;
|
|
3478
|
-
for (const { from, to } of
|
|
3479
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3479
3480
|
const sawBlock = false;
|
|
3480
|
-
syntaxTree2(
|
|
3481
|
+
syntaxTree2(state2).iterate({
|
|
3481
3482
|
from,
|
|
3482
3483
|
to,
|
|
3483
3484
|
enter: (node) => {
|
|
@@ -3486,9 +3487,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3486
3487
|
return false;
|
|
3487
3488
|
}
|
|
3488
3489
|
lastBlock = node.from;
|
|
3489
|
-
let line2 =
|
|
3490
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
3490
3491
|
if (line2.number > 1) {
|
|
3491
|
-
const prevLine =
|
|
3492
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
3492
3493
|
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
3493
3494
|
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
3494
3495
|
lines.push(prevLine);
|
|
@@ -3500,10 +3501,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3500
3501
|
if (line2.to >= node.to) {
|
|
3501
3502
|
break;
|
|
3502
3503
|
}
|
|
3503
|
-
line2 =
|
|
3504
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
3504
3505
|
}
|
|
3505
|
-
if (!enable && line2.number <
|
|
3506
|
-
const nextLine =
|
|
3506
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
3507
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
3507
3508
|
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
3508
3509
|
lines.push(nextLine);
|
|
3509
3510
|
}
|
|
@@ -3513,7 +3514,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3513
3514
|
}
|
|
3514
3515
|
});
|
|
3515
3516
|
let line;
|
|
3516
|
-
if (!sawBlock && enable && from === to && !/\S/.test((line =
|
|
3517
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3517
3518
|
lines.push(line);
|
|
3518
3519
|
}
|
|
3519
3520
|
}
|
|
@@ -3537,10 +3538,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3537
3538
|
if (!changes.length) {
|
|
3538
3539
|
return false;
|
|
3539
3540
|
}
|
|
3540
|
-
const changeSet =
|
|
3541
|
-
dispatch(
|
|
3541
|
+
const changeSet = state2.changes(changes);
|
|
3542
|
+
dispatch(state2.update({
|
|
3542
3543
|
changes: changeSet,
|
|
3543
|
-
selection:
|
|
3544
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3544
3545
|
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3545
3546
|
scrollIntoView: true
|
|
3546
3547
|
}));
|
|
@@ -3552,11 +3553,11 @@ var toggleBlockquote = (target) => {
|
|
|
3552
3553
|
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3553
3554
|
};
|
|
3554
3555
|
var addCodeblock = (target) => {
|
|
3555
|
-
const { state, dispatch } = target;
|
|
3556
|
-
const { selection } =
|
|
3556
|
+
const { state: state2, dispatch } = target;
|
|
3557
|
+
const { selection } = state2;
|
|
3557
3558
|
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
3558
3559
|
const { head } = selection.main;
|
|
3559
|
-
const line =
|
|
3560
|
+
const line = state2.doc.lineAt(head);
|
|
3560
3561
|
if (!/\S/.test(line.text) && head === line.from) {
|
|
3561
3562
|
snippets.codeblock(target, null, line.from, line.to);
|
|
3562
3563
|
return true;
|
|
@@ -3566,7 +3567,7 @@ var addCodeblock = (target) => {
|
|
|
3566
3567
|
for (const { from, to } of selection.ranges) {
|
|
3567
3568
|
let blockFrom = from;
|
|
3568
3569
|
let blockTo = to;
|
|
3569
|
-
syntaxTree2(
|
|
3570
|
+
syntaxTree2(state2).iterate({
|
|
3570
3571
|
from,
|
|
3571
3572
|
to,
|
|
3572
3573
|
enter: (node) => {
|
|
@@ -3575,8 +3576,8 @@ var addCodeblock = (target) => {
|
|
|
3575
3576
|
blockFrom = node.from;
|
|
3576
3577
|
blockTo = node.to;
|
|
3577
3578
|
} else {
|
|
3578
|
-
blockFrom = Math.min(blockFrom,
|
|
3579
|
-
blockTo = Math.max(blockTo,
|
|
3579
|
+
blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
|
|
3580
|
+
blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
|
|
3580
3581
|
}
|
|
3581
3582
|
}
|
|
3582
3583
|
}
|
|
@@ -3594,7 +3595,7 @@ var addCodeblock = (target) => {
|
|
|
3594
3595
|
return false;
|
|
3595
3596
|
}
|
|
3596
3597
|
const changes = ranges.map(({ from, to }) => {
|
|
3597
|
-
const column = from -
|
|
3598
|
+
const column = from - state2.doc.lineAt(from).from;
|
|
3598
3599
|
return [
|
|
3599
3600
|
{
|
|
3600
3601
|
from,
|
|
@@ -3606,30 +3607,30 @@ var addCodeblock = (target) => {
|
|
|
3606
3607
|
}
|
|
3607
3608
|
];
|
|
3608
3609
|
});
|
|
3609
|
-
dispatch(
|
|
3610
|
+
dispatch(state2.update({
|
|
3610
3611
|
changes,
|
|
3611
3612
|
userEvent: "format.codeblock.add",
|
|
3612
3613
|
scrollIntoView: true
|
|
3613
3614
|
}));
|
|
3614
3615
|
return true;
|
|
3615
3616
|
};
|
|
3616
|
-
var removeCodeblock = ({ state, dispatch }) => {
|
|
3617
|
+
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3617
3618
|
const changes = [];
|
|
3618
3619
|
let lastBlock = -1;
|
|
3619
|
-
for (const { from, to } of
|
|
3620
|
-
syntaxTree2(
|
|
3620
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3621
|
+
syntaxTree2(state2).iterate({
|
|
3621
3622
|
from,
|
|
3622
3623
|
to,
|
|
3623
3624
|
enter: (node) => {
|
|
3624
3625
|
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
3625
3626
|
lastBlock = node.from;
|
|
3626
|
-
const firstLine =
|
|
3627
|
+
const firstLine = state2.doc.lineAt(node.from);
|
|
3627
3628
|
if (node.name === "FencedCode") {
|
|
3628
3629
|
changes.push({
|
|
3629
3630
|
from: node.from,
|
|
3630
3631
|
to: firstLine.to + 1 + node.from - firstLine.from
|
|
3631
3632
|
});
|
|
3632
|
-
const lastLine =
|
|
3633
|
+
const lastLine = state2.doc.lineAt(node.to);
|
|
3633
3634
|
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
3634
3635
|
changes.push({
|
|
3635
3636
|
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
@@ -3638,7 +3639,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3638
3639
|
}
|
|
3639
3640
|
} else {
|
|
3640
3641
|
const column = node.from - firstLine.from;
|
|
3641
|
-
for (let line = firstLine; ; line =
|
|
3642
|
+
for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
|
|
3642
3643
|
changes.push({
|
|
3643
3644
|
from: line.from + column - 4,
|
|
3644
3645
|
to: line.from + column
|
|
@@ -3655,7 +3656,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3655
3656
|
if (!changes.length) {
|
|
3656
3657
|
return false;
|
|
3657
3658
|
}
|
|
3658
|
-
dispatch(
|
|
3659
|
+
dispatch(state2.update({
|
|
3659
3660
|
changes,
|
|
3660
3661
|
userEvent: "format.codeblock.remove",
|
|
3661
3662
|
scrollIntoView: true
|
|
@@ -3714,7 +3715,7 @@ var Textblocks = {
|
|
|
3714
3715
|
TableCell: "tablecell",
|
|
3715
3716
|
Task: "paragraph"
|
|
3716
3717
|
};
|
|
3717
|
-
var getFormatting = (
|
|
3718
|
+
var getFormatting = (state2) => {
|
|
3718
3719
|
let blockType = null;
|
|
3719
3720
|
const inline = [
|
|
3720
3721
|
null,
|
|
@@ -3740,7 +3741,7 @@ var getFormatting = (state) => {
|
|
|
3740
3741
|
continue;
|
|
3741
3742
|
} else if (currentBlock.active[i]) {
|
|
3742
3743
|
inline[i] = true;
|
|
3743
|
-
} else if (/\S/.test(
|
|
3744
|
+
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3744
3745
|
inline[i] = false;
|
|
3745
3746
|
}
|
|
3746
3747
|
}
|
|
@@ -3751,12 +3752,12 @@ var getFormatting = (state) => {
|
|
|
3751
3752
|
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3752
3753
|
}
|
|
3753
3754
|
};
|
|
3754
|
-
const { selection } =
|
|
3755
|
+
const { selection } = state2;
|
|
3755
3756
|
for (const range of selection.ranges) {
|
|
3756
3757
|
if (range.empty && inline.some((v) => v === null)) {
|
|
3757
3758
|
const contextSize = Math.min(range.head, 6);
|
|
3758
|
-
const contextBefore =
|
|
3759
|
-
let contextAfter =
|
|
3759
|
+
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3760
|
+
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3760
3761
|
for (let i = 0; i < contextSize; i++) {
|
|
3761
3762
|
const ch = contextAfter[i];
|
|
3762
3763
|
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
@@ -3775,7 +3776,7 @@ var getFormatting = (state) => {
|
|
|
3775
3776
|
}
|
|
3776
3777
|
}
|
|
3777
3778
|
}
|
|
3778
|
-
syntaxTree2(
|
|
3779
|
+
syntaxTree2(state2).iterate({
|
|
3779
3780
|
from: range.from,
|
|
3780
3781
|
to: range.to,
|
|
3781
3782
|
enter: (node) => {
|
|
@@ -3849,7 +3850,7 @@ var getFormatting = (state) => {
|
|
|
3849
3850
|
}
|
|
3850
3851
|
});
|
|
3851
3852
|
}
|
|
3852
|
-
const { from, to } =
|
|
3853
|
+
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3853
3854
|
const blankLine = from === to;
|
|
3854
3855
|
return {
|
|
3855
3856
|
blankLine,
|
|
@@ -3864,17 +3865,17 @@ var getFormatting = (state) => {
|
|
|
3864
3865
|
};
|
|
3865
3866
|
};
|
|
3866
3867
|
var useFormattingState = () => {
|
|
3867
|
-
const [
|
|
3868
|
+
const [state2, setState] = useState(null);
|
|
3868
3869
|
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3869
3870
|
if (update2.docChanged || update2.selectionSet) {
|
|
3870
3871
|
const newState = getFormatting(update2.state);
|
|
3871
|
-
if (!
|
|
3872
|
+
if (!state2 || !compareFormatting(state2, newState)) {
|
|
3872
3873
|
setState(newState);
|
|
3873
3874
|
}
|
|
3874
3875
|
}
|
|
3875
3876
|
}), []);
|
|
3876
3877
|
return [
|
|
3877
|
-
|
|
3878
|
+
state2,
|
|
3878
3879
|
observer
|
|
3879
3880
|
];
|
|
3880
3881
|
};
|
|
@@ -3885,8 +3886,8 @@ import { StateField as StateField5 } from "@codemirror/state";
|
|
|
3885
3886
|
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3886
3887
|
var image = (options = {}) => {
|
|
3887
3888
|
return StateField5.define({
|
|
3888
|
-
create: (
|
|
3889
|
-
return Decoration6.set(buildDecorations2(0,
|
|
3889
|
+
create: (state2) => {
|
|
3890
|
+
return Decoration6.set(buildDecorations2(0, state2.doc.length, state2));
|
|
3890
3891
|
},
|
|
3891
3892
|
update: (value, tr) => {
|
|
3892
3893
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3920,16 +3921,16 @@ var preloadImage = (url) => {
|
|
|
3920
3921
|
preloaded.add(url);
|
|
3921
3922
|
}
|
|
3922
3923
|
};
|
|
3923
|
-
var buildDecorations2 = (from, to,
|
|
3924
|
+
var buildDecorations2 = (from, to, state2) => {
|
|
3924
3925
|
const decorations = [];
|
|
3925
|
-
const cursor =
|
|
3926
|
-
syntaxTree3(
|
|
3926
|
+
const cursor = state2.selection.main.head;
|
|
3927
|
+
syntaxTree3(state2).iterate({
|
|
3927
3928
|
enter: (node) => {
|
|
3928
3929
|
if (node.name === "Image") {
|
|
3929
3930
|
const urlNode = node.node.getChild("URL");
|
|
3930
3931
|
if (urlNode) {
|
|
3931
|
-
const hide2 =
|
|
3932
|
-
const url =
|
|
3932
|
+
const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
|
|
3933
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3933
3934
|
preloadImage(url);
|
|
3934
3935
|
decorations.push(Decoration6.replace({
|
|
3935
3936
|
block: true,
|
|
@@ -3959,6 +3960,8 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
3959
3960
|
return img;
|
|
3960
3961
|
}
|
|
3961
3962
|
};
|
|
3963
|
+
var imageUpload = (options = {}) => {
|
|
3964
|
+
};
|
|
3962
3965
|
|
|
3963
3966
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
3964
3967
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
@@ -4000,21 +4003,21 @@ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "
|
|
|
4000
4003
|
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4001
4004
|
var table = (options = {}) => {
|
|
4002
4005
|
return StateField6.define({
|
|
4003
|
-
create: (
|
|
4006
|
+
create: (state2) => update(state2, options),
|
|
4004
4007
|
update: (_, tr) => update(tr.state, options),
|
|
4005
4008
|
provide: (field) => EditorView15.decorations.from(field)
|
|
4006
4009
|
});
|
|
4007
4010
|
};
|
|
4008
|
-
var update = (
|
|
4011
|
+
var update = (state2, options) => {
|
|
4009
4012
|
const builder = new RangeSetBuilder3();
|
|
4010
|
-
const cursor =
|
|
4013
|
+
const cursor = state2.selection.main.head;
|
|
4011
4014
|
const tables = [];
|
|
4012
4015
|
const getTable = () => tables[tables.length - 1];
|
|
4013
4016
|
const getRow = () => {
|
|
4014
4017
|
const table2 = getTable();
|
|
4015
4018
|
return table2.rows?.[table2.rows.length - 1];
|
|
4016
4019
|
};
|
|
4017
|
-
syntaxTree5(
|
|
4020
|
+
syntaxTree5(state2).iterate({
|
|
4018
4021
|
enter: (node) => {
|
|
4019
4022
|
switch (node.name) {
|
|
4020
4023
|
case "Table": {
|
|
@@ -4035,9 +4038,9 @@ var update = (state, options) => {
|
|
|
4035
4038
|
case "TableCell": {
|
|
4036
4039
|
const row = getRow();
|
|
4037
4040
|
if (row) {
|
|
4038
|
-
row.push(
|
|
4041
|
+
row.push(state2.sliceDoc(node.from, node.to));
|
|
4039
4042
|
} else {
|
|
4040
|
-
getTable().header?.push(
|
|
4043
|
+
getTable().header?.push(state2.sliceDoc(node.from, node.to));
|
|
4041
4044
|
}
|
|
4042
4045
|
break;
|
|
4043
4046
|
}
|
|
@@ -4045,7 +4048,7 @@ var update = (state, options) => {
|
|
|
4045
4048
|
}
|
|
4046
4049
|
});
|
|
4047
4050
|
tables.forEach((table2) => {
|
|
4048
|
-
const hide2 =
|
|
4051
|
+
const hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4049
4052
|
if (hide2) {
|
|
4050
4053
|
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
4051
4054
|
widget: new TableWidget(table2)
|
|
@@ -4136,6 +4139,7 @@ var mention = ({ onSearch }) => {
|
|
|
4136
4139
|
import { Facet as Facet6 } from "@codemirror/state";
|
|
4137
4140
|
import { keymap as keymap7 } from "@codemirror/view";
|
|
4138
4141
|
import { vim } from "@replit/codemirror-vim";
|
|
4142
|
+
var focusEvent = "focus.container";
|
|
4139
4143
|
var editorMode = Facet6.define({
|
|
4140
4144
|
combine: (modes) => modes[0] ?? {}
|
|
4141
4145
|
});
|
|
@@ -4152,7 +4156,7 @@ var EditorModes = {
|
|
|
4152
4156
|
key: "Alt-Escape",
|
|
4153
4157
|
run: (view) => {
|
|
4154
4158
|
view.dispatch({
|
|
4155
|
-
userEvent:
|
|
4159
|
+
userEvent: focusEvent
|
|
4156
4160
|
});
|
|
4157
4161
|
return true;
|
|
4158
4162
|
}
|
|
@@ -4161,8 +4165,95 @@ var EditorModes = {
|
|
|
4161
4165
|
]
|
|
4162
4166
|
};
|
|
4163
4167
|
|
|
4168
|
+
// packages/ui/react-ui-editor/src/extensions/state.ts
|
|
4169
|
+
import { Transaction as Transaction2 } from "@codemirror/state";
|
|
4170
|
+
import { EditorView as EditorView16, keymap as keymap8 } from "@codemirror/view";
|
|
4171
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
4172
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4173
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4174
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
|
|
4175
|
+
var scrollAnnotation = "dxos.org/cm/scrolling";
|
|
4176
|
+
var keyPrefix = "dxos.org/react-ui-editor/state";
|
|
4177
|
+
var localStorageStateStoreAdapter = {
|
|
4178
|
+
setState: (id, state2) => {
|
|
4179
|
+
invariant4(id, void 0, {
|
|
4180
|
+
F: __dxlog_file11,
|
|
4181
|
+
L: 35,
|
|
4182
|
+
S: void 0,
|
|
4183
|
+
A: [
|
|
4184
|
+
"id",
|
|
4185
|
+
""
|
|
4186
|
+
]
|
|
4187
|
+
});
|
|
4188
|
+
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state2));
|
|
4189
|
+
},
|
|
4190
|
+
getState: (id) => {
|
|
4191
|
+
invariant4(id, void 0, {
|
|
4192
|
+
F: __dxlog_file11,
|
|
4193
|
+
L: 39,
|
|
4194
|
+
S: void 0,
|
|
4195
|
+
A: [
|
|
4196
|
+
"id",
|
|
4197
|
+
""
|
|
4198
|
+
]
|
|
4199
|
+
});
|
|
4200
|
+
const state2 = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
4201
|
+
return state2 ? JSON.parse(state2) : void 0;
|
|
4202
|
+
}
|
|
4203
|
+
};
|
|
4204
|
+
var state = ({ getState, setState } = {}) => {
|
|
4205
|
+
const setStateDebounced = debounce2(setState, 1e3);
|
|
4206
|
+
return [
|
|
4207
|
+
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
4208
|
+
EditorView16.updateListener.of(({ view, changes, transactions }) => {
|
|
4209
|
+
const id = view.state.facet(documentId2);
|
|
4210
|
+
if (!id || transactions.some((tr) => tr.isUserEvent(scrollAnnotation))) {
|
|
4211
|
+
return;
|
|
4212
|
+
}
|
|
4213
|
+
if (setState) {
|
|
4214
|
+
const { top } = view.dom.getBoundingClientRect();
|
|
4215
|
+
const pos = view.posAtCoords({
|
|
4216
|
+
x: 0,
|
|
4217
|
+
y: top
|
|
4218
|
+
});
|
|
4219
|
+
if (pos !== null) {
|
|
4220
|
+
const { anchor, head } = view.state.selection.main;
|
|
4221
|
+
setStateDebounced(id, {
|
|
4222
|
+
scrollTo: {
|
|
4223
|
+
from: pos,
|
|
4224
|
+
yMargin: 0
|
|
4225
|
+
},
|
|
4226
|
+
selection: {
|
|
4227
|
+
anchor,
|
|
4228
|
+
head
|
|
4229
|
+
}
|
|
4230
|
+
});
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
}),
|
|
4234
|
+
getState && keymap8.of([
|
|
4235
|
+
{
|
|
4236
|
+
key: "ctrl-r",
|
|
4237
|
+
run: (view) => {
|
|
4238
|
+
const state2 = getState(view.state.facet(documentId2));
|
|
4239
|
+
if (state2) {
|
|
4240
|
+
view.dispatch({
|
|
4241
|
+
effects: EditorView16.scrollIntoView(state2.scrollTo.from, {
|
|
4242
|
+
yMargin: 0
|
|
4243
|
+
}),
|
|
4244
|
+
selection: state2.selection,
|
|
4245
|
+
annotations: Transaction2.userEvent.of(scrollAnnotation)
|
|
4246
|
+
});
|
|
4247
|
+
}
|
|
4248
|
+
return true;
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
])
|
|
4252
|
+
].filter(isNotFalsy3);
|
|
4253
|
+
};
|
|
4254
|
+
|
|
4164
4255
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4165
|
-
import { keymap as
|
|
4256
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
|
4166
4257
|
var defaultItems = [
|
|
4167
4258
|
"hello world!",
|
|
4168
4259
|
"this is a test.",
|
|
@@ -4172,7 +4263,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4172
4263
|
let t;
|
|
4173
4264
|
let idx = 0;
|
|
4174
4265
|
return [
|
|
4175
|
-
|
|
4266
|
+
keymap9.of([
|
|
4176
4267
|
{
|
|
4177
4268
|
// Reset.
|
|
4178
4269
|
key: "alt-meta-'",
|
|
@@ -4219,9 +4310,11 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4219
4310
|
};
|
|
4220
4311
|
|
|
4221
4312
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4222
|
-
var
|
|
4313
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4223
4314
|
var instanceCount = 0;
|
|
4224
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo =
|
|
4315
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo = EditorView17.scrollIntoView(0, {
|
|
4316
|
+
yMargin: 0
|
|
4317
|
+
}), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4225
4318
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
4226
4319
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
4227
4320
|
tabBehavior: "limited"
|
|
@@ -4244,38 +4337,38 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4244
4337
|
id,
|
|
4245
4338
|
instanceId
|
|
4246
4339
|
}, {
|
|
4247
|
-
F:
|
|
4340
|
+
F: __dxlog_file12,
|
|
4248
4341
|
L: 88,
|
|
4249
4342
|
S: void 0,
|
|
4250
4343
|
C: (f, a) => f(...a)
|
|
4251
4344
|
});
|
|
4252
|
-
const
|
|
4345
|
+
const state2 = EditorState2.create({
|
|
4253
4346
|
doc,
|
|
4254
4347
|
selection,
|
|
4255
4348
|
extensions: [
|
|
4256
4349
|
id && documentId2.of(id),
|
|
4257
4350
|
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4258
|
-
|
|
4351
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4259
4352
|
log9.catch(err, void 0, {
|
|
4260
|
-
F:
|
|
4353
|
+
F: __dxlog_file12,
|
|
4261
4354
|
L: 101,
|
|
4262
4355
|
S: void 0,
|
|
4263
4356
|
C: (f, a) => f(...a)
|
|
4264
4357
|
});
|
|
4265
4358
|
}),
|
|
4266
4359
|
// Focus.
|
|
4267
|
-
|
|
4360
|
+
EditorView17.updateListener.of((update2) => {
|
|
4268
4361
|
update2.transactions.forEach((transaction) => {
|
|
4269
|
-
if (transaction.isUserEvent(
|
|
4362
|
+
if (transaction.isUserEvent(focusEvent)) {
|
|
4270
4363
|
rootRef.current?.focus();
|
|
4271
4364
|
}
|
|
4272
4365
|
});
|
|
4273
4366
|
}),
|
|
4274
4367
|
extensions
|
|
4275
|
-
].filter(
|
|
4368
|
+
].filter(isNotFalsy4)
|
|
4276
4369
|
});
|
|
4277
|
-
const view2 = new
|
|
4278
|
-
state,
|
|
4370
|
+
const view2 = new EditorView17({
|
|
4371
|
+
state: state2,
|
|
4279
4372
|
parent: rootRef.current,
|
|
4280
4373
|
scrollTo,
|
|
4281
4374
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
@@ -4287,18 +4380,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4287
4380
|
view3.update(trs);
|
|
4288
4381
|
}
|
|
4289
4382
|
});
|
|
4290
|
-
|
|
4291
|
-
if (moveToEndOfLine) {
|
|
4383
|
+
if (moveToEndOfLine && !(scrollTo || selection)) {
|
|
4292
4384
|
const { to } = view2.state.doc.lineAt(0);
|
|
4293
|
-
view2
|
|
4385
|
+
view2.dispatch({
|
|
4294
4386
|
selection: {
|
|
4295
4387
|
anchor: to
|
|
4296
4388
|
}
|
|
4297
4389
|
});
|
|
4298
4390
|
}
|
|
4299
|
-
if (
|
|
4391
|
+
if (state2.facet(editorMode).noTabster) {
|
|
4300
4392
|
rootRef.current?.removeAttribute("data-tabster");
|
|
4301
4393
|
}
|
|
4394
|
+
setView(view2);
|
|
4302
4395
|
return () => {
|
|
4303
4396
|
view2?.destroy();
|
|
4304
4397
|
setView(null);
|
|
@@ -4331,9 +4424,10 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4331
4424
|
});
|
|
4332
4425
|
|
|
4333
4426
|
// 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, Quotes } from "@phosphor-icons/react";
|
|
4427
|
+
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
4335
4428
|
import { createContext } from "@radix-ui/react-context";
|
|
4336
|
-
import React2, { useRef as useRef2, useState as useState3 } from "react";
|
|
4429
|
+
import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
4430
|
+
import { useDropzone } from "react-dropzone";
|
|
4337
4431
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4338
4432
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4339
4433
|
var tooltipProps = {
|
|
@@ -4350,10 +4444,10 @@ var HeadingIcons = {
|
|
|
4350
4444
|
"6": TextHSix
|
|
4351
4445
|
};
|
|
4352
4446
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4353
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
4447
|
+
var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
4354
4448
|
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
4355
4449
|
onAction,
|
|
4356
|
-
state
|
|
4450
|
+
state: state2
|
|
4357
4451
|
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
4358
4452
|
density: "fine"
|
|
4359
4453
|
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
@@ -4367,7 +4461,7 @@ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
|
4367
4461
|
};
|
|
4368
4462
|
var buttonStyles = "min-bs-0 p-2";
|
|
4369
4463
|
var iconStyles = getSize(5);
|
|
4370
|
-
var
|
|
4464
|
+
var ToolbarToggleButton = ({ Icon, children, ...props }) => {
|
|
4371
4465
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4372
4466
|
asChild: true
|
|
4373
4467
|
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
@@ -4380,14 +4474,27 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
|
4380
4474
|
className: "sr-only"
|
|
4381
4475
|
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4382
4476
|
};
|
|
4477
|
+
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4478
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4479
|
+
asChild: true
|
|
4480
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4481
|
+
variant: "ghost",
|
|
4482
|
+
...props,
|
|
4483
|
+
classNames: buttonStyles
|
|
4484
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
4485
|
+
className: iconStyles
|
|
4486
|
+
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4487
|
+
className: "sr-only"
|
|
4488
|
+
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4489
|
+
};
|
|
4383
4490
|
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4384
4491
|
role: "separator",
|
|
4385
4492
|
className: "grow"
|
|
4386
4493
|
});
|
|
4387
4494
|
var MarkdownHeading = () => {
|
|
4388
4495
|
const { t } = useTranslation(translationKey);
|
|
4389
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
4390
|
-
const blockType =
|
|
4496
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
|
|
4497
|
+
const blockType = state2 ? state2.blockType : "paragraph";
|
|
4391
4498
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4392
4499
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4393
4500
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
@@ -4461,43 +4568,43 @@ var markdownStyles = [
|
|
|
4461
4568
|
{
|
|
4462
4569
|
type: "strong",
|
|
4463
4570
|
Icon: TextB,
|
|
4464
|
-
getState: (
|
|
4571
|
+
getState: (state2) => state2.strong
|
|
4465
4572
|
},
|
|
4466
4573
|
{
|
|
4467
4574
|
type: "emphasis",
|
|
4468
4575
|
Icon: TextItalic,
|
|
4469
|
-
getState: (
|
|
4576
|
+
getState: (state2) => state2.emphasis
|
|
4470
4577
|
},
|
|
4471
4578
|
{
|
|
4472
4579
|
type: "strikethrough",
|
|
4473
4580
|
Icon: TextStrikethrough,
|
|
4474
|
-
getState: (
|
|
4581
|
+
getState: (state2) => state2.strikethrough
|
|
4475
4582
|
},
|
|
4476
4583
|
{
|
|
4477
4584
|
type: "code",
|
|
4478
4585
|
Icon: Code,
|
|
4479
|
-
getState: (
|
|
4586
|
+
getState: (state2) => state2.code
|
|
4480
4587
|
},
|
|
4481
4588
|
{
|
|
4482
4589
|
type: "link",
|
|
4483
4590
|
Icon: Link,
|
|
4484
|
-
getState: (
|
|
4591
|
+
getState: (state2) => state2.link
|
|
4485
4592
|
}
|
|
4486
4593
|
];
|
|
4487
4594
|
var MarkdownStyles = () => {
|
|
4488
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4595
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4489
4596
|
const { t } = useTranslation(translationKey);
|
|
4490
4597
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4491
4598
|
type: "multiple",
|
|
4492
|
-
value: markdownStyles.filter(({ getState }) =>
|
|
4493
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4599
|
+
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
4600
|
+
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4494
4601
|
key: type,
|
|
4495
4602
|
value: type,
|
|
4496
4603
|
Icon,
|
|
4497
|
-
disabled:
|
|
4498
|
-
onClick:
|
|
4604
|
+
disabled: state2?.blockType === "codeblock",
|
|
4605
|
+
onClick: state2 ? () => onAction?.({
|
|
4499
4606
|
type,
|
|
4500
|
-
data: !getState(
|
|
4607
|
+
data: !getState(state2)
|
|
4501
4608
|
}) : void 0
|
|
4502
4609
|
}, t(`${type} label`))));
|
|
4503
4610
|
};
|
|
@@ -4505,32 +4612,32 @@ var markdownLists = [
|
|
|
4505
4612
|
{
|
|
4506
4613
|
type: "list-bullet",
|
|
4507
4614
|
Icon: ListBullets,
|
|
4508
|
-
getState: (
|
|
4615
|
+
getState: (state2) => state2.listStyle === "bullet"
|
|
4509
4616
|
},
|
|
4510
4617
|
{
|
|
4511
4618
|
type: "list-ordered",
|
|
4512
4619
|
Icon: ListNumbers,
|
|
4513
|
-
getState: (
|
|
4620
|
+
getState: (state2) => state2.listStyle === "ordered"
|
|
4514
4621
|
},
|
|
4515
4622
|
{
|
|
4516
4623
|
type: "list-task",
|
|
4517
4624
|
Icon: ListChecks,
|
|
4518
|
-
getState: (
|
|
4625
|
+
getState: (state2) => state2.listStyle === "task"
|
|
4519
4626
|
}
|
|
4520
4627
|
];
|
|
4521
4628
|
var MarkdownLists = () => {
|
|
4522
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4629
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4523
4630
|
const { t } = useTranslation(translationKey);
|
|
4524
4631
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4525
4632
|
type: "single",
|
|
4526
|
-
value:
|
|
4527
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4633
|
+
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
4634
|
+
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4528
4635
|
key: type,
|
|
4529
4636
|
value: type,
|
|
4530
4637
|
Icon,
|
|
4531
|
-
onClick:
|
|
4638
|
+
onClick: state2 ? () => onAction?.({
|
|
4532
4639
|
type,
|
|
4533
|
-
data: !getState(
|
|
4640
|
+
data: !getState(state2)
|
|
4534
4641
|
}) : void 0
|
|
4535
4642
|
}, t(`${type} label`))));
|
|
4536
4643
|
};
|
|
@@ -4538,63 +4645,100 @@ var markdownBlocks = [
|
|
|
4538
4645
|
{
|
|
4539
4646
|
type: "blockquote",
|
|
4540
4647
|
Icon: Quotes,
|
|
4541
|
-
getState: (
|
|
4648
|
+
getState: (state2) => state2.blockQuote
|
|
4542
4649
|
},
|
|
4543
4650
|
{
|
|
4544
4651
|
type: "codeblock",
|
|
4545
4652
|
Icon: CodeBlock,
|
|
4546
|
-
getState: (
|
|
4653
|
+
getState: (state2) => state2.blockType === "codeblock"
|
|
4547
4654
|
},
|
|
4548
4655
|
{
|
|
4549
4656
|
type: "table",
|
|
4550
4657
|
Icon: Table2,
|
|
4551
|
-
getState: (
|
|
4552
|
-
disabled: (
|
|
4658
|
+
getState: (state2) => state2.blockType === "tablecell",
|
|
4659
|
+
disabled: (state2) => !state2.blankLine
|
|
4553
4660
|
}
|
|
4554
4661
|
];
|
|
4555
4662
|
var MarkdownBlocks = () => {
|
|
4556
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4663
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4557
4664
|
const { t } = useTranslation(translationKey);
|
|
4558
|
-
const value = markdownBlocks.find(({ getState }) =>
|
|
4665
|
+
const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
|
|
4559
4666
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4560
4667
|
type: "single",
|
|
4561
4668
|
value: value?.type ?? ""
|
|
4562
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4669
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4563
4670
|
key: type,
|
|
4564
4671
|
value: type,
|
|
4565
4672
|
Icon,
|
|
4566
|
-
disabled: !
|
|
4567
|
-
onClick:
|
|
4673
|
+
disabled: !state2 || disabled?.(state2),
|
|
4674
|
+
onClick: state2 ? () => onAction?.({
|
|
4568
4675
|
type,
|
|
4569
|
-
data: !getState(
|
|
4676
|
+
data: !getState(state2)
|
|
4570
4677
|
}) : void 0
|
|
4571
4678
|
}, t(`${type} label`))));
|
|
4572
4679
|
};
|
|
4573
4680
|
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
|
|
4681
|
+
var MarkdownCustom = ({ onUpload } = {}) => {
|
|
4575
4682
|
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4576
4683
|
const { t } = useTranslation(translationKey);
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4684
|
+
const { acceptedFiles, getInputProps, open } = useDropzone({
|
|
4685
|
+
multiple: false,
|
|
4686
|
+
noDrag: true,
|
|
4687
|
+
accept: {
|
|
4688
|
+
"image/*": [
|
|
4689
|
+
".jpg",
|
|
4690
|
+
".jpeg",
|
|
4691
|
+
".png",
|
|
4692
|
+
".gif"
|
|
4693
|
+
]
|
|
4694
|
+
}
|
|
4695
|
+
});
|
|
4696
|
+
useEffect3(() => {
|
|
4697
|
+
if (onUpload && acceptedFiles.length) {
|
|
4698
|
+
setTimeout(async () => {
|
|
4699
|
+
const f = acceptedFiles[0];
|
|
4700
|
+
const file = new File([
|
|
4701
|
+
f
|
|
4702
|
+
], f.name, {
|
|
4703
|
+
type: f.type,
|
|
4704
|
+
lastModified: f.lastModified
|
|
4705
|
+
});
|
|
4706
|
+
const { url } = await onUpload(file);
|
|
4707
|
+
if (url) {
|
|
4708
|
+
onAction?.({
|
|
4709
|
+
type: "image",
|
|
4710
|
+
data: url
|
|
4711
|
+
});
|
|
4712
|
+
}
|
|
4713
|
+
});
|
|
4714
|
+
}
|
|
4715
|
+
}, [
|
|
4716
|
+
acceptedFiles
|
|
4717
|
+
]);
|
|
4718
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("input", getInputProps()), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4719
|
+
value: "image",
|
|
4720
|
+
Icon: Image,
|
|
4721
|
+
onClick: () => open()
|
|
4722
|
+
}, t("image label")));
|
|
4723
|
+
};
|
|
4724
|
+
var MarkdownActions = () => {
|
|
4725
|
+
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4726
|
+
const { t } = useTranslation(translationKey);
|
|
4727
|
+
return /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4728
|
+
value: "comment",
|
|
4729
|
+
Icon: ChatText,
|
|
4582
4730
|
onClick: () => onAction?.({
|
|
4583
4731
|
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))));
|
|
4732
|
+
})
|
|
4733
|
+
}, t("comment label"));
|
|
4591
4734
|
};
|
|
4592
4735
|
var Toolbar = {
|
|
4593
4736
|
Root: ToolbarRoot,
|
|
4594
|
-
Button:
|
|
4737
|
+
Button: ToolbarToggleButton,
|
|
4595
4738
|
Separator: ToolbarSeparator,
|
|
4596
4739
|
Markdown: MarkdownStandard,
|
|
4597
|
-
|
|
4740
|
+
Custom: MarkdownCustom,
|
|
4741
|
+
Actions: MarkdownActions
|
|
4598
4742
|
};
|
|
4599
4743
|
|
|
4600
4744
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
@@ -4631,7 +4775,13 @@ var useActionHandler = (view) => {
|
|
|
4631
4775
|
insertTable(view);
|
|
4632
4776
|
break;
|
|
4633
4777
|
case "link":
|
|
4634
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4778
|
+
(action.data === false ? removeLink : addLink())(view);
|
|
4779
|
+
break;
|
|
4780
|
+
case "image":
|
|
4781
|
+
addLink({
|
|
4782
|
+
url: action.data,
|
|
4783
|
+
image: true
|
|
4784
|
+
})(view);
|
|
4635
4785
|
break;
|
|
4636
4786
|
case "comment":
|
|
4637
4787
|
createComment(view);
|
|
@@ -4660,43 +4810,43 @@ var useDocAccessor = (text) => {
|
|
|
4660
4810
|
|
|
4661
4811
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4662
4812
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4663
|
-
import { EditorView as
|
|
4664
|
-
import { useEffect as
|
|
4813
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
4814
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4665
4815
|
import { log as log10 } from "@dxos/log";
|
|
4666
|
-
import { isNotFalsy as
|
|
4667
|
-
var
|
|
4816
|
+
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4817
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4668
4818
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4669
4819
|
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4670
4820
|
const onUpdate = useRef3();
|
|
4671
4821
|
const [view, setView] = useState4();
|
|
4672
4822
|
const parentRef = useRef3(null);
|
|
4673
|
-
|
|
4823
|
+
useEffect4(() => {
|
|
4674
4824
|
let view2;
|
|
4675
4825
|
if (parentRef.current) {
|
|
4676
|
-
const
|
|
4826
|
+
const state2 = EditorState3.create({
|
|
4677
4827
|
doc,
|
|
4678
4828
|
selection,
|
|
4679
4829
|
extensions: [
|
|
4680
4830
|
id && documentId2.of(id),
|
|
4681
4831
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4682
|
-
|
|
4832
|
+
EditorView18.exceptionSink.of((err) => {
|
|
4683
4833
|
log10.catch(err, void 0, {
|
|
4684
|
-
F:
|
|
4834
|
+
F: __dxlog_file13,
|
|
4685
4835
|
L: 44,
|
|
4686
4836
|
S: void 0,
|
|
4687
4837
|
C: (f, a) => f(...a)
|
|
4688
4838
|
});
|
|
4689
4839
|
}),
|
|
4690
4840
|
extensions,
|
|
4691
|
-
|
|
4841
|
+
EditorView18.updateListener.of(() => {
|
|
4692
4842
|
onUpdate.current?.();
|
|
4693
4843
|
})
|
|
4694
|
-
].filter(
|
|
4844
|
+
].filter(isNotFalsy5)
|
|
4695
4845
|
});
|
|
4696
|
-
view2 = new
|
|
4846
|
+
view2 = new EditorView18({
|
|
4697
4847
|
parent: parentRef.current,
|
|
4698
4848
|
scrollTo,
|
|
4699
|
-
state,
|
|
4849
|
+
state: state2,
|
|
4700
4850
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4701
4851
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4702
4852
|
dispatchTransactions: (trs, view3) => {
|
|
@@ -4712,7 +4862,7 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
4712
4862
|
view2?.destroy();
|
|
4713
4863
|
};
|
|
4714
4864
|
}, deps);
|
|
4715
|
-
|
|
4865
|
+
useEffect4(() => {
|
|
4716
4866
|
if (view) {
|
|
4717
4867
|
if (!selection && !view.state.selection.main.anchor) {
|
|
4718
4868
|
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
@@ -4788,14 +4938,17 @@ export {
|
|
|
4788
4938
|
editorMode,
|
|
4789
4939
|
editorWithToolbarLayout,
|
|
4790
4940
|
focusComment,
|
|
4941
|
+
focusEvent,
|
|
4791
4942
|
formattingKeymap,
|
|
4792
4943
|
getFormatting,
|
|
4793
4944
|
getToken,
|
|
4794
4945
|
image,
|
|
4946
|
+
imageUpload,
|
|
4795
4947
|
insertTable,
|
|
4796
|
-
|
|
4948
|
+
keymap10 as keymap,
|
|
4797
4949
|
linkTooltip,
|
|
4798
4950
|
listener,
|
|
4951
|
+
localStorageStateStoreAdapter,
|
|
4799
4952
|
logChanges,
|
|
4800
4953
|
markdownHighlightStyle,
|
|
4801
4954
|
markdownTags,
|
|
@@ -4811,6 +4964,7 @@ export {
|
|
|
4811
4964
|
setHeading,
|
|
4812
4965
|
setSelection,
|
|
4813
4966
|
setStyle,
|
|
4967
|
+
state,
|
|
4814
4968
|
table,
|
|
4815
4969
|
tags2 as tags,
|
|
4816
4970
|
toggleBlockquote,
|