@dxos/react-ui-editor 0.4.8-main.0602afb → 0.4.8-main.1473255
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 +322 -232
- 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/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/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/factories.ts +0 -3
- package/src/extensions/index.ts +1 -0
- package/src/extensions/markdown/decorate.ts +1 -1
- 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;
|
|
@@ -2233,9 +2233,6 @@ var createBasicExtensions = (_props) => {
|
|
|
2233
2233
|
var defaultSlots = {
|
|
2234
2234
|
editor: {
|
|
2235
2235
|
className: "w-full bs-full"
|
|
2236
|
-
},
|
|
2237
|
-
content: {
|
|
2238
|
-
className: "!p-2"
|
|
2239
2236
|
}
|
|
2240
2237
|
};
|
|
2241
2238
|
var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
@@ -2563,7 +2560,7 @@ var CheckboxWidget = class extends WidgetType3 {
|
|
|
2563
2560
|
}
|
|
2564
2561
|
toDOM(view) {
|
|
2565
2562
|
const input = document.createElement("input");
|
|
2566
|
-
input.className = "cm-task-checkbox";
|
|
2563
|
+
input.className = "cm-task-checkbox ch-checkbox ch-focus-ring -mbs-0.5";
|
|
2567
2564
|
input.type = "checkbox";
|
|
2568
2565
|
input.checked = this._checked;
|
|
2569
2566
|
if (view.state.readOnly) {
|
|
@@ -2609,8 +2606,8 @@ var checkedTask = Decoration5.replace({
|
|
|
2609
2606
|
var uncheckedTask = Decoration5.replace({
|
|
2610
2607
|
widget: new CheckboxWidget(false)
|
|
2611
2608
|
});
|
|
2612
|
-
var editingRange = (
|
|
2613
|
-
const { readOnly, selection: { main: { head } } } =
|
|
2609
|
+
var editingRange = (state2, range, focus) => {
|
|
2610
|
+
const { readOnly, selection: { main: { head } } } = state2;
|
|
2614
2611
|
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
2615
2612
|
};
|
|
2616
2613
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
@@ -2623,14 +2620,14 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
2623
2620
|
var buildDecorations = (view, options, focus) => {
|
|
2624
2621
|
const deco = new RangeSetBuilder2();
|
|
2625
2622
|
const atomicDeco = new RangeSetBuilder2();
|
|
2626
|
-
const { state } = view;
|
|
2623
|
+
const { state: state2 } = view;
|
|
2627
2624
|
for (const { from, to } of view.visibleRanges) {
|
|
2628
|
-
syntaxTree(
|
|
2625
|
+
syntaxTree(state2).iterate({
|
|
2629
2626
|
from,
|
|
2630
2627
|
to,
|
|
2631
2628
|
enter: (node) => {
|
|
2632
2629
|
if (node.name === "FencedCode") {
|
|
2633
|
-
const editing = editingRange(
|
|
2630
|
+
const editing = editingRange(state2, node, focus);
|
|
2634
2631
|
for (const block of view.viewportLineBlocks) {
|
|
2635
2632
|
if (block.to < node.from) {
|
|
2636
2633
|
continue;
|
|
@@ -2639,7 +2636,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2639
2636
|
break;
|
|
2640
2637
|
}
|
|
2641
2638
|
const first = block.from <= node.from;
|
|
2642
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(
|
|
2639
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
2643
2640
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2644
2641
|
if (!editing && (first || last)) {
|
|
2645
2642
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -2649,9 +2646,9 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2649
2646
|
} else if (node.name === "Link") {
|
|
2650
2647
|
const marks = node.node.getChildren("LinkMark");
|
|
2651
2648
|
const urlNode = node.node.getChild("URL");
|
|
2652
|
-
const editing = editingRange(
|
|
2649
|
+
const editing = editingRange(state2, node, focus);
|
|
2653
2650
|
if (urlNode && marks.length >= 2) {
|
|
2654
|
-
const url =
|
|
2651
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
2655
2652
|
if (!editing) {
|
|
2656
2653
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2657
2654
|
}
|
|
@@ -2672,24 +2669,24 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2672
2669
|
}
|
|
2673
2670
|
} else if (node.name === "HeaderMark") {
|
|
2674
2671
|
const parent = node.node.parent;
|
|
2675
|
-
if (/^ATX/.test(parent.name) && !editingRange(
|
|
2676
|
-
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);
|
|
2677
2674
|
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2678
2675
|
}
|
|
2679
2676
|
} else if (node.name === "HorizontalRule") {
|
|
2680
|
-
if (!editingRange(
|
|
2677
|
+
if (!editingRange(state2, node, focus)) {
|
|
2681
2678
|
deco.add(node.from, node.to, horizontalRule);
|
|
2682
2679
|
}
|
|
2683
2680
|
} else if (node.name === "TaskMarker") {
|
|
2684
|
-
if (!editingRange(
|
|
2685
|
-
const checked =
|
|
2681
|
+
if (!editingRange(state2, node, focus)) {
|
|
2682
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2686
2683
|
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2687
2684
|
class: "cm-task"
|
|
2688
2685
|
}));
|
|
2689
2686
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2690
2687
|
}
|
|
2691
2688
|
} else if (MarksByParent.has(node.name)) {
|
|
2692
|
-
if (!editingRange(
|
|
2689
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
2693
2690
|
atomicDeco.add(node.from, node.to, hide);
|
|
2694
2691
|
}
|
|
2695
2692
|
}
|
|
@@ -2814,13 +2811,13 @@ var List;
|
|
|
2814
2811
|
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2815
2812
|
List2[List2["Task"] = 2] = "Task";
|
|
2816
2813
|
})(List || (List = {}));
|
|
2817
|
-
var setHeading = (level) => ({ state, dispatch }) => {
|
|
2818
|
-
const { selection: { ranges }, doc } =
|
|
2814
|
+
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2815
|
+
const { selection: { ranges }, doc } = state2;
|
|
2819
2816
|
const changes = [];
|
|
2820
2817
|
let prevBlock = -1;
|
|
2821
2818
|
for (const range of ranges) {
|
|
2822
2819
|
let sawBlock = false;
|
|
2823
|
-
syntaxTree2(
|
|
2820
|
+
syntaxTree2(state2).iterate({
|
|
2824
2821
|
from: range.from,
|
|
2825
2822
|
to: range.to,
|
|
2826
2823
|
enter: (node) => {
|
|
@@ -2873,7 +2870,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2873
2870
|
}
|
|
2874
2871
|
});
|
|
2875
2872
|
let line;
|
|
2876
|
-
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)) {
|
|
2877
2874
|
changes.push({
|
|
2878
2875
|
from: line.from,
|
|
2879
2876
|
to: line.to,
|
|
@@ -2884,23 +2881,23 @@ var setHeading = (level) => ({ state, dispatch }) => {
|
|
|
2884
2881
|
if (!changes.length) {
|
|
2885
2882
|
return false;
|
|
2886
2883
|
}
|
|
2887
|
-
const changeSet =
|
|
2888
|
-
dispatch(
|
|
2884
|
+
const changeSet = state2.changes(changes);
|
|
2885
|
+
dispatch(state2.update({
|
|
2889
2886
|
changes: changeSet,
|
|
2890
|
-
selection:
|
|
2887
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2891
2888
|
userEvent: "format.setHeading",
|
|
2892
2889
|
scrollIntoView: true
|
|
2893
2890
|
}));
|
|
2894
2891
|
return true;
|
|
2895
2892
|
};
|
|
2896
|
-
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
2893
|
+
var setStyle = (type, enable) => ({ state: state2, dispatch }) => {
|
|
2897
2894
|
const marker = inlineMarkerText(type);
|
|
2898
|
-
const changes =
|
|
2895
|
+
const changes = state2.changeByRange((range) => {
|
|
2899
2896
|
if (!enable && range.empty) {
|
|
2900
|
-
const after =
|
|
2897
|
+
const after = state2.doc.sliceString(range.head, range.head + 6);
|
|
2901
2898
|
const found = after.indexOf(marker);
|
|
2902
2899
|
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
2903
|
-
const before =
|
|
2900
|
+
const before = state2.doc.sliceString(range.head - 6, range.head);
|
|
2904
2901
|
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
2905
2902
|
...before.slice(before.length - found)
|
|
2906
2903
|
].reverse().join("") === after.slice(0, found)) {
|
|
@@ -2927,14 +2924,14 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2927
2924
|
let startCovered = false;
|
|
2928
2925
|
let endCovered = false;
|
|
2929
2926
|
let { from, to } = range;
|
|
2930
|
-
syntaxTree2(
|
|
2927
|
+
syntaxTree2(state2).iterate({
|
|
2931
2928
|
from,
|
|
2932
2929
|
to,
|
|
2933
2930
|
enter: (node) => {
|
|
2934
2931
|
const { name } = node;
|
|
2935
2932
|
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
2936
2933
|
blockStart = blockContentStart(node);
|
|
2937
|
-
blockEnd = blockContentEnd(node,
|
|
2934
|
+
blockEnd = blockContentEnd(node, state2.doc);
|
|
2938
2935
|
startCovered = endCovered = false;
|
|
2939
2936
|
} else if (name === "Link" || name === "Image" && enable) {
|
|
2940
2937
|
if (from < node.from && to > node.from && to <= node.to) {
|
|
@@ -2979,7 +2976,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2979
2976
|
});
|
|
2980
2977
|
if (markType !== type && closeStart >= to) {
|
|
2981
2978
|
changesAtEnd.push({
|
|
2982
|
-
from: skipSpaces(Math.min(to, blockEnd),
|
|
2979
|
+
from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
|
|
2983
2980
|
insert: inlineMarkerText(markType)
|
|
2984
2981
|
});
|
|
2985
2982
|
}
|
|
@@ -2991,7 +2988,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
2991
2988
|
});
|
|
2992
2989
|
if (markType !== type && openEnd <= from) {
|
|
2993
2990
|
changes2.push({
|
|
2994
|
-
from: skipSpaces(Math.max(from, blockStart),
|
|
2991
|
+
from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
|
|
2995
2992
|
insert: inlineMarkerText(markType)
|
|
2996
2993
|
});
|
|
2997
2994
|
}
|
|
@@ -3021,7 +3018,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3021
3018
|
changes2.push(startCovered);
|
|
3022
3019
|
} else if (startCovered) {
|
|
3023
3020
|
changes2.push({
|
|
3024
|
-
from: skipSpaces(rangeStart,
|
|
3021
|
+
from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
|
|
3025
3022
|
insert: marker
|
|
3026
3023
|
});
|
|
3027
3024
|
}
|
|
@@ -3029,7 +3026,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3029
3026
|
changes2.push(endCovered);
|
|
3030
3027
|
} else if (endCovered) {
|
|
3031
3028
|
changes2.push({
|
|
3032
|
-
from: skipSpaces(rangeEnd,
|
|
3029
|
+
from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
|
|
3033
3030
|
insert: marker
|
|
3034
3031
|
});
|
|
3035
3032
|
}
|
|
@@ -3037,7 +3034,7 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3037
3034
|
}
|
|
3038
3035
|
}
|
|
3039
3036
|
});
|
|
3040
|
-
if (blockStart < 0 && range.empty && enable && !/\S/.test(
|
|
3037
|
+
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
3041
3038
|
return {
|
|
3042
3039
|
changes: {
|
|
3043
3040
|
from: range.head,
|
|
@@ -3046,13 +3043,13 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
|
3046
3043
|
range: EditorSelection.cursor(range.head + marker.length)
|
|
3047
3044
|
};
|
|
3048
3045
|
}
|
|
3049
|
-
const changeSet =
|
|
3046
|
+
const changeSet = state2.changes(changes2.concat(changesAtEnd));
|
|
3050
3047
|
return {
|
|
3051
3048
|
changes: changeSet,
|
|
3052
3049
|
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
3053
3050
|
};
|
|
3054
3051
|
});
|
|
3055
|
-
dispatch(
|
|
3052
|
+
dispatch(state2.update(changes, {
|
|
3056
3053
|
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
3057
3054
|
scrollIntoView: true
|
|
3058
3055
|
}));
|
|
@@ -3126,8 +3123,8 @@ var insertTable = (view) => {
|
|
|
3126
3123
|
const { from } = doc.line(number);
|
|
3127
3124
|
snippets.table(view, null, from, from);
|
|
3128
3125
|
};
|
|
3129
|
-
var removeLinkInner = (from, to, changes,
|
|
3130
|
-
syntaxTree2(
|
|
3126
|
+
var removeLinkInner = (from, to, changes, state2) => {
|
|
3127
|
+
syntaxTree2(state2).iterate({
|
|
3131
3128
|
from,
|
|
3132
3129
|
to,
|
|
3133
3130
|
enter: (node) => {
|
|
@@ -3141,8 +3138,8 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3141
3138
|
});
|
|
3142
3139
|
} else if (name === "LinkTitle" || name === "URL") {
|
|
3143
3140
|
changes.push({
|
|
3144
|
-
from: skipSpaces(node2.from,
|
|
3145
|
-
to: skipSpaces(node2.to,
|
|
3141
|
+
from: skipSpaces(node2.from, state2.doc, -1),
|
|
3142
|
+
to: skipSpaces(node2.to, state2.doc, 1)
|
|
3146
3143
|
});
|
|
3147
3144
|
}
|
|
3148
3145
|
});
|
|
@@ -3151,32 +3148,32 @@ var removeLinkInner = (from, to, changes, state) => {
|
|
|
3151
3148
|
}
|
|
3152
3149
|
});
|
|
3153
3150
|
};
|
|
3154
|
-
var removeLink = ({ state, dispatch }) => {
|
|
3151
|
+
var removeLink = ({ state: state2, dispatch }) => {
|
|
3155
3152
|
const changes = [];
|
|
3156
|
-
for (const { from, to } of
|
|
3157
|
-
removeLinkInner(from, to, changes,
|
|
3153
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3154
|
+
removeLinkInner(from, to, changes, state2);
|
|
3158
3155
|
}
|
|
3159
3156
|
if (!changes) {
|
|
3160
3157
|
return false;
|
|
3161
3158
|
}
|
|
3162
|
-
dispatch(
|
|
3159
|
+
dispatch(state2.update({
|
|
3163
3160
|
changes,
|
|
3164
3161
|
userEvent: "format.link.remove",
|
|
3165
3162
|
scrollIntoView: true
|
|
3166
3163
|
}));
|
|
3167
3164
|
return true;
|
|
3168
3165
|
};
|
|
3169
|
-
var addLink = ({ state, dispatch }) => {
|
|
3170
|
-
const changes =
|
|
3166
|
+
var addLink = ({ state: state2, dispatch }) => {
|
|
3167
|
+
const changes = state2.changeByRange((range) => {
|
|
3171
3168
|
let { from, to } = range;
|
|
3172
3169
|
const cutStyles = [];
|
|
3173
3170
|
let okay = null;
|
|
3174
|
-
syntaxTree2(
|
|
3171
|
+
syntaxTree2(state2).iterate({
|
|
3175
3172
|
from,
|
|
3176
3173
|
to,
|
|
3177
3174
|
enter: (node) => {
|
|
3178
3175
|
if (Object.hasOwn(Textblocks, node.name)) {
|
|
3179
|
-
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);
|
|
3180
3177
|
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
3181
3178
|
const sNode = node.node;
|
|
3182
3179
|
if (node.from < from && node.to <= to) {
|
|
@@ -3196,7 +3193,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3196
3193
|
}
|
|
3197
3194
|
});
|
|
3198
3195
|
if (okay === null) {
|
|
3199
|
-
const line =
|
|
3196
|
+
const line = state2.doc.lineAt(from);
|
|
3200
3197
|
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
3201
3198
|
}
|
|
3202
3199
|
if (!okay) {
|
|
@@ -3206,26 +3203,26 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3206
3203
|
}
|
|
3207
3204
|
const changes2 = [];
|
|
3208
3205
|
const changesAfter = [];
|
|
3209
|
-
removeLinkInner(from, to, changesAfter,
|
|
3206
|
+
removeLinkInner(from, to, changesAfter, state2);
|
|
3210
3207
|
let cursorOffset = 1;
|
|
3211
3208
|
for (const style of cutStyles) {
|
|
3212
3209
|
const type = InlineMarker[style.name];
|
|
3213
3210
|
const mark2 = inlineMarkerText(type);
|
|
3214
3211
|
if (style.from < from) {
|
|
3215
3212
|
changes2.push({
|
|
3216
|
-
from: skipSpaces(from,
|
|
3213
|
+
from: skipSpaces(from, state2.doc, -1),
|
|
3217
3214
|
insert: mark2
|
|
3218
3215
|
});
|
|
3219
3216
|
changesAfter.push({
|
|
3220
|
-
from: skipSpaces(from,
|
|
3217
|
+
from: skipSpaces(from, state2.doc, 1, to),
|
|
3221
3218
|
insert: mark2
|
|
3222
3219
|
});
|
|
3223
3220
|
} else {
|
|
3224
3221
|
changes2.push({
|
|
3225
|
-
from: skipSpaces(to,
|
|
3222
|
+
from: skipSpaces(to, state2.doc, -1, from),
|
|
3226
3223
|
insert: mark2
|
|
3227
3224
|
});
|
|
3228
|
-
const after = skipSpaces(to,
|
|
3225
|
+
const after = skipSpaces(to, state2.doc, 1);
|
|
3229
3226
|
if (after === to) {
|
|
3230
3227
|
cursorOffset += mark2.length;
|
|
3231
3228
|
}
|
|
@@ -3242,7 +3239,7 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3242
3239
|
from: to,
|
|
3243
3240
|
insert: "]()"
|
|
3244
3241
|
});
|
|
3245
|
-
const changeSet =
|
|
3242
|
+
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
3246
3243
|
return {
|
|
3247
3244
|
changes: changeSet,
|
|
3248
3245
|
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
@@ -3251,20 +3248,20 @@ var addLink = ({ state, dispatch }) => {
|
|
|
3251
3248
|
if (changes.changes.empty) {
|
|
3252
3249
|
return false;
|
|
3253
3250
|
}
|
|
3254
|
-
dispatch(
|
|
3251
|
+
dispatch(state2.update(changes, {
|
|
3255
3252
|
userEvent: "format.link.add",
|
|
3256
3253
|
scrollIntoView: true
|
|
3257
3254
|
}));
|
|
3258
3255
|
return true;
|
|
3259
3256
|
};
|
|
3260
|
-
var addList = (type) => ({ state, dispatch }) => {
|
|
3257
|
+
var addList = (type) => ({ state: state2, dispatch }) => {
|
|
3261
3258
|
let lastBlock = -1;
|
|
3262
3259
|
let counter = 1;
|
|
3263
3260
|
let first = true;
|
|
3264
3261
|
let parentColumn = null;
|
|
3265
3262
|
const blocks = [];
|
|
3266
|
-
for (const { from, to } of
|
|
3267
|
-
syntaxTree2(
|
|
3263
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3264
|
+
syntaxTree2(state2).iterate({
|
|
3268
3265
|
from,
|
|
3269
3266
|
to,
|
|
3270
3267
|
enter: (node) => {
|
|
@@ -3276,7 +3273,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3276
3273
|
}
|
|
3277
3274
|
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
3278
3275
|
const item = before.lastChild;
|
|
3279
|
-
const itemLine =
|
|
3276
|
+
const itemLine = state2.doc.lineAt(item.from);
|
|
3280
3277
|
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
3281
3278
|
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
3282
3279
|
if (type === 0) {
|
|
@@ -3311,10 +3308,10 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3311
3308
|
});
|
|
3312
3309
|
}
|
|
3313
3310
|
if (!blocks.length) {
|
|
3314
|
-
const { from, to } =
|
|
3311
|
+
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
3315
3312
|
if (from === to) {
|
|
3316
3313
|
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
3317
|
-
dispatch(
|
|
3314
|
+
dispatch(state2.update({
|
|
3318
3315
|
changes: [
|
|
3319
3316
|
{
|
|
3320
3317
|
from,
|
|
@@ -3335,11 +3332,11 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3335
3332
|
for (let i = 0; i < blocks.length; i++) {
|
|
3336
3333
|
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
3337
3334
|
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
3338
|
-
let padding = nodeFrom > 0 && !/\s/.test(
|
|
3335
|
+
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
3339
3336
|
if (type === 0) {
|
|
3340
3337
|
padding += String(counter2).length;
|
|
3341
3338
|
}
|
|
3342
|
-
let line =
|
|
3339
|
+
let line = state2.doc.lineAt(nodeFrom);
|
|
3343
3340
|
const column = nodeFrom - line.from;
|
|
3344
3341
|
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
3345
3342
|
padding = Math.max(padding, parentColumn2 - column);
|
|
@@ -3364,7 +3361,7 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3364
3361
|
insert: mark2
|
|
3365
3362
|
});
|
|
3366
3363
|
while (line.to < node.to) {
|
|
3367
|
-
line =
|
|
3364
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3368
3365
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3369
3366
|
changes.push({
|
|
3370
3367
|
from: line.from + Math.min(open, column),
|
|
@@ -3379,25 +3376,25 @@ var addList = (type) => ({ state, dispatch }) => {
|
|
|
3379
3376
|
next = next.nextSibling;
|
|
3380
3377
|
}
|
|
3381
3378
|
if (next?.name === "OrderedList") {
|
|
3382
|
-
renumberListItems(next.firstChild, last.counter + 1, changes,
|
|
3379
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
3383
3380
|
}
|
|
3384
3381
|
}
|
|
3385
|
-
const changeSet =
|
|
3386
|
-
dispatch(
|
|
3382
|
+
const changeSet = state2.changes(changes);
|
|
3383
|
+
dispatch(state2.update({
|
|
3387
3384
|
changes: changeSet,
|
|
3388
|
-
selection:
|
|
3385
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3389
3386
|
userEvent: "format.list.add",
|
|
3390
3387
|
scrollIntoView: true
|
|
3391
3388
|
}));
|
|
3392
3389
|
return true;
|
|
3393
3390
|
};
|
|
3394
|
-
var removeList = (type) => ({ state, dispatch }) => {
|
|
3391
|
+
var removeList = (type) => ({ state: state2, dispatch }) => {
|
|
3395
3392
|
let lastBlock = -1;
|
|
3396
3393
|
const changes = [];
|
|
3397
3394
|
const stack = [];
|
|
3398
3395
|
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
3399
|
-
for (const { from, to } of
|
|
3400
|
-
syntaxTree2(
|
|
3396
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3397
|
+
syntaxTree2(state2).iterate({
|
|
3401
3398
|
from,
|
|
3402
3399
|
to,
|
|
3403
3400
|
enter: (node) => {
|
|
@@ -3414,7 +3411,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3414
3411
|
stack.pop();
|
|
3415
3412
|
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
3416
3413
|
lastBlock = node.from;
|
|
3417
|
-
let line =
|
|
3414
|
+
let line = state2.doc.lineAt(node.from);
|
|
3418
3415
|
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
3419
3416
|
if (!mark2) {
|
|
3420
3417
|
return false;
|
|
@@ -3425,7 +3422,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3425
3422
|
to: node.from + mark2[0].length
|
|
3426
3423
|
});
|
|
3427
3424
|
while (line.to < node.to) {
|
|
3428
|
-
line =
|
|
3425
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
3429
3426
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3430
3427
|
if (open > column) {
|
|
3431
3428
|
changes.push({
|
|
@@ -3435,7 +3432,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3435
3432
|
}
|
|
3436
3433
|
}
|
|
3437
3434
|
if (node.to >= to) {
|
|
3438
|
-
renumberListItems(node.node.nextSibling, 1, changes,
|
|
3435
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
3439
3436
|
}
|
|
3440
3437
|
return false;
|
|
3441
3438
|
}
|
|
@@ -3445,7 +3442,7 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3445
3442
|
if (!changes.length) {
|
|
3446
3443
|
return false;
|
|
3447
3444
|
}
|
|
3448
|
-
dispatch(
|
|
3445
|
+
dispatch(state2.update({
|
|
3449
3446
|
changes,
|
|
3450
3447
|
userEvent: "format.list.remove",
|
|
3451
3448
|
scrollIntoView: true
|
|
@@ -3475,12 +3472,12 @@ var renumberListItems = (item, counter, changes, doc) => {
|
|
|
3475
3472
|
}
|
|
3476
3473
|
}
|
|
3477
3474
|
};
|
|
3478
|
-
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
3475
|
+
var setBlockquote = (enable) => ({ state: state2, dispatch }) => {
|
|
3479
3476
|
const lines = [];
|
|
3480
3477
|
let lastBlock = -1;
|
|
3481
|
-
for (const { from, to } of
|
|
3478
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3482
3479
|
const sawBlock = false;
|
|
3483
|
-
syntaxTree2(
|
|
3480
|
+
syntaxTree2(state2).iterate({
|
|
3484
3481
|
from,
|
|
3485
3482
|
to,
|
|
3486
3483
|
enter: (node) => {
|
|
@@ -3489,9 +3486,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3489
3486
|
return false;
|
|
3490
3487
|
}
|
|
3491
3488
|
lastBlock = node.from;
|
|
3492
|
-
let line2 =
|
|
3489
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
3493
3490
|
if (line2.number > 1) {
|
|
3494
|
-
const prevLine =
|
|
3491
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
3495
3492
|
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
3496
3493
|
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
3497
3494
|
lines.push(prevLine);
|
|
@@ -3503,10 +3500,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3503
3500
|
if (line2.to >= node.to) {
|
|
3504
3501
|
break;
|
|
3505
3502
|
}
|
|
3506
|
-
line2 =
|
|
3503
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
3507
3504
|
}
|
|
3508
|
-
if (!enable && line2.number <
|
|
3509
|
-
const nextLine =
|
|
3505
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
3506
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
3510
3507
|
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
3511
3508
|
lines.push(nextLine);
|
|
3512
3509
|
}
|
|
@@ -3516,7 +3513,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3516
3513
|
}
|
|
3517
3514
|
});
|
|
3518
3515
|
let line;
|
|
3519
|
-
if (!sawBlock && enable && from === to && !/\S/.test((line =
|
|
3516
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3520
3517
|
lines.push(line);
|
|
3521
3518
|
}
|
|
3522
3519
|
}
|
|
@@ -3540,10 +3537,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
|
3540
3537
|
if (!changes.length) {
|
|
3541
3538
|
return false;
|
|
3542
3539
|
}
|
|
3543
|
-
const changeSet =
|
|
3544
|
-
dispatch(
|
|
3540
|
+
const changeSet = state2.changes(changes);
|
|
3541
|
+
dispatch(state2.update({
|
|
3545
3542
|
changes: changeSet,
|
|
3546
|
-
selection:
|
|
3543
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3547
3544
|
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3548
3545
|
scrollIntoView: true
|
|
3549
3546
|
}));
|
|
@@ -3555,11 +3552,11 @@ var toggleBlockquote = (target) => {
|
|
|
3555
3552
|
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3556
3553
|
};
|
|
3557
3554
|
var addCodeblock = (target) => {
|
|
3558
|
-
const { state, dispatch } = target;
|
|
3559
|
-
const { selection } =
|
|
3555
|
+
const { state: state2, dispatch } = target;
|
|
3556
|
+
const { selection } = state2;
|
|
3560
3557
|
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
3561
3558
|
const { head } = selection.main;
|
|
3562
|
-
const line =
|
|
3559
|
+
const line = state2.doc.lineAt(head);
|
|
3563
3560
|
if (!/\S/.test(line.text) && head === line.from) {
|
|
3564
3561
|
snippets.codeblock(target, null, line.from, line.to);
|
|
3565
3562
|
return true;
|
|
@@ -3569,7 +3566,7 @@ var addCodeblock = (target) => {
|
|
|
3569
3566
|
for (const { from, to } of selection.ranges) {
|
|
3570
3567
|
let blockFrom = from;
|
|
3571
3568
|
let blockTo = to;
|
|
3572
|
-
syntaxTree2(
|
|
3569
|
+
syntaxTree2(state2).iterate({
|
|
3573
3570
|
from,
|
|
3574
3571
|
to,
|
|
3575
3572
|
enter: (node) => {
|
|
@@ -3578,8 +3575,8 @@ var addCodeblock = (target) => {
|
|
|
3578
3575
|
blockFrom = node.from;
|
|
3579
3576
|
blockTo = node.to;
|
|
3580
3577
|
} else {
|
|
3581
|
-
blockFrom = Math.min(blockFrom,
|
|
3582
|
-
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);
|
|
3583
3580
|
}
|
|
3584
3581
|
}
|
|
3585
3582
|
}
|
|
@@ -3597,7 +3594,7 @@ var addCodeblock = (target) => {
|
|
|
3597
3594
|
return false;
|
|
3598
3595
|
}
|
|
3599
3596
|
const changes = ranges.map(({ from, to }) => {
|
|
3600
|
-
const column = from -
|
|
3597
|
+
const column = from - state2.doc.lineAt(from).from;
|
|
3601
3598
|
return [
|
|
3602
3599
|
{
|
|
3603
3600
|
from,
|
|
@@ -3609,30 +3606,30 @@ var addCodeblock = (target) => {
|
|
|
3609
3606
|
}
|
|
3610
3607
|
];
|
|
3611
3608
|
});
|
|
3612
|
-
dispatch(
|
|
3609
|
+
dispatch(state2.update({
|
|
3613
3610
|
changes,
|
|
3614
3611
|
userEvent: "format.codeblock.add",
|
|
3615
3612
|
scrollIntoView: true
|
|
3616
3613
|
}));
|
|
3617
3614
|
return true;
|
|
3618
3615
|
};
|
|
3619
|
-
var removeCodeblock = ({ state, dispatch }) => {
|
|
3616
|
+
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3620
3617
|
const changes = [];
|
|
3621
3618
|
let lastBlock = -1;
|
|
3622
|
-
for (const { from, to } of
|
|
3623
|
-
syntaxTree2(
|
|
3619
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
3620
|
+
syntaxTree2(state2).iterate({
|
|
3624
3621
|
from,
|
|
3625
3622
|
to,
|
|
3626
3623
|
enter: (node) => {
|
|
3627
3624
|
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
3628
3625
|
lastBlock = node.from;
|
|
3629
|
-
const firstLine =
|
|
3626
|
+
const firstLine = state2.doc.lineAt(node.from);
|
|
3630
3627
|
if (node.name === "FencedCode") {
|
|
3631
3628
|
changes.push({
|
|
3632
3629
|
from: node.from,
|
|
3633
3630
|
to: firstLine.to + 1 + node.from - firstLine.from
|
|
3634
3631
|
});
|
|
3635
|
-
const lastLine =
|
|
3632
|
+
const lastLine = state2.doc.lineAt(node.to);
|
|
3636
3633
|
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
3637
3634
|
changes.push({
|
|
3638
3635
|
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
@@ -3641,7 +3638,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3641
3638
|
}
|
|
3642
3639
|
} else {
|
|
3643
3640
|
const column = node.from - firstLine.from;
|
|
3644
|
-
for (let line = firstLine; ; line =
|
|
3641
|
+
for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
|
|
3645
3642
|
changes.push({
|
|
3646
3643
|
from: line.from + column - 4,
|
|
3647
3644
|
to: line.from + column
|
|
@@ -3658,7 +3655,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3658
3655
|
if (!changes.length) {
|
|
3659
3656
|
return false;
|
|
3660
3657
|
}
|
|
3661
|
-
dispatch(
|
|
3658
|
+
dispatch(state2.update({
|
|
3662
3659
|
changes,
|
|
3663
3660
|
userEvent: "format.codeblock.remove",
|
|
3664
3661
|
scrollIntoView: true
|
|
@@ -3717,7 +3714,7 @@ var Textblocks = {
|
|
|
3717
3714
|
TableCell: "tablecell",
|
|
3718
3715
|
Task: "paragraph"
|
|
3719
3716
|
};
|
|
3720
|
-
var getFormatting = (
|
|
3717
|
+
var getFormatting = (state2) => {
|
|
3721
3718
|
let blockType = null;
|
|
3722
3719
|
const inline = [
|
|
3723
3720
|
null,
|
|
@@ -3743,7 +3740,7 @@ var getFormatting = (state) => {
|
|
|
3743
3740
|
continue;
|
|
3744
3741
|
} else if (currentBlock.active[i]) {
|
|
3745
3742
|
inline[i] = true;
|
|
3746
|
-
} else if (/\S/.test(
|
|
3743
|
+
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3747
3744
|
inline[i] = false;
|
|
3748
3745
|
}
|
|
3749
3746
|
}
|
|
@@ -3754,12 +3751,12 @@ var getFormatting = (state) => {
|
|
|
3754
3751
|
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3755
3752
|
}
|
|
3756
3753
|
};
|
|
3757
|
-
const { selection } =
|
|
3754
|
+
const { selection } = state2;
|
|
3758
3755
|
for (const range of selection.ranges) {
|
|
3759
3756
|
if (range.empty && inline.some((v) => v === null)) {
|
|
3760
3757
|
const contextSize = Math.min(range.head, 6);
|
|
3761
|
-
const contextBefore =
|
|
3762
|
-
let contextAfter =
|
|
3758
|
+
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3759
|
+
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3763
3760
|
for (let i = 0; i < contextSize; i++) {
|
|
3764
3761
|
const ch = contextAfter[i];
|
|
3765
3762
|
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
@@ -3778,7 +3775,7 @@ var getFormatting = (state) => {
|
|
|
3778
3775
|
}
|
|
3779
3776
|
}
|
|
3780
3777
|
}
|
|
3781
|
-
syntaxTree2(
|
|
3778
|
+
syntaxTree2(state2).iterate({
|
|
3782
3779
|
from: range.from,
|
|
3783
3780
|
to: range.to,
|
|
3784
3781
|
enter: (node) => {
|
|
@@ -3852,7 +3849,7 @@ var getFormatting = (state) => {
|
|
|
3852
3849
|
}
|
|
3853
3850
|
});
|
|
3854
3851
|
}
|
|
3855
|
-
const { from, to } =
|
|
3852
|
+
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3856
3853
|
const blankLine = from === to;
|
|
3857
3854
|
return {
|
|
3858
3855
|
blankLine,
|
|
@@ -3867,17 +3864,17 @@ var getFormatting = (state) => {
|
|
|
3867
3864
|
};
|
|
3868
3865
|
};
|
|
3869
3866
|
var useFormattingState = () => {
|
|
3870
|
-
const [
|
|
3867
|
+
const [state2, setState] = useState(null);
|
|
3871
3868
|
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3872
3869
|
if (update2.docChanged || update2.selectionSet) {
|
|
3873
3870
|
const newState = getFormatting(update2.state);
|
|
3874
|
-
if (!
|
|
3871
|
+
if (!state2 || !compareFormatting(state2, newState)) {
|
|
3875
3872
|
setState(newState);
|
|
3876
3873
|
}
|
|
3877
3874
|
}
|
|
3878
3875
|
}), []);
|
|
3879
3876
|
return [
|
|
3880
|
-
|
|
3877
|
+
state2,
|
|
3881
3878
|
observer
|
|
3882
3879
|
];
|
|
3883
3880
|
};
|
|
@@ -3888,8 +3885,8 @@ import { StateField as StateField5 } from "@codemirror/state";
|
|
|
3888
3885
|
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3889
3886
|
var image = (options = {}) => {
|
|
3890
3887
|
return StateField5.define({
|
|
3891
|
-
create: (
|
|
3892
|
-
return Decoration6.set(buildDecorations2(0,
|
|
3888
|
+
create: (state2) => {
|
|
3889
|
+
return Decoration6.set(buildDecorations2(0, state2.doc.length, state2));
|
|
3893
3890
|
},
|
|
3894
3891
|
update: (value, tr) => {
|
|
3895
3892
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3923,16 +3920,16 @@ var preloadImage = (url) => {
|
|
|
3923
3920
|
preloaded.add(url);
|
|
3924
3921
|
}
|
|
3925
3922
|
};
|
|
3926
|
-
var buildDecorations2 = (from, to,
|
|
3923
|
+
var buildDecorations2 = (from, to, state2) => {
|
|
3927
3924
|
const decorations = [];
|
|
3928
|
-
const cursor =
|
|
3929
|
-
syntaxTree3(
|
|
3925
|
+
const cursor = state2.selection.main.head;
|
|
3926
|
+
syntaxTree3(state2).iterate({
|
|
3930
3927
|
enter: (node) => {
|
|
3931
3928
|
if (node.name === "Image") {
|
|
3932
3929
|
const urlNode = node.node.getChild("URL");
|
|
3933
3930
|
if (urlNode) {
|
|
3934
|
-
const hide2 =
|
|
3935
|
-
const url =
|
|
3931
|
+
const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
|
|
3932
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3936
3933
|
preloadImage(url);
|
|
3937
3934
|
decorations.push(Decoration6.replace({
|
|
3938
3935
|
block: true,
|
|
@@ -4003,21 +4000,21 @@ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "
|
|
|
4003
4000
|
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4004
4001
|
var table = (options = {}) => {
|
|
4005
4002
|
return StateField6.define({
|
|
4006
|
-
create: (
|
|
4003
|
+
create: (state2) => update(state2, options),
|
|
4007
4004
|
update: (_, tr) => update(tr.state, options),
|
|
4008
4005
|
provide: (field) => EditorView15.decorations.from(field)
|
|
4009
4006
|
});
|
|
4010
4007
|
};
|
|
4011
|
-
var update = (
|
|
4008
|
+
var update = (state2, options) => {
|
|
4012
4009
|
const builder = new RangeSetBuilder3();
|
|
4013
|
-
const cursor =
|
|
4010
|
+
const cursor = state2.selection.main.head;
|
|
4014
4011
|
const tables = [];
|
|
4015
4012
|
const getTable = () => tables[tables.length - 1];
|
|
4016
4013
|
const getRow = () => {
|
|
4017
4014
|
const table2 = getTable();
|
|
4018
4015
|
return table2.rows?.[table2.rows.length - 1];
|
|
4019
4016
|
};
|
|
4020
|
-
syntaxTree5(
|
|
4017
|
+
syntaxTree5(state2).iterate({
|
|
4021
4018
|
enter: (node) => {
|
|
4022
4019
|
switch (node.name) {
|
|
4023
4020
|
case "Table": {
|
|
@@ -4038,9 +4035,9 @@ var update = (state, options) => {
|
|
|
4038
4035
|
case "TableCell": {
|
|
4039
4036
|
const row = getRow();
|
|
4040
4037
|
if (row) {
|
|
4041
|
-
row.push(
|
|
4038
|
+
row.push(state2.sliceDoc(node.from, node.to));
|
|
4042
4039
|
} else {
|
|
4043
|
-
getTable().header?.push(
|
|
4040
|
+
getTable().header?.push(state2.sliceDoc(node.from, node.to));
|
|
4044
4041
|
}
|
|
4045
4042
|
break;
|
|
4046
4043
|
}
|
|
@@ -4048,7 +4045,7 @@ var update = (state, options) => {
|
|
|
4048
4045
|
}
|
|
4049
4046
|
});
|
|
4050
4047
|
tables.forEach((table2) => {
|
|
4051
|
-
const hide2 =
|
|
4048
|
+
const hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4052
4049
|
if (hide2) {
|
|
4053
4050
|
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
4054
4051
|
widget: new TableWidget(table2)
|
|
@@ -4139,6 +4136,7 @@ var mention = ({ onSearch }) => {
|
|
|
4139
4136
|
import { Facet as Facet6 } from "@codemirror/state";
|
|
4140
4137
|
import { keymap as keymap7 } from "@codemirror/view";
|
|
4141
4138
|
import { vim } from "@replit/codemirror-vim";
|
|
4139
|
+
var focusEvent = "focus.container";
|
|
4142
4140
|
var editorMode = Facet6.define({
|
|
4143
4141
|
combine: (modes) => modes[0] ?? {}
|
|
4144
4142
|
});
|
|
@@ -4155,7 +4153,7 @@ var EditorModes = {
|
|
|
4155
4153
|
key: "Alt-Escape",
|
|
4156
4154
|
run: (view) => {
|
|
4157
4155
|
view.dispatch({
|
|
4158
|
-
userEvent:
|
|
4156
|
+
userEvent: focusEvent
|
|
4159
4157
|
});
|
|
4160
4158
|
return true;
|
|
4161
4159
|
}
|
|
@@ -4164,8 +4162,95 @@ var EditorModes = {
|
|
|
4164
4162
|
]
|
|
4165
4163
|
};
|
|
4166
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
|
+
|
|
4167
4252
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4168
|
-
import { keymap as
|
|
4253
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
|
4169
4254
|
var defaultItems = [
|
|
4170
4255
|
"hello world!",
|
|
4171
4256
|
"this is a test.",
|
|
@@ -4175,7 +4260,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4175
4260
|
let t;
|
|
4176
4261
|
let idx = 0;
|
|
4177
4262
|
return [
|
|
4178
|
-
|
|
4263
|
+
keymap9.of([
|
|
4179
4264
|
{
|
|
4180
4265
|
// Reset.
|
|
4181
4266
|
key: "alt-meta-'",
|
|
@@ -4222,9 +4307,11 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4222
4307
|
};
|
|
4223
4308
|
|
|
4224
4309
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4225
|
-
var
|
|
4310
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4226
4311
|
var instanceCount = 0;
|
|
4227
|
-
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) => {
|
|
4228
4315
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
4229
4316
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
4230
4317
|
tabBehavior: "limited"
|
|
@@ -4247,38 +4334,38 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4247
4334
|
id,
|
|
4248
4335
|
instanceId
|
|
4249
4336
|
}, {
|
|
4250
|
-
F:
|
|
4337
|
+
F: __dxlog_file12,
|
|
4251
4338
|
L: 88,
|
|
4252
4339
|
S: void 0,
|
|
4253
4340
|
C: (f, a) => f(...a)
|
|
4254
4341
|
});
|
|
4255
|
-
const
|
|
4342
|
+
const state2 = EditorState2.create({
|
|
4256
4343
|
doc,
|
|
4257
4344
|
selection,
|
|
4258
4345
|
extensions: [
|
|
4259
4346
|
id && documentId2.of(id),
|
|
4260
4347
|
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4261
|
-
|
|
4348
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4262
4349
|
log9.catch(err, void 0, {
|
|
4263
|
-
F:
|
|
4350
|
+
F: __dxlog_file12,
|
|
4264
4351
|
L: 101,
|
|
4265
4352
|
S: void 0,
|
|
4266
4353
|
C: (f, a) => f(...a)
|
|
4267
4354
|
});
|
|
4268
4355
|
}),
|
|
4269
4356
|
// Focus.
|
|
4270
|
-
|
|
4357
|
+
EditorView17.updateListener.of((update2) => {
|
|
4271
4358
|
update2.transactions.forEach((transaction) => {
|
|
4272
|
-
if (transaction.isUserEvent(
|
|
4359
|
+
if (transaction.isUserEvent(focusEvent)) {
|
|
4273
4360
|
rootRef.current?.focus();
|
|
4274
4361
|
}
|
|
4275
4362
|
});
|
|
4276
4363
|
}),
|
|
4277
4364
|
extensions
|
|
4278
|
-
].filter(
|
|
4365
|
+
].filter(isNotFalsy4)
|
|
4279
4366
|
});
|
|
4280
|
-
const view2 = new
|
|
4281
|
-
state,
|
|
4367
|
+
const view2 = new EditorView17({
|
|
4368
|
+
state: state2,
|
|
4282
4369
|
parent: rootRef.current,
|
|
4283
4370
|
scrollTo,
|
|
4284
4371
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
@@ -4290,18 +4377,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4290
4377
|
view3.update(trs);
|
|
4291
4378
|
}
|
|
4292
4379
|
});
|
|
4293
|
-
|
|
4294
|
-
if (moveToEndOfLine) {
|
|
4380
|
+
if (moveToEndOfLine && !(scrollTo || selection)) {
|
|
4295
4381
|
const { to } = view2.state.doc.lineAt(0);
|
|
4296
|
-
view2
|
|
4382
|
+
view2.dispatch({
|
|
4297
4383
|
selection: {
|
|
4298
4384
|
anchor: to
|
|
4299
4385
|
}
|
|
4300
4386
|
});
|
|
4301
4387
|
}
|
|
4302
|
-
if (
|
|
4388
|
+
if (state2.facet(editorMode).noTabster) {
|
|
4303
4389
|
rootRef.current?.removeAttribute("data-tabster");
|
|
4304
4390
|
}
|
|
4391
|
+
setView(view2);
|
|
4305
4392
|
return () => {
|
|
4306
4393
|
view2?.destroy();
|
|
4307
4394
|
setView(null);
|
|
@@ -4353,10 +4440,10 @@ var HeadingIcons = {
|
|
|
4353
4440
|
"6": TextHSix
|
|
4354
4441
|
};
|
|
4355
4442
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4356
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
4443
|
+
var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
4357
4444
|
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
4358
4445
|
onAction,
|
|
4359
|
-
state
|
|
4446
|
+
state: state2
|
|
4360
4447
|
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
4361
4448
|
density: "fine"
|
|
4362
4449
|
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
@@ -4389,8 +4476,8 @@ var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
4389
4476
|
});
|
|
4390
4477
|
var MarkdownHeading = () => {
|
|
4391
4478
|
const { t } = useTranslation(translationKey);
|
|
4392
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
4393
|
-
const blockType =
|
|
4479
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
|
|
4480
|
+
const blockType = state2 ? state2.blockType : "paragraph";
|
|
4394
4481
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4395
4482
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4396
4483
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
@@ -4464,43 +4551,43 @@ var markdownStyles = [
|
|
|
4464
4551
|
{
|
|
4465
4552
|
type: "strong",
|
|
4466
4553
|
Icon: TextB,
|
|
4467
|
-
getState: (
|
|
4554
|
+
getState: (state2) => state2.strong
|
|
4468
4555
|
},
|
|
4469
4556
|
{
|
|
4470
4557
|
type: "emphasis",
|
|
4471
4558
|
Icon: TextItalic,
|
|
4472
|
-
getState: (
|
|
4559
|
+
getState: (state2) => state2.emphasis
|
|
4473
4560
|
},
|
|
4474
4561
|
{
|
|
4475
4562
|
type: "strikethrough",
|
|
4476
4563
|
Icon: TextStrikethrough,
|
|
4477
|
-
getState: (
|
|
4564
|
+
getState: (state2) => state2.strikethrough
|
|
4478
4565
|
},
|
|
4479
4566
|
{
|
|
4480
4567
|
type: "code",
|
|
4481
4568
|
Icon: Code,
|
|
4482
|
-
getState: (
|
|
4569
|
+
getState: (state2) => state2.code
|
|
4483
4570
|
},
|
|
4484
4571
|
{
|
|
4485
4572
|
type: "link",
|
|
4486
4573
|
Icon: Link,
|
|
4487
|
-
getState: (
|
|
4574
|
+
getState: (state2) => state2.link
|
|
4488
4575
|
}
|
|
4489
4576
|
];
|
|
4490
4577
|
var MarkdownStyles = () => {
|
|
4491
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4578
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4492
4579
|
const { t } = useTranslation(translationKey);
|
|
4493
4580
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4494
4581
|
type: "multiple",
|
|
4495
|
-
value: markdownStyles.filter(({ getState }) =>
|
|
4582
|
+
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
4496
4583
|
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4497
4584
|
key: type,
|
|
4498
4585
|
value: type,
|
|
4499
4586
|
Icon,
|
|
4500
|
-
disabled:
|
|
4501
|
-
onClick:
|
|
4587
|
+
disabled: state2?.blockType === "codeblock",
|
|
4588
|
+
onClick: state2 ? () => onAction?.({
|
|
4502
4589
|
type,
|
|
4503
|
-
data: !getState(
|
|
4590
|
+
data: !getState(state2)
|
|
4504
4591
|
}) : void 0
|
|
4505
4592
|
}, t(`${type} label`))));
|
|
4506
4593
|
};
|
|
@@ -4508,32 +4595,32 @@ var markdownLists = [
|
|
|
4508
4595
|
{
|
|
4509
4596
|
type: "list-bullet",
|
|
4510
4597
|
Icon: ListBullets,
|
|
4511
|
-
getState: (
|
|
4598
|
+
getState: (state2) => state2.listStyle === "bullet"
|
|
4512
4599
|
},
|
|
4513
4600
|
{
|
|
4514
4601
|
type: "list-ordered",
|
|
4515
4602
|
Icon: ListNumbers,
|
|
4516
|
-
getState: (
|
|
4603
|
+
getState: (state2) => state2.listStyle === "ordered"
|
|
4517
4604
|
},
|
|
4518
4605
|
{
|
|
4519
4606
|
type: "list-task",
|
|
4520
4607
|
Icon: ListChecks,
|
|
4521
|
-
getState: (
|
|
4608
|
+
getState: (state2) => state2.listStyle === "task"
|
|
4522
4609
|
}
|
|
4523
4610
|
];
|
|
4524
4611
|
var MarkdownLists = () => {
|
|
4525
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4612
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4526
4613
|
const { t } = useTranslation(translationKey);
|
|
4527
4614
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4528
4615
|
type: "single",
|
|
4529
|
-
value:
|
|
4616
|
+
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
4530
4617
|
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4531
4618
|
key: type,
|
|
4532
4619
|
value: type,
|
|
4533
4620
|
Icon,
|
|
4534
|
-
onClick:
|
|
4621
|
+
onClick: state2 ? () => onAction?.({
|
|
4535
4622
|
type,
|
|
4536
|
-
data: !getState(
|
|
4623
|
+
data: !getState(state2)
|
|
4537
4624
|
}) : void 0
|
|
4538
4625
|
}, t(`${type} label`))));
|
|
4539
4626
|
};
|
|
@@ -4541,24 +4628,24 @@ var markdownBlocks = [
|
|
|
4541
4628
|
{
|
|
4542
4629
|
type: "blockquote",
|
|
4543
4630
|
Icon: Quotes,
|
|
4544
|
-
getState: (
|
|
4631
|
+
getState: (state2) => state2.blockQuote
|
|
4545
4632
|
},
|
|
4546
4633
|
{
|
|
4547
4634
|
type: "codeblock",
|
|
4548
4635
|
Icon: CodeBlock,
|
|
4549
|
-
getState: (
|
|
4636
|
+
getState: (state2) => state2.blockType === "codeblock"
|
|
4550
4637
|
},
|
|
4551
4638
|
{
|
|
4552
4639
|
type: "table",
|
|
4553
4640
|
Icon: Table2,
|
|
4554
|
-
getState: (
|
|
4555
|
-
disabled: (
|
|
4641
|
+
getState: (state2) => state2.blockType === "tablecell",
|
|
4642
|
+
disabled: (state2) => !state2.blankLine
|
|
4556
4643
|
}
|
|
4557
4644
|
];
|
|
4558
4645
|
var MarkdownBlocks = () => {
|
|
4559
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4646
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4560
4647
|
const { t } = useTranslation(translationKey);
|
|
4561
|
-
const value = markdownBlocks.find(({ getState }) =>
|
|
4648
|
+
const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
|
|
4562
4649
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4563
4650
|
type: "single",
|
|
4564
4651
|
value: value?.type ?? ""
|
|
@@ -4566,10 +4653,10 @@ var MarkdownBlocks = () => {
|
|
|
4566
4653
|
key: type,
|
|
4567
4654
|
value: type,
|
|
4568
4655
|
Icon,
|
|
4569
|
-
disabled: !
|
|
4570
|
-
onClick:
|
|
4656
|
+
disabled: !state2 || disabled?.(state2),
|
|
4657
|
+
onClick: state2 ? () => onAction?.({
|
|
4571
4658
|
type,
|
|
4572
|
-
data: !getState(
|
|
4659
|
+
data: !getState(state2)
|
|
4573
4660
|
}) : void 0
|
|
4574
4661
|
}, t(`${type} label`))));
|
|
4575
4662
|
};
|
|
@@ -4663,11 +4750,11 @@ var useDocAccessor = (text) => {
|
|
|
4663
4750
|
|
|
4664
4751
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4665
4752
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4666
|
-
import { EditorView as
|
|
4753
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
4667
4754
|
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4668
4755
|
import { log as log10 } from "@dxos/log";
|
|
4669
|
-
import { isNotFalsy as
|
|
4670
|
-
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";
|
|
4671
4758
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4672
4759
|
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4673
4760
|
const onUpdate = useRef3();
|
|
@@ -4676,30 +4763,30 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
4676
4763
|
useEffect3(() => {
|
|
4677
4764
|
let view2;
|
|
4678
4765
|
if (parentRef.current) {
|
|
4679
|
-
const
|
|
4766
|
+
const state2 = EditorState3.create({
|
|
4680
4767
|
doc,
|
|
4681
4768
|
selection,
|
|
4682
4769
|
extensions: [
|
|
4683
4770
|
id && documentId2.of(id),
|
|
4684
4771
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4685
|
-
|
|
4772
|
+
EditorView18.exceptionSink.of((err) => {
|
|
4686
4773
|
log10.catch(err, void 0, {
|
|
4687
|
-
F:
|
|
4774
|
+
F: __dxlog_file13,
|
|
4688
4775
|
L: 44,
|
|
4689
4776
|
S: void 0,
|
|
4690
4777
|
C: (f, a) => f(...a)
|
|
4691
4778
|
});
|
|
4692
4779
|
}),
|
|
4693
4780
|
extensions,
|
|
4694
|
-
|
|
4781
|
+
EditorView18.updateListener.of(() => {
|
|
4695
4782
|
onUpdate.current?.();
|
|
4696
4783
|
})
|
|
4697
|
-
].filter(
|
|
4784
|
+
].filter(isNotFalsy5)
|
|
4698
4785
|
});
|
|
4699
|
-
view2 = new
|
|
4786
|
+
view2 = new EditorView18({
|
|
4700
4787
|
parent: parentRef.current,
|
|
4701
4788
|
scrollTo,
|
|
4702
|
-
state,
|
|
4789
|
+
state: state2,
|
|
4703
4790
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4704
4791
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4705
4792
|
dispatchTransactions: (trs, view3) => {
|
|
@@ -4791,14 +4878,16 @@ export {
|
|
|
4791
4878
|
editorMode,
|
|
4792
4879
|
editorWithToolbarLayout,
|
|
4793
4880
|
focusComment,
|
|
4881
|
+
focusEvent,
|
|
4794
4882
|
formattingKeymap,
|
|
4795
4883
|
getFormatting,
|
|
4796
4884
|
getToken,
|
|
4797
4885
|
image,
|
|
4798
4886
|
insertTable,
|
|
4799
|
-
|
|
4887
|
+
keymap10 as keymap,
|
|
4800
4888
|
linkTooltip,
|
|
4801
4889
|
listener,
|
|
4890
|
+
localStorageStateStoreAdapter,
|
|
4802
4891
|
logChanges,
|
|
4803
4892
|
markdownHighlightStyle,
|
|
4804
4893
|
markdownTags,
|
|
@@ -4814,6 +4903,7 @@ export {
|
|
|
4814
4903
|
setHeading,
|
|
4815
4904
|
setSelection,
|
|
4816
4905
|
setStyle,
|
|
4906
|
+
state,
|
|
4817
4907
|
table,
|
|
4818
4908
|
tags2 as tags,
|
|
4819
4909
|
toggleBlockquote,
|