@dxos/react-ui-editor 0.4.7-main.733903e → 0.4.7-main.76c1dea
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 +997 -728
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +9 -0
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +0 -9
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/index.d.ts +0 -2
- package/dist/types/src/components/TextEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → extensions/automerge}/automerge.stories.d.ts +5 -2
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -0
- package/dist/types/src/extensions/command/command.d.ts +10 -0
- package/dist/types/src/extensions/command/command.d.ts.map +1 -0
- package/dist/types/src/extensions/command/hint.d.ts +7 -0
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -0
- package/dist/types/src/extensions/command/index.d.ts +2 -0
- package/dist/types/src/extensions/command/index.d.ts.map +1 -0
- package/dist/types/src/extensions/command/state.d.ts +18 -0
- package/dist/types/src/extensions/command/state.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor-line-margin.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts +3 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +4 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/util/dom.d.ts +15 -0
- package/dist/types/src/extensions/util/dom.d.ts.map +1 -0
- package/dist/types/src/hooks/defs.d.ts +5 -11
- package/dist/types/src/hooks/defs.d.ts.map +1 -1
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +20 -5
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor/hooks.stories.d.ts → hooks/useTextEditor.stories.d.ts} +2 -3
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/index.d.ts +0 -1
- package/dist/types/src/styles/index.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +31 -31
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +95 -8
- package/src/components/TextEditor/TextEditor.stories.tsx +0 -15
- package/src/components/TextEditor/TextEditor.tsx +13 -6
- package/src/components/TextEditor/index.ts +0 -3
- package/src/components/Toolbar/Toolbar.stories.tsx +2 -1
- package/src/{components/TextEditor → extensions/automerge}/automerge.stories.tsx +32 -37
- package/src/extensions/awareness.ts +3 -3
- package/src/extensions/command/command.ts +35 -0
- package/src/extensions/command/hint.ts +76 -0
- package/src/extensions/command/index.ts +5 -0
- package/src/extensions/command/state.ts +106 -0
- package/src/extensions/comments.ts +2 -1
- package/src/extensions/cursor-line-margin.ts +5 -2
- package/src/extensions/dnd.ts +17 -0
- package/src/extensions/index.ts +2 -1
- package/src/extensions/listener.ts +3 -3
- package/src/extensions/markdown/bundle.ts +4 -15
- package/src/extensions/markdown/decorate.ts +76 -32
- package/src/extensions/mention.ts +3 -1
- package/src/extensions/util/dom.ts +36 -0
- package/src/hooks/defs.ts +6 -20
- package/src/hooks/useActionHandler.ts +11 -11
- package/src/hooks/useEditorView.ts +0 -1
- package/src/{components/TextEditor/hooks.stories.tsx → hooks/useTextEditor.stories.tsx} +8 -8
- package/src/hooks/useTextEditor.ts +69 -14
- package/src/hooks/useTextModel.ts +20 -18
- package/src/index.ts +2 -0
- package/src/styles/index.ts +0 -1
- package/src/themes/default.ts +1 -0
- package/src/util.ts +1 -1
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/basic.d.ts +0 -9
- package/dist/types/src/extensions/basic.d.ts.map +0 -1
- package/dist/types/src/styles/cursors.d.ts +0 -5
- package/dist/types/src/styles/cursors.d.ts.map +0 -1
- package/src/extensions/basic.ts +0 -41
- package/src/styles/cursors.ts +0 -21
|
@@ -23,20 +23,19 @@ 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 keymap9 } from "@codemirror/view";
|
|
27
|
+
import { tags as tags2 } from "@lezer/highlight";
|
|
27
28
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
28
29
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
29
30
|
|
|
30
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/index.ts
|
|
31
|
-
import { tags as tags2 } from "@lezer/highlight";
|
|
32
|
-
|
|
33
31
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
34
|
-
import { EditorState as
|
|
35
|
-
import { EditorView as
|
|
32
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
|
33
|
+
import { EditorView as EditorView17, scrollPastEnd as scrollPastEnd2 } from "@codemirror/view";
|
|
36
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
37
|
-
import
|
|
38
|
-
import React, { forwardRef, useCallback, useEffect as
|
|
39
|
-
import {
|
|
35
|
+
import defaultsDeep3 from "lodash.defaultsdeep";
|
|
36
|
+
import React, { forwardRef, useCallback, useEffect as useEffect3, useImperativeHandle, useRef as useRef3, useState as useState5, useMemo as useMemo3 } from "react";
|
|
37
|
+
import { DocAccessor } from "@dxos/echo-schema";
|
|
38
|
+
import { log as log9 } from "@dxos/log";
|
|
40
39
|
import { useThemeContext } from "@dxos/react-ui";
|
|
41
40
|
import { focusRing } from "@dxos/react-ui-theme";
|
|
42
41
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
@@ -596,7 +595,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
596
595
|
to: startLine.from + startLine.length,
|
|
597
596
|
value: Decoration2.mark({
|
|
598
597
|
attributes: {
|
|
599
|
-
style: `background-color: ${
|
|
598
|
+
style: `background-color: ${lightColor}`
|
|
600
599
|
},
|
|
601
600
|
class: "cm-collab-selection"
|
|
602
601
|
})
|
|
@@ -606,7 +605,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
606
605
|
to: end,
|
|
607
606
|
value: Decoration2.mark({
|
|
608
607
|
attributes: {
|
|
609
|
-
style: `background-color: ${
|
|
608
|
+
style: `background-color: ${lightColor}`
|
|
610
609
|
},
|
|
611
610
|
class: "cm-collab-selection"
|
|
612
611
|
})
|
|
@@ -618,7 +617,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
618
617
|
to: linePos,
|
|
619
618
|
value: Decoration2.line({
|
|
620
619
|
attributes: {
|
|
621
|
-
style: `background-color: ${
|
|
620
|
+
style: `background-color: ${lightColor}`,
|
|
622
621
|
class: "cm-collab-selectionLine"
|
|
623
622
|
}
|
|
624
623
|
})
|
|
@@ -733,28 +732,8 @@ var styles2 = EditorView3.baseTheme({
|
|
|
733
732
|
}
|
|
734
733
|
});
|
|
735
734
|
|
|
736
|
-
// packages/ui/react-ui-editor/src/extensions/basic.ts
|
|
737
|
-
import { closeBrackets } from "@codemirror/autocomplete";
|
|
738
|
-
import { history } from "@codemirror/commands";
|
|
739
|
-
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
740
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
741
|
-
import { drawSelection, EditorView as EditorView4, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
742
|
-
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
743
|
-
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true, bracketMatching: _bracketMatching = true } = {}) => [
|
|
744
|
-
lineWrapping && EditorView4.lineWrapping,
|
|
745
|
-
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
746
|
-
_bracketMatching && bracketMatching(),
|
|
747
|
-
closeBrackets(),
|
|
748
|
-
drawSelection(),
|
|
749
|
-
highlightActiveLine(),
|
|
750
|
-
history(),
|
|
751
|
-
_placeholder && placeholder(_placeholder),
|
|
752
|
-
// https://github.com/codemirror/theme-one-dark
|
|
753
|
-
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
754
|
-
].filter(isNotFalsy2);
|
|
755
|
-
|
|
756
735
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
757
|
-
import { EditorView as
|
|
736
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
758
737
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
759
738
|
import { invariant } from "@dxos/invariant";
|
|
760
739
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
@@ -802,7 +781,7 @@ var blast = (options = defaultOptions) => {
|
|
|
802
781
|
};
|
|
803
782
|
return [
|
|
804
783
|
// Cursor moved.
|
|
805
|
-
|
|
784
|
+
EditorView4.updateListener.of((update2) => {
|
|
806
785
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
807
786
|
if (blaster) {
|
|
808
787
|
blaster.destroy();
|
|
@@ -1063,52 +1042,232 @@ var random = (min, max) => {
|
|
|
1063
1042
|
return min + ~~(Math.random() * (max - min + 1));
|
|
1064
1043
|
};
|
|
1065
1044
|
|
|
1066
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1067
|
-
import {
|
|
1068
|
-
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
|
1069
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
|
|
1070
|
-
import sortBy from "lodash.sortby";
|
|
1071
|
-
import { useEffect } from "react";
|
|
1072
|
-
import { debounce } from "@dxos/async";
|
|
1073
|
-
import { nonNullable } from "@dxos/util";
|
|
1045
|
+
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1046
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1074
1047
|
|
|
1075
|
-
// packages/ui/react-ui-editor/src/
|
|
1076
|
-
import
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
{
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1048
|
+
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
|
1049
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
1050
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1051
|
+
|
|
1052
|
+
// packages/ui/react-ui-editor/src/extensions/command/state.ts
|
|
1053
|
+
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
|
1054
|
+
import { showTooltip } from "@codemirror/view";
|
|
1055
|
+
var commandConfig = Facet3.define({
|
|
1056
|
+
combine: (providers) => providers[0]
|
|
1057
|
+
});
|
|
1058
|
+
var commandState = StateField3.define({
|
|
1059
|
+
create: () => ({}),
|
|
1060
|
+
update: (state, tr) => {
|
|
1061
|
+
for (const effect of tr.effects) {
|
|
1062
|
+
if (effect.is(closeEffect)) {
|
|
1063
|
+
return {};
|
|
1064
|
+
}
|
|
1065
|
+
if (effect.is(openEffect)) {
|
|
1066
|
+
const options = tr.state.facet(commandConfig);
|
|
1067
|
+
const { pos, fullWidth } = effect.value;
|
|
1068
|
+
const tooltip = {
|
|
1069
|
+
pos,
|
|
1070
|
+
above: false,
|
|
1071
|
+
arrow: false,
|
|
1072
|
+
strictSide: true,
|
|
1073
|
+
create: (view) => {
|
|
1074
|
+
const dom = document.createElement("div");
|
|
1075
|
+
const tooltipView = {
|
|
1076
|
+
dom,
|
|
1077
|
+
mount: (view2) => {
|
|
1078
|
+
if (fullWidth) {
|
|
1079
|
+
const parent = dom.parentElement;
|
|
1080
|
+
const { paddingLeft, paddingRight } = window.getComputedStyle(parent);
|
|
1081
|
+
const widthWithoutPadding = parent.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
|
|
1082
|
+
dom.style.width = `${widthWithoutPadding}px`;
|
|
1083
|
+
}
|
|
1084
|
+
options.onRender(dom, (action) => {
|
|
1085
|
+
view2.dispatch({
|
|
1086
|
+
effects: closeEffect.of(null)
|
|
1087
|
+
});
|
|
1088
|
+
if (action?.insert?.length) {
|
|
1089
|
+
view2.dispatch({
|
|
1090
|
+
changes: {
|
|
1091
|
+
from: pos,
|
|
1092
|
+
insert: action.insert
|
|
1093
|
+
},
|
|
1094
|
+
selection: {
|
|
1095
|
+
anchor: pos + action.insert.length
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
setTimeout(() => view2.focus());
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
return tooltipView;
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
return {
|
|
1107
|
+
tooltip
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return state;
|
|
1101
1112
|
},
|
|
1113
|
+
provide: (f) => [
|
|
1114
|
+
showTooltip.from(f, (value) => value.tooltip ?? null)
|
|
1115
|
+
]
|
|
1116
|
+
});
|
|
1117
|
+
var openEffect = StateEffect2.define();
|
|
1118
|
+
var closeEffect = StateEffect2.define();
|
|
1119
|
+
var openCommand = (view) => {
|
|
1120
|
+
if (view.state.field(commandState, false)) {
|
|
1121
|
+
const selection = view.state.selection.main;
|
|
1122
|
+
const line = view.state.doc.lineAt(selection.from);
|
|
1123
|
+
if (line.from === selection.from && line.from === line.to) {
|
|
1124
|
+
view.dispatch({
|
|
1125
|
+
effects: openEffect.of({
|
|
1126
|
+
pos: selection.anchor,
|
|
1127
|
+
fullWidth: true
|
|
1128
|
+
})
|
|
1129
|
+
});
|
|
1130
|
+
return true;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
return false;
|
|
1134
|
+
};
|
|
1135
|
+
var closeCommand = (view) => {
|
|
1136
|
+
if (view.state.field(commandState, false)) {
|
|
1137
|
+
view.dispatch({
|
|
1138
|
+
effects: closeEffect.of(null)
|
|
1139
|
+
});
|
|
1140
|
+
return true;
|
|
1141
|
+
}
|
|
1142
|
+
return false;
|
|
1143
|
+
};
|
|
1144
|
+
var commandKeyBindings = [
|
|
1102
1145
|
{
|
|
1103
|
-
|
|
1104
|
-
|
|
1146
|
+
key: "/",
|
|
1147
|
+
run: openCommand
|
|
1105
1148
|
},
|
|
1106
1149
|
{
|
|
1107
|
-
|
|
1108
|
-
|
|
1150
|
+
key: "Escape",
|
|
1151
|
+
run: closeCommand
|
|
1109
1152
|
}
|
|
1110
1153
|
];
|
|
1111
|
-
|
|
1154
|
+
|
|
1155
|
+
// packages/ui/react-ui-editor/src/extensions/util/dom.ts
|
|
1156
|
+
var flattenRect = (rect, left) => {
|
|
1157
|
+
const x = left ? rect.left : rect.right;
|
|
1158
|
+
return {
|
|
1159
|
+
left: x,
|
|
1160
|
+
right: x,
|
|
1161
|
+
top: rect.top,
|
|
1162
|
+
bottom: rect.bottom
|
|
1163
|
+
};
|
|
1164
|
+
};
|
|
1165
|
+
var scratchRange;
|
|
1166
|
+
var textRange = (node, from, to = from) => {
|
|
1167
|
+
const range = scratchRange || (scratchRange = document.createRange());
|
|
1168
|
+
range.setEnd(node, to);
|
|
1169
|
+
range.setStart(node, from);
|
|
1170
|
+
return range;
|
|
1171
|
+
};
|
|
1172
|
+
var clientRectsFor = (dom) => {
|
|
1173
|
+
if (dom.nodeType === 3) {
|
|
1174
|
+
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
|
1175
|
+
} else if (dom.nodeType === 1) {
|
|
1176
|
+
return dom.getClientRects();
|
|
1177
|
+
} else {
|
|
1178
|
+
return [];
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
|
1183
|
+
var CommandHint = class extends WidgetType2 {
|
|
1184
|
+
constructor(content) {
|
|
1185
|
+
super();
|
|
1186
|
+
this.content = content;
|
|
1187
|
+
}
|
|
1188
|
+
toDOM() {
|
|
1189
|
+
const wrap = document.createElement("span");
|
|
1190
|
+
wrap.className = "cm-placeholder";
|
|
1191
|
+
wrap.style.pointerEvents = "none";
|
|
1192
|
+
wrap.appendChild(typeof this.content === "string" ? document.createTextNode(this.content) : this.content);
|
|
1193
|
+
if (typeof this.content === "string") {
|
|
1194
|
+
wrap.setAttribute("aria-label", "placeholder " + this.content);
|
|
1195
|
+
} else {
|
|
1196
|
+
wrap.setAttribute("aria-hidden", "true");
|
|
1197
|
+
}
|
|
1198
|
+
return wrap;
|
|
1199
|
+
}
|
|
1200
|
+
coordsAt(dom) {
|
|
1201
|
+
const rects = dom.firstChild ? clientRectsFor(dom.firstChild) : [];
|
|
1202
|
+
if (!rects.length) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
const style = window.getComputedStyle(dom.parentNode);
|
|
1206
|
+
const rect = flattenRect(rects[0], style.direction !== "rtl");
|
|
1207
|
+
const lineHeight = parseInt(style.lineHeight);
|
|
1208
|
+
if (rect.bottom - rect.top > lineHeight * 1.5) {
|
|
1209
|
+
return {
|
|
1210
|
+
left: rect.left,
|
|
1211
|
+
right: rect.right,
|
|
1212
|
+
top: rect.top,
|
|
1213
|
+
bottom: rect.top + lineHeight
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
return rect;
|
|
1217
|
+
}
|
|
1218
|
+
ignoreEvent() {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
1223
|
+
constructor() {
|
|
1224
|
+
this.deco = Decoration3.none;
|
|
1225
|
+
}
|
|
1226
|
+
update(update2) {
|
|
1227
|
+
const builder = new RangeSetBuilder();
|
|
1228
|
+
const cState = update2.view.state.field(commandState, false);
|
|
1229
|
+
if (!cState?.tooltip) {
|
|
1230
|
+
const selection = update2.view.state.selection.main;
|
|
1231
|
+
const line = update2.view.state.doc.lineAt(selection.from);
|
|
1232
|
+
if (selection.from === selection.to && line.from === line.to) {
|
|
1233
|
+
const hint = onHint();
|
|
1234
|
+
if (hint) {
|
|
1235
|
+
builder.add(selection.from, selection.to, Decoration3.widget({
|
|
1236
|
+
widget: new CommandHint(hint)
|
|
1237
|
+
}));
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
this.deco = builder.finish();
|
|
1242
|
+
}
|
|
1243
|
+
}, {
|
|
1244
|
+
provide: (plugin) => [
|
|
1245
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
|
1246
|
+
]
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1250
|
+
var command = (options) => {
|
|
1251
|
+
return [
|
|
1252
|
+
commandConfig.of(options),
|
|
1253
|
+
commandState,
|
|
1254
|
+
keymap3.of(commandKeyBindings),
|
|
1255
|
+
hintViewPlugin(options),
|
|
1256
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
|
1257
|
+
return focusing ? closeEffect.of(null) : null;
|
|
1258
|
+
})
|
|
1259
|
+
];
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1263
|
+
import { invertedEffects } from "@codemirror/commands";
|
|
1264
|
+
import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
|
1265
|
+
import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7 } from "@codemirror/view";
|
|
1266
|
+
import sortBy from "lodash.sortby";
|
|
1267
|
+
import { useEffect } from "react";
|
|
1268
|
+
import { debounce } from "@dxos/async";
|
|
1269
|
+
import { log as log3 } from "@dxos/log";
|
|
1270
|
+
import { nonNullable } from "@dxos/util";
|
|
1112
1271
|
|
|
1113
1272
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1114
1273
|
import { mx } from "@dxos/react-ui-theme";
|
|
@@ -1175,18 +1334,26 @@ var logChanges = (trs) => {
|
|
|
1175
1334
|
return changes2;
|
|
1176
1335
|
}).filter(Boolean);
|
|
1177
1336
|
if (changes.length) {
|
|
1178
|
-
|
|
1337
|
+
log2.info("changes", {
|
|
1338
|
+
changes
|
|
1339
|
+
}, {
|
|
1340
|
+
F: __dxlog_file3,
|
|
1341
|
+
L: 39,
|
|
1342
|
+
S: void 0,
|
|
1343
|
+
C: (f, a) => f(...a)
|
|
1344
|
+
});
|
|
1179
1345
|
}
|
|
1180
1346
|
};
|
|
1181
1347
|
|
|
1182
1348
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1183
|
-
var
|
|
1349
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1350
|
+
var documentId = Facet4.define({
|
|
1184
1351
|
combine: (values) => values[0]
|
|
1185
1352
|
});
|
|
1186
|
-
var setComments =
|
|
1187
|
-
var setSelection =
|
|
1188
|
-
var setCommentState =
|
|
1189
|
-
var commentsState =
|
|
1353
|
+
var setComments = StateEffect3.define();
|
|
1354
|
+
var setSelection = StateEffect3.define();
|
|
1355
|
+
var setCommentState = StateEffect3.define();
|
|
1356
|
+
var commentsState = StateField4.define({
|
|
1190
1357
|
create: (state) => ({
|
|
1191
1358
|
id: state.facet(documentId),
|
|
1192
1359
|
comments: [],
|
|
@@ -1224,7 +1391,7 @@ var commentsState = StateField3.define({
|
|
|
1224
1391
|
return value;
|
|
1225
1392
|
}
|
|
1226
1393
|
});
|
|
1227
|
-
var styles3 =
|
|
1394
|
+
var styles3 = EditorView7.baseTheme({
|
|
1228
1395
|
"&light .cm-comment, &light .cm-comment-current": {
|
|
1229
1396
|
mixBlendMode: "darken"
|
|
1230
1397
|
},
|
|
@@ -1246,26 +1413,31 @@ var styles3 = EditorView6.baseTheme({
|
|
|
1246
1413
|
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1247
1414
|
}
|
|
1248
1415
|
});
|
|
1249
|
-
var commentMark =
|
|
1416
|
+
var commentMark = Decoration4.mark({
|
|
1250
1417
|
class: "cm-comment",
|
|
1251
1418
|
attributes: {
|
|
1252
1419
|
"data-testid": "cm-comment"
|
|
1253
1420
|
}
|
|
1254
1421
|
});
|
|
1255
|
-
var commentCurrentMark =
|
|
1422
|
+
var commentCurrentMark = Decoration4.mark({
|
|
1256
1423
|
class: "cm-comment-current",
|
|
1257
1424
|
attributes: {
|
|
1258
1425
|
"data-testid": "cm-comment"
|
|
1259
1426
|
}
|
|
1260
1427
|
});
|
|
1261
|
-
var commentsDecorations =
|
|
1428
|
+
var commentsDecorations = EditorView7.decorations.compute([
|
|
1262
1429
|
commentsState
|
|
1263
1430
|
], (state) => {
|
|
1264
1431
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
1265
1432
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1266
1433
|
const range = comment.range;
|
|
1267
1434
|
if (!range || range.from === range.to) {
|
|
1268
|
-
|
|
1435
|
+
log3.warn("Invalid range:", range, {
|
|
1436
|
+
F: __dxlog_file4,
|
|
1437
|
+
L: 132,
|
|
1438
|
+
S: void 0,
|
|
1439
|
+
C: (f, a) => f(...a)
|
|
1440
|
+
});
|
|
1269
1441
|
return void 0;
|
|
1270
1442
|
}
|
|
1271
1443
|
if (comment.comment.id === current) {
|
|
@@ -1274,7 +1446,7 @@ var commentsDecorations = EditorView6.decorations.compute([
|
|
|
1274
1446
|
return commentMark.range(range.from, range.to);
|
|
1275
1447
|
}
|
|
1276
1448
|
}).filter(nonNullable);
|
|
1277
|
-
return
|
|
1449
|
+
return Decoration4.set(decorations);
|
|
1278
1450
|
});
|
|
1279
1451
|
var trackPastedComments = (onUpdate) => {
|
|
1280
1452
|
let tracked = null;
|
|
@@ -1296,7 +1468,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1296
1468
|
}
|
|
1297
1469
|
};
|
|
1298
1470
|
return [
|
|
1299
|
-
|
|
1471
|
+
EditorView7.domEventHandlers({
|
|
1300
1472
|
cut: handleTrack,
|
|
1301
1473
|
copy: handleTrack
|
|
1302
1474
|
}),
|
|
@@ -1318,7 +1490,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1318
1490
|
return effects;
|
|
1319
1491
|
}),
|
|
1320
1492
|
// Handle paste or the undo of comment deletion.
|
|
1321
|
-
|
|
1493
|
+
EditorView7.updateListener.of((update2) => {
|
|
1322
1494
|
const restore = [];
|
|
1323
1495
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1324
1496
|
const tr = update2.transactions[i];
|
|
@@ -1374,7 +1546,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
1374
1546
|
from: changes.mapPos(comment.from, 1),
|
|
1375
1547
|
to: changes.mapPos(comment.to, 1)
|
|
1376
1548
|
});
|
|
1377
|
-
var restoreCommentEffect =
|
|
1549
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
1378
1550
|
map: mapTrackedComment
|
|
1379
1551
|
});
|
|
1380
1552
|
var createComment = (view) => {
|
|
@@ -1415,7 +1587,7 @@ var createComment = (view) => {
|
|
|
1415
1587
|
}
|
|
1416
1588
|
return false;
|
|
1417
1589
|
};
|
|
1418
|
-
var optionsFacet =
|
|
1590
|
+
var optionsFacet = Facet4.define({
|
|
1419
1591
|
combine: (providers) => providers[0]
|
|
1420
1592
|
});
|
|
1421
1593
|
var comments = (options = {}) => {
|
|
@@ -1430,7 +1602,7 @@ var comments = (options = {}) => {
|
|
|
1430
1602
|
//
|
|
1431
1603
|
// Keymap.
|
|
1432
1604
|
//
|
|
1433
|
-
options.onCreate ?
|
|
1605
|
+
options.onCreate ? keymap4.of([
|
|
1434
1606
|
{
|
|
1435
1607
|
key: shortcut,
|
|
1436
1608
|
run: callbackWrapper(createComment)
|
|
@@ -1469,7 +1641,7 @@ var comments = (options = {}) => {
|
|
|
1469
1641
|
//
|
|
1470
1642
|
// Track deleted ranges and update ranges for decorations.
|
|
1471
1643
|
//
|
|
1472
|
-
|
|
1644
|
+
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1473
1645
|
let mod = false;
|
|
1474
1646
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1475
1647
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1501,7 +1673,7 @@ var comments = (options = {}) => {
|
|
|
1501
1673
|
//
|
|
1502
1674
|
// Track selection/proximity.
|
|
1503
1675
|
//
|
|
1504
|
-
|
|
1676
|
+
EditorView7.updateListener.of(({ view, state }) => {
|
|
1505
1677
|
let min = Infinity;
|
|
1506
1678
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1507
1679
|
const { head } = state.selection.main;
|
|
@@ -1550,7 +1722,7 @@ var focusComment = (view, id, center = true) => {
|
|
|
1550
1722
|
},
|
|
1551
1723
|
effects: [
|
|
1552
1724
|
//
|
|
1553
|
-
|
|
1725
|
+
EditorView7.scrollIntoView(range.from, center ? {
|
|
1554
1726
|
y: "center"
|
|
1555
1727
|
} : void 0),
|
|
1556
1728
|
setSelection.of({
|
|
@@ -1578,14 +1750,16 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1578
1750
|
};
|
|
1579
1751
|
|
|
1580
1752
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1581
|
-
import { Facet as
|
|
1582
|
-
import { EditorView as
|
|
1583
|
-
|
|
1753
|
+
import { Facet as Facet5, Transaction } from "@codemirror/state";
|
|
1754
|
+
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1755
|
+
import { log as log4 } from "@dxos/log";
|
|
1756
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts";
|
|
1757
|
+
var cursorLineMarginFacet = Facet5.define({
|
|
1584
1758
|
combine: (input) => input[0] ?? 3
|
|
1585
1759
|
});
|
|
1586
1760
|
var annotation = "cursorLineMargin";
|
|
1587
1761
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1588
|
-
var cursorLineMargin =
|
|
1762
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1589
1763
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1590
1764
|
return;
|
|
1591
1765
|
}
|
|
@@ -1603,7 +1777,12 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1603
1777
|
const needsScrollTop = false;
|
|
1604
1778
|
const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
|
|
1605
1779
|
if (needsScrollTop && needsScrollBot) {
|
|
1606
|
-
|
|
1780
|
+
log4.warn("is cursorScrollMargin too large for the editor size?", void 0, {
|
|
1781
|
+
F: __dxlog_file5,
|
|
1782
|
+
L: 66,
|
|
1783
|
+
S: void 0,
|
|
1784
|
+
C: (f, a) => f(...a)
|
|
1785
|
+
});
|
|
1607
1786
|
return;
|
|
1608
1787
|
}
|
|
1609
1788
|
if (!needsScrollTop && !needsScrollBot) {
|
|
@@ -1621,38 +1800,57 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1621
1800
|
}
|
|
1622
1801
|
view.dispatch({
|
|
1623
1802
|
annotations: Transaction.userEvent.of(annotation),
|
|
1624
|
-
effects:
|
|
1803
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1625
1804
|
y: needsScrollTop ? "start" : "end",
|
|
1626
1805
|
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1627
1806
|
})
|
|
1628
1807
|
});
|
|
1629
1808
|
});
|
|
1630
1809
|
|
|
1810
|
+
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1811
|
+
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1812
|
+
import { log as log5 } from "@dxos/log";
|
|
1813
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/dnd.ts";
|
|
1814
|
+
var dnd = () => {
|
|
1815
|
+
return EditorView9.domEventHandlers({
|
|
1816
|
+
drop: (event, view) => {
|
|
1817
|
+
log5.info("domEventHandlersDrop", {
|
|
1818
|
+
event
|
|
1819
|
+
}, {
|
|
1820
|
+
F: __dxlog_file6,
|
|
1821
|
+
L: 14,
|
|
1822
|
+
S: void 0,
|
|
1823
|
+
C: (f, a) => f(...a)
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
};
|
|
1828
|
+
|
|
1631
1829
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1632
|
-
import { EditorView as
|
|
1830
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1633
1831
|
var listener = ({ onFocus, onChange }) => {
|
|
1634
1832
|
const extensions = [];
|
|
1635
|
-
onFocus && extensions.push(
|
|
1636
|
-
onFocus(
|
|
1833
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1834
|
+
onFocus(focusing);
|
|
1637
1835
|
return null;
|
|
1638
1836
|
}));
|
|
1639
|
-
onChange && extensions.push(
|
|
1837
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1640
1838
|
onChange(update2.state.doc.toString());
|
|
1641
1839
|
}));
|
|
1642
1840
|
return extensions;
|
|
1643
1841
|
};
|
|
1644
1842
|
|
|
1645
1843
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1646
|
-
import { closeBrackets
|
|
1647
|
-
import { history
|
|
1844
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1845
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1648
1846
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1649
|
-
import { bracketMatching
|
|
1847
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1650
1848
|
import { languages } from "@codemirror/language-data";
|
|
1651
1849
|
import { searchKeymap } from "@codemirror/search";
|
|
1652
1850
|
import { EditorState } from "@codemirror/state";
|
|
1653
|
-
import { oneDarkHighlightStyle
|
|
1654
|
-
import {
|
|
1655
|
-
import { isNotFalsy as
|
|
1851
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1852
|
+
import { EditorView as EditorView11, drawSelection, dropCursor, keymap as keymap5, placeholder } from "@codemirror/view";
|
|
1853
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1656
1854
|
|
|
1657
1855
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1658
1856
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1845,19 +2043,17 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1845
2043
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1846
2044
|
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1847
2045
|
return [
|
|
1848
|
-
|
|
2046
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2047
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
1849
2048
|
EditorState.allowMultipleSelections.of(true),
|
|
1850
2049
|
EditorState.tabSize.of(2),
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
closeBrackets2(),
|
|
1854
|
-
crosshairCursor(),
|
|
2050
|
+
bracketMatching(),
|
|
2051
|
+
closeBrackets(),
|
|
1855
2052
|
dropCursor(),
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
history2(),
|
|
2053
|
+
drawSelection(),
|
|
2054
|
+
history(),
|
|
1859
2055
|
indentOnInput(),
|
|
1860
|
-
_placeholder &&
|
|
2056
|
+
_placeholder && placeholder(_placeholder),
|
|
1861
2057
|
// Main extension.
|
|
1862
2058
|
// https://github.com/codemirror/lang-markdown
|
|
1863
2059
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1877,10 +2073,10 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1877
2073
|
]
|
|
1878
2074
|
}),
|
|
1879
2075
|
// https://github.com/codemirror/theme-one-dark
|
|
1880
|
-
themeMode === "dark" ?
|
|
2076
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
1881
2077
|
// Custom styles.
|
|
1882
|
-
|
|
1883
|
-
|
|
2078
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
2079
|
+
keymap5.of([
|
|
1884
2080
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1885
2081
|
indentWithTab,
|
|
1886
2082
|
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
@@ -1892,22 +2088,22 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1892
2088
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1893
2089
|
...standardKeymap
|
|
1894
2090
|
])
|
|
1895
|
-
].filter(
|
|
2091
|
+
].filter(isNotFalsy2);
|
|
1896
2092
|
};
|
|
1897
2093
|
|
|
1898
2094
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
1899
2095
|
import { syntaxTree } from "@codemirror/language";
|
|
1900
|
-
import { RangeSetBuilder } from "@codemirror/state";
|
|
1901
|
-
import { EditorView as
|
|
2096
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2097
|
+
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1902
2098
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1903
|
-
var HorizontalRuleWidget = class extends
|
|
2099
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
1904
2100
|
toDOM() {
|
|
1905
2101
|
const el = document.createElement("span");
|
|
1906
2102
|
el.className = "cm-hr";
|
|
1907
2103
|
return el;
|
|
1908
2104
|
}
|
|
1909
2105
|
};
|
|
1910
|
-
var LinkButton = class extends
|
|
2106
|
+
var LinkButton = class extends WidgetType3 {
|
|
1911
2107
|
constructor(url, render) {
|
|
1912
2108
|
super();
|
|
1913
2109
|
this.url = url;
|
|
@@ -1922,7 +2118,7 @@ var LinkButton = class extends WidgetType2 {
|
|
|
1922
2118
|
return el;
|
|
1923
2119
|
}
|
|
1924
2120
|
};
|
|
1925
|
-
var CheckboxWidget = class extends
|
|
2121
|
+
var CheckboxWidget = class extends WidgetType3 {
|
|
1926
2122
|
constructor(_checked) {
|
|
1927
2123
|
super();
|
|
1928
2124
|
this._checked = _checked;
|
|
@@ -1959,28 +2155,28 @@ var CheckboxWidget = class extends WidgetType2 {
|
|
|
1959
2155
|
return false;
|
|
1960
2156
|
}
|
|
1961
2157
|
};
|
|
1962
|
-
var hide =
|
|
1963
|
-
var fencedCodeLine =
|
|
2158
|
+
var hide = Decoration5.replace({});
|
|
2159
|
+
var fencedCodeLine = Decoration5.line({
|
|
1964
2160
|
class: mx2("cm-code cm-codeblock-line")
|
|
1965
2161
|
});
|
|
1966
|
-
var fencedCodeLineFirst =
|
|
2162
|
+
var fencedCodeLineFirst = Decoration5.line({
|
|
1967
2163
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
1968
2164
|
});
|
|
1969
|
-
var fencedCodeLineLast =
|
|
2165
|
+
var fencedCodeLineLast = Decoration5.line({
|
|
1970
2166
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
1971
2167
|
});
|
|
1972
|
-
var horizontalRule =
|
|
2168
|
+
var horizontalRule = Decoration5.replace({
|
|
1973
2169
|
widget: new HorizontalRuleWidget()
|
|
1974
2170
|
});
|
|
1975
|
-
var checkedTask =
|
|
2171
|
+
var checkedTask = Decoration5.replace({
|
|
1976
2172
|
widget: new CheckboxWidget(true)
|
|
1977
2173
|
});
|
|
1978
|
-
var uncheckedTask =
|
|
2174
|
+
var uncheckedTask = Decoration5.replace({
|
|
1979
2175
|
widget: new CheckboxWidget(false)
|
|
1980
2176
|
});
|
|
1981
|
-
var editingRange = (state, range) => {
|
|
2177
|
+
var editingRange = (state, range, focus) => {
|
|
1982
2178
|
const { readOnly, selection: { main: { head } } } = state;
|
|
1983
|
-
return !readOnly && head >= range.from && head <= range.to;
|
|
2179
|
+
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
1984
2180
|
};
|
|
1985
2181
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1986
2182
|
"CodeMark",
|
|
@@ -1989,8 +2185,9 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
1989
2185
|
"SubscriptMark",
|
|
1990
2186
|
"SuperscriptMark"
|
|
1991
2187
|
]);
|
|
1992
|
-
var buildDecorations = (view, options) => {
|
|
1993
|
-
const
|
|
2188
|
+
var buildDecorations = (view, options, focus) => {
|
|
2189
|
+
const deco = new RangeSetBuilder2();
|
|
2190
|
+
const atomicDeco = new RangeSetBuilder2();
|
|
1994
2191
|
const { state } = view;
|
|
1995
2192
|
for (const { from, to } of view.visibleRanges) {
|
|
1996
2193
|
syntaxTree(state).iterate({
|
|
@@ -1998,7 +2195,7 @@ var buildDecorations = (view, options) => {
|
|
|
1998
2195
|
to,
|
|
1999
2196
|
enter: (node) => {
|
|
2000
2197
|
if (node.name === "FencedCode") {
|
|
2001
|
-
const editing = editingRange(state, node);
|
|
2198
|
+
const editing = editingRange(state, node, focus);
|
|
2002
2199
|
for (const block of view.viewportLineBlocks) {
|
|
2003
2200
|
if (block.to < node.from) {
|
|
2004
2201
|
continue;
|
|
@@ -2007,23 +2204,23 @@ var buildDecorations = (view, options) => {
|
|
|
2007
2204
|
break;
|
|
2008
2205
|
}
|
|
2009
2206
|
const first = block.from <= node.from;
|
|
2010
|
-
const last = block.to >= node.to;
|
|
2011
|
-
|
|
2207
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
|
2208
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2012
2209
|
if (!editing && (first || last)) {
|
|
2013
|
-
|
|
2210
|
+
atomicDeco.add(block.from, block.to, hide);
|
|
2014
2211
|
}
|
|
2015
2212
|
}
|
|
2016
2213
|
return false;
|
|
2017
2214
|
} else if (node.name === "Link") {
|
|
2018
2215
|
const marks = node.node.getChildren("LinkMark");
|
|
2019
2216
|
const urlNode = node.node.getChild("URL");
|
|
2020
|
-
const editing = editingRange(state, node);
|
|
2217
|
+
const editing = editingRange(state, node, focus);
|
|
2021
2218
|
if (urlNode && marks.length >= 2) {
|
|
2022
2219
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
2023
2220
|
if (!editing) {
|
|
2024
|
-
|
|
2221
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2025
2222
|
}
|
|
2026
|
-
|
|
2223
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
2027
2224
|
tagName: "a",
|
|
2028
2225
|
attributes: {
|
|
2029
2226
|
class: "cm-link",
|
|
@@ -2033,57 +2230,87 @@ var buildDecorations = (view, options) => {
|
|
|
2033
2230
|
}
|
|
2034
2231
|
}));
|
|
2035
2232
|
if (!editing) {
|
|
2036
|
-
|
|
2233
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
2037
2234
|
widget: new LinkButton(url, options.renderLinkButton)
|
|
2038
2235
|
}) : hide);
|
|
2039
2236
|
}
|
|
2040
2237
|
}
|
|
2041
2238
|
} else if (node.name === "HeaderMark") {
|
|
2042
2239
|
const parent = node.node.parent;
|
|
2043
|
-
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
|
|
2240
|
+
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from), focus)) {
|
|
2044
2241
|
const next = state.doc.sliceString(node.to, node.to + 1);
|
|
2045
|
-
|
|
2242
|
+
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2046
2243
|
}
|
|
2047
2244
|
} else if (node.name === "HorizontalRule") {
|
|
2048
|
-
if (!editingRange(state, node)) {
|
|
2049
|
-
|
|
2245
|
+
if (!editingRange(state, node, focus)) {
|
|
2246
|
+
deco.add(node.from, node.to, horizontalRule);
|
|
2050
2247
|
}
|
|
2051
2248
|
} else if (node.name === "TaskMarker") {
|
|
2052
|
-
if (!editingRange(state, node)) {
|
|
2249
|
+
if (!editingRange(state, node, focus)) {
|
|
2053
2250
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2054
|
-
|
|
2251
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2055
2252
|
class: "cm-task"
|
|
2056
2253
|
}));
|
|
2057
|
-
|
|
2254
|
+
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2058
2255
|
}
|
|
2059
2256
|
} else if (MarksByParent.has(node.name)) {
|
|
2060
|
-
if (!editingRange(state, node.node.parent)) {
|
|
2061
|
-
|
|
2257
|
+
if (!editingRange(state, node.node.parent, focus)) {
|
|
2258
|
+
atomicDeco.add(node.from, node.to, hide);
|
|
2062
2259
|
}
|
|
2063
2260
|
}
|
|
2064
2261
|
}
|
|
2065
2262
|
});
|
|
2066
2263
|
}
|
|
2067
|
-
return
|
|
2264
|
+
return {
|
|
2265
|
+
deco: deco.finish(),
|
|
2266
|
+
atomicDeco: atomicDeco.finish()
|
|
2267
|
+
};
|
|
2068
2268
|
};
|
|
2269
|
+
var forceUpdate = StateEffect4.define();
|
|
2069
2270
|
var decorateMarkdown = (options = {}) => {
|
|
2070
2271
|
return [
|
|
2071
|
-
|
|
2272
|
+
ViewPlugin4.fromClass(class {
|
|
2072
2273
|
constructor(view) {
|
|
2073
|
-
this.
|
|
2274
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2074
2275
|
}
|
|
2075
2276
|
update(update2) {
|
|
2076
|
-
if (update2.docChanged || update2.
|
|
2077
|
-
this.
|
|
2277
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
2278
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2279
|
+
this.clearUpdate();
|
|
2280
|
+
} else if (update2.selectionSet) {
|
|
2281
|
+
this.scheduleUpdate(update2.view);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
2285
|
+
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
2286
|
+
scheduleUpdate(view) {
|
|
2287
|
+
this.clearUpdate();
|
|
2288
|
+
this.pendingUpdate = setTimeout(() => {
|
|
2289
|
+
view.dispatch({
|
|
2290
|
+
effects: forceUpdate.of(null)
|
|
2291
|
+
});
|
|
2292
|
+
}, options.selectionChangeDelay);
|
|
2293
|
+
}
|
|
2294
|
+
clearUpdate() {
|
|
2295
|
+
if (this.pendingUpdate) {
|
|
2296
|
+
clearTimeout(this.pendingUpdate);
|
|
2297
|
+
this.pendingUpdate = void 0;
|
|
2078
2298
|
}
|
|
2079
2299
|
}
|
|
2300
|
+
destroy() {
|
|
2301
|
+
this.clearUpdate();
|
|
2302
|
+
}
|
|
2080
2303
|
}, {
|
|
2081
|
-
|
|
2304
|
+
provide: (plugin) => [
|
|
2305
|
+
EditorView12.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2306
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2307
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
2308
|
+
]
|
|
2082
2309
|
}),
|
|
2083
2310
|
formattingStyles
|
|
2084
2311
|
];
|
|
2085
2312
|
};
|
|
2086
|
-
var formattingStyles =
|
|
2313
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
2087
2314
|
"& .cm-code": {
|
|
2088
2315
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2089
2316
|
},
|
|
@@ -2136,7 +2363,7 @@ var formattingStyles = EditorView10.baseTheme({
|
|
|
2136
2363
|
import { snippet } from "@codemirror/autocomplete";
|
|
2137
2364
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2138
2365
|
import { EditorSelection } from "@codemirror/state";
|
|
2139
|
-
import { EditorView as
|
|
2366
|
+
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2140
2367
|
import { useState, useMemo } from "react";
|
|
2141
2368
|
var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
2142
2369
|
var Inline;
|
|
@@ -3008,7 +3235,7 @@ var toggleCodeblock = (target) => {
|
|
|
3008
3235
|
};
|
|
3009
3236
|
var formatting = (options = {}) => {
|
|
3010
3237
|
return [
|
|
3011
|
-
|
|
3238
|
+
keymap6.of([
|
|
3012
3239
|
{
|
|
3013
3240
|
key: "meta-b",
|
|
3014
3241
|
run: toggleStrong
|
|
@@ -3206,7 +3433,7 @@ var getFormatting = (state) => {
|
|
|
3206
3433
|
};
|
|
3207
3434
|
var useFormattingState = () => {
|
|
3208
3435
|
const [state, setState] = useState(null);
|
|
3209
|
-
const observer = useMemo(() =>
|
|
3436
|
+
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3210
3437
|
if (update2.docChanged || update2.selectionSet) {
|
|
3211
3438
|
const newState = getFormatting(update2.state);
|
|
3212
3439
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3222,12 +3449,12 @@ var useFormattingState = () => {
|
|
|
3222
3449
|
|
|
3223
3450
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3224
3451
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3225
|
-
import { StateField as
|
|
3226
|
-
import { Decoration as
|
|
3452
|
+
import { StateField as StateField5 } from "@codemirror/state";
|
|
3453
|
+
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3227
3454
|
var image = (options = {}) => {
|
|
3228
|
-
return
|
|
3455
|
+
return StateField5.define({
|
|
3229
3456
|
create: (state) => {
|
|
3230
|
-
return
|
|
3457
|
+
return Decoration6.set(buildDecorations2(0, state.doc.length, state));
|
|
3231
3458
|
},
|
|
3232
3459
|
update: (value, tr) => {
|
|
3233
3460
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3250,7 +3477,7 @@ var image = (options = {}) => {
|
|
|
3250
3477
|
add: buildDecorations2(from, to, tr.state)
|
|
3251
3478
|
});
|
|
3252
3479
|
},
|
|
3253
|
-
provide: (field) =>
|
|
3480
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3254
3481
|
});
|
|
3255
3482
|
};
|
|
3256
3483
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3272,7 +3499,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3272
3499
|
const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3273
3500
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3274
3501
|
preloadImage(url);
|
|
3275
|
-
decorations.push(
|
|
3502
|
+
decorations.push(Decoration6.replace({
|
|
3276
3503
|
block: true,
|
|
3277
3504
|
widget: new ImageWidget(url)
|
|
3278
3505
|
}).range(hide2 ? node.from : node.to, node.to));
|
|
@@ -3284,7 +3511,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3284
3511
|
});
|
|
3285
3512
|
return decorations;
|
|
3286
3513
|
};
|
|
3287
|
-
var ImageWidget = class extends
|
|
3514
|
+
var ImageWidget = class extends WidgetType4 {
|
|
3288
3515
|
constructor(_url) {
|
|
3289
3516
|
super();
|
|
3290
3517
|
this._url = _url;
|
|
@@ -3337,17 +3564,17 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3337
3564
|
|
|
3338
3565
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3339
3566
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3340
|
-
import { RangeSetBuilder as
|
|
3341
|
-
import { Decoration as
|
|
3567
|
+
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
|
|
3568
|
+
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3342
3569
|
var table = (options = {}) => {
|
|
3343
|
-
return
|
|
3570
|
+
return StateField6.define({
|
|
3344
3571
|
create: (state) => update(state, options),
|
|
3345
3572
|
update: (_, tr) => update(tr.state, options),
|
|
3346
|
-
provide: (field) =>
|
|
3573
|
+
provide: (field) => EditorView15.decorations.from(field)
|
|
3347
3574
|
});
|
|
3348
3575
|
};
|
|
3349
3576
|
var update = (state, options) => {
|
|
3350
|
-
const builder = new
|
|
3577
|
+
const builder = new RangeSetBuilder3();
|
|
3351
3578
|
const cursor = state.selection.main.head;
|
|
3352
3579
|
const tables = [];
|
|
3353
3580
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3387,16 +3614,16 @@ var update = (state, options) => {
|
|
|
3387
3614
|
});
|
|
3388
3615
|
tables.forEach((table2) => {
|
|
3389
3616
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3390
|
-
hide2 && builder.add(table2.from, table2.to,
|
|
3617
|
+
hide2 && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3391
3618
|
widget: new TableWidget(table2)
|
|
3392
3619
|
}));
|
|
3393
|
-
builder.add(table2.from, table2.to,
|
|
3620
|
+
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
3394
3621
|
class: "cm-table"
|
|
3395
3622
|
}));
|
|
3396
3623
|
});
|
|
3397
3624
|
return builder.finish();
|
|
3398
3625
|
};
|
|
3399
|
-
var TableWidget = class extends
|
|
3626
|
+
var TableWidget = class extends WidgetType5 {
|
|
3400
3627
|
constructor(_table) {
|
|
3401
3628
|
super();
|
|
3402
3629
|
this._table = _table;
|
|
@@ -3435,6 +3662,8 @@ var TableWidget = class extends WidgetType4 {
|
|
|
3435
3662
|
|
|
3436
3663
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3437
3664
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
3665
|
+
import { log as log6 } from "@dxos/log";
|
|
3666
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
|
3438
3667
|
var mention = ({ onSearch }) => {
|
|
3439
3668
|
return autocompletion2({
|
|
3440
3669
|
// TODO(burdon): Not working.
|
|
@@ -3446,7 +3675,14 @@ var mention = ({ onSearch }) => {
|
|
|
3446
3675
|
icons: false,
|
|
3447
3676
|
override: [
|
|
3448
3677
|
(context) => {
|
|
3449
|
-
|
|
3678
|
+
log6.info("completion context", {
|
|
3679
|
+
context
|
|
3680
|
+
}, {
|
|
3681
|
+
F: __dxlog_file7,
|
|
3682
|
+
L: 26,
|
|
3683
|
+
S: void 0,
|
|
3684
|
+
C: (f, a) => f(...a)
|
|
3685
|
+
});
|
|
3450
3686
|
const match = context.matchBefore(/@(\w+)?/);
|
|
3451
3687
|
if (!match || match.from === match.to && !context.explicit) {
|
|
3452
3688
|
return null;
|
|
@@ -3463,10 +3699,10 @@ var mention = ({ onSearch }) => {
|
|
|
3463
3699
|
};
|
|
3464
3700
|
|
|
3465
3701
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
3466
|
-
import { Facet as
|
|
3467
|
-
import { keymap as
|
|
3702
|
+
import { Facet as Facet6 } from "@codemirror/state";
|
|
3703
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
3468
3704
|
import { vim } from "@replit/codemirror-vim";
|
|
3469
|
-
var editorMode =
|
|
3705
|
+
var editorMode = Facet6.define({
|
|
3470
3706
|
combine: (modes) => modes[0] ?? {}
|
|
3471
3707
|
});
|
|
3472
3708
|
var EditorModes = {
|
|
@@ -3477,7 +3713,7 @@ var EditorModes = {
|
|
|
3477
3713
|
type: "vim",
|
|
3478
3714
|
noTabster: true
|
|
3479
3715
|
}),
|
|
3480
|
-
|
|
3716
|
+
keymap7.of([
|
|
3481
3717
|
{
|
|
3482
3718
|
key: "Alt-Escape",
|
|
3483
3719
|
run: (view) => {
|
|
@@ -3497,7 +3733,7 @@ var outliner = (options = {}) => {
|
|
|
3497
3733
|
};
|
|
3498
3734
|
|
|
3499
3735
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
3500
|
-
import { keymap as
|
|
3736
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
3501
3737
|
var defaultItems = [
|
|
3502
3738
|
"hello world!",
|
|
3503
3739
|
"this is a test.",
|
|
@@ -3507,7 +3743,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3507
3743
|
let t;
|
|
3508
3744
|
let idx = 0;
|
|
3509
3745
|
return [
|
|
3510
|
-
|
|
3746
|
+
keymap8.of([
|
|
3511
3747
|
{
|
|
3512
3748
|
// Reset.
|
|
3513
3749
|
key: "alt-meta-'",
|
|
@@ -3553,147 +3789,331 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3553
3789
|
];
|
|
3554
3790
|
};
|
|
3555
3791
|
|
|
3556
|
-
// packages/ui/react-ui-editor/src/
|
|
3557
|
-
import
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3792
|
+
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
3793
|
+
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
3794
|
+
import { Context as Context2 } from "@dxos/context";
|
|
3795
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
3796
|
+
import { log as log7 } from "@dxos/log";
|
|
3797
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
3798
|
+
var DEBOUNCE_INTERVAL = 100;
|
|
3799
|
+
var SpaceAwarenessProvider = class {
|
|
3800
|
+
constructor(params) {
|
|
3801
|
+
this._remoteStates = /* @__PURE__ */ new Map();
|
|
3802
|
+
this.remoteStateChange = new Event2();
|
|
3803
|
+
this._space = params.space;
|
|
3804
|
+
this._channel = params.channel;
|
|
3805
|
+
this._peerId = params.peerId;
|
|
3806
|
+
this._info = params.info;
|
|
3807
|
+
}
|
|
3808
|
+
open() {
|
|
3809
|
+
this._ctx = new Context2();
|
|
3810
|
+
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
3811
|
+
if (this._localState) {
|
|
3812
|
+
await this._space.postMessage(this._channel, {
|
|
3813
|
+
kind: "post",
|
|
3814
|
+
state: this._localState
|
|
3815
|
+
});
|
|
3816
|
+
await sleep(DEBOUNCE_INTERVAL);
|
|
3817
|
+
}
|
|
3818
|
+
});
|
|
3819
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
3820
|
+
switch (message.payload.kind) {
|
|
3821
|
+
case "query": {
|
|
3822
|
+
this._handleQueryMessage();
|
|
3823
|
+
break;
|
|
3824
|
+
}
|
|
3825
|
+
case "post": {
|
|
3826
|
+
this._handlePostMessage(message.payload);
|
|
3827
|
+
break;
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
}));
|
|
3831
|
+
void this._space.postMessage(this._channel, {
|
|
3832
|
+
kind: "query"
|
|
3833
|
+
}).catch((err) => {
|
|
3834
|
+
log7.debug("failed to query awareness", {
|
|
3835
|
+
err
|
|
3836
|
+
}, {
|
|
3837
|
+
F: __dxlog_file8,
|
|
3838
|
+
L: 89,
|
|
3839
|
+
S: this,
|
|
3840
|
+
C: (f, a) => f(...a)
|
|
3841
|
+
});
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
close() {
|
|
3845
|
+
void this._ctx?.dispose();
|
|
3846
|
+
this._ctx = void 0;
|
|
3847
|
+
this._postTask = void 0;
|
|
3848
|
+
}
|
|
3849
|
+
getRemoteStates() {
|
|
3850
|
+
return Array.from(this._remoteStates.values());
|
|
3851
|
+
}
|
|
3852
|
+
update(position) {
|
|
3853
|
+
invariant2(this._postTask, void 0, {
|
|
3854
|
+
F: __dxlog_file8,
|
|
3855
|
+
L: 104,
|
|
3856
|
+
S: this,
|
|
3857
|
+
A: [
|
|
3858
|
+
"this._postTask",
|
|
3859
|
+
""
|
|
3860
|
+
]
|
|
3861
|
+
});
|
|
3862
|
+
this._localState = {
|
|
3863
|
+
peerId: this._peerId,
|
|
3864
|
+
position,
|
|
3865
|
+
info: this._info
|
|
3866
|
+
};
|
|
3867
|
+
this._postTask.schedule();
|
|
3868
|
+
}
|
|
3869
|
+
_handleQueryMessage() {
|
|
3870
|
+
invariant2(this._postTask, void 0, {
|
|
3871
|
+
F: __dxlog_file8,
|
|
3872
|
+
L: 115,
|
|
3873
|
+
S: this,
|
|
3874
|
+
A: [
|
|
3875
|
+
"this._postTask",
|
|
3876
|
+
""
|
|
3877
|
+
]
|
|
3878
|
+
});
|
|
3879
|
+
this._postTask.schedule();
|
|
3880
|
+
}
|
|
3881
|
+
_handlePostMessage(message) {
|
|
3882
|
+
invariant2(message.kind === "post", void 0, {
|
|
3883
|
+
F: __dxlog_file8,
|
|
3884
|
+
L: 120,
|
|
3885
|
+
S: this,
|
|
3886
|
+
A: [
|
|
3887
|
+
"message.kind === 'post'",
|
|
3888
|
+
""
|
|
3889
|
+
]
|
|
3890
|
+
});
|
|
3891
|
+
this._remoteStates.set(message.state.peerId, message.state);
|
|
3892
|
+
this.remoteStateChange.emit();
|
|
3893
|
+
}
|
|
3894
|
+
};
|
|
3895
|
+
|
|
3896
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3897
|
+
var useActionHandler = (view) => {
|
|
3898
|
+
return (action) => {
|
|
3899
|
+
if (!view) {
|
|
3900
|
+
return;
|
|
3901
|
+
}
|
|
3902
|
+
let inlineType, listType;
|
|
3903
|
+
switch (action.type) {
|
|
3904
|
+
case "heading":
|
|
3905
|
+
setHeading(parseInt(action.data))(view);
|
|
3906
|
+
break;
|
|
3907
|
+
case "strong":
|
|
3908
|
+
case "emphasis":
|
|
3909
|
+
case "strikethrough":
|
|
3910
|
+
case "code":
|
|
3911
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
3912
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3913
|
+
break;
|
|
3914
|
+
case "list-ordered":
|
|
3915
|
+
case "list-bullet":
|
|
3916
|
+
case "list-task":
|
|
3917
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
3918
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3919
|
+
break;
|
|
3920
|
+
case "blockquote":
|
|
3921
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3922
|
+
break;
|
|
3923
|
+
case "codeblock":
|
|
3924
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3925
|
+
break;
|
|
3926
|
+
case "table":
|
|
3927
|
+
insertTable(view);
|
|
3928
|
+
break;
|
|
3929
|
+
case "link":
|
|
3930
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
3931
|
+
break;
|
|
3932
|
+
case "comment":
|
|
3933
|
+
createComment(view);
|
|
3934
|
+
break;
|
|
3935
|
+
}
|
|
3936
|
+
setTimeout(() => {
|
|
3937
|
+
if (!view.hasFocus) {
|
|
3938
|
+
view.focus();
|
|
3939
|
+
}
|
|
3940
|
+
});
|
|
3941
|
+
};
|
|
3942
|
+
};
|
|
3943
|
+
|
|
3944
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3945
|
+
import { useRef, useState as useState2 } from "react";
|
|
3946
|
+
var useEditorView = (id) => {
|
|
3947
|
+
const editorRef = useRef(null);
|
|
3948
|
+
const [prev, setPrev] = useState2([
|
|
3949
|
+
null,
|
|
3950
|
+
""
|
|
3951
|
+
]);
|
|
3952
|
+
if (prev[0] !== editorRef.current) {
|
|
3953
|
+
setPrev([
|
|
3954
|
+
editorRef.current,
|
|
3955
|
+
id
|
|
3956
|
+
]);
|
|
3957
|
+
}
|
|
3958
|
+
return [
|
|
3959
|
+
editorRef,
|
|
3960
|
+
prev[1] !== id
|
|
3961
|
+
];
|
|
3962
|
+
};
|
|
3963
|
+
|
|
3964
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3965
|
+
import { closeBrackets as closeBrackets2 } from "@codemirror/autocomplete";
|
|
3966
|
+
import { history as history2 } from "@codemirror/commands";
|
|
3967
|
+
import { bracketMatching as bracketMatching2 } from "@codemirror/language";
|
|
3968
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState2 } from "@codemirror/state";
|
|
3969
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor as dropCursor2, EditorView as EditorView16, highlightActiveLine, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
|
|
3970
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
3971
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
3972
|
+
import { log as log8 } from "@dxos/log";
|
|
3973
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
3974
|
+
|
|
3975
|
+
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
3976
|
+
import get4 from "lodash.get";
|
|
3977
|
+
var defaultTheme = {
|
|
3653
3978
|
//
|
|
3654
|
-
//
|
|
3979
|
+
// Main layout:
|
|
3980
|
+
// https://codemirror.net/examples/styling
|
|
3655
3981
|
//
|
|
3656
|
-
"
|
|
3657
|
-
|
|
3982
|
+
// <div class="cm-editor [cm-focused] [generated classes]">
|
|
3983
|
+
// <div class="cm-scroller">
|
|
3984
|
+
// <div class="cm-gutters">
|
|
3985
|
+
// <div class="cm-gutter [...]">
|
|
3986
|
+
// <div class="cm-gutterElement">...</div>
|
|
3987
|
+
// </div>
|
|
3988
|
+
// </div>
|
|
3989
|
+
// <div class="cm-content" role="textbox" contenteditable="true">
|
|
3990
|
+
// <div class="cm-line"></div>
|
|
3991
|
+
// </div>
|
|
3992
|
+
// <div class="cm-selectionLayer">
|
|
3993
|
+
// <div class="cm-selectionBackground"></div>
|
|
3994
|
+
// </div>
|
|
3995
|
+
// <div class="cm-cursorLayer">
|
|
3996
|
+
// <div class="cm-cursor"></div>
|
|
3997
|
+
// </div>
|
|
3998
|
+
// </div>
|
|
3999
|
+
// </div>
|
|
4000
|
+
//
|
|
4001
|
+
"&": {},
|
|
4002
|
+
"&.cm-focused": {
|
|
4003
|
+
outline: "none"
|
|
3658
4004
|
},
|
|
3659
|
-
|
|
3660
|
-
|
|
4005
|
+
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
4006
|
+
".cm-scroller": {
|
|
4007
|
+
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
4008
|
+
// Inside of that is the scroller element. If the editor has its own scrollbar, this one should be styled with overflow: auto. But it doesn't have to—the editor also supports growing to accomodate its content, or growing up to a certain max-height and then scrolling.
|
|
4009
|
+
overflowY: "auto",
|
|
4010
|
+
fontFamily: get4(tokens, "fontFamily.mono", []).join(","),
|
|
4011
|
+
lineHeight: 1.5
|
|
3661
4012
|
},
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
textDecorationLine: "underline",
|
|
3668
|
-
textDecorationThickness: "1px",
|
|
3669
|
-
textUnderlineOffset: "2px",
|
|
3670
|
-
borderRadius: ".125rem",
|
|
3671
|
-
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4013
|
+
".cm-content": {
|
|
4014
|
+
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
4015
|
+
// padding: 'unset',
|
|
4016
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
4017
|
+
fontSize: "16px"
|
|
3672
4018
|
},
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
4019
|
+
"&light .cm-content": {
|
|
4020
|
+
color: get4(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
4021
|
+
caretColor: "black"
|
|
4022
|
+
},
|
|
4023
|
+
"&dark .cm-content": {
|
|
4024
|
+
color: get4(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
4025
|
+
caretColor: "white"
|
|
3678
4026
|
},
|
|
3679
|
-
".cm-tooltip-below": {},
|
|
3680
4027
|
//
|
|
3681
|
-
//
|
|
4028
|
+
// Cursor
|
|
3682
4029
|
//
|
|
3683
|
-
".cm-
|
|
3684
|
-
|
|
3685
|
-
marginLeft: "-3px"
|
|
4030
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
4031
|
+
borderLeft: "2px solid black"
|
|
3686
4032
|
},
|
|
3687
|
-
".cm-
|
|
3688
|
-
|
|
3689
|
-
".cm-completionIcon": {
|
|
3690
|
-
display: "none"
|
|
4033
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
4034
|
+
borderLeft: "2px solid white"
|
|
3691
4035
|
},
|
|
3692
|
-
".cm-
|
|
3693
|
-
|
|
4036
|
+
"&light .cm-placeholder": {
|
|
4037
|
+
color: get4(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
3694
4038
|
},
|
|
3695
|
-
".cm-
|
|
3696
|
-
|
|
4039
|
+
"&dark .cm-placeholder": {
|
|
4040
|
+
color: get4(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
4041
|
+
},
|
|
4042
|
+
//
|
|
4043
|
+
// line
|
|
4044
|
+
//
|
|
4045
|
+
".cm-line": {
|
|
4046
|
+
paddingInline: 0
|
|
4047
|
+
},
|
|
4048
|
+
".cm-activeLine": {
|
|
4049
|
+
background: "transparent"
|
|
4050
|
+
},
|
|
4051
|
+
//
|
|
4052
|
+
// gutter
|
|
4053
|
+
//
|
|
4054
|
+
".cm-gutterElement": {
|
|
4055
|
+
width: "48px"
|
|
4056
|
+
},
|
|
4057
|
+
//
|
|
4058
|
+
// Selection
|
|
4059
|
+
//
|
|
4060
|
+
"&light .cm-selectionBackground": {
|
|
4061
|
+
background: get4(tokens, "extend.colors.primary.100")
|
|
4062
|
+
},
|
|
4063
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4064
|
+
background: get4(tokens, "extend.colors.primary.200")
|
|
4065
|
+
},
|
|
4066
|
+
"&dark .cm-selectionBackground": {
|
|
4067
|
+
background: get4(tokens, "extend.colors.primary.700")
|
|
4068
|
+
},
|
|
4069
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4070
|
+
background: get4(tokens, "extend.colors.primary.600")
|
|
4071
|
+
},
|
|
4072
|
+
//
|
|
4073
|
+
// Search
|
|
4074
|
+
//
|
|
4075
|
+
"&light .cm-searchMatch": {
|
|
4076
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.100")
|
|
4077
|
+
},
|
|
4078
|
+
"&dark .cm-searchMatch": {
|
|
4079
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.700")
|
|
4080
|
+
},
|
|
4081
|
+
//
|
|
4082
|
+
// link
|
|
4083
|
+
//
|
|
4084
|
+
".cm-link": {
|
|
4085
|
+
color: get4(tokens, "extend.colors.primary.500"),
|
|
4086
|
+
textDecorationLine: "underline",
|
|
4087
|
+
textDecorationThickness: "1px",
|
|
4088
|
+
textUnderlineOffset: "2px",
|
|
4089
|
+
borderRadius: ".125rem",
|
|
4090
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4091
|
+
},
|
|
4092
|
+
//
|
|
4093
|
+
// tooltip
|
|
4094
|
+
//
|
|
4095
|
+
".cm-tooltip": {
|
|
4096
|
+
border: "none",
|
|
4097
|
+
background: "unset"
|
|
4098
|
+
},
|
|
4099
|
+
".cm-tooltip-below": {},
|
|
4100
|
+
//
|
|
4101
|
+
// autocomplete
|
|
4102
|
+
//
|
|
4103
|
+
".cm-tooltip-autocomplete": {
|
|
4104
|
+
marginTop: "4px",
|
|
4105
|
+
marginLeft: "-3px"
|
|
4106
|
+
},
|
|
4107
|
+
".cm-tooltip-autocomplete ul li": {},
|
|
4108
|
+
".cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
4109
|
+
".cm-completionIcon": {
|
|
4110
|
+
display: "none"
|
|
4111
|
+
},
|
|
4112
|
+
".cm-completionLabel": {
|
|
4113
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4114
|
+
},
|
|
4115
|
+
".cm-completionMatchedText": {
|
|
4116
|
+
textDecoration: "none"
|
|
3697
4117
|
},
|
|
3698
4118
|
//
|
|
3699
4119
|
// table
|
|
@@ -3803,19 +4223,238 @@ var codeTheme = {
|
|
|
3803
4223
|
}
|
|
3804
4224
|
};
|
|
3805
4225
|
|
|
4226
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4227
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4228
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps = []) => {
|
|
4229
|
+
const onUpdate = useRef2();
|
|
4230
|
+
const [view, setView] = useState3();
|
|
4231
|
+
const parentRef = useRef2(null);
|
|
4232
|
+
useEffect2(() => {
|
|
4233
|
+
let view2;
|
|
4234
|
+
if (parentRef.current) {
|
|
4235
|
+
const state = EditorState2.create({
|
|
4236
|
+
doc,
|
|
4237
|
+
selection,
|
|
4238
|
+
extensions: [
|
|
4239
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4240
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4241
|
+
log8.catch(err, void 0, {
|
|
4242
|
+
F: __dxlog_file9,
|
|
4243
|
+
L: 70,
|
|
4244
|
+
S: void 0,
|
|
4245
|
+
C: (f, a) => f(...a)
|
|
4246
|
+
});
|
|
4247
|
+
}),
|
|
4248
|
+
extensions,
|
|
4249
|
+
EditorView16.updateListener.of(() => {
|
|
4250
|
+
onUpdate.current?.();
|
|
4251
|
+
})
|
|
4252
|
+
].filter(isNotFalsy3)
|
|
4253
|
+
});
|
|
4254
|
+
view2 = new EditorView16({
|
|
4255
|
+
parent: parentRef.current,
|
|
4256
|
+
scrollTo,
|
|
4257
|
+
state,
|
|
4258
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4259
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4260
|
+
dispatchTransactions: (trs, view3) => {
|
|
4261
|
+
if (debug) {
|
|
4262
|
+
logChanges(trs);
|
|
4263
|
+
}
|
|
4264
|
+
view3.update(trs);
|
|
4265
|
+
}
|
|
4266
|
+
});
|
|
4267
|
+
setView(view2);
|
|
4268
|
+
}
|
|
4269
|
+
return () => {
|
|
4270
|
+
view2?.destroy();
|
|
4271
|
+
};
|
|
4272
|
+
}, deps);
|
|
4273
|
+
useEffect2(() => {
|
|
4274
|
+
if (view) {
|
|
4275
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4276
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4277
|
+
}
|
|
4278
|
+
if (selection || scrollTo) {
|
|
4279
|
+
onUpdate.current = () => {
|
|
4280
|
+
onUpdate.current = void 0;
|
|
4281
|
+
view.dispatch({
|
|
4282
|
+
selection,
|
|
4283
|
+
effects: scrollTo && [
|
|
4284
|
+
scrollTo
|
|
4285
|
+
],
|
|
4286
|
+
scrollIntoView: !scrollTo
|
|
4287
|
+
});
|
|
4288
|
+
};
|
|
4289
|
+
}
|
|
4290
|
+
if (autoFocus) {
|
|
4291
|
+
view.focus();
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
}, [
|
|
4295
|
+
view,
|
|
4296
|
+
autoFocus,
|
|
4297
|
+
selection,
|
|
4298
|
+
scrollTo
|
|
4299
|
+
]);
|
|
4300
|
+
return {
|
|
4301
|
+
parentRef,
|
|
4302
|
+
view
|
|
4303
|
+
};
|
|
4304
|
+
};
|
|
4305
|
+
var defaults = {
|
|
4306
|
+
bracketMatching: true,
|
|
4307
|
+
closeBrackets: true,
|
|
4308
|
+
drawSelection: true,
|
|
4309
|
+
editable: true,
|
|
4310
|
+
history: true,
|
|
4311
|
+
lineWrapping: true
|
|
4312
|
+
};
|
|
4313
|
+
var createBasicExtensions = (_props) => {
|
|
4314
|
+
const props = defaultsDeep2({}, _props, defaults);
|
|
4315
|
+
return [
|
|
4316
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4317
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4318
|
+
log8.catch(err, void 0, {
|
|
4319
|
+
F: __dxlog_file9,
|
|
4320
|
+
L: 167,
|
|
4321
|
+
S: void 0,
|
|
4322
|
+
C: (f, a) => f(...a)
|
|
4323
|
+
});
|
|
4324
|
+
}),
|
|
4325
|
+
props.allowMultipleSelections && EditorState2.allowMultipleSelections.of(true),
|
|
4326
|
+
props.bracketMatching && bracketMatching2(),
|
|
4327
|
+
props.closeBrackets && closeBrackets2(),
|
|
4328
|
+
props.crosshairCursor && crosshairCursor(),
|
|
4329
|
+
props.dropCursor && dropCursor2(),
|
|
4330
|
+
props.drawSelection && drawSelection2(),
|
|
4331
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
4332
|
+
props.history && history2(),
|
|
4333
|
+
props.lineNumbers && lineNumbers(),
|
|
4334
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
4335
|
+
props.placeholder && placeholder2(props.placeholder),
|
|
4336
|
+
props.readonly && [
|
|
4337
|
+
EditorState2.readOnly.of(true),
|
|
4338
|
+
EditorView16.editable.of(false)
|
|
4339
|
+
],
|
|
4340
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
4341
|
+
props.tabSize && EditorState2.tabSize.of(props.tabSize)
|
|
4342
|
+
].filter(isNotFalsy3);
|
|
4343
|
+
};
|
|
4344
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4345
|
+
return [
|
|
4346
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4347
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4348
|
+
theme && EditorView16.theme(theme),
|
|
4349
|
+
slots?.editor?.className && EditorView16.editorAttributes.of({
|
|
4350
|
+
class: slots.editor.className
|
|
4351
|
+
}),
|
|
4352
|
+
slots?.content?.className && EditorView16.contentAttributes.of({
|
|
4353
|
+
class: slots.content.className
|
|
4354
|
+
})
|
|
4355
|
+
].filter(isNotFalsy3);
|
|
4356
|
+
};
|
|
4357
|
+
|
|
4358
|
+
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4359
|
+
import get5 from "lodash.get";
|
|
4360
|
+
import { useState as useState4, useMemo as useMemo2 } from "react";
|
|
4361
|
+
import { generateName } from "@dxos/display-name";
|
|
4362
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
4363
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4364
|
+
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4365
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4366
|
+
import { hexToHue } from "@dxos/util";
|
|
4367
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4368
|
+
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4369
|
+
const extensions = [
|
|
4370
|
+
automerge(text)
|
|
4371
|
+
];
|
|
4372
|
+
const peerId = identity?.identityKey.toHex();
|
|
4373
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
4374
|
+
if (space && identity) {
|
|
4375
|
+
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4376
|
+
space,
|
|
4377
|
+
channel: `awareness.${id}`,
|
|
4378
|
+
peerId: identity.identityKey.toHex(),
|
|
4379
|
+
info: {
|
|
4380
|
+
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4381
|
+
color: cursorDarkValue,
|
|
4382
|
+
lightColor: cursorLightValue
|
|
4383
|
+
}
|
|
4384
|
+
});
|
|
4385
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4386
|
+
}
|
|
4387
|
+
return extensions;
|
|
4388
|
+
};
|
|
4389
|
+
var useTextModel = (props) => useMemo2(() => createModel(props), Object.values(props));
|
|
4390
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4391
|
+
const [content, setContent] = useState4(defaultContent ?? "");
|
|
4392
|
+
return {
|
|
4393
|
+
id,
|
|
4394
|
+
content,
|
|
4395
|
+
text: () => content,
|
|
4396
|
+
setContent
|
|
4397
|
+
};
|
|
4398
|
+
};
|
|
4399
|
+
var createModel = ({ space, identity, text }) => {
|
|
4400
|
+
if (!text) {
|
|
4401
|
+
return void 0;
|
|
4402
|
+
}
|
|
4403
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
4404
|
+
F: __dxlog_file10,
|
|
4405
|
+
L: 89,
|
|
4406
|
+
S: void 0,
|
|
4407
|
+
A: [
|
|
4408
|
+
"isAutomergeObject(text)",
|
|
4409
|
+
""
|
|
4410
|
+
]
|
|
4411
|
+
});
|
|
4412
|
+
const obj = text;
|
|
4413
|
+
const doc = getRawDoc(obj, [
|
|
4414
|
+
obj.field
|
|
4415
|
+
]);
|
|
4416
|
+
const peerId = identity?.identityKey.toHex();
|
|
4417
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
4418
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4419
|
+
space,
|
|
4420
|
+
channel: `automerge.awareness.${obj.id}`,
|
|
4421
|
+
info: {
|
|
4422
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4423
|
+
color: cursorLightValue,
|
|
4424
|
+
lightColor: cursorDarkValue
|
|
4425
|
+
},
|
|
4426
|
+
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4427
|
+
});
|
|
4428
|
+
const extensions = [
|
|
4429
|
+
automerge({
|
|
4430
|
+
handle: doc.handle,
|
|
4431
|
+
path: doc.path
|
|
4432
|
+
})
|
|
4433
|
+
];
|
|
4434
|
+
if (awarenessProvider2) {
|
|
4435
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4436
|
+
}
|
|
4437
|
+
return {
|
|
4438
|
+
id: obj.id,
|
|
4439
|
+
content: doc,
|
|
4440
|
+
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4441
|
+
extension: extensions
|
|
4442
|
+
};
|
|
4443
|
+
};
|
|
4444
|
+
|
|
3806
4445
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3807
|
-
var
|
|
3808
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo =
|
|
4446
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4447
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo = EditorView17.scrollIntoView(0), moveToEndOfLine, selection, theme, slots = defaultSlots, extensions = [], scrollPastEnd: _scrollPastEnd, debug }, forwardedRef) => {
|
|
3809
4448
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
3810
4449
|
tabBehavior: "limited"
|
|
3811
4450
|
});
|
|
3812
4451
|
const { themeMode } = useThemeContext();
|
|
3813
|
-
const rootRef =
|
|
3814
|
-
const [view, setView] =
|
|
4452
|
+
const rootRef = useRef3(null);
|
|
4453
|
+
const [view, setView] = useState5(null);
|
|
3815
4454
|
useImperativeHandle(forwardedRef, () => view, [
|
|
3816
4455
|
view
|
|
3817
4456
|
]);
|
|
3818
|
-
|
|
4457
|
+
useEffect3(() => {
|
|
3819
4458
|
if (autoFocus) {
|
|
3820
4459
|
view?.focus();
|
|
3821
4460
|
}
|
|
@@ -3823,38 +4462,38 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3823
4462
|
view,
|
|
3824
4463
|
autoFocus
|
|
3825
4464
|
]);
|
|
3826
|
-
|
|
4465
|
+
useEffect3(() => {
|
|
3827
4466
|
if (!model || !rootRef.current) {
|
|
3828
4467
|
return;
|
|
3829
4468
|
}
|
|
3830
|
-
const state =
|
|
3831
|
-
doc: model.
|
|
4469
|
+
const state = EditorState3.create({
|
|
4470
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
3832
4471
|
selection,
|
|
3833
4472
|
extensions: [
|
|
3834
4473
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
F:
|
|
3838
|
-
L:
|
|
4474
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4475
|
+
log9.catch(err, void 0, {
|
|
4476
|
+
F: __dxlog_file11,
|
|
4477
|
+
L: 123,
|
|
3839
4478
|
S: void 0,
|
|
3840
4479
|
C: (f, a) => f(...a)
|
|
3841
4480
|
});
|
|
3842
4481
|
}),
|
|
3843
4482
|
// Theme.
|
|
3844
4483
|
// TODO(burdon): Make base theme configurable.
|
|
3845
|
-
|
|
3846
|
-
theme &&
|
|
3847
|
-
|
|
3848
|
-
slots.editor?.className &&
|
|
4484
|
+
EditorView17.baseTheme(defaultTheme),
|
|
4485
|
+
theme && EditorView17.theme(theme),
|
|
4486
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
4487
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
3849
4488
|
class: slots.editor.className
|
|
3850
4489
|
}),
|
|
3851
|
-
slots.content?.className &&
|
|
4490
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3852
4491
|
class: slots.content.className
|
|
3853
4492
|
}),
|
|
3854
4493
|
// NOTE: Assumes default line height.
|
|
3855
|
-
_scrollPastEnd &&
|
|
4494
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
3856
4495
|
// Focus.
|
|
3857
|
-
|
|
4496
|
+
EditorView17.updateListener.of((update2) => {
|
|
3858
4497
|
update2.transactions.forEach((transaction) => {
|
|
3859
4498
|
if (transaction.isUserEvent("focus.container")) {
|
|
3860
4499
|
rootRef.current?.focus();
|
|
@@ -3862,8 +4501,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3862
4501
|
});
|
|
3863
4502
|
}),
|
|
3864
4503
|
// State.
|
|
3865
|
-
|
|
3866
|
-
|
|
4504
|
+
EditorView17.editable.of(!readonly),
|
|
4505
|
+
EditorState3.readOnly.of(!!readonly),
|
|
3867
4506
|
// Storage and replication.
|
|
3868
4507
|
// NOTE: This must come before user extensions.
|
|
3869
4508
|
model.extension,
|
|
@@ -3871,7 +4510,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3871
4510
|
...extensions
|
|
3872
4511
|
].filter(isNotFalsy4)
|
|
3873
4512
|
});
|
|
3874
|
-
const view2 = new
|
|
4513
|
+
const view2 = new EditorView17({
|
|
3875
4514
|
state,
|
|
3876
4515
|
parent: rootRef.current,
|
|
3877
4516
|
scrollTo,
|
|
@@ -3928,14 +4567,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3928
4567
|
...tabsterDOMAttribute
|
|
3929
4568
|
});
|
|
3930
4569
|
});
|
|
3931
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4570
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping = true, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3932
4571
|
const { themeMode } = useThemeContext();
|
|
3933
|
-
const updatedSlots =
|
|
3934
|
-
const extensions =
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
placeholder: placeholder3
|
|
3938
|
-
|
|
4572
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4573
|
+
const extensions = useMemo3(() => [
|
|
4574
|
+
createBasicExtensions({
|
|
4575
|
+
lineWrapping,
|
|
4576
|
+
placeholder: placeholder3
|
|
4577
|
+
}),
|
|
4578
|
+
createThemeExtensions({
|
|
4579
|
+
themeMode
|
|
3939
4580
|
}),
|
|
3940
4581
|
..._extensions ?? []
|
|
3941
4582
|
], [
|
|
@@ -3955,8 +4596,8 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
3955
4596
|
});
|
|
3956
4597
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3957
4598
|
const { themeMode } = useThemeContext();
|
|
3958
|
-
const updatedSlots =
|
|
3959
|
-
const extensions =
|
|
4599
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4600
|
+
const extensions = useMemo3(() => [
|
|
3960
4601
|
createMarkdownExtensions({
|
|
3961
4602
|
themeMode,
|
|
3962
4603
|
placeholder: placeholder3
|
|
@@ -3994,7 +4635,7 @@ var defaultMarkdownSlots = {
|
|
|
3994
4635
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
3995
4636
|
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
3996
4637
|
import { createContext } from "@radix-ui/react-context";
|
|
3997
|
-
import React2, { useRef as
|
|
4638
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
3998
4639
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
3999
4640
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4000
4641
|
var tooltipProps = {
|
|
@@ -4052,9 +4693,9 @@ var MarkdownHeading = () => {
|
|
|
4052
4693
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4053
4694
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4054
4695
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4055
|
-
const suppressNextTooltip =
|
|
4056
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4057
|
-
const [selectOpen, setSelectOpen] =
|
|
4696
|
+
const suppressNextTooltip = useRef4(false);
|
|
4697
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4698
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4058
4699
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4059
4700
|
open: tooltipOpen,
|
|
4060
4701
|
onOpenChange: (nextOpen) => {
|
|
@@ -4257,378 +4898,6 @@ var Toolbar = {
|
|
|
4257
4898
|
Markdown: MarkdownStandard,
|
|
4258
4899
|
Extended: MarkdownExtended
|
|
4259
4900
|
};
|
|
4260
|
-
|
|
4261
|
-
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4262
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4263
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4264
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
4265
|
-
import { log as log4 } from "@dxos/log";
|
|
4266
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4267
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
4268
|
-
var SpaceAwarenessProvider = class {
|
|
4269
|
-
constructor(params) {
|
|
4270
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4271
|
-
this.remoteStateChange = new Event2();
|
|
4272
|
-
this._space = params.space;
|
|
4273
|
-
this._channel = params.channel;
|
|
4274
|
-
this._peerId = params.peerId;
|
|
4275
|
-
this._info = params.info;
|
|
4276
|
-
}
|
|
4277
|
-
open() {
|
|
4278
|
-
this._ctx = new Context2();
|
|
4279
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4280
|
-
if (this._localState) {
|
|
4281
|
-
await this._space.postMessage(this._channel, {
|
|
4282
|
-
kind: "post",
|
|
4283
|
-
state: this._localState
|
|
4284
|
-
});
|
|
4285
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
4286
|
-
}
|
|
4287
|
-
});
|
|
4288
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4289
|
-
switch (message.payload.kind) {
|
|
4290
|
-
case "query": {
|
|
4291
|
-
this._handleQueryMessage();
|
|
4292
|
-
break;
|
|
4293
|
-
}
|
|
4294
|
-
case "post": {
|
|
4295
|
-
this._handlePostMessage(message.payload);
|
|
4296
|
-
break;
|
|
4297
|
-
}
|
|
4298
|
-
}
|
|
4299
|
-
}));
|
|
4300
|
-
void this._space.postMessage(this._channel, {
|
|
4301
|
-
kind: "query"
|
|
4302
|
-
}).catch((err) => {
|
|
4303
|
-
log4.debug("failed to query awareness", {
|
|
4304
|
-
err
|
|
4305
|
-
}, {
|
|
4306
|
-
F: __dxlog_file5,
|
|
4307
|
-
L: 89,
|
|
4308
|
-
S: this,
|
|
4309
|
-
C: (f, a) => f(...a)
|
|
4310
|
-
});
|
|
4311
|
-
});
|
|
4312
|
-
}
|
|
4313
|
-
close() {
|
|
4314
|
-
void this._ctx?.dispose();
|
|
4315
|
-
this._ctx = void 0;
|
|
4316
|
-
this._postTask = void 0;
|
|
4317
|
-
}
|
|
4318
|
-
getRemoteStates() {
|
|
4319
|
-
return Array.from(this._remoteStates.values());
|
|
4320
|
-
}
|
|
4321
|
-
update(position) {
|
|
4322
|
-
invariant2(this._postTask, void 0, {
|
|
4323
|
-
F: __dxlog_file5,
|
|
4324
|
-
L: 104,
|
|
4325
|
-
S: this,
|
|
4326
|
-
A: [
|
|
4327
|
-
"this._postTask",
|
|
4328
|
-
""
|
|
4329
|
-
]
|
|
4330
|
-
});
|
|
4331
|
-
this._localState = {
|
|
4332
|
-
peerId: this._peerId,
|
|
4333
|
-
position,
|
|
4334
|
-
info: this._info
|
|
4335
|
-
};
|
|
4336
|
-
this._postTask.schedule();
|
|
4337
|
-
}
|
|
4338
|
-
_handleQueryMessage() {
|
|
4339
|
-
invariant2(this._postTask, void 0, {
|
|
4340
|
-
F: __dxlog_file5,
|
|
4341
|
-
L: 115,
|
|
4342
|
-
S: this,
|
|
4343
|
-
A: [
|
|
4344
|
-
"this._postTask",
|
|
4345
|
-
""
|
|
4346
|
-
]
|
|
4347
|
-
});
|
|
4348
|
-
this._postTask.schedule();
|
|
4349
|
-
}
|
|
4350
|
-
_handlePostMessage(message) {
|
|
4351
|
-
invariant2(message.kind === "post", void 0, {
|
|
4352
|
-
F: __dxlog_file5,
|
|
4353
|
-
L: 120,
|
|
4354
|
-
S: this,
|
|
4355
|
-
A: [
|
|
4356
|
-
"message.kind === 'post'",
|
|
4357
|
-
""
|
|
4358
|
-
]
|
|
4359
|
-
});
|
|
4360
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
4361
|
-
this.remoteStateChange.emit();
|
|
4362
|
-
}
|
|
4363
|
-
};
|
|
4364
|
-
|
|
4365
|
-
// packages/ui/react-ui-editor/src/hooks/defs.ts
|
|
4366
|
-
import { StateField as StateField6 } from "@codemirror/state";
|
|
4367
|
-
var modelState = StateField6.define({
|
|
4368
|
-
create: () => void 0,
|
|
4369
|
-
update: (model) => model
|
|
4370
|
-
});
|
|
4371
|
-
|
|
4372
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4373
|
-
var useActionHandler = (view) => {
|
|
4374
|
-
return (action) => {
|
|
4375
|
-
if (!view) {
|
|
4376
|
-
return;
|
|
4377
|
-
}
|
|
4378
|
-
let inlineType, listType;
|
|
4379
|
-
switch (action.type) {
|
|
4380
|
-
case "heading":
|
|
4381
|
-
setHeading(parseInt(action.data))(view);
|
|
4382
|
-
break;
|
|
4383
|
-
case "strong":
|
|
4384
|
-
case "emphasis":
|
|
4385
|
-
case "strikethrough":
|
|
4386
|
-
case "code":
|
|
4387
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4388
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4389
|
-
break;
|
|
4390
|
-
case "list-ordered":
|
|
4391
|
-
case "list-bullet":
|
|
4392
|
-
case "list-task":
|
|
4393
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4394
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4395
|
-
break;
|
|
4396
|
-
case "blockquote":
|
|
4397
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4398
|
-
break;
|
|
4399
|
-
case "codeblock":
|
|
4400
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4401
|
-
break;
|
|
4402
|
-
case "table":
|
|
4403
|
-
insertTable(view);
|
|
4404
|
-
break;
|
|
4405
|
-
case "link":
|
|
4406
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4407
|
-
break;
|
|
4408
|
-
case "comment":
|
|
4409
|
-
createComment(view);
|
|
4410
|
-
break;
|
|
4411
|
-
}
|
|
4412
|
-
setTimeout(() => {
|
|
4413
|
-
if (!view.hasFocus) {
|
|
4414
|
-
view.focus();
|
|
4415
|
-
}
|
|
4416
|
-
});
|
|
4417
|
-
};
|
|
4418
|
-
};
|
|
4419
|
-
|
|
4420
|
-
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4421
|
-
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4422
|
-
var useEditorView = (id) => {
|
|
4423
|
-
const editorRef = useRef3(null);
|
|
4424
|
-
const [prev, setPrev] = useState4([
|
|
4425
|
-
null,
|
|
4426
|
-
""
|
|
4427
|
-
]);
|
|
4428
|
-
if (prev[0] !== editorRef.current) {
|
|
4429
|
-
setPrev([
|
|
4430
|
-
editorRef.current,
|
|
4431
|
-
id
|
|
4432
|
-
]);
|
|
4433
|
-
}
|
|
4434
|
-
return [
|
|
4435
|
-
editorRef,
|
|
4436
|
-
prev[1] !== id
|
|
4437
|
-
];
|
|
4438
|
-
};
|
|
4439
|
-
|
|
4440
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4441
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4442
|
-
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4443
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4444
|
-
import { log as log5 } from "@dxos/log";
|
|
4445
|
-
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4446
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4447
|
-
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps) => {
|
|
4448
|
-
const onUpdate = useRef4();
|
|
4449
|
-
const [view, setView] = useState5();
|
|
4450
|
-
const parentRef = useRef4(null);
|
|
4451
|
-
useEffect3(() => {
|
|
4452
|
-
let view2;
|
|
4453
|
-
if (parentRef.current) {
|
|
4454
|
-
const state = EditorState3.create({
|
|
4455
|
-
doc,
|
|
4456
|
-
selection,
|
|
4457
|
-
extensions: [
|
|
4458
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4459
|
-
EditorView15.exceptionSink.of((err) => {
|
|
4460
|
-
log5.catch(err, void 0, {
|
|
4461
|
-
F: __dxlog_file6,
|
|
4462
|
-
L: 57,
|
|
4463
|
-
S: void 0,
|
|
4464
|
-
C: (f, a) => f(...a)
|
|
4465
|
-
});
|
|
4466
|
-
}),
|
|
4467
|
-
extensions,
|
|
4468
|
-
EditorView15.updateListener.of(() => {
|
|
4469
|
-
onUpdate.current?.();
|
|
4470
|
-
})
|
|
4471
|
-
].filter(isNotFalsy5)
|
|
4472
|
-
});
|
|
4473
|
-
view2 = new EditorView15({
|
|
4474
|
-
parent: parentRef.current,
|
|
4475
|
-
scrollTo,
|
|
4476
|
-
state,
|
|
4477
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4478
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4479
|
-
dispatchTransactions: (trs, view3) => {
|
|
4480
|
-
if (debug) {
|
|
4481
|
-
logChanges(trs);
|
|
4482
|
-
}
|
|
4483
|
-
view3.update(trs);
|
|
4484
|
-
}
|
|
4485
|
-
});
|
|
4486
|
-
setView(view2);
|
|
4487
|
-
}
|
|
4488
|
-
return () => {
|
|
4489
|
-
view2?.destroy();
|
|
4490
|
-
};
|
|
4491
|
-
}, deps);
|
|
4492
|
-
useEffect3(() => {
|
|
4493
|
-
if (view) {
|
|
4494
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4495
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4496
|
-
}
|
|
4497
|
-
if (selection || scrollTo) {
|
|
4498
|
-
onUpdate.current = () => {
|
|
4499
|
-
onUpdate.current = void 0;
|
|
4500
|
-
view.dispatch({
|
|
4501
|
-
selection,
|
|
4502
|
-
effects: scrollTo && [
|
|
4503
|
-
scrollTo
|
|
4504
|
-
],
|
|
4505
|
-
scrollIntoView: !scrollTo
|
|
4506
|
-
});
|
|
4507
|
-
};
|
|
4508
|
-
}
|
|
4509
|
-
if (autoFocus) {
|
|
4510
|
-
view.focus();
|
|
4511
|
-
}
|
|
4512
|
-
}
|
|
4513
|
-
}, [
|
|
4514
|
-
view,
|
|
4515
|
-
autoFocus,
|
|
4516
|
-
selection,
|
|
4517
|
-
scrollTo
|
|
4518
|
-
]);
|
|
4519
|
-
return {
|
|
4520
|
-
parentRef,
|
|
4521
|
-
view
|
|
4522
|
-
};
|
|
4523
|
-
};
|
|
4524
|
-
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4525
|
-
return [
|
|
4526
|
-
//
|
|
4527
|
-
EditorState3.readOnly.of(readonly),
|
|
4528
|
-
EditorView15.editable.of(!readonly)
|
|
4529
|
-
];
|
|
4530
|
-
};
|
|
4531
|
-
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4532
|
-
return [
|
|
4533
|
-
//
|
|
4534
|
-
EditorView15.baseTheme(defaultTheme),
|
|
4535
|
-
theme && EditorView15.theme(theme),
|
|
4536
|
-
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4537
|
-
EditorView15.editorAttributes.of({
|
|
4538
|
-
class: slots?.editor?.className ?? ""
|
|
4539
|
-
}),
|
|
4540
|
-
EditorView15.contentAttributes.of({
|
|
4541
|
-
class: slots?.content?.className ?? ""
|
|
4542
|
-
})
|
|
4543
|
-
].filter(isNotFalsy5);
|
|
4544
|
-
};
|
|
4545
|
-
|
|
4546
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4547
|
-
import get5 from "lodash.get";
|
|
4548
|
-
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4549
|
-
import { generateName } from "@dxos/display-name";
|
|
4550
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
4551
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4552
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4553
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4554
|
-
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4555
|
-
const extensions = [
|
|
4556
|
-
automerge(text)
|
|
4557
|
-
];
|
|
4558
|
-
if (space && identity) {
|
|
4559
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4560
|
-
space,
|
|
4561
|
-
channel: `awareness.${id}`,
|
|
4562
|
-
peerId: identity.identityKey.toHex(),
|
|
4563
|
-
info: {
|
|
4564
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4565
|
-
color: cursorColor.color,
|
|
4566
|
-
lightColor: cursorColor.light
|
|
4567
|
-
}
|
|
4568
|
-
});
|
|
4569
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4570
|
-
}
|
|
4571
|
-
return extensions;
|
|
4572
|
-
};
|
|
4573
|
-
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4574
|
-
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4575
|
-
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4576
|
-
return {
|
|
4577
|
-
id,
|
|
4578
|
-
content,
|
|
4579
|
-
setContent,
|
|
4580
|
-
text: () => content
|
|
4581
|
-
};
|
|
4582
|
-
};
|
|
4583
|
-
var createModel = ({ space, identity, text }) => {
|
|
4584
|
-
if (!text) {
|
|
4585
|
-
return void 0;
|
|
4586
|
-
}
|
|
4587
|
-
invariant3(isAutomergeObject(text), void 0, {
|
|
4588
|
-
F: __dxlog_file7,
|
|
4589
|
-
L: 83,
|
|
4590
|
-
S: void 0,
|
|
4591
|
-
A: [
|
|
4592
|
-
"isAutomergeObject(text)",
|
|
4593
|
-
""
|
|
4594
|
-
]
|
|
4595
|
-
});
|
|
4596
|
-
const obj = text;
|
|
4597
|
-
const doc = getRawDoc(obj, [
|
|
4598
|
-
obj.field
|
|
4599
|
-
]);
|
|
4600
|
-
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4601
|
-
space,
|
|
4602
|
-
channel: `automerge.awareness.${obj.id}`,
|
|
4603
|
-
info: {
|
|
4604
|
-
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4605
|
-
color: cursorColor.color,
|
|
4606
|
-
lightColor: cursorColor.light
|
|
4607
|
-
},
|
|
4608
|
-
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4609
|
-
});
|
|
4610
|
-
const extensions = [
|
|
4611
|
-
modelState.init(() => model),
|
|
4612
|
-
automerge({
|
|
4613
|
-
handle: doc.handle,
|
|
4614
|
-
path: doc.path
|
|
4615
|
-
})
|
|
4616
|
-
];
|
|
4617
|
-
if (awarenessProvider2) {
|
|
4618
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4619
|
-
}
|
|
4620
|
-
const model = {
|
|
4621
|
-
id: obj.id,
|
|
4622
|
-
content: doc,
|
|
4623
|
-
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4624
|
-
extension: extensions,
|
|
4625
|
-
peer: identity ? {
|
|
4626
|
-
id: identity.identityKey.toHex(),
|
|
4627
|
-
name: identity.profile?.displayName
|
|
4628
|
-
} : void 0
|
|
4629
|
-
};
|
|
4630
|
-
return model;
|
|
4631
|
-
};
|
|
4632
4901
|
export {
|
|
4633
4902
|
BaseTextEditor,
|
|
4634
4903
|
Cursor,
|
|
@@ -4657,11 +4926,11 @@ export {
|
|
|
4657
4926
|
blast,
|
|
4658
4927
|
callbackWrapper,
|
|
4659
4928
|
codeTheme,
|
|
4929
|
+
command,
|
|
4660
4930
|
comments,
|
|
4661
4931
|
compareFormatting,
|
|
4662
|
-
|
|
4932
|
+
createBasicExtensions,
|
|
4663
4933
|
createComment,
|
|
4664
|
-
createDataExtensions,
|
|
4665
4934
|
createMarkdownExtensions,
|
|
4666
4935
|
createThemeExtensions,
|
|
4667
4936
|
cursorLineMargin,
|
|
@@ -4672,6 +4941,7 @@ export {
|
|
|
4672
4941
|
defaultSlots,
|
|
4673
4942
|
defaultTextSlots,
|
|
4674
4943
|
defaultTheme,
|
|
4944
|
+
dnd,
|
|
4675
4945
|
editorFillLayoutEditor,
|
|
4676
4946
|
editorFillLayoutRoot,
|
|
4677
4947
|
editorMode,
|
|
@@ -4682,7 +4952,7 @@ export {
|
|
|
4682
4952
|
getToken,
|
|
4683
4953
|
image,
|
|
4684
4954
|
insertTable,
|
|
4685
|
-
|
|
4955
|
+
keymap9 as keymap,
|
|
4686
4956
|
linkTooltip,
|
|
4687
4957
|
listener,
|
|
4688
4958
|
logChanges,
|
|
@@ -4691,7 +4961,6 @@ export {
|
|
|
4691
4961
|
markdownTagsExtensions,
|
|
4692
4962
|
markdownTheme,
|
|
4693
4963
|
mention,
|
|
4694
|
-
modelState,
|
|
4695
4964
|
outliner,
|
|
4696
4965
|
removeBlockquote,
|
|
4697
4966
|
removeCodeblock,
|