@dxos/react-ui-editor 0.4.8-main.97e86fe → 0.4.8-main.a32da92
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 +321 -228
- 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 +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.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/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/package.json +24 -27
- package/src/components/TextEditor/TextEditor.stories.tsx +16 -4
- package/src/components/TextEditor/TextEditor.tsx +11 -10
- package/src/components/Toolbar/Toolbar.stories.tsx +1 -1
- package/src/extensions/index.ts +1 -0
- package/src/extensions/modes.ts +3 -1
- package/src/extensions/state.ts +90 -0
- package/src/hooks/useTextEditor.stories.tsx +3 -3
|
@@ -23,18 +23,18 @@ var translations_default = [
|
|
|
23
23
|
];
|
|
24
24
|
|
|
25
25
|
// packages/ui/react-ui-editor/src/index.ts
|
|
26
|
-
import { keymap as
|
|
26
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
|
27
27
|
import { tags as tags2 } from "@lezer/highlight";
|
|
28
28
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
29
29
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
30
30
|
|
|
31
31
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
32
32
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
33
|
-
import { EditorView as
|
|
33
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
34
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
35
35
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
36
36
|
import { log as log9 } from "@dxos/log";
|
|
37
|
-
import { isNotFalsy as
|
|
37
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
38
38
|
|
|
39
39
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
40
40
|
import { StateField } from "@codemirror/state";
|
|
@@ -56,8 +56,8 @@ var Cursor = class _Cursor {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
static {
|
|
59
|
-
this.getCursorFromRange = (
|
|
60
|
-
const cursorConverter2 =
|
|
59
|
+
this.getCursorFromRange = (state2, range) => {
|
|
60
|
+
const cursorConverter2 = state2.facet(_Cursor.converter);
|
|
61
61
|
const from = cursorConverter2.toCursor(range.from);
|
|
62
62
|
const to = cursorConverter2.toCursor(range.to, -1);
|
|
63
63
|
return [
|
|
@@ -67,8 +67,8 @@ var Cursor = class _Cursor {
|
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
static {
|
|
70
|
-
this.getRangeFromCursor = (
|
|
71
|
-
const cursorConverter2 =
|
|
70
|
+
this.getRangeFromCursor = (state2, cursor) => {
|
|
71
|
+
const cursorConverter2 = state2.facet(_Cursor.converter);
|
|
72
72
|
const parts = cursor.split(":");
|
|
73
73
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
74
74
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
@@ -85,15 +85,15 @@ var annotationMark = Decoration.mark({
|
|
|
85
85
|
class: "cm-annotation"
|
|
86
86
|
});
|
|
87
87
|
var annotations = (options = {}) => {
|
|
88
|
-
const match = (
|
|
88
|
+
const match = (state2) => {
|
|
89
89
|
const annotations2 = [];
|
|
90
|
-
const text =
|
|
90
|
+
const text = state2.doc.toString();
|
|
91
91
|
if (options.match) {
|
|
92
92
|
const matches = text.matchAll(options.match);
|
|
93
93
|
for (const match2 of matches) {
|
|
94
94
|
const from = match2.index;
|
|
95
95
|
const to = from + match2[0].length;
|
|
96
|
-
const cursor = Cursor.getCursorFromRange(
|
|
96
|
+
const cursor = Cursor.getCursorFromRange(state2, {
|
|
97
97
|
from,
|
|
98
98
|
to
|
|
99
99
|
});
|
|
@@ -105,8 +105,8 @@ var annotations = (options = {}) => {
|
|
|
105
105
|
return annotations2;
|
|
106
106
|
};
|
|
107
107
|
const annotationsState = StateField.define({
|
|
108
|
-
create: (
|
|
109
|
-
return match(
|
|
108
|
+
create: (state2) => {
|
|
109
|
+
return match(state2);
|
|
110
110
|
},
|
|
111
111
|
update: (value, tr) => {
|
|
112
112
|
if (!tr.changes.empty) {
|
|
@@ -119,10 +119,10 @@ var annotations = (options = {}) => {
|
|
|
119
119
|
annotationsState,
|
|
120
120
|
EditorView.decorations.compute([
|
|
121
121
|
annotationsState
|
|
122
|
-
], (
|
|
123
|
-
const annotations2 =
|
|
122
|
+
], (state2) => {
|
|
123
|
+
const annotations2 = state2.field(annotationsState);
|
|
124
124
|
const decorations = annotations2.map((annotation2) => {
|
|
125
|
-
const range = Cursor.getRangeFromCursor(
|
|
125
|
+
const range = Cursor.getRangeFromCursor(state2, annotation2.cursor);
|
|
126
126
|
return range && annotationMark.range(range.from, range.to);
|
|
127
127
|
}).filter(isNotFalsy);
|
|
128
128
|
return Decoration.set(decorations);
|
|
@@ -239,8 +239,8 @@ var cursorConverter = ({ handle, path }) => ({
|
|
|
239
239
|
|
|
240
240
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
241
241
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
242
|
-
var getPath = (
|
|
243
|
-
var getLastHeads = (
|
|
242
|
+
var getPath = (state2, field) => state2.field(field).path;
|
|
243
|
+
var getLastHeads = (state2, field) => state2.field(field).lastHeads;
|
|
244
244
|
var updateHeadsEffect = StateEffect.define({});
|
|
245
245
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
246
246
|
newHeads
|
|
@@ -255,8 +255,8 @@ import { next as A3 } from "@dxos/automerge/automerge";
|
|
|
255
255
|
|
|
256
256
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
|
257
257
|
import { next as A2 } from "@dxos/automerge/automerge";
|
|
258
|
-
var updateAutomerge = (field, handle, transactions,
|
|
259
|
-
const { lastHeads, path } =
|
|
258
|
+
var updateAutomerge = (field, handle, transactions, state2) => {
|
|
259
|
+
const { lastHeads, path } = state2.field(field);
|
|
260
260
|
let hasChanges = false;
|
|
261
261
|
for (const tr of transactions) {
|
|
262
262
|
tr.changes.iterChanges(() => {
|
|
@@ -303,7 +303,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
|
|
|
303
303
|
annotations: reconcileAnnotation.of(false)
|
|
304
304
|
});
|
|
305
305
|
};
|
|
306
|
-
var handlePatch = (patch, target,
|
|
306
|
+
var handlePatch = (patch, target, state2) => {
|
|
307
307
|
if (patch.action === "insert") {
|
|
308
308
|
return handleInsert(target, patch);
|
|
309
309
|
} else if (patch.action === "splice") {
|
|
@@ -311,7 +311,7 @@ var handlePatch = (patch, target, state) => {
|
|
|
311
311
|
} else if (patch.action === "del") {
|
|
312
312
|
return handleDel(target, patch);
|
|
313
313
|
} else if (patch.action === "put") {
|
|
314
|
-
return handlePut(target, patch,
|
|
314
|
+
return handlePut(target, patch, state2);
|
|
315
315
|
} else {
|
|
316
316
|
return null;
|
|
317
317
|
}
|
|
@@ -355,7 +355,7 @@ var handleDel = (target, patch) => {
|
|
|
355
355
|
}
|
|
356
356
|
];
|
|
357
357
|
};
|
|
358
|
-
var handlePut = (target, patch,
|
|
358
|
+
var handlePut = (target, patch, state2) => {
|
|
359
359
|
const index = charPath(target, [
|
|
360
360
|
...patch.path,
|
|
361
361
|
0
|
|
@@ -363,7 +363,7 @@ var handlePut = (target, patch, state) => {
|
|
|
363
363
|
if (index == null) {
|
|
364
364
|
return [];
|
|
365
365
|
}
|
|
366
|
-
const length =
|
|
366
|
+
const length = state2.doc.length;
|
|
367
367
|
if (typeof patch.value !== "string") {
|
|
368
368
|
return [];
|
|
369
369
|
}
|
|
@@ -561,9 +561,9 @@ var RemoteSelectionsDecorator = class {
|
|
|
561
561
|
_updateRemoteSelections(update2) {
|
|
562
562
|
const decorations = [];
|
|
563
563
|
const awarenessStates = this._provider.getRemoteStates();
|
|
564
|
-
for (const
|
|
565
|
-
const anchor =
|
|
566
|
-
const head =
|
|
564
|
+
for (const state2 of awarenessStates) {
|
|
565
|
+
const anchor = state2.position?.anchor ? this._cursorConverter.fromCursor(state2.position.anchor) : null;
|
|
566
|
+
const head = state2.position?.head ? this._cursorConverter.fromCursor(state2.position.head) : null;
|
|
567
567
|
if (anchor == null || head == null) {
|
|
568
568
|
continue;
|
|
569
569
|
}
|
|
@@ -571,8 +571,8 @@ var RemoteSelectionsDecorator = class {
|
|
|
571
571
|
const end = Math.min(Math.max(anchor, head), update2.view.state.doc.length);
|
|
572
572
|
const startLine = update2.view.state.doc.lineAt(start);
|
|
573
573
|
const endLine = update2.view.state.doc.lineAt(end);
|
|
574
|
-
const color =
|
|
575
|
-
const lightColor =
|
|
574
|
+
const color = state2.info.color ?? "#30bced";
|
|
575
|
+
const lightColor = state2.info.lightColor ?? color + "33";
|
|
576
576
|
if (startLine.number === endLine.number) {
|
|
577
577
|
decorations.push({
|
|
578
578
|
from: start,
|
|
@@ -625,7 +625,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
625
625
|
value: Decoration2.widget({
|
|
626
626
|
side: head - anchor > 0 ? -1 : 1,
|
|
627
627
|
block: false,
|
|
628
|
-
widget: new RemoteCaretWidget(
|
|
628
|
+
widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", color)
|
|
629
629
|
})
|
|
630
630
|
});
|
|
631
631
|
}
|
|
@@ -1156,7 +1156,7 @@ var commandConfig = Facet3.define({
|
|
|
1156
1156
|
});
|
|
1157
1157
|
var commandState = StateField3.define({
|
|
1158
1158
|
create: () => ({}),
|
|
1159
|
-
update: (
|
|
1159
|
+
update: (state2, tr) => {
|
|
1160
1160
|
for (const effect of tr.effects) {
|
|
1161
1161
|
if (effect.is(closeEffect)) {
|
|
1162
1162
|
return {};
|
|
@@ -1207,7 +1207,7 @@ var commandState = StateField3.define({
|
|
|
1207
1207
|
};
|
|
1208
1208
|
}
|
|
1209
1209
|
}
|
|
1210
|
-
return
|
|
1210
|
+
return state2;
|
|
1211
1211
|
},
|
|
1212
1212
|
provide: (field) => [
|
|
1213
1213
|
showTooltip.from(field, (value) => value.tooltip ?? null)
|
|
@@ -1453,8 +1453,8 @@ var setComments = StateEffect3.define();
|
|
|
1453
1453
|
var setSelection = StateEffect3.define();
|
|
1454
1454
|
var setCommentState = StateEffect3.define();
|
|
1455
1455
|
var commentsState = StateField4.define({
|
|
1456
|
-
create: (
|
|
1457
|
-
id:
|
|
1456
|
+
create: (state2) => ({
|
|
1457
|
+
id: state2.facet(documentId),
|
|
1458
1458
|
comments: [],
|
|
1459
1459
|
selection: {}
|
|
1460
1460
|
}),
|
|
@@ -1526,8 +1526,8 @@ var commentCurrentMark = Decoration4.mark({
|
|
|
1526
1526
|
});
|
|
1527
1527
|
var commentsDecorations = EditorView7.decorations.compute([
|
|
1528
1528
|
commentsState
|
|
1529
|
-
], (
|
|
1530
|
-
const { selection: { current }, comments: comments2 } =
|
|
1529
|
+
], (state2) => {
|
|
1530
|
+
const { selection: { current }, comments: comments2 } = state2.field(commentsState);
|
|
1531
1531
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1532
1532
|
const range = comment.range;
|
|
1533
1533
|
if (!range || range.from === range.to) {
|
|
@@ -1691,7 +1691,7 @@ var optionsFacet = Facet4.define({
|
|
|
1691
1691
|
});
|
|
1692
1692
|
var comments = (options = {}) => {
|
|
1693
1693
|
const { key: shortcut = "meta-'" } = options;
|
|
1694
|
-
const handleSelect = debounce((
|
|
1694
|
+
const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
|
|
1695
1695
|
return [
|
|
1696
1696
|
optionsFacet.of(options),
|
|
1697
1697
|
documentId.of(options.id),
|
|
@@ -1740,9 +1740,9 @@ var comments = (options = {}) => {
|
|
|
1740
1740
|
//
|
|
1741
1741
|
// Track deleted ranges and update ranges for decorations.
|
|
1742
1742
|
//
|
|
1743
|
-
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1743
|
+
EditorView7.updateListener.of(({ view, state: state2, changes }) => {
|
|
1744
1744
|
let mod = false;
|
|
1745
|
-
const { comments: comments2, ...value } =
|
|
1745
|
+
const { comments: comments2, ...value } = state2.field(commentsState);
|
|
1746
1746
|
changes.iterChanges((from, to, from2, to2) => {
|
|
1747
1747
|
comments2.forEach(({ comment, range }) => {
|
|
1748
1748
|
if (from2 === to2) {
|
|
@@ -1772,10 +1772,10 @@ var comments = (options = {}) => {
|
|
|
1772
1772
|
//
|
|
1773
1773
|
// Track selection/proximity.
|
|
1774
1774
|
//
|
|
1775
|
-
EditorView7.updateListener.of(({ view, state }) => {
|
|
1775
|
+
EditorView7.updateListener.of(({ view, state: state2 }) => {
|
|
1776
1776
|
let min = Infinity;
|
|
1777
|
-
const { selection: { current, closest }, comments: comments2 } =
|
|
1778
|
-
const { head } =
|
|
1777
|
+
const { selection: { current, closest }, comments: comments2 } = state2.field(commentsState);
|
|
1778
|
+
const { head } = state2.selection.main;
|
|
1779
1779
|
const selection = {};
|
|
1780
1780
|
comments2.forEach(({ comment, range }) => {
|
|
1781
1781
|
if (head >= range.from && head <= range.to) {
|
|
@@ -1796,7 +1796,7 @@ var comments = (options = {}) => {
|
|
|
1796
1796
|
});
|
|
1797
1797
|
handleSelect({
|
|
1798
1798
|
selection,
|
|
1799
|
-
id:
|
|
1799
|
+
id: state2.facet(documentId),
|
|
1800
1800
|
comments: comments2.map(({ comment, range }) => ({
|
|
1801
1801
|
comment,
|
|
1802
1802
|
range,
|
|
@@ -1864,11 +1864,11 @@ var cursorLineMargin = (options = {
|
|
|
1864
1864
|
if (!lines || lines <= 0) {
|
|
1865
1865
|
return [];
|
|
1866
1866
|
}
|
|
1867
|
-
return EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1867
|
+
return EditorView8.updateListener.of(({ transactions, state: state2, selectionSet, startState, view }) => {
|
|
1868
1868
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1869
1869
|
return;
|
|
1870
1870
|
}
|
|
1871
|
-
const s =
|
|
1871
|
+
const s = state2;
|
|
1872
1872
|
const { main } = s.selection;
|
|
1873
1873
|
const rect = view.dom.getBoundingClientRect();
|
|
1874
1874
|
const viewportTop = rect.top - view.documentTop;
|
|
@@ -2606,8 +2606,8 @@ var checkedTask = Decoration5.replace({
|
|
|
2606
2606
|
var uncheckedTask = Decoration5.replace({
|
|
2607
2607
|
widget: new CheckboxWidget(false)
|
|
2608
2608
|
});
|
|
2609
|
-
var editingRange = (
|
|
2610
|
-
const { readOnly, selection: { main: { head } } } =
|
|
2609
|
+
var editingRange = (state2, range, focus) => {
|
|
2610
|
+
const { readOnly, selection: { main: { head } } } = state2;
|
|
2611
2611
|
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
2612
2612
|
};
|
|
2613
2613
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
@@ -2620,14 +2620,14 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
2620
2620
|
var buildDecorations = (view, options, focus) => {
|
|
2621
2621
|
const deco = new RangeSetBuilder2();
|
|
2622
2622
|
const atomicDeco = new RangeSetBuilder2();
|
|
2623
|
-
const { state } = view;
|
|
2623
|
+
const { state: state2 } = view;
|
|
2624
2624
|
for (const { from, to } of view.visibleRanges) {
|
|
2625
|
-
syntaxTree(
|
|
2625
|
+
syntaxTree(state2).iterate({
|
|
2626
2626
|
from,
|
|
2627
2627
|
to,
|
|
2628
2628
|
enter: (node) => {
|
|
2629
2629
|
if (node.name === "FencedCode") {
|
|
2630
|
-
const editing = editingRange(
|
|
2630
|
+
const editing = editingRange(state2, node, focus);
|
|
2631
2631
|
for (const block of view.viewportLineBlocks) {
|
|
2632
2632
|
if (block.to < node.from) {
|
|
2633
2633
|
continue;
|
|
@@ -2636,7 +2636,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2636
2636
|
break;
|
|
2637
2637
|
}
|
|
2638
2638
|
const first = block.from <= node.from;
|
|
2639
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(
|
|
2639
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
2640
2640
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2641
2641
|
if (!editing && (first || last)) {
|
|
2642
2642
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -2646,9 +2646,9 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2646
2646
|
} else if (node.name === "Link") {
|
|
2647
2647
|
const marks = node.node.getChildren("LinkMark");
|
|
2648
2648
|
const urlNode = node.node.getChild("URL");
|
|
2649
|
-
const editing = editingRange(
|
|
2649
|
+
const editing = editingRange(state2, node, focus);
|
|
2650
2650
|
if (urlNode && marks.length >= 2) {
|
|
2651
|
-
const url =
|
|
2651
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
2652
2652
|
if (!editing) {
|
|
2653
2653
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2654
2654
|
}
|
|
@@ -2669,24 +2669,24 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2669
2669
|
}
|
|
2670
2670
|
} else if (node.name === "HeaderMark") {
|
|
2671
2671
|
const parent = node.node.parent;
|
|
2672
|
-
if (/^ATX/.test(parent.name) && !editingRange(
|
|
2673
|
-
const next =
|
|
2672
|
+
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
2673
|
+
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
2674
2674
|
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2675
2675
|
}
|
|
2676
2676
|
} else if (node.name === "HorizontalRule") {
|
|
2677
|
-
if (!editingRange(
|
|
2677
|
+
if (!editingRange(state2, node, focus)) {
|
|
2678
2678
|
deco.add(node.from, node.to, horizontalRule);
|
|
2679
2679
|
}
|
|
2680
2680
|
} else if (node.name === "TaskMarker") {
|
|
2681
|
-
if (!editingRange(
|
|
2682
|
-
const checked =
|
|
2681
|
+
if (!editingRange(state2, node, focus)) {
|
|
2682
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2683
2683
|
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2684
2684
|
class: "cm-task"
|
|
2685
2685
|
}));
|
|
2686
2686
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2687
2687
|
}
|
|
2688
2688
|
} else if (MarksByParent.has(node.name)) {
|
|
2689
|
-
if (!editingRange(
|
|
2689
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
2690
2690
|
atomicDeco.add(node.from, node.to, hide);
|
|
2691
2691
|
}
|
|
2692
2692
|
}
|
|
@@ -2811,13 +2811,13 @@ var List;
|
|
|
2811
2811
|
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2812
2812
|
List2[List2["Task"] = 2] = "Task";
|
|
2813
2813
|
})(List || (List = {}));
|
|
2814
|
-
var setHeading = (level) => ({ state, dispatch }) => {
|
|
2815
|
-
const { selection: { ranges }, doc } =
|
|
2814
|
+
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2815
|
+
const { selection: { ranges }, doc } = state2;
|
|
2816
2816
|
const changes = [];
|
|
2817
2817
|
let prevBlock = -1;
|
|
2818
2818
|
for (const range of ranges) {
|
|
2819
2819
|
let sawBlock = false;
|
|
2820
|
-
syntaxTree2(
|
|
2820
|
+
syntaxTree2(state2).iterate({
|
|
2821
2821
|
from: range.from,
|
|
2822
2822
|
to: range.to,
|
|
2823
2823
|
enter: (node) => {
|
|
@@ -2870,7 +2870,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2870
2870
|
}
|
|
2871
2871
|
});
|
|
2872
2872
|
let line;
|
|
2873
|
-
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line =
|
|
2873
|
+
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2874
2874
|
changes.push({
|
|
2875
2875
|
from: line.from,
|
|
2876
2876
|
to: line.to,
|
|
@@ -2881,23 +2881,23 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2881
2881
|
if (!changes.length) {
|
|
2882
2882
|
return false;
|
|
2883
2883
|
}
|
|
2884
|
-
const changeSet =
|
|
2885
|
-
dispatch(
|
|
2884
|
+
const changeSet = state2.changes(changes);
|
|
2885
|
+
dispatch(state2.update({
|
|
2886
2886
|
changes: changeSet,
|
|
2887
|
-
selection:
|
|
2887
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2888
2888
|
userEvent: "format.setHeading",
|
|
2889
2889
|
scrollIntoView: true
|
|
2890
2890
|
}));
|
|
2891
2891
|
return true;
|
|
2892
2892
|
};
|
|
2893
|
-
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
2893
|
+
var setStyle = (type, enable) => ({ state: state2, dispatch }) => {
|
|
2894
2894
|
const marker = inlineMarkerText(type);
|
|
2895
|
-
const changes =
|
|
2895
|
+
const changes = state2.changeByRange((range) => {
|
|
2896
2896
|
if (!enable && range.empty) {
|
|
2897
|
-
const after =
|
|
2897
|
+
const after = state2.doc.sliceString(range.head, range.head + 6);
|
|
2898
2898
|
const found = after.indexOf(marker);
|
|
2899
2899
|
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
2900
|
-
const before =
|
|
2900
|
+
const before = state2.doc.sliceString(range.head - 6, range.head);
|
|
2901
2901
|
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
2902
2902
|
...before.slice(before.length - found)
|
|
2903
2903
|
].reverse().join("") === after.slice(0, found)) {
|
|
@@ -2924,14 +2924,14 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2924
2924
|
let startCovered = false;
|
|
2925
2925
|
let endCovered = false;
|
|
2926
2926
|
let { from, to } = range;
|
|
2927
|
-
syntaxTree2(
|
|
2927
|
+
syntaxTree2(state2).iterate({
|
|
2928
2928
|
from,
|
|
2929
2929
|
to,
|
|
2930
2930
|
enter: (node) => {
|
|
2931
2931
|
const { name } = node;
|
|
2932
2932
|
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
2933
2933
|
blockStart = blockContentStart(node);
|
|
2934
|
-
blockEnd = blockContentEnd(node,
|
|
2934
|
+
blockEnd = blockContentEnd(node, state2.doc);
|
|
2935
2935
|
startCovered = endCovered = false;
|
|
2936
2936
|
} else if (name === "Link" || name === "Image" && enable) {
|
|
2937
2937
|
if (from < node.from && to > node.from && to <= node.to) {
|
|
@@ -2976,7 +2976,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2976
2976
|
});
|
|
2977
2977
|
if (markType !== type && closeStart >= to) {
|
|
2978
2978
|
changesAtEnd.push({
|
|
2979
|
-
from: skipSpaces(Math.min(to, blockEnd),
|
|
2979
|
+
from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
|
|
2980
2980
|
insert: inlineMarkerText(markType)
|
|
2981
2981
|
});
|
|
2982
2982
|
}
|
|
@@ -2988,7 +2988,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2988
2988
|
});
|
|
2989
2989
|
if (markType !== type && openEnd <= from) {
|
|
2990
2990
|
changes2.push({
|
|
2991
|
-
from: skipSpaces(Math.max(from, blockStart),
|
|
2991
|
+
from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
|
|
2992
2992
|
insert: inlineMarkerText(markType)
|
|
2993
2993
|
});
|
|
2994
2994
|
}
|
|
@@ -3018,7 +3018,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3018
3018
|
changes2.push(startCovered);
|
|
3019
3019
|
} else if (startCovered) {
|
|
3020
3020
|
changes2.push({
|
|
3021
|
-
from: skipSpaces(rangeStart,
|
|
3021
|
+
from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
|
|
3022
3022
|
insert: marker
|
|
3023
3023
|
});
|
|
3024
3024
|
}
|
|
@@ -3026,7 +3026,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3026
3026
|
changes2.push(endCovered);
|
|
3027
3027
|
} else if (endCovered) {
|
|
3028
3028
|
changes2.push({
|
|
3029
|
-
from: skipSpaces(rangeEnd,
|
|
3029
|
+
from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
|
|
3030
3030
|
insert: marker
|
|
3031
3031
|
});
|
|
3032
3032
|
}
|
|
@@ -3034,7 +3034,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3034
3034
|
}
|
|
3035
3035
|
}
|
|
3036
3036
|
});
|
|
3037
|
-
if (blockStart < 0 && range.empty && enable && !/\S/.test(
|
|
3037
|
+
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
3038
3038
|
return {
|
|
3039
3039
|
changes: {
|
|
3040
3040
|
from: range.head,
|
|
@@ -3043,13 +3043,13 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3043
3043
|
range: EditorSelection.cursor(range.head + marker.length)
|
|
3044
3044
|
};
|
|
3045
3045
|
}
|
|
3046
|
-
const changeSet =
|
|
3046
|
+
const changeSet = state2.changes(changes2.concat(changesAtEnd));
|
|
3047
3047
|
return {
|
|
3048
3048
|
changes: changeSet,
|
|
3049
3049
|
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
3050
3050
|
};
|
|
3051
3051
|
});
|
|
3052
|
-
dispatch(
|
|
3052
|
+
dispatch(state2.update(changes, {
|
|
3053
3053
|
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
3054
3054
|
scrollIntoView: true
|
|
3055
3055
|
}));
|
|
@@ -3123,8 +3123,8 @@ var insertTable = (view) => {
|
|
|
3123
3123
|
const { from } = doc.line(number);
|
|
3124
3124
|
snippets.table(view, null, from, from);
|
|
3125
3125
|
};
|
|
3126
|
-
var removeLinkInner = (from, to, changes,
|
|
3127
|
-
syntaxTree2(
|
|
3126
|
+
var removeLinkInner = (from, to, changes, state2) => {
|
|
3127
|
+
syntaxTree2(state2).iterate({
|
|
3128
3128
|
from,
|
|
3129
3129
|
to,
|
|
3130
3130
|
enter: (node) => {
|
|
@@ -3138,8 +3138,8 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3138
3138
|
});
|
|
3139
3139
|
} else if (name === "LinkTitle" || name === "URL") {
|
|
3140
3140
|
changes.push({
|
|
3141
|
-
from: skipSpaces(node2.from,
|
|
3142
|
-
to: skipSpaces(node2.to,
|
|
3141
|
+
from: skipSpaces(node2.from, state2.doc, -1),
|
|
3142
|
+
to: skipSpaces(node2.to, state2.doc, 1)
|
|
3143
3143
|
});
|
|
3144
3144
|
}
|
|
3145
3145
|
});
|
|
@@ -3148,32 +3148,32 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3148
3148
|
}
|
|
3149
3149
|
});
|
|
3150
3150
|
};
|
|
3151
|
-
var removeLink = ({ state, dispatch }) => {
|
|
3151
|
+
var removeLink = ({ state: state2, dispatch }) => {
|
|
3152
3152
|
const changes = [];
|
|
3153
|
-
for (const { from, to } of
|
|
3154
|
-
removeLinkInner(from, to, changes,
|
|
3153
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3154
|
+
removeLinkInner(from, to, changes, state2);
|
|
3155
3155
|
}
|
|
3156
3156
|
if (!changes) {
|
|
3157
3157
|
return false;
|
|
3158
3158
|
}
|
|
3159
|
-
dispatch(
|
|
3159
|
+
dispatch(state2.update({
|
|
3160
3160
|
changes,
|
|
3161
3161
|
userEvent: "format.link.remove",
|
|
3162
3162
|
scrollIntoView: true
|
|
3163
3163
|
}));
|
|
3164
3164
|
return true;
|
|
3165
3165
|
};
|
|
3166
|
-
var addLink = ({ state, dispatch }) => {
|
|
3167
|
-
const changes =
|
|
3166
|
+
var addLink = ({ state: state2, dispatch }) => {
|
|
3167
|
+
const changes = state2.changeByRange((range) => {
|
|
3168
3168
|
let { from, to } = range;
|
|
3169
3169
|
const cutStyles = [];
|
|
3170
3170
|
let okay = null;
|
|
3171
|
-
syntaxTree2(
|
|
3171
|
+
syntaxTree2(state2).iterate({
|
|
3172
3172
|
from,
|
|
3173
3173
|
to,
|
|
3174
3174
|
enter: (node) => {
|
|
3175
3175
|
if (Object.hasOwn(Textblocks, node.name)) {
|
|
3176
|
-
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node,
|
|
3176
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
|
|
3177
3177
|
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
3178
3178
|
const sNode = node.node;
|
|
3179
3179
|
if (node.from < from && node.to <= to) {
|
|
@@ -3193,7 +3193,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3193
3193
|
}
|
|
3194
3194
|
});
|
|
3195
3195
|
if (okay === null) {
|
|
3196
|
-
const line =
|
|
3196
|
+
const line = state2.doc.lineAt(from);
|
|
3197
3197
|
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
3198
3198
|
}
|
|
3199
3199
|
if (!okay) {
|
|
@@ -3203,26 +3203,26 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3203
3203
|
}
|
|
3204
3204
|
const changes2 = [];
|
|
3205
3205
|
const changesAfter = [];
|
|
3206
|
-
removeLinkInner(from, to, changesAfter,
|
|
3206
|
+
removeLinkInner(from, to, changesAfter, state2);
|
|
3207
3207
|
let cursorOffset = 1;
|
|
3208
3208
|
for (const style of cutStyles) {
|
|
3209
3209
|
const type = InlineMarker[style.name];
|
|
3210
3210
|
const mark2 = inlineMarkerText(type);
|
|
3211
3211
|
if (style.from < from) {
|
|
3212
3212
|
changes2.push({
|
|
3213
|
-
from: skipSpaces(from,
|
|
3213
|
+
from: skipSpaces(from, state2.doc, -1),
|
|
3214
3214
|
insert: mark2
|
|
3215
3215
|
});
|
|
3216
3216
|
changesAfter.push({
|
|
3217
|
-
from: skipSpaces(from,
|
|
3217
|
+
from: skipSpaces(from, state2.doc, 1, to),
|
|
3218
3218
|
insert: mark2
|
|
3219
3219
|
});
|
|
3220
3220
|
} else {
|
|
3221
3221
|
changes2.push({
|
|
3222
|
-
from: skipSpaces(to,
|
|
3222
|
+
from: skipSpaces(to, state2.doc, -1, from),
|
|
3223
3223
|
insert: mark2
|
|
3224
3224
|
});
|
|
3225
|
-
const after = skipSpaces(to,
|
|
3225
|
+
const after = skipSpaces(to, state2.doc, 1);
|
|
3226
3226
|
if (after === to) {
|
|
3227
3227
|
cursorOffset += mark2.length;
|
|
3228
3228
|
}
|
|
@@ -3239,7 +3239,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3239
3239
|
from: to,
|
|
3240
3240
|
insert: "]()"
|
|
3241
3241
|
});
|
|
3242
|
-
const changeSet =
|
|
3242
|
+
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
3243
3243
|
return {
|
|
3244
3244
|
changes: changeSet,
|
|
3245
3245
|
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
@@ -3248,20 +3248,20 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3248
3248
|
if (changes.changes.empty) {
|
|
3249
3249
|
return false;
|
|
3250
3250
|
}
|
|
3251
|
-
dispatch(
|
|
3251
|
+
dispatch(state2.update(changes, {
|
|
3252
3252
|
userEvent: "format.link.add",
|
|
3253
3253
|
scrollIntoView: true
|
|
3254
3254
|
}));
|
|
3255
3255
|
return true;
|
|
3256
3256
|
};
|
|
3257
|
-
var addList = (type) => ({ state, dispatch }) => {
|
|
3257
|
+
var addList = (type) => ({ state: state2, dispatch }) => {
|
|
3258
3258
|
let lastBlock = -1;
|
|
3259
3259
|
let counter = 1;
|
|
3260
3260
|
let first = true;
|
|
3261
3261
|
let parentColumn = null;
|
|
3262
3262
|
const blocks = [];
|
|
3263
|
-
for (const { from, to } of
|
|
3264
|
-
syntaxTree2(
|
|
3263
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3264
|
+
syntaxTree2(state2).iterate({
|
|
3265
3265
|
from,
|
|
3266
3266
|
to,
|
|
3267
3267
|
enter: (node) => {
|
|
@@ -3273,7 +3273,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3273
3273
|
}
|
|
3274
3274
|
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
3275
3275
|
const item = before.lastChild;
|
|
3276
|
-
const itemLine =
|
|
3276
|
+
const itemLine = state2.doc.lineAt(item.from);
|
|
3277
3277
|
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
3278
3278
|
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
3279
3279
|
if (type === 0) {
|
|
@@ -3308,10 +3308,10 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3308
3308
|
});
|
|
3309
3309
|
}
|
|
3310
3310
|
if (!blocks.length) {
|
|
3311
|
-
const { from, to } =
|
|
3311
|
+
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
3312
3312
|
if (from === to) {
|
|
3313
3313
|
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
3314
|
-
dispatch(
|
|
3314
|
+
dispatch(state2.update({
|
|
3315
3315
|
changes: [
|
|
3316
3316
|
{
|
|
3317
3317
|
from,
|
|
@@ -3332,11 +3332,11 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3332
3332
|
for (let i = 0; i < blocks.length; i++) {
|
|
3333
3333
|
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
3334
3334
|
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
3335
|
-
let padding = nodeFrom > 0 && !/\s/.test(
|
|
3335
|
+
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
3336
3336
|
if (type === 0) {
|
|
3337
3337
|
padding += String(counter2).length;
|
|
3338
3338
|
}
|
|
3339
|
-
let line =
|
|
3339
|
+
let line = state2.doc.lineAt(nodeFrom);
|
|
3340
3340
|
const column = nodeFrom - line.from;
|
|
3341
3341
|
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
3342
3342
|
padding = Math.max(padding, parentColumn2 - column);
|
|
@@ -3361,7 +3361,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3361
3361
|
insert: mark2
|
|
3362
3362
|
});
|
|
3363
3363
|
while (line.to < node.to) {
|
|
3364
|
-
line =
|
|
3364
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3365
3365
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3366
3366
|
changes.push({
|
|
3367
3367
|
from: line.from + Math.min(open, column),
|
|
@@ -3376,25 +3376,25 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3376
3376
|
next = next.nextSibling;
|
|
3377
3377
|
}
|
|
3378
3378
|
if (next?.name === "OrderedList") {
|
|
3379
|
-
renumberListItems(next.firstChild, last.counter + 1, changes,
|
|
3379
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
3380
3380
|
}
|
|
3381
3381
|
}
|
|
3382
|
-
const changeSet =
|
|
3383
|
-
dispatch(
|
|
3382
|
+
const changeSet = state2.changes(changes);
|
|
3383
|
+
dispatch(state2.update({
|
|
3384
3384
|
changes: changeSet,
|
|
3385
|
-
selection:
|
|
3385
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3386
3386
|
userEvent: "format.list.add",
|
|
3387
3387
|
scrollIntoView: true
|
|
3388
3388
|
}));
|
|
3389
3389
|
return true;
|
|
3390
3390
|
};
|
|
3391
|
-
var removeList = (type) => ({ state, dispatch }) => {
|
|
3391
|
+
var removeList = (type) => ({ state: state2, dispatch }) => {
|
|
3392
3392
|
let lastBlock = -1;
|
|
3393
3393
|
const changes = [];
|
|
3394
3394
|
const stack = [];
|
|
3395
3395
|
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
3396
|
-
for (const { from, to } of
|
|
3397
|
-
syntaxTree2(
|
|
3396
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3397
|
+
syntaxTree2(state2).iterate({
|
|
3398
3398
|
from,
|
|
3399
3399
|
to,
|
|
3400
3400
|
enter: (node) => {
|
|
@@ -3411,7 +3411,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3411
3411
|
stack.pop();
|
|
3412
3412
|
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
3413
3413
|
lastBlock = node.from;
|
|
3414
|
-
let line =
|
|
3414
|
+
let line = state2.doc.lineAt(node.from);
|
|
3415
3415
|
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
3416
3416
|
if (!mark2) {
|
|
3417
3417
|
return false;
|
|
@@ -3422,7 +3422,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3422
3422
|
to: node.from + mark2[0].length
|
|
3423
3423
|
});
|
|
3424
3424
|
while (line.to < node.to) {
|
|
3425
|
-
line =
|
|
3425
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3426
3426
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3427
3427
|
if (open > column) {
|
|
3428
3428
|
changes.push({
|
|
@@ -3432,7 +3432,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3432
3432
|
}
|
|
3433
3433
|
}
|
|
3434
3434
|
if (node.to >= to) {
|
|
3435
|
-
renumberListItems(node.node.nextSibling, 1, changes,
|
|
3435
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
3436
3436
|
}
|
|
3437
3437
|
return false;
|
|
3438
3438
|
}
|
|
@@ -3442,7 +3442,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3442
3442
|
if (!changes.length) {
|
|
3443
3443
|
return false;
|
|
3444
3444
|
}
|
|
3445
|
-
dispatch(
|
|
3445
|
+
dispatch(state2.update({
|
|
3446
3446
|
changes,
|
|
3447
3447
|
userEvent: "format.list.remove",
|
|
3448
3448
|
scrollIntoView: true
|
|
@@ -3472,12 +3472,12 @@ var renumberListItems = (item, counter, changes, doc) => {
|
|
|
3472
3472
|
}
|
|
3473
3473
|
}
|
|
3474
3474
|
};
|
|
3475
|
-
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
3475
|
+
var setBlockquote = (enable) => ({ state: state2, dispatch }) => {
|
|
3476
3476
|
const lines = [];
|
|
3477
3477
|
let lastBlock = -1;
|
|
3478
|
-
for (const { from, to } of
|
|
3478
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3479
3479
|
const sawBlock = false;
|
|
3480
|
-
syntaxTree2(
|
|
3480
|
+
syntaxTree2(state2).iterate({
|
|
3481
3481
|
from,
|
|
3482
3482
|
to,
|
|
3483
3483
|
enter: (node) => {
|
|
@@ -3486,9 +3486,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3486
3486
|
return false;
|
|
3487
3487
|
}
|
|
3488
3488
|
lastBlock = node.from;
|
|
3489
|
-
let line2 =
|
|
3489
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
3490
3490
|
if (line2.number > 1) {
|
|
3491
|
-
const prevLine =
|
|
3491
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
3492
3492
|
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
3493
3493
|
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
3494
3494
|
lines.push(prevLine);
|
|
@@ -3500,10 +3500,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3500
3500
|
if (line2.to >= node.to) {
|
|
3501
3501
|
break;
|
|
3502
3502
|
}
|
|
3503
|
-
line2 =
|
|
3503
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
3504
3504
|
}
|
|
3505
|
-
if (!enable && line2.number <
|
|
3506
|
-
const nextLine =
|
|
3505
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
3506
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
3507
3507
|
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
3508
3508
|
lines.push(nextLine);
|
|
3509
3509
|
}
|
|
@@ -3513,7 +3513,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3513
3513
|
}
|
|
3514
3514
|
});
|
|
3515
3515
|
let line;
|
|
3516
|
-
if (!sawBlock && enable && from === to && !/\S/.test((line =
|
|
3516
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3517
3517
|
lines.push(line);
|
|
3518
3518
|
}
|
|
3519
3519
|
}
|
|
@@ -3537,10 +3537,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3537
3537
|
if (!changes.length) {
|
|
3538
3538
|
return false;
|
|
3539
3539
|
}
|
|
3540
|
-
const changeSet =
|
|
3541
|
-
dispatch(
|
|
3540
|
+
const changeSet = state2.changes(changes);
|
|
3541
|
+
dispatch(state2.update({
|
|
3542
3542
|
changes: changeSet,
|
|
3543
|
-
selection:
|
|
3543
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3544
3544
|
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3545
3545
|
scrollIntoView: true
|
|
3546
3546
|
}));
|
|
@@ -3552,11 +3552,11 @@ var toggleBlockquote = (target) => {
|
|
|
3552
3552
|
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3553
3553
|
};
|
|
3554
3554
|
var addCodeblock = (target) => {
|
|
3555
|
-
const { state, dispatch } = target;
|
|
3556
|
-
const { selection } =
|
|
3555
|
+
const { state: state2, dispatch } = target;
|
|
3556
|
+
const { selection } = state2;
|
|
3557
3557
|
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
3558
3558
|
const { head } = selection.main;
|
|
3559
|
-
const line =
|
|
3559
|
+
const line = state2.doc.lineAt(head);
|
|
3560
3560
|
if (!/\S/.test(line.text) && head === line.from) {
|
|
3561
3561
|
snippets.codeblock(target, null, line.from, line.to);
|
|
3562
3562
|
return true;
|
|
@@ -3566,7 +3566,7 @@ var addCodeblock = (target) => {
|
|
|
3566
3566
|
for (const { from, to } of selection.ranges) {
|
|
3567
3567
|
let blockFrom = from;
|
|
3568
3568
|
let blockTo = to;
|
|
3569
|
-
syntaxTree2(
|
|
3569
|
+
syntaxTree2(state2).iterate({
|
|
3570
3570
|
from,
|
|
3571
3571
|
to,
|
|
3572
3572
|
enter: (node) => {
|
|
@@ -3575,8 +3575,8 @@ var addCodeblock = (target) => {
|
|
|
3575
3575
|
blockFrom = node.from;
|
|
3576
3576
|
blockTo = node.to;
|
|
3577
3577
|
} else {
|
|
3578
|
-
blockFrom = Math.min(blockFrom,
|
|
3579
|
-
blockTo = Math.max(blockTo,
|
|
3578
|
+
blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
|
|
3579
|
+
blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
|
|
3580
3580
|
}
|
|
3581
3581
|
}
|
|
3582
3582
|
}
|
|
@@ -3594,7 +3594,7 @@ var addCodeblock = (target) => {
|
|
|
3594
3594
|
return false;
|
|
3595
3595
|
}
|
|
3596
3596
|
const changes = ranges.map(({ from, to }) => {
|
|
3597
|
-
const column = from -
|
|
3597
|
+
const column = from - state2.doc.lineAt(from).from;
|
|
3598
3598
|
return [
|
|
3599
3599
|
{
|
|
3600
3600
|
from,
|
|
@@ -3606,30 +3606,30 @@ var addCodeblock = (target) => {
|
|
|
3606
3606
|
}
|
|
3607
3607
|
];
|
|
3608
3608
|
});
|
|
3609
|
-
dispatch(
|
|
3609
|
+
dispatch(state2.update({
|
|
3610
3610
|
changes,
|
|
3611
3611
|
userEvent: "format.codeblock.add",
|
|
3612
3612
|
scrollIntoView: true
|
|
3613
3613
|
}));
|
|
3614
3614
|
return true;
|
|
3615
3615
|
};
|
|
3616
|
-
var removeCodeblock = ({ state, dispatch }) => {
|
|
3616
|
+
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3617
3617
|
const changes = [];
|
|
3618
3618
|
let lastBlock = -1;
|
|
3619
|
-
for (const { from, to } of
|
|
3620
|
-
syntaxTree2(
|
|
3619
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3620
|
+
syntaxTree2(state2).iterate({
|
|
3621
3621
|
from,
|
|
3622
3622
|
to,
|
|
3623
3623
|
enter: (node) => {
|
|
3624
3624
|
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
3625
3625
|
lastBlock = node.from;
|
|
3626
|
-
const firstLine =
|
|
3626
|
+
const firstLine = state2.doc.lineAt(node.from);
|
|
3627
3627
|
if (node.name === "FencedCode") {
|
|
3628
3628
|
changes.push({
|
|
3629
3629
|
from: node.from,
|
|
3630
3630
|
to: firstLine.to + 1 + node.from - firstLine.from
|
|
3631
3631
|
});
|
|
3632
|
-
const lastLine =
|
|
3632
|
+
const lastLine = state2.doc.lineAt(node.to);
|
|
3633
3633
|
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
3634
3634
|
changes.push({
|
|
3635
3635
|
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
@@ -3638,7 +3638,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3638
3638
|
}
|
|
3639
3639
|
} else {
|
|
3640
3640
|
const column = node.from - firstLine.from;
|
|
3641
|
-
for (let line = firstLine; ; line =
|
|
3641
|
+
for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
|
|
3642
3642
|
changes.push({
|
|
3643
3643
|
from: line.from + column - 4,
|
|
3644
3644
|
to: line.from + column
|
|
@@ -3655,7 +3655,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3655
3655
|
if (!changes.length) {
|
|
3656
3656
|
return false;
|
|
3657
3657
|
}
|
|
3658
|
-
dispatch(
|
|
3658
|
+
dispatch(state2.update({
|
|
3659
3659
|
changes,
|
|
3660
3660
|
userEvent: "format.codeblock.remove",
|
|
3661
3661
|
scrollIntoView: true
|
|
@@ -3714,7 +3714,7 @@ var Textblocks = {
|
|
|
3714
3714
|
TableCell: "tablecell",
|
|
3715
3715
|
Task: "paragraph"
|
|
3716
3716
|
};
|
|
3717
|
-
var getFormatting = (
|
|
3717
|
+
var getFormatting = (state2) => {
|
|
3718
3718
|
let blockType = null;
|
|
3719
3719
|
const inline = [
|
|
3720
3720
|
null,
|
|
@@ -3740,7 +3740,7 @@ var getFormatting = (state) => {
|
|
|
3740
3740
|
continue;
|
|
3741
3741
|
} else if (currentBlock.active[i]) {
|
|
3742
3742
|
inline[i] = true;
|
|
3743
|
-
} else if (/\S/.test(
|
|
3743
|
+
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3744
3744
|
inline[i] = false;
|
|
3745
3745
|
}
|
|
3746
3746
|
}
|
|
@@ -3751,12 +3751,12 @@ var getFormatting = (state) => {
|
|
|
3751
3751
|
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3752
3752
|
}
|
|
3753
3753
|
};
|
|
3754
|
-
const { selection } =
|
|
3754
|
+
const { selection } = state2;
|
|
3755
3755
|
for (const range of selection.ranges) {
|
|
3756
3756
|
if (range.empty && inline.some((v) => v === null)) {
|
|
3757
3757
|
const contextSize = Math.min(range.head, 6);
|
|
3758
|
-
const contextBefore =
|
|
3759
|
-
let contextAfter =
|
|
3758
|
+
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3759
|
+
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3760
3760
|
for (let i = 0; i < contextSize; i++) {
|
|
3761
3761
|
const ch = contextAfter[i];
|
|
3762
3762
|
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
@@ -3775,7 +3775,7 @@ var getFormatting = (state) => {
|
|
|
3775
3775
|
}
|
|
3776
3776
|
}
|
|
3777
3777
|
}
|
|
3778
|
-
syntaxTree2(
|
|
3778
|
+
syntaxTree2(state2).iterate({
|
|
3779
3779
|
from: range.from,
|
|
3780
3780
|
to: range.to,
|
|
3781
3781
|
enter: (node) => {
|
|
@@ -3849,7 +3849,7 @@ var getFormatting = (state) => {
|
|
|
3849
3849
|
}
|
|
3850
3850
|
});
|
|
3851
3851
|
}
|
|
3852
|
-
const { from, to } =
|
|
3852
|
+
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3853
3853
|
const blankLine = from === to;
|
|
3854
3854
|
return {
|
|
3855
3855
|
blankLine,
|
|
@@ -3864,17 +3864,17 @@ var getFormatting = (state) => {
|
|
|
3864
3864
|
};
|
|
3865
3865
|
};
|
|
3866
3866
|
var useFormattingState = () => {
|
|
3867
|
-
const [
|
|
3867
|
+
const [state2, setState] = useState(null);
|
|
3868
3868
|
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3869
3869
|
if (update2.docChanged || update2.selectionSet) {
|
|
3870
3870
|
const newState = getFormatting(update2.state);
|
|
3871
|
-
if (!
|
|
3871
|
+
if (!state2 || !compareFormatting(state2, newState)) {
|
|
3872
3872
|
setState(newState);
|
|
3873
3873
|
}
|
|
3874
3874
|
}
|
|
3875
3875
|
}), []);
|
|
3876
3876
|
return [
|
|
3877
|
-
|
|
3877
|
+
state2,
|
|
3878
3878
|
observer
|
|
3879
3879
|
];
|
|
3880
3880
|
};
|
|
@@ -3885,8 +3885,8 @@ import { StateField as StateField5 } from "@codemirror/state";
|
|
|
3885
3885
|
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3886
3886
|
var image = (options = {}) => {
|
|
3887
3887
|
return StateField5.define({
|
|
3888
|
-
create: (
|
|
3889
|
-
return Decoration6.set(buildDecorations2(0,
|
|
3888
|
+
create: (state2) => {
|
|
3889
|
+
return Decoration6.set(buildDecorations2(0, state2.doc.length, state2));
|
|
3890
3890
|
},
|
|
3891
3891
|
update: (value, tr) => {
|
|
3892
3892
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3920,16 +3920,16 @@ var preloadImage = (url) => {
|
|
|
3920
3920
|
preloaded.add(url);
|
|
3921
3921
|
}
|
|
3922
3922
|
};
|
|
3923
|
-
var buildDecorations2 = (from, to,
|
|
3923
|
+
var buildDecorations2 = (from, to, state2) => {
|
|
3924
3924
|
const decorations = [];
|
|
3925
|
-
const cursor =
|
|
3926
|
-
syntaxTree3(
|
|
3925
|
+
const cursor = state2.selection.main.head;
|
|
3926
|
+
syntaxTree3(state2).iterate({
|
|
3927
3927
|
enter: (node) => {
|
|
3928
3928
|
if (node.name === "Image") {
|
|
3929
3929
|
const urlNode = node.node.getChild("URL");
|
|
3930
3930
|
if (urlNode) {
|
|
3931
|
-
const hide2 =
|
|
3932
|
-
const url =
|
|
3931
|
+
const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
|
|
3932
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3933
3933
|
preloadImage(url);
|
|
3934
3934
|
decorations.push(Decoration6.replace({
|
|
3935
3935
|
block: true,
|
|
@@ -4000,21 +4000,21 @@ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "
|
|
|
4000
4000
|
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4001
4001
|
var table = (options = {}) => {
|
|
4002
4002
|
return StateField6.define({
|
|
4003
|
-
create: (
|
|
4003
|
+
create: (state2) => update(state2, options),
|
|
4004
4004
|
update: (_, tr) => update(tr.state, options),
|
|
4005
4005
|
provide: (field) => EditorView15.decorations.from(field)
|
|
4006
4006
|
});
|
|
4007
4007
|
};
|
|
4008
|
-
var update = (
|
|
4008
|
+
var update = (state2, options) => {
|
|
4009
4009
|
const builder = new RangeSetBuilder3();
|
|
4010
|
-
const cursor =
|
|
4010
|
+
const cursor = state2.selection.main.head;
|
|
4011
4011
|
const tables = [];
|
|
4012
4012
|
const getTable = () => tables[tables.length - 1];
|
|
4013
4013
|
const getRow = () => {
|
|
4014
4014
|
const table2 = getTable();
|
|
4015
4015
|
return table2.rows?.[table2.rows.length - 1];
|
|
4016
4016
|
};
|
|
4017
|
-
syntaxTree5(
|
|
4017
|
+
syntaxTree5(state2).iterate({
|
|
4018
4018
|
enter: (node) => {
|
|
4019
4019
|
switch (node.name) {
|
|
4020
4020
|
case "Table": {
|
|
@@ -4035,9 +4035,9 @@ var update = (state, options) => {
|
|
|
4035
4035
|
case "TableCell": {
|
|
4036
4036
|
const row = getRow();
|
|
4037
4037
|
if (row) {
|
|
4038
|
-
row.push(
|
|
4038
|
+
row.push(state2.sliceDoc(node.from, node.to));
|
|
4039
4039
|
} else {
|
|
4040
|
-
getTable().header?.push(
|
|
4040
|
+
getTable().header?.push(state2.sliceDoc(node.from, node.to));
|
|
4041
4041
|
}
|
|
4042
4042
|
break;
|
|
4043
4043
|
}
|
|
@@ -4045,7 +4045,7 @@ var update = (state, options) => {
|
|
|
4045
4045
|
}
|
|
4046
4046
|
});
|
|
4047
4047
|
tables.forEach((table2) => {
|
|
4048
|
-
const hide2 =
|
|
4048
|
+
const hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4049
4049
|
if (hide2) {
|
|
4050
4050
|
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
4051
4051
|
widget: new TableWidget(table2)
|
|
@@ -4136,6 +4136,7 @@ var mention = ({ onSearch }) => {
|
|
|
4136
4136
|
import { Facet as Facet6 } from "@codemirror/state";
|
|
4137
4137
|
import { keymap as keymap7 } from "@codemirror/view";
|
|
4138
4138
|
import { vim } from "@replit/codemirror-vim";
|
|
4139
|
+
var focusEvent = "focus.container";
|
|
4139
4140
|
var editorMode = Facet6.define({
|
|
4140
4141
|
combine: (modes) => modes[0] ?? {}
|
|
4141
4142
|
});
|
|
@@ -4152,7 +4153,7 @@ var EditorModes = {
|
|
|
4152
4153
|
key: "Alt-Escape",
|
|
4153
4154
|
run: (view) => {
|
|
4154
4155
|
view.dispatch({
|
|
4155
|
-
userEvent:
|
|
4156
|
+
userEvent: focusEvent
|
|
4156
4157
|
});
|
|
4157
4158
|
return true;
|
|
4158
4159
|
}
|
|
@@ -4161,8 +4162,95 @@ var EditorModes = {
|
|
|
4161
4162
|
]
|
|
4162
4163
|
};
|
|
4163
4164
|
|
|
4165
|
+
// packages/ui/react-ui-editor/src/extensions/state.ts
|
|
4166
|
+
import { Transaction as Transaction2 } from "@codemirror/state";
|
|
4167
|
+
import { EditorView as EditorView16, keymap as keymap8 } from "@codemirror/view";
|
|
4168
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
4169
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4170
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4171
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
|
|
4172
|
+
var scrollAnnotation = "dxos.org/cm/scrolling";
|
|
4173
|
+
var keyPrefix = "dxos.org/react-ui-editor/state";
|
|
4174
|
+
var localStorageStateStoreAdapter = {
|
|
4175
|
+
setState: (id, state2) => {
|
|
4176
|
+
invariant4(id, void 0, {
|
|
4177
|
+
F: __dxlog_file11,
|
|
4178
|
+
L: 35,
|
|
4179
|
+
S: void 0,
|
|
4180
|
+
A: [
|
|
4181
|
+
"id",
|
|
4182
|
+
""
|
|
4183
|
+
]
|
|
4184
|
+
});
|
|
4185
|
+
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state2));
|
|
4186
|
+
},
|
|
4187
|
+
getState: (id) => {
|
|
4188
|
+
invariant4(id, void 0, {
|
|
4189
|
+
F: __dxlog_file11,
|
|
4190
|
+
L: 39,
|
|
4191
|
+
S: void 0,
|
|
4192
|
+
A: [
|
|
4193
|
+
"id",
|
|
4194
|
+
""
|
|
4195
|
+
]
|
|
4196
|
+
});
|
|
4197
|
+
const state2 = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
4198
|
+
return state2 ? JSON.parse(state2) : void 0;
|
|
4199
|
+
}
|
|
4200
|
+
};
|
|
4201
|
+
var state = ({ getState, setState } = {}) => {
|
|
4202
|
+
const setStateDebounced = debounce2(setState, 1e3);
|
|
4203
|
+
return [
|
|
4204
|
+
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
4205
|
+
EditorView16.updateListener.of(({ view, changes, transactions }) => {
|
|
4206
|
+
const id = view.state.facet(documentId2);
|
|
4207
|
+
if (!id || transactions.some((tr) => tr.isUserEvent(scrollAnnotation))) {
|
|
4208
|
+
return;
|
|
4209
|
+
}
|
|
4210
|
+
if (setState) {
|
|
4211
|
+
const { top } = view.dom.getBoundingClientRect();
|
|
4212
|
+
const pos = view.posAtCoords({
|
|
4213
|
+
x: 0,
|
|
4214
|
+
y: top
|
|
4215
|
+
});
|
|
4216
|
+
if (pos !== null) {
|
|
4217
|
+
const { anchor, head } = view.state.selection.main;
|
|
4218
|
+
setStateDebounced(id, {
|
|
4219
|
+
scrollTo: {
|
|
4220
|
+
from: pos,
|
|
4221
|
+
yMargin: 0
|
|
4222
|
+
},
|
|
4223
|
+
selection: {
|
|
4224
|
+
anchor,
|
|
4225
|
+
head
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
}),
|
|
4231
|
+
getState && keymap8.of([
|
|
4232
|
+
{
|
|
4233
|
+
key: "ctrl-r",
|
|
4234
|
+
run: (view) => {
|
|
4235
|
+
const state2 = getState(view.state.facet(documentId2));
|
|
4236
|
+
if (state2) {
|
|
4237
|
+
view.dispatch({
|
|
4238
|
+
effects: EditorView16.scrollIntoView(state2.scrollTo.from, {
|
|
4239
|
+
yMargin: 0
|
|
4240
|
+
}),
|
|
4241
|
+
selection: state2.selection,
|
|
4242
|
+
annotations: Transaction2.userEvent.of(scrollAnnotation)
|
|
4243
|
+
});
|
|
4244
|
+
}
|
|
4245
|
+
return true;
|
|
4246
|
+
}
|
|
4247
|
+
}
|
|
4248
|
+
])
|
|
4249
|
+
].filter(isNotFalsy3);
|
|
4250
|
+
};
|
|
4251
|
+
|
|
4164
4252
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4165
|
-
import { keymap as
|
|
4253
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
|
4166
4254
|
var defaultItems = [
|
|
4167
4255
|
"hello world!",
|
|
4168
4256
|
"this is a test.",
|
|
@@ -4172,7 +4260,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4172
4260
|
let t;
|
|
4173
4261
|
let idx = 0;
|
|
4174
4262
|
return [
|
|
4175
|
-
|
|
4263
|
+
keymap9.of([
|
|
4176
4264
|
{
|
|
4177
4265
|
// Reset.
|
|
4178
4266
|
key: "alt-meta-'",
|
|
@@ -4219,9 +4307,11 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4219
4307
|
};
|
|
4220
4308
|
|
|
4221
4309
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4222
|
-
var
|
|
4310
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4223
4311
|
var instanceCount = 0;
|
|
4224
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo =
|
|
4312
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo = EditorView17.scrollIntoView(0, {
|
|
4313
|
+
yMargin: 0
|
|
4314
|
+
}), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4225
4315
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
4226
4316
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
4227
4317
|
tabBehavior: "limited"
|
|
@@ -4244,38 +4334,38 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4244
4334
|
id,
|
|
4245
4335
|
instanceId
|
|
4246
4336
|
}, {
|
|
4247
|
-
F:
|
|
4337
|
+
F: __dxlog_file12,
|
|
4248
4338
|
L: 88,
|
|
4249
4339
|
S: void 0,
|
|
4250
4340
|
C: (f, a) => f(...a)
|
|
4251
4341
|
});
|
|
4252
|
-
const
|
|
4342
|
+
const state2 = EditorState2.create({
|
|
4253
4343
|
doc,
|
|
4254
4344
|
selection,
|
|
4255
4345
|
extensions: [
|
|
4256
4346
|
id && documentId2.of(id),
|
|
4257
4347
|
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4258
|
-
|
|
4348
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4259
4349
|
log9.catch(err, void 0, {
|
|
4260
|
-
F:
|
|
4350
|
+
F: __dxlog_file12,
|
|
4261
4351
|
L: 101,
|
|
4262
4352
|
S: void 0,
|
|
4263
4353
|
C: (f, a) => f(...a)
|
|
4264
4354
|
});
|
|
4265
4355
|
}),
|
|
4266
4356
|
// Focus.
|
|
4267
|
-
|
|
4357
|
+
EditorView17.updateListener.of((update2) => {
|
|
4268
4358
|
update2.transactions.forEach((transaction) => {
|
|
4269
|
-
if (transaction.isUserEvent(
|
|
4359
|
+
if (transaction.isUserEvent(focusEvent)) {
|
|
4270
4360
|
rootRef.current?.focus();
|
|
4271
4361
|
}
|
|
4272
4362
|
});
|
|
4273
4363
|
}),
|
|
4274
4364
|
extensions
|
|
4275
|
-
].filter(
|
|
4365
|
+
].filter(isNotFalsy4)
|
|
4276
4366
|
});
|
|
4277
|
-
const view2 = new
|
|
4278
|
-
state,
|
|
4367
|
+
const view2 = new EditorView17({
|
|
4368
|
+
state: state2,
|
|
4279
4369
|
parent: rootRef.current,
|
|
4280
4370
|
scrollTo,
|
|
4281
4371
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
@@ -4287,18 +4377,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4287
4377
|
view3.update(trs);
|
|
4288
4378
|
}
|
|
4289
4379
|
});
|
|
4290
|
-
|
|
4291
|
-
if (moveToEndOfLine) {
|
|
4380
|
+
if (moveToEndOfLine && !(scrollTo || selection)) {
|
|
4292
4381
|
const { to } = view2.state.doc.lineAt(0);
|
|
4293
|
-
view2
|
|
4382
|
+
view2.dispatch({
|
|
4294
4383
|
selection: {
|
|
4295
4384
|
anchor: to
|
|
4296
4385
|
}
|
|
4297
4386
|
});
|
|
4298
4387
|
}
|
|
4299
|
-
if (
|
|
4388
|
+
if (state2.facet(editorMode).noTabster) {
|
|
4300
4389
|
rootRef.current?.removeAttribute("data-tabster");
|
|
4301
4390
|
}
|
|
4391
|
+
setView(view2);
|
|
4302
4392
|
return () => {
|
|
4303
4393
|
view2?.destroy();
|
|
4304
4394
|
setView(null);
|
|
@@ -4350,10 +4440,10 @@ var HeadingIcons = {
|
|
|
4350
4440
|
"6": TextHSix
|
|
4351
4441
|
};
|
|
4352
4442
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4353
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
4443
|
+
var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
4354
4444
|
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
4355
4445
|
onAction,
|
|
4356
|
-
state
|
|
4446
|
+
state: state2
|
|
4357
4447
|
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
4358
4448
|
density: "fine"
|
|
4359
4449
|
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
@@ -4386,8 +4476,8 @@ var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
4386
4476
|
});
|
|
4387
4477
|
var MarkdownHeading = () => {
|
|
4388
4478
|
const { t } = useTranslation(translationKey);
|
|
4389
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
4390
|
-
const blockType =
|
|
4479
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
|
|
4480
|
+
const blockType = state2 ? state2.blockType : "paragraph";
|
|
4391
4481
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4392
4482
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4393
4483
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
@@ -4461,43 +4551,43 @@ var markdownStyles = [
|
|
|
4461
4551
|
{
|
|
4462
4552
|
type: "strong",
|
|
4463
4553
|
Icon: TextB,
|
|
4464
|
-
getState: (
|
|
4554
|
+
getState: (state2) => state2.strong
|
|
4465
4555
|
},
|
|
4466
4556
|
{
|
|
4467
4557
|
type: "emphasis",
|
|
4468
4558
|
Icon: TextItalic,
|
|
4469
|
-
getState: (
|
|
4559
|
+
getState: (state2) => state2.emphasis
|
|
4470
4560
|
},
|
|
4471
4561
|
{
|
|
4472
4562
|
type: "strikethrough",
|
|
4473
4563
|
Icon: TextStrikethrough,
|
|
4474
|
-
getState: (
|
|
4564
|
+
getState: (state2) => state2.strikethrough
|
|
4475
4565
|
},
|
|
4476
4566
|
{
|
|
4477
4567
|
type: "code",
|
|
4478
4568
|
Icon: Code,
|
|
4479
|
-
getState: (
|
|
4569
|
+
getState: (state2) => state2.code
|
|
4480
4570
|
},
|
|
4481
4571
|
{
|
|
4482
4572
|
type: "link",
|
|
4483
4573
|
Icon: Link,
|
|
4484
|
-
getState: (
|
|
4574
|
+
getState: (state2) => state2.link
|
|
4485
4575
|
}
|
|
4486
4576
|
];
|
|
4487
4577
|
var MarkdownStyles = () => {
|
|
4488
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4578
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4489
4579
|
const { t } = useTranslation(translationKey);
|
|
4490
4580
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4491
4581
|
type: "multiple",
|
|
4492
|
-
value: markdownStyles.filter(({ getState }) =>
|
|
4582
|
+
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
4493
4583
|
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4494
4584
|
key: type,
|
|
4495
4585
|
value: type,
|
|
4496
4586
|
Icon,
|
|
4497
|
-
disabled:
|
|
4498
|
-
onClick:
|
|
4587
|
+
disabled: state2?.blockType === "codeblock",
|
|
4588
|
+
onClick: state2 ? () => onAction?.({
|
|
4499
4589
|
type,
|
|
4500
|
-
data: !getState(
|
|
4590
|
+
data: !getState(state2)
|
|
4501
4591
|
}) : void 0
|
|
4502
4592
|
}, t(`${type} label`))));
|
|
4503
4593
|
};
|
|
@@ -4505,32 +4595,32 @@ var markdownLists = [
|
|
|
4505
4595
|
{
|
|
4506
4596
|
type: "list-bullet",
|
|
4507
4597
|
Icon: ListBullets,
|
|
4508
|
-
getState: (
|
|
4598
|
+
getState: (state2) => state2.listStyle === "bullet"
|
|
4509
4599
|
},
|
|
4510
4600
|
{
|
|
4511
4601
|
type: "list-ordered",
|
|
4512
4602
|
Icon: ListNumbers,
|
|
4513
|
-
getState: (
|
|
4603
|
+
getState: (state2) => state2.listStyle === "ordered"
|
|
4514
4604
|
},
|
|
4515
4605
|
{
|
|
4516
4606
|
type: "list-task",
|
|
4517
4607
|
Icon: ListChecks,
|
|
4518
|
-
getState: (
|
|
4608
|
+
getState: (state2) => state2.listStyle === "task"
|
|
4519
4609
|
}
|
|
4520
4610
|
];
|
|
4521
4611
|
var MarkdownLists = () => {
|
|
4522
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4612
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4523
4613
|
const { t } = useTranslation(translationKey);
|
|
4524
4614
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4525
4615
|
type: "single",
|
|
4526
|
-
value:
|
|
4616
|
+
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
4527
4617
|
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4528
4618
|
key: type,
|
|
4529
4619
|
value: type,
|
|
4530
4620
|
Icon,
|
|
4531
|
-
onClick:
|
|
4621
|
+
onClick: state2 ? () => onAction?.({
|
|
4532
4622
|
type,
|
|
4533
|
-
data: !getState(
|
|
4623
|
+
data: !getState(state2)
|
|
4534
4624
|
}) : void 0
|
|
4535
4625
|
}, t(`${type} label`))));
|
|
4536
4626
|
};
|
|
@@ -4538,24 +4628,24 @@ var markdownBlocks = [
|
|
|
4538
4628
|
{
|
|
4539
4629
|
type: "blockquote",
|
|
4540
4630
|
Icon: Quotes,
|
|
4541
|
-
getState: (
|
|
4631
|
+
getState: (state2) => state2.blockQuote
|
|
4542
4632
|
},
|
|
4543
4633
|
{
|
|
4544
4634
|
type: "codeblock",
|
|
4545
4635
|
Icon: CodeBlock,
|
|
4546
|
-
getState: (
|
|
4636
|
+
getState: (state2) => state2.blockType === "codeblock"
|
|
4547
4637
|
},
|
|
4548
4638
|
{
|
|
4549
4639
|
type: "table",
|
|
4550
4640
|
Icon: Table2,
|
|
4551
|
-
getState: (
|
|
4552
|
-
disabled: (
|
|
4641
|
+
getState: (state2) => state2.blockType === "tablecell",
|
|
4642
|
+
disabled: (state2) => !state2.blankLine
|
|
4553
4643
|
}
|
|
4554
4644
|
];
|
|
4555
4645
|
var MarkdownBlocks = () => {
|
|
4556
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4646
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4557
4647
|
const { t } = useTranslation(translationKey);
|
|
4558
|
-
const value = markdownBlocks.find(({ getState }) =>
|
|
4648
|
+
const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
|
|
4559
4649
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4560
4650
|
type: "single",
|
|
4561
4651
|
value: value?.type ?? ""
|
|
@@ -4563,10 +4653,10 @@ var MarkdownBlocks = () => {
|
|
|
4563
4653
|
key: type,
|
|
4564
4654
|
value: type,
|
|
4565
4655
|
Icon,
|
|
4566
|
-
disabled: !
|
|
4567
|
-
onClick:
|
|
4656
|
+
disabled: !state2 || disabled?.(state2),
|
|
4657
|
+
onClick: state2 ? () => onAction?.({
|
|
4568
4658
|
type,
|
|
4569
|
-
data: !getState(
|
|
4659
|
+
data: !getState(state2)
|
|
4570
4660
|
}) : void 0
|
|
4571
4661
|
}, t(`${type} label`))));
|
|
4572
4662
|
};
|
|
@@ -4660,11 +4750,11 @@ var useDocAccessor = (text) => {
|
|
|
4660
4750
|
|
|
4661
4751
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4662
4752
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4663
|
-
import { EditorView as
|
|
4753
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
4664
4754
|
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4665
4755
|
import { log as log10 } from "@dxos/log";
|
|
4666
|
-
import { isNotFalsy as
|
|
4667
|
-
var
|
|
4756
|
+
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4757
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4668
4758
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4669
4759
|
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4670
4760
|
const onUpdate = useRef3();
|
|
@@ -4673,30 +4763,30 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
4673
4763
|
useEffect3(() => {
|
|
4674
4764
|
let view2;
|
|
4675
4765
|
if (parentRef.current) {
|
|
4676
|
-
const
|
|
4766
|
+
const state2 = EditorState3.create({
|
|
4677
4767
|
doc,
|
|
4678
4768
|
selection,
|
|
4679
4769
|
extensions: [
|
|
4680
4770
|
id && documentId2.of(id),
|
|
4681
4771
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4682
|
-
|
|
4772
|
+
EditorView18.exceptionSink.of((err) => {
|
|
4683
4773
|
log10.catch(err, void 0, {
|
|
4684
|
-
F:
|
|
4774
|
+
F: __dxlog_file13,
|
|
4685
4775
|
L: 44,
|
|
4686
4776
|
S: void 0,
|
|
4687
4777
|
C: (f, a) => f(...a)
|
|
4688
4778
|
});
|
|
4689
4779
|
}),
|
|
4690
4780
|
extensions,
|
|
4691
|
-
|
|
4781
|
+
EditorView18.updateListener.of(() => {
|
|
4692
4782
|
onUpdate.current?.();
|
|
4693
4783
|
})
|
|
4694
|
-
].filter(
|
|
4784
|
+
].filter(isNotFalsy5)
|
|
4695
4785
|
});
|
|
4696
|
-
view2 = new
|
|
4786
|
+
view2 = new EditorView18({
|
|
4697
4787
|
parent: parentRef.current,
|
|
4698
4788
|
scrollTo,
|
|
4699
|
-
state,
|
|
4789
|
+
state: state2,
|
|
4700
4790
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4701
4791
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4702
4792
|
dispatchTransactions: (trs, view3) => {
|
|
@@ -4788,14 +4878,16 @@ export {
|
|
|
4788
4878
|
editorMode,
|
|
4789
4879
|
editorWithToolbarLayout,
|
|
4790
4880
|
focusComment,
|
|
4881
|
+
focusEvent,
|
|
4791
4882
|
formattingKeymap,
|
|
4792
4883
|
getFormatting,
|
|
4793
4884
|
getToken,
|
|
4794
4885
|
image,
|
|
4795
4886
|
insertTable,
|
|
4796
|
-
|
|
4887
|
+
keymap10 as keymap,
|
|
4797
4888
|
linkTooltip,
|
|
4798
4889
|
listener,
|
|
4890
|
+
localStorageStateStoreAdapter,
|
|
4799
4891
|
logChanges,
|
|
4800
4892
|
markdownHighlightStyle,
|
|
4801
4893
|
markdownTags,
|
|
@@ -4811,6 +4903,7 @@ export {
|
|
|
4811
4903
|
setHeading,
|
|
4812
4904
|
setSelection,
|
|
4813
4905
|
setStyle,
|
|
4906
|
+
state,
|
|
4814
4907
|
table,
|
|
4815
4908
|
tags2 as tags,
|
|
4816
4909
|
toggleBlockquote,
|