@dxos/react-ui-editor 0.4.7-main.b23cefb → 0.4.7-main.b51ad3a
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 +982 -711
- 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 +3 -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/themes/default.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +95 -8
- package/src/components/TextEditor/TextEditor.stories.tsx +0 -15
- package/src/components/TextEditor/TextEditor.tsx +11 -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/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 -14
- package/src/extensions/markdown/decorate.ts +21 -14
- 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 +11 -16
- package/src/index.ts +2 -0
- 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/src/extensions/basic.ts +0 -41
|
@@ -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";
|
|
@@ -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,13 +1042,231 @@ var random = (min, max) => {
|
|
|
1063
1042
|
return min + ~~(Math.random() * (max - min + 1));
|
|
1064
1043
|
};
|
|
1065
1044
|
|
|
1045
|
+
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1046
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1047
|
+
|
|
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;
|
|
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 = [
|
|
1145
|
+
{
|
|
1146
|
+
key: "/",
|
|
1147
|
+
run: openCommand
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
key: "Escape",
|
|
1151
|
+
run: closeCommand
|
|
1152
|
+
}
|
|
1153
|
+
];
|
|
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
|
+
|
|
1066
1262
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1067
1263
|
import { invertedEffects } from "@codemirror/commands";
|
|
1068
|
-
import { Facet as
|
|
1069
|
-
import { hoverTooltip, keymap as
|
|
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";
|
|
1070
1266
|
import sortBy from "lodash.sortby";
|
|
1071
1267
|
import { useEffect } from "react";
|
|
1072
1268
|
import { debounce } from "@dxos/async";
|
|
1269
|
+
import { log as log3 } from "@dxos/log";
|
|
1073
1270
|
import { nonNullable } from "@dxos/util";
|
|
1074
1271
|
|
|
1075
1272
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
@@ -1137,18 +1334,26 @@ var logChanges = (trs) => {
|
|
|
1137
1334
|
return changes2;
|
|
1138
1335
|
}).filter(Boolean);
|
|
1139
1336
|
if (changes.length) {
|
|
1140
|
-
|
|
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
|
+
});
|
|
1141
1345
|
}
|
|
1142
1346
|
};
|
|
1143
1347
|
|
|
1144
1348
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1145
|
-
var
|
|
1349
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1350
|
+
var documentId = Facet4.define({
|
|
1146
1351
|
combine: (values) => values[0]
|
|
1147
1352
|
});
|
|
1148
|
-
var setComments =
|
|
1149
|
-
var setSelection =
|
|
1150
|
-
var setCommentState =
|
|
1151
|
-
var commentsState =
|
|
1353
|
+
var setComments = StateEffect3.define();
|
|
1354
|
+
var setSelection = StateEffect3.define();
|
|
1355
|
+
var setCommentState = StateEffect3.define();
|
|
1356
|
+
var commentsState = StateField4.define({
|
|
1152
1357
|
create: (state) => ({
|
|
1153
1358
|
id: state.facet(documentId),
|
|
1154
1359
|
comments: [],
|
|
@@ -1186,7 +1391,7 @@ var commentsState = StateField3.define({
|
|
|
1186
1391
|
return value;
|
|
1187
1392
|
}
|
|
1188
1393
|
});
|
|
1189
|
-
var styles3 =
|
|
1394
|
+
var styles3 = EditorView7.baseTheme({
|
|
1190
1395
|
"&light .cm-comment, &light .cm-comment-current": {
|
|
1191
1396
|
mixBlendMode: "darken"
|
|
1192
1397
|
},
|
|
@@ -1208,26 +1413,31 @@ var styles3 = EditorView6.baseTheme({
|
|
|
1208
1413
|
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1209
1414
|
}
|
|
1210
1415
|
});
|
|
1211
|
-
var commentMark =
|
|
1416
|
+
var commentMark = Decoration4.mark({
|
|
1212
1417
|
class: "cm-comment",
|
|
1213
1418
|
attributes: {
|
|
1214
1419
|
"data-testid": "cm-comment"
|
|
1215
1420
|
}
|
|
1216
1421
|
});
|
|
1217
|
-
var commentCurrentMark =
|
|
1422
|
+
var commentCurrentMark = Decoration4.mark({
|
|
1218
1423
|
class: "cm-comment-current",
|
|
1219
1424
|
attributes: {
|
|
1220
1425
|
"data-testid": "cm-comment"
|
|
1221
1426
|
}
|
|
1222
1427
|
});
|
|
1223
|
-
var commentsDecorations =
|
|
1428
|
+
var commentsDecorations = EditorView7.decorations.compute([
|
|
1224
1429
|
commentsState
|
|
1225
1430
|
], (state) => {
|
|
1226
1431
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
1227
1432
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1228
1433
|
const range = comment.range;
|
|
1229
1434
|
if (!range || range.from === range.to) {
|
|
1230
|
-
|
|
1435
|
+
log3.warn("Invalid range:", range, {
|
|
1436
|
+
F: __dxlog_file4,
|
|
1437
|
+
L: 132,
|
|
1438
|
+
S: void 0,
|
|
1439
|
+
C: (f, a) => f(...a)
|
|
1440
|
+
});
|
|
1231
1441
|
return void 0;
|
|
1232
1442
|
}
|
|
1233
1443
|
if (comment.comment.id === current) {
|
|
@@ -1236,7 +1446,7 @@ var commentsDecorations = EditorView6.decorations.compute([
|
|
|
1236
1446
|
return commentMark.range(range.from, range.to);
|
|
1237
1447
|
}
|
|
1238
1448
|
}).filter(nonNullable);
|
|
1239
|
-
return
|
|
1449
|
+
return Decoration4.set(decorations);
|
|
1240
1450
|
});
|
|
1241
1451
|
var trackPastedComments = (onUpdate) => {
|
|
1242
1452
|
let tracked = null;
|
|
@@ -1258,7 +1468,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1258
1468
|
}
|
|
1259
1469
|
};
|
|
1260
1470
|
return [
|
|
1261
|
-
|
|
1471
|
+
EditorView7.domEventHandlers({
|
|
1262
1472
|
cut: handleTrack,
|
|
1263
1473
|
copy: handleTrack
|
|
1264
1474
|
}),
|
|
@@ -1280,7 +1490,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1280
1490
|
return effects;
|
|
1281
1491
|
}),
|
|
1282
1492
|
// Handle paste or the undo of comment deletion.
|
|
1283
|
-
|
|
1493
|
+
EditorView7.updateListener.of((update2) => {
|
|
1284
1494
|
const restore = [];
|
|
1285
1495
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1286
1496
|
const tr = update2.transactions[i];
|
|
@@ -1336,7 +1546,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
1336
1546
|
from: changes.mapPos(comment.from, 1),
|
|
1337
1547
|
to: changes.mapPos(comment.to, 1)
|
|
1338
1548
|
});
|
|
1339
|
-
var restoreCommentEffect =
|
|
1549
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
1340
1550
|
map: mapTrackedComment
|
|
1341
1551
|
});
|
|
1342
1552
|
var createComment = (view) => {
|
|
@@ -1377,7 +1587,7 @@ var createComment = (view) => {
|
|
|
1377
1587
|
}
|
|
1378
1588
|
return false;
|
|
1379
1589
|
};
|
|
1380
|
-
var optionsFacet =
|
|
1590
|
+
var optionsFacet = Facet4.define({
|
|
1381
1591
|
combine: (providers) => providers[0]
|
|
1382
1592
|
});
|
|
1383
1593
|
var comments = (options = {}) => {
|
|
@@ -1392,7 +1602,7 @@ var comments = (options = {}) => {
|
|
|
1392
1602
|
//
|
|
1393
1603
|
// Keymap.
|
|
1394
1604
|
//
|
|
1395
|
-
options.onCreate ?
|
|
1605
|
+
options.onCreate ? keymap4.of([
|
|
1396
1606
|
{
|
|
1397
1607
|
key: shortcut,
|
|
1398
1608
|
run: callbackWrapper(createComment)
|
|
@@ -1431,7 +1641,7 @@ var comments = (options = {}) => {
|
|
|
1431
1641
|
//
|
|
1432
1642
|
// Track deleted ranges and update ranges for decorations.
|
|
1433
1643
|
//
|
|
1434
|
-
|
|
1644
|
+
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1435
1645
|
let mod = false;
|
|
1436
1646
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1437
1647
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1463,7 +1673,7 @@ var comments = (options = {}) => {
|
|
|
1463
1673
|
//
|
|
1464
1674
|
// Track selection/proximity.
|
|
1465
1675
|
//
|
|
1466
|
-
|
|
1676
|
+
EditorView7.updateListener.of(({ view, state }) => {
|
|
1467
1677
|
let min = Infinity;
|
|
1468
1678
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1469
1679
|
const { head } = state.selection.main;
|
|
@@ -1512,7 +1722,7 @@ var focusComment = (view, id, center = true) => {
|
|
|
1512
1722
|
},
|
|
1513
1723
|
effects: [
|
|
1514
1724
|
//
|
|
1515
|
-
|
|
1725
|
+
EditorView7.scrollIntoView(range.from, center ? {
|
|
1516
1726
|
y: "center"
|
|
1517
1727
|
} : void 0),
|
|
1518
1728
|
setSelection.of({
|
|
@@ -1540,14 +1750,16 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1540
1750
|
};
|
|
1541
1751
|
|
|
1542
1752
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1543
|
-
import { Facet as
|
|
1544
|
-
import { EditorView as
|
|
1545
|
-
|
|
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({
|
|
1546
1758
|
combine: (input) => input[0] ?? 3
|
|
1547
1759
|
});
|
|
1548
1760
|
var annotation = "cursorLineMargin";
|
|
1549
1761
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1550
|
-
var cursorLineMargin =
|
|
1762
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1551
1763
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1552
1764
|
return;
|
|
1553
1765
|
}
|
|
@@ -1565,7 +1777,12 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1565
1777
|
const needsScrollTop = false;
|
|
1566
1778
|
const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
|
|
1567
1779
|
if (needsScrollTop && needsScrollBot) {
|
|
1568
|
-
|
|
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
|
+
});
|
|
1569
1786
|
return;
|
|
1570
1787
|
}
|
|
1571
1788
|
if (!needsScrollTop && !needsScrollBot) {
|
|
@@ -1583,38 +1800,57 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1583
1800
|
}
|
|
1584
1801
|
view.dispatch({
|
|
1585
1802
|
annotations: Transaction.userEvent.of(annotation),
|
|
1586
|
-
effects:
|
|
1803
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1587
1804
|
y: needsScrollTop ? "start" : "end",
|
|
1588
1805
|
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1589
1806
|
})
|
|
1590
1807
|
});
|
|
1591
1808
|
});
|
|
1592
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
|
+
|
|
1593
1829
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1594
|
-
import { EditorView as
|
|
1830
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1595
1831
|
var listener = ({ onFocus, onChange }) => {
|
|
1596
1832
|
const extensions = [];
|
|
1597
|
-
onFocus && extensions.push(
|
|
1598
|
-
onFocus(
|
|
1833
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1834
|
+
onFocus(focusing);
|
|
1599
1835
|
return null;
|
|
1600
1836
|
}));
|
|
1601
|
-
onChange && extensions.push(
|
|
1837
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1602
1838
|
onChange(update2.state.doc.toString());
|
|
1603
1839
|
}));
|
|
1604
1840
|
return extensions;
|
|
1605
1841
|
};
|
|
1606
1842
|
|
|
1607
1843
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1608
|
-
import { closeBrackets
|
|
1609
|
-
import { history
|
|
1844
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1845
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1610
1846
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1611
|
-
import { bracketMatching
|
|
1847
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1612
1848
|
import { languages } from "@codemirror/language-data";
|
|
1613
1849
|
import { searchKeymap } from "@codemirror/search";
|
|
1614
1850
|
import { EditorState } from "@codemirror/state";
|
|
1615
|
-
import { oneDarkHighlightStyle
|
|
1616
|
-
import {
|
|
1617
|
-
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";
|
|
1618
1854
|
|
|
1619
1855
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1620
1856
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1807,19 +2043,17 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1807
2043
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1808
2044
|
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1809
2045
|
return [
|
|
1810
|
-
|
|
2046
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2047
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
1811
2048
|
EditorState.allowMultipleSelections.of(true),
|
|
1812
2049
|
EditorState.tabSize.of(2),
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
closeBrackets2(),
|
|
1816
|
-
crosshairCursor(),
|
|
2050
|
+
bracketMatching(),
|
|
2051
|
+
closeBrackets(),
|
|
1817
2052
|
dropCursor(),
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
history2(),
|
|
2053
|
+
drawSelection(),
|
|
2054
|
+
history(),
|
|
1821
2055
|
indentOnInput(),
|
|
1822
|
-
_placeholder &&
|
|
2056
|
+
_placeholder && placeholder(_placeholder),
|
|
1823
2057
|
// Main extension.
|
|
1824
2058
|
// https://github.com/codemirror/lang-markdown
|
|
1825
2059
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1839,10 +2073,10 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1839
2073
|
]
|
|
1840
2074
|
}),
|
|
1841
2075
|
// https://github.com/codemirror/theme-one-dark
|
|
1842
|
-
themeMode === "dark" ?
|
|
2076
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
1843
2077
|
// Custom styles.
|
|
1844
|
-
|
|
1845
|
-
|
|
2078
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
2079
|
+
keymap5.of([
|
|
1846
2080
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1847
2081
|
indentWithTab,
|
|
1848
2082
|
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
@@ -1854,22 +2088,22 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1854
2088
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1855
2089
|
...standardKeymap
|
|
1856
2090
|
])
|
|
1857
|
-
].filter(
|
|
2091
|
+
].filter(isNotFalsy2);
|
|
1858
2092
|
};
|
|
1859
2093
|
|
|
1860
2094
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
1861
2095
|
import { syntaxTree } from "@codemirror/language";
|
|
1862
|
-
import { RangeSetBuilder, StateEffect as
|
|
1863
|
-
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";
|
|
1864
2098
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1865
|
-
var HorizontalRuleWidget = class extends
|
|
2099
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
1866
2100
|
toDOM() {
|
|
1867
2101
|
const el = document.createElement("span");
|
|
1868
2102
|
el.className = "cm-hr";
|
|
1869
2103
|
return el;
|
|
1870
2104
|
}
|
|
1871
2105
|
};
|
|
1872
|
-
var LinkButton = class extends
|
|
2106
|
+
var LinkButton = class extends WidgetType3 {
|
|
1873
2107
|
constructor(url, render) {
|
|
1874
2108
|
super();
|
|
1875
2109
|
this.url = url;
|
|
@@ -1884,7 +2118,7 @@ var LinkButton = class extends WidgetType2 {
|
|
|
1884
2118
|
return el;
|
|
1885
2119
|
}
|
|
1886
2120
|
};
|
|
1887
|
-
var CheckboxWidget = class extends
|
|
2121
|
+
var CheckboxWidget = class extends WidgetType3 {
|
|
1888
2122
|
constructor(_checked) {
|
|
1889
2123
|
super();
|
|
1890
2124
|
this._checked = _checked;
|
|
@@ -1921,28 +2155,28 @@ var CheckboxWidget = class extends WidgetType2 {
|
|
|
1921
2155
|
return false;
|
|
1922
2156
|
}
|
|
1923
2157
|
};
|
|
1924
|
-
var hide =
|
|
1925
|
-
var fencedCodeLine =
|
|
2158
|
+
var hide = Decoration5.replace({});
|
|
2159
|
+
var fencedCodeLine = Decoration5.line({
|
|
1926
2160
|
class: mx2("cm-code cm-codeblock-line")
|
|
1927
2161
|
});
|
|
1928
|
-
var fencedCodeLineFirst =
|
|
2162
|
+
var fencedCodeLineFirst = Decoration5.line({
|
|
1929
2163
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
1930
2164
|
});
|
|
1931
|
-
var fencedCodeLineLast =
|
|
2165
|
+
var fencedCodeLineLast = Decoration5.line({
|
|
1932
2166
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
1933
2167
|
});
|
|
1934
|
-
var horizontalRule =
|
|
2168
|
+
var horizontalRule = Decoration5.replace({
|
|
1935
2169
|
widget: new HorizontalRuleWidget()
|
|
1936
2170
|
});
|
|
1937
|
-
var checkedTask =
|
|
2171
|
+
var checkedTask = Decoration5.replace({
|
|
1938
2172
|
widget: new CheckboxWidget(true)
|
|
1939
2173
|
});
|
|
1940
|
-
var uncheckedTask =
|
|
2174
|
+
var uncheckedTask = Decoration5.replace({
|
|
1941
2175
|
widget: new CheckboxWidget(false)
|
|
1942
2176
|
});
|
|
1943
2177
|
var editingRange = (state, range, focus) => {
|
|
1944
2178
|
const { readOnly, selection: { main: { head } } } = state;
|
|
1945
|
-
return focus && !readOnly && head >= range.from && head
|
|
2179
|
+
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
1946
2180
|
};
|
|
1947
2181
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1948
2182
|
"CodeMark",
|
|
@@ -1952,8 +2186,8 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
1952
2186
|
"SuperscriptMark"
|
|
1953
2187
|
]);
|
|
1954
2188
|
var buildDecorations = (view, options, focus) => {
|
|
1955
|
-
const deco = new
|
|
1956
|
-
const atomicDeco = new
|
|
2189
|
+
const deco = new RangeSetBuilder2();
|
|
2190
|
+
const atomicDeco = new RangeSetBuilder2();
|
|
1957
2191
|
const { state } = view;
|
|
1958
2192
|
for (const { from, to } of view.visibleRanges) {
|
|
1959
2193
|
syntaxTree(state).iterate({
|
|
@@ -1970,7 +2204,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
1970
2204
|
break;
|
|
1971
2205
|
}
|
|
1972
2206
|
const first = block.from <= node.from;
|
|
1973
|
-
const last = block.to >= node.to;
|
|
2207
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
|
1974
2208
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
1975
2209
|
if (!editing && (first || last)) {
|
|
1976
2210
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -1986,7 +2220,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
1986
2220
|
if (!editing) {
|
|
1987
2221
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
1988
2222
|
}
|
|
1989
|
-
deco.add(marks[0].to, marks[1].from,
|
|
2223
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
1990
2224
|
tagName: "a",
|
|
1991
2225
|
attributes: {
|
|
1992
2226
|
class: "cm-link",
|
|
@@ -1996,7 +2230,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
1996
2230
|
}
|
|
1997
2231
|
}));
|
|
1998
2232
|
if (!editing) {
|
|
1999
|
-
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ?
|
|
2233
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
2000
2234
|
widget: new LinkButton(url, options.renderLinkButton)
|
|
2001
2235
|
}) : hide);
|
|
2002
2236
|
}
|
|
@@ -2014,7 +2248,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2014
2248
|
} else if (node.name === "TaskMarker") {
|
|
2015
2249
|
if (!editingRange(state, node, focus)) {
|
|
2016
2250
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2017
|
-
atomicDeco.add(node.from - 2, node.from - 1,
|
|
2251
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2018
2252
|
class: "cm-task"
|
|
2019
2253
|
}));
|
|
2020
2254
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
@@ -2032,50 +2266,51 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2032
2266
|
atomicDeco: atomicDeco.finish()
|
|
2033
2267
|
};
|
|
2034
2268
|
};
|
|
2035
|
-
var forceUpdate =
|
|
2269
|
+
var forceUpdate = StateEffect4.define();
|
|
2036
2270
|
var decorateMarkdown = (options = {}) => {
|
|
2037
2271
|
return [
|
|
2038
|
-
|
|
2272
|
+
ViewPlugin4.fromClass(class {
|
|
2039
2273
|
constructor(view) {
|
|
2040
|
-
this.pendingUpdate = -1;
|
|
2041
2274
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2042
2275
|
}
|
|
2043
2276
|
update(update2) {
|
|
2044
|
-
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate)))) {
|
|
2277
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
2045
2278
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2046
2279
|
this.clearUpdate();
|
|
2047
2280
|
} else if (update2.selectionSet) {
|
|
2048
2281
|
this.scheduleUpdate(update2.view);
|
|
2049
2282
|
}
|
|
2050
2283
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
window.clearTimeout(this.pendingUpdate);
|
|
2054
|
-
this.pendingUpdate = -1;
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
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.
|
|
2057
2286
|
scheduleUpdate(view) {
|
|
2058
2287
|
this.clearUpdate();
|
|
2059
|
-
this.pendingUpdate =
|
|
2288
|
+
this.pendingUpdate = setTimeout(() => {
|
|
2060
2289
|
view.dispatch({
|
|
2061
2290
|
effects: forceUpdate.of(null)
|
|
2062
2291
|
});
|
|
2063
|
-
}, options.selectionChangeDelay
|
|
2292
|
+
}, options.selectionChangeDelay);
|
|
2293
|
+
}
|
|
2294
|
+
clearUpdate() {
|
|
2295
|
+
if (this.pendingUpdate) {
|
|
2296
|
+
clearTimeout(this.pendingUpdate);
|
|
2297
|
+
this.pendingUpdate = void 0;
|
|
2298
|
+
}
|
|
2064
2299
|
}
|
|
2065
2300
|
destroy() {
|
|
2066
2301
|
this.clearUpdate();
|
|
2067
2302
|
}
|
|
2068
2303
|
}, {
|
|
2069
2304
|
provide: (plugin) => [
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
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)
|
|
2073
2308
|
]
|
|
2074
2309
|
}),
|
|
2075
2310
|
formattingStyles
|
|
2076
2311
|
];
|
|
2077
2312
|
};
|
|
2078
|
-
var formattingStyles =
|
|
2313
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
2079
2314
|
"& .cm-code": {
|
|
2080
2315
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2081
2316
|
},
|
|
@@ -2128,7 +2363,7 @@ var formattingStyles = EditorView10.baseTheme({
|
|
|
2128
2363
|
import { snippet } from "@codemirror/autocomplete";
|
|
2129
2364
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2130
2365
|
import { EditorSelection } from "@codemirror/state";
|
|
2131
|
-
import { EditorView as
|
|
2366
|
+
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2132
2367
|
import { useState, useMemo } from "react";
|
|
2133
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;
|
|
2134
2369
|
var Inline;
|
|
@@ -3000,7 +3235,7 @@ var toggleCodeblock = (target) => {
|
|
|
3000
3235
|
};
|
|
3001
3236
|
var formatting = (options = {}) => {
|
|
3002
3237
|
return [
|
|
3003
|
-
|
|
3238
|
+
keymap6.of([
|
|
3004
3239
|
{
|
|
3005
3240
|
key: "meta-b",
|
|
3006
3241
|
run: toggleStrong
|
|
@@ -3198,7 +3433,7 @@ var getFormatting = (state) => {
|
|
|
3198
3433
|
};
|
|
3199
3434
|
var useFormattingState = () => {
|
|
3200
3435
|
const [state, setState] = useState(null);
|
|
3201
|
-
const observer = useMemo(() =>
|
|
3436
|
+
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3202
3437
|
if (update2.docChanged || update2.selectionSet) {
|
|
3203
3438
|
const newState = getFormatting(update2.state);
|
|
3204
3439
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3214,12 +3449,12 @@ var useFormattingState = () => {
|
|
|
3214
3449
|
|
|
3215
3450
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3216
3451
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3217
|
-
import { StateField as
|
|
3218
|
-
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";
|
|
3219
3454
|
var image = (options = {}) => {
|
|
3220
|
-
return
|
|
3455
|
+
return StateField5.define({
|
|
3221
3456
|
create: (state) => {
|
|
3222
|
-
return
|
|
3457
|
+
return Decoration6.set(buildDecorations2(0, state.doc.length, state));
|
|
3223
3458
|
},
|
|
3224
3459
|
update: (value, tr) => {
|
|
3225
3460
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3242,7 +3477,7 @@ var image = (options = {}) => {
|
|
|
3242
3477
|
add: buildDecorations2(from, to, tr.state)
|
|
3243
3478
|
});
|
|
3244
3479
|
},
|
|
3245
|
-
provide: (field) =>
|
|
3480
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3246
3481
|
});
|
|
3247
3482
|
};
|
|
3248
3483
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3264,7 +3499,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3264
3499
|
const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3265
3500
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3266
3501
|
preloadImage(url);
|
|
3267
|
-
decorations.push(
|
|
3502
|
+
decorations.push(Decoration6.replace({
|
|
3268
3503
|
block: true,
|
|
3269
3504
|
widget: new ImageWidget(url)
|
|
3270
3505
|
}).range(hide2 ? node.from : node.to, node.to));
|
|
@@ -3276,7 +3511,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3276
3511
|
});
|
|
3277
3512
|
return decorations;
|
|
3278
3513
|
};
|
|
3279
|
-
var ImageWidget = class extends
|
|
3514
|
+
var ImageWidget = class extends WidgetType4 {
|
|
3280
3515
|
constructor(_url) {
|
|
3281
3516
|
super();
|
|
3282
3517
|
this._url = _url;
|
|
@@ -3329,17 +3564,17 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3329
3564
|
|
|
3330
3565
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3331
3566
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3332
|
-
import { RangeSetBuilder as
|
|
3333
|
-
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";
|
|
3334
3569
|
var table = (options = {}) => {
|
|
3335
|
-
return
|
|
3570
|
+
return StateField6.define({
|
|
3336
3571
|
create: (state) => update(state, options),
|
|
3337
3572
|
update: (_, tr) => update(tr.state, options),
|
|
3338
|
-
provide: (field) =>
|
|
3573
|
+
provide: (field) => EditorView15.decorations.from(field)
|
|
3339
3574
|
});
|
|
3340
3575
|
};
|
|
3341
3576
|
var update = (state, options) => {
|
|
3342
|
-
const builder = new
|
|
3577
|
+
const builder = new RangeSetBuilder3();
|
|
3343
3578
|
const cursor = state.selection.main.head;
|
|
3344
3579
|
const tables = [];
|
|
3345
3580
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3379,16 +3614,16 @@ var update = (state, options) => {
|
|
|
3379
3614
|
});
|
|
3380
3615
|
tables.forEach((table2) => {
|
|
3381
3616
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3382
|
-
hide2 && builder.add(table2.from, table2.to,
|
|
3617
|
+
hide2 && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3383
3618
|
widget: new TableWidget(table2)
|
|
3384
3619
|
}));
|
|
3385
|
-
builder.add(table2.from, table2.to,
|
|
3620
|
+
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
3386
3621
|
class: "cm-table"
|
|
3387
3622
|
}));
|
|
3388
3623
|
});
|
|
3389
3624
|
return builder.finish();
|
|
3390
3625
|
};
|
|
3391
|
-
var TableWidget = class extends
|
|
3626
|
+
var TableWidget = class extends WidgetType5 {
|
|
3392
3627
|
constructor(_table) {
|
|
3393
3628
|
super();
|
|
3394
3629
|
this._table = _table;
|
|
@@ -3427,6 +3662,8 @@ var TableWidget = class extends WidgetType4 {
|
|
|
3427
3662
|
|
|
3428
3663
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3429
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";
|
|
3430
3667
|
var mention = ({ onSearch }) => {
|
|
3431
3668
|
return autocompletion2({
|
|
3432
3669
|
// TODO(burdon): Not working.
|
|
@@ -3438,7 +3675,14 @@ var mention = ({ onSearch }) => {
|
|
|
3438
3675
|
icons: false,
|
|
3439
3676
|
override: [
|
|
3440
3677
|
(context) => {
|
|
3441
|
-
|
|
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
|
+
});
|
|
3442
3686
|
const match = context.matchBefore(/@(\w+)?/);
|
|
3443
3687
|
if (!match || match.from === match.to && !context.explicit) {
|
|
3444
3688
|
return null;
|
|
@@ -3455,10 +3699,10 @@ var mention = ({ onSearch }) => {
|
|
|
3455
3699
|
};
|
|
3456
3700
|
|
|
3457
3701
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
3458
|
-
import { Facet as
|
|
3459
|
-
import { keymap as
|
|
3702
|
+
import { Facet as Facet6 } from "@codemirror/state";
|
|
3703
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
3460
3704
|
import { vim } from "@replit/codemirror-vim";
|
|
3461
|
-
var editorMode =
|
|
3705
|
+
var editorMode = Facet6.define({
|
|
3462
3706
|
combine: (modes) => modes[0] ?? {}
|
|
3463
3707
|
});
|
|
3464
3708
|
var EditorModes = {
|
|
@@ -3469,7 +3713,7 @@ var EditorModes = {
|
|
|
3469
3713
|
type: "vim",
|
|
3470
3714
|
noTabster: true
|
|
3471
3715
|
}),
|
|
3472
|
-
|
|
3716
|
+
keymap7.of([
|
|
3473
3717
|
{
|
|
3474
3718
|
key: "Alt-Escape",
|
|
3475
3719
|
run: (view) => {
|
|
@@ -3489,7 +3733,7 @@ var outliner = (options = {}) => {
|
|
|
3489
3733
|
};
|
|
3490
3734
|
|
|
3491
3735
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
3492
|
-
import { keymap as
|
|
3736
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
3493
3737
|
var defaultItems = [
|
|
3494
3738
|
"hello world!",
|
|
3495
3739
|
"this is a test.",
|
|
@@ -3499,7 +3743,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3499
3743
|
let t;
|
|
3500
3744
|
let idx = 0;
|
|
3501
3745
|
return [
|
|
3502
|
-
|
|
3746
|
+
keymap8.of([
|
|
3503
3747
|
{
|
|
3504
3748
|
// Reset.
|
|
3505
3749
|
key: "alt-meta-'",
|
|
@@ -3545,171 +3789,355 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3545
3789
|
];
|
|
3546
3790
|
};
|
|
3547
3791
|
|
|
3548
|
-
// packages/ui/react-ui-editor/src/
|
|
3549
|
-
import
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
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
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
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 = {
|
|
3672
3978
|
//
|
|
3673
|
-
//
|
|
3979
|
+
// Main layout:
|
|
3980
|
+
// https://codemirror.net/examples/styling
|
|
3674
3981
|
//
|
|
3675
|
-
"
|
|
3676
|
-
|
|
3677
|
-
|
|
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"
|
|
3678
4004
|
},
|
|
3679
|
-
|
|
3680
|
-
".cm-
|
|
3681
|
-
|
|
3682
|
-
|
|
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
|
|
3683
4012
|
},
|
|
3684
|
-
".cm-
|
|
3685
|
-
|
|
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"
|
|
3686
4018
|
},
|
|
3687
|
-
".cm-
|
|
3688
|
-
|
|
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"
|
|
3689
4026
|
},
|
|
3690
4027
|
//
|
|
3691
|
-
//
|
|
4028
|
+
// Cursor
|
|
3692
4029
|
//
|
|
3693
|
-
".cm-
|
|
3694
|
-
|
|
3695
|
-
textDecoration: "none !important"
|
|
4030
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
4031
|
+
borderLeft: "2px solid black"
|
|
3696
4032
|
},
|
|
3697
|
-
".cm-
|
|
3698
|
-
|
|
3699
|
-
borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.500")}`,
|
|
3700
|
-
fontWeight: 100,
|
|
3701
|
-
textAlign: "left",
|
|
3702
|
-
color: get4(tokens, "extend.colors.neutral.500")
|
|
4033
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
4034
|
+
borderLeft: "2px solid white"
|
|
3703
4035
|
},
|
|
3704
|
-
".cm-
|
|
3705
|
-
|
|
4036
|
+
"&light .cm-placeholder": {
|
|
4037
|
+
color: get4(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
4038
|
+
},
|
|
4039
|
+
"&dark .cm-placeholder": {
|
|
4040
|
+
color: get4(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
3706
4041
|
},
|
|
3707
4042
|
//
|
|
3708
|
-
//
|
|
4043
|
+
// line
|
|
3709
4044
|
//
|
|
3710
|
-
".cm-
|
|
3711
|
-
|
|
3712
|
-
|
|
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"
|
|
4117
|
+
},
|
|
4118
|
+
//
|
|
4119
|
+
// table
|
|
4120
|
+
//
|
|
4121
|
+
".cm-table *": {
|
|
4122
|
+
fontFamily: `${get4(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
4123
|
+
textDecoration: "none !important"
|
|
4124
|
+
},
|
|
4125
|
+
".cm-table-head": {
|
|
4126
|
+
padding: "2px 16px 2px 0px",
|
|
4127
|
+
borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.500")}`,
|
|
4128
|
+
fontWeight: 100,
|
|
4129
|
+
textAlign: "left",
|
|
4130
|
+
color: get4(tokens, "extend.colors.neutral.500")
|
|
4131
|
+
},
|
|
4132
|
+
".cm-table-cell": {
|
|
4133
|
+
padding: "2px 16px 2px 0px"
|
|
4134
|
+
},
|
|
4135
|
+
//
|
|
4136
|
+
// image
|
|
4137
|
+
//
|
|
4138
|
+
".cm-image": {
|
|
4139
|
+
display: "block",
|
|
4140
|
+
height: "0"
|
|
3713
4141
|
},
|
|
3714
4142
|
".cm-image.cm-loaded-image": {
|
|
3715
4143
|
height: "auto",
|
|
@@ -3795,19 +4223,238 @@ var codeTheme = {
|
|
|
3795
4223
|
}
|
|
3796
4224
|
};
|
|
3797
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
|
+
|
|
3798
4445
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3799
|
-
var
|
|
3800
|
-
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) => {
|
|
3801
4448
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
3802
4449
|
tabBehavior: "limited"
|
|
3803
4450
|
});
|
|
3804
4451
|
const { themeMode } = useThemeContext();
|
|
3805
|
-
const rootRef =
|
|
3806
|
-
const [view, setView] =
|
|
4452
|
+
const rootRef = useRef3(null);
|
|
4453
|
+
const [view, setView] = useState5(null);
|
|
3807
4454
|
useImperativeHandle(forwardedRef, () => view, [
|
|
3808
4455
|
view
|
|
3809
4456
|
]);
|
|
3810
|
-
|
|
4457
|
+
useEffect3(() => {
|
|
3811
4458
|
if (autoFocus) {
|
|
3812
4459
|
view?.focus();
|
|
3813
4460
|
}
|
|
@@ -3815,38 +4462,38 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3815
4462
|
view,
|
|
3816
4463
|
autoFocus
|
|
3817
4464
|
]);
|
|
3818
|
-
|
|
4465
|
+
useEffect3(() => {
|
|
3819
4466
|
if (!model || !rootRef.current) {
|
|
3820
4467
|
return;
|
|
3821
4468
|
}
|
|
3822
|
-
const state =
|
|
3823
|
-
doc: model.
|
|
4469
|
+
const state = EditorState3.create({
|
|
4470
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
3824
4471
|
selection,
|
|
3825
4472
|
extensions: [
|
|
3826
4473
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
F:
|
|
3830
|
-
L:
|
|
4474
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4475
|
+
log9.catch(err, void 0, {
|
|
4476
|
+
F: __dxlog_file11,
|
|
4477
|
+
L: 123,
|
|
3831
4478
|
S: void 0,
|
|
3832
4479
|
C: (f, a) => f(...a)
|
|
3833
4480
|
});
|
|
3834
4481
|
}),
|
|
3835
4482
|
// Theme.
|
|
3836
4483
|
// TODO(burdon): Make base theme configurable.
|
|
3837
|
-
|
|
3838
|
-
theme &&
|
|
3839
|
-
|
|
3840
|
-
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({
|
|
3841
4488
|
class: slots.editor.className
|
|
3842
4489
|
}),
|
|
3843
|
-
slots.content?.className &&
|
|
4490
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3844
4491
|
class: slots.content.className
|
|
3845
4492
|
}),
|
|
3846
4493
|
// NOTE: Assumes default line height.
|
|
3847
|
-
_scrollPastEnd &&
|
|
4494
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
3848
4495
|
// Focus.
|
|
3849
|
-
|
|
4496
|
+
EditorView17.updateListener.of((update2) => {
|
|
3850
4497
|
update2.transactions.forEach((transaction) => {
|
|
3851
4498
|
if (transaction.isUserEvent("focus.container")) {
|
|
3852
4499
|
rootRef.current?.focus();
|
|
@@ -3854,8 +4501,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3854
4501
|
});
|
|
3855
4502
|
}),
|
|
3856
4503
|
// State.
|
|
3857
|
-
|
|
3858
|
-
|
|
4504
|
+
EditorView17.editable.of(!readonly),
|
|
4505
|
+
EditorState3.readOnly.of(!!readonly),
|
|
3859
4506
|
// Storage and replication.
|
|
3860
4507
|
// NOTE: This must come before user extensions.
|
|
3861
4508
|
model.extension,
|
|
@@ -3863,7 +4510,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3863
4510
|
...extensions
|
|
3864
4511
|
].filter(isNotFalsy4)
|
|
3865
4512
|
});
|
|
3866
|
-
const view2 = new
|
|
4513
|
+
const view2 = new EditorView17({
|
|
3867
4514
|
state,
|
|
3868
4515
|
parent: rootRef.current,
|
|
3869
4516
|
scrollTo,
|
|
@@ -3920,14 +4567,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3920
4567
|
...tabsterDOMAttribute
|
|
3921
4568
|
});
|
|
3922
4569
|
});
|
|
3923
|
-
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) => {
|
|
3924
4571
|
const { themeMode } = useThemeContext();
|
|
3925
|
-
const updatedSlots =
|
|
3926
|
-
const extensions =
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
placeholder: placeholder3
|
|
3930
|
-
|
|
4572
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4573
|
+
const extensions = useMemo3(() => [
|
|
4574
|
+
createBasicExtensions({
|
|
4575
|
+
lineWrapping,
|
|
4576
|
+
placeholder: placeholder3
|
|
4577
|
+
}),
|
|
4578
|
+
createThemeExtensions({
|
|
4579
|
+
themeMode
|
|
3931
4580
|
}),
|
|
3932
4581
|
..._extensions ?? []
|
|
3933
4582
|
], [
|
|
@@ -3947,8 +4596,8 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
3947
4596
|
});
|
|
3948
4597
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3949
4598
|
const { themeMode } = useThemeContext();
|
|
3950
|
-
const updatedSlots =
|
|
3951
|
-
const extensions =
|
|
4599
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4600
|
+
const extensions = useMemo3(() => [
|
|
3952
4601
|
createMarkdownExtensions({
|
|
3953
4602
|
themeMode,
|
|
3954
4603
|
placeholder: placeholder3
|
|
@@ -3986,7 +4635,7 @@ var defaultMarkdownSlots = {
|
|
|
3986
4635
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
3987
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";
|
|
3988
4637
|
import { createContext } from "@radix-ui/react-context";
|
|
3989
|
-
import React2, { useRef as
|
|
4638
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
3990
4639
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
3991
4640
|
import { getSize } from "@dxos/react-ui-theme";
|
|
3992
4641
|
var tooltipProps = {
|
|
@@ -4044,9 +4693,9 @@ var MarkdownHeading = () => {
|
|
|
4044
4693
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4045
4694
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4046
4695
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4047
|
-
const suppressNextTooltip =
|
|
4048
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4049
|
-
const [selectOpen, setSelectOpen] =
|
|
4696
|
+
const suppressNextTooltip = useRef4(false);
|
|
4697
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4698
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4050
4699
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4051
4700
|
open: tooltipOpen,
|
|
4052
4701
|
onOpenChange: (nextOpen) => {
|
|
@@ -4249,384 +4898,6 @@ var Toolbar = {
|
|
|
4249
4898
|
Markdown: MarkdownStandard,
|
|
4250
4899
|
Extended: MarkdownExtended
|
|
4251
4900
|
};
|
|
4252
|
-
|
|
4253
|
-
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4254
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4255
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4256
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
4257
|
-
import { log as log4 } from "@dxos/log";
|
|
4258
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4259
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
4260
|
-
var SpaceAwarenessProvider = class {
|
|
4261
|
-
constructor(params) {
|
|
4262
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4263
|
-
this.remoteStateChange = new Event2();
|
|
4264
|
-
this._space = params.space;
|
|
4265
|
-
this._channel = params.channel;
|
|
4266
|
-
this._peerId = params.peerId;
|
|
4267
|
-
this._info = params.info;
|
|
4268
|
-
}
|
|
4269
|
-
open() {
|
|
4270
|
-
this._ctx = new Context2();
|
|
4271
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4272
|
-
if (this._localState) {
|
|
4273
|
-
await this._space.postMessage(this._channel, {
|
|
4274
|
-
kind: "post",
|
|
4275
|
-
state: this._localState
|
|
4276
|
-
});
|
|
4277
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
4278
|
-
}
|
|
4279
|
-
});
|
|
4280
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4281
|
-
switch (message.payload.kind) {
|
|
4282
|
-
case "query": {
|
|
4283
|
-
this._handleQueryMessage();
|
|
4284
|
-
break;
|
|
4285
|
-
}
|
|
4286
|
-
case "post": {
|
|
4287
|
-
this._handlePostMessage(message.payload);
|
|
4288
|
-
break;
|
|
4289
|
-
}
|
|
4290
|
-
}
|
|
4291
|
-
}));
|
|
4292
|
-
void this._space.postMessage(this._channel, {
|
|
4293
|
-
kind: "query"
|
|
4294
|
-
}).catch((err) => {
|
|
4295
|
-
log4.debug("failed to query awareness", {
|
|
4296
|
-
err
|
|
4297
|
-
}, {
|
|
4298
|
-
F: __dxlog_file5,
|
|
4299
|
-
L: 89,
|
|
4300
|
-
S: this,
|
|
4301
|
-
C: (f, a) => f(...a)
|
|
4302
|
-
});
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
|
-
close() {
|
|
4306
|
-
void this._ctx?.dispose();
|
|
4307
|
-
this._ctx = void 0;
|
|
4308
|
-
this._postTask = void 0;
|
|
4309
|
-
}
|
|
4310
|
-
getRemoteStates() {
|
|
4311
|
-
return Array.from(this._remoteStates.values());
|
|
4312
|
-
}
|
|
4313
|
-
update(position) {
|
|
4314
|
-
invariant2(this._postTask, void 0, {
|
|
4315
|
-
F: __dxlog_file5,
|
|
4316
|
-
L: 104,
|
|
4317
|
-
S: this,
|
|
4318
|
-
A: [
|
|
4319
|
-
"this._postTask",
|
|
4320
|
-
""
|
|
4321
|
-
]
|
|
4322
|
-
});
|
|
4323
|
-
this._localState = {
|
|
4324
|
-
peerId: this._peerId,
|
|
4325
|
-
position,
|
|
4326
|
-
info: this._info
|
|
4327
|
-
};
|
|
4328
|
-
this._postTask.schedule();
|
|
4329
|
-
}
|
|
4330
|
-
_handleQueryMessage() {
|
|
4331
|
-
invariant2(this._postTask, void 0, {
|
|
4332
|
-
F: __dxlog_file5,
|
|
4333
|
-
L: 115,
|
|
4334
|
-
S: this,
|
|
4335
|
-
A: [
|
|
4336
|
-
"this._postTask",
|
|
4337
|
-
""
|
|
4338
|
-
]
|
|
4339
|
-
});
|
|
4340
|
-
this._postTask.schedule();
|
|
4341
|
-
}
|
|
4342
|
-
_handlePostMessage(message) {
|
|
4343
|
-
invariant2(message.kind === "post", void 0, {
|
|
4344
|
-
F: __dxlog_file5,
|
|
4345
|
-
L: 120,
|
|
4346
|
-
S: this,
|
|
4347
|
-
A: [
|
|
4348
|
-
"message.kind === 'post'",
|
|
4349
|
-
""
|
|
4350
|
-
]
|
|
4351
|
-
});
|
|
4352
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
4353
|
-
this.remoteStateChange.emit();
|
|
4354
|
-
}
|
|
4355
|
-
};
|
|
4356
|
-
|
|
4357
|
-
// packages/ui/react-ui-editor/src/hooks/defs.ts
|
|
4358
|
-
import { StateField as StateField6 } from "@codemirror/state";
|
|
4359
|
-
var modelState = StateField6.define({
|
|
4360
|
-
create: () => void 0,
|
|
4361
|
-
update: (model) => model
|
|
4362
|
-
});
|
|
4363
|
-
|
|
4364
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4365
|
-
var useActionHandler = (view) => {
|
|
4366
|
-
return (action) => {
|
|
4367
|
-
if (!view) {
|
|
4368
|
-
return;
|
|
4369
|
-
}
|
|
4370
|
-
let inlineType, listType;
|
|
4371
|
-
switch (action.type) {
|
|
4372
|
-
case "heading":
|
|
4373
|
-
setHeading(parseInt(action.data))(view);
|
|
4374
|
-
break;
|
|
4375
|
-
case "strong":
|
|
4376
|
-
case "emphasis":
|
|
4377
|
-
case "strikethrough":
|
|
4378
|
-
case "code":
|
|
4379
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4380
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4381
|
-
break;
|
|
4382
|
-
case "list-ordered":
|
|
4383
|
-
case "list-bullet":
|
|
4384
|
-
case "list-task":
|
|
4385
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4386
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4387
|
-
break;
|
|
4388
|
-
case "blockquote":
|
|
4389
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4390
|
-
break;
|
|
4391
|
-
case "codeblock":
|
|
4392
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4393
|
-
break;
|
|
4394
|
-
case "table":
|
|
4395
|
-
insertTable(view);
|
|
4396
|
-
break;
|
|
4397
|
-
case "link":
|
|
4398
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4399
|
-
break;
|
|
4400
|
-
case "comment":
|
|
4401
|
-
createComment(view);
|
|
4402
|
-
break;
|
|
4403
|
-
}
|
|
4404
|
-
setTimeout(() => {
|
|
4405
|
-
if (!view.hasFocus) {
|
|
4406
|
-
view.focus();
|
|
4407
|
-
}
|
|
4408
|
-
});
|
|
4409
|
-
};
|
|
4410
|
-
};
|
|
4411
|
-
|
|
4412
|
-
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4413
|
-
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4414
|
-
var useEditorView = (id) => {
|
|
4415
|
-
const editorRef = useRef3(null);
|
|
4416
|
-
const [prev, setPrev] = useState4([
|
|
4417
|
-
null,
|
|
4418
|
-
""
|
|
4419
|
-
]);
|
|
4420
|
-
if (prev[0] !== editorRef.current) {
|
|
4421
|
-
setPrev([
|
|
4422
|
-
editorRef.current,
|
|
4423
|
-
id
|
|
4424
|
-
]);
|
|
4425
|
-
}
|
|
4426
|
-
return [
|
|
4427
|
-
editorRef,
|
|
4428
|
-
prev[1] !== id
|
|
4429
|
-
];
|
|
4430
|
-
};
|
|
4431
|
-
|
|
4432
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4433
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4434
|
-
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4435
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4436
|
-
import { log as log5 } from "@dxos/log";
|
|
4437
|
-
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4438
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4439
|
-
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps) => {
|
|
4440
|
-
const onUpdate = useRef4();
|
|
4441
|
-
const [view, setView] = useState5();
|
|
4442
|
-
const parentRef = useRef4(null);
|
|
4443
|
-
useEffect3(() => {
|
|
4444
|
-
let view2;
|
|
4445
|
-
if (parentRef.current) {
|
|
4446
|
-
const state = EditorState3.create({
|
|
4447
|
-
doc,
|
|
4448
|
-
selection,
|
|
4449
|
-
extensions: [
|
|
4450
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4451
|
-
EditorView15.exceptionSink.of((err) => {
|
|
4452
|
-
log5.catch(err, void 0, {
|
|
4453
|
-
F: __dxlog_file6,
|
|
4454
|
-
L: 57,
|
|
4455
|
-
S: void 0,
|
|
4456
|
-
C: (f, a) => f(...a)
|
|
4457
|
-
});
|
|
4458
|
-
}),
|
|
4459
|
-
extensions,
|
|
4460
|
-
EditorView15.updateListener.of(() => {
|
|
4461
|
-
onUpdate.current?.();
|
|
4462
|
-
})
|
|
4463
|
-
].filter(isNotFalsy5)
|
|
4464
|
-
});
|
|
4465
|
-
view2 = new EditorView15({
|
|
4466
|
-
parent: parentRef.current,
|
|
4467
|
-
scrollTo,
|
|
4468
|
-
state,
|
|
4469
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4470
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4471
|
-
dispatchTransactions: (trs, view3) => {
|
|
4472
|
-
if (debug) {
|
|
4473
|
-
logChanges(trs);
|
|
4474
|
-
}
|
|
4475
|
-
view3.update(trs);
|
|
4476
|
-
}
|
|
4477
|
-
});
|
|
4478
|
-
setView(view2);
|
|
4479
|
-
}
|
|
4480
|
-
return () => {
|
|
4481
|
-
view2?.destroy();
|
|
4482
|
-
};
|
|
4483
|
-
}, deps);
|
|
4484
|
-
useEffect3(() => {
|
|
4485
|
-
if (view) {
|
|
4486
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4487
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4488
|
-
}
|
|
4489
|
-
if (selection || scrollTo) {
|
|
4490
|
-
onUpdate.current = () => {
|
|
4491
|
-
onUpdate.current = void 0;
|
|
4492
|
-
view.dispatch({
|
|
4493
|
-
selection,
|
|
4494
|
-
effects: scrollTo && [
|
|
4495
|
-
scrollTo
|
|
4496
|
-
],
|
|
4497
|
-
scrollIntoView: !scrollTo
|
|
4498
|
-
});
|
|
4499
|
-
};
|
|
4500
|
-
}
|
|
4501
|
-
if (autoFocus) {
|
|
4502
|
-
view.focus();
|
|
4503
|
-
}
|
|
4504
|
-
}
|
|
4505
|
-
}, [
|
|
4506
|
-
view,
|
|
4507
|
-
autoFocus,
|
|
4508
|
-
selection,
|
|
4509
|
-
scrollTo
|
|
4510
|
-
]);
|
|
4511
|
-
return {
|
|
4512
|
-
parentRef,
|
|
4513
|
-
view
|
|
4514
|
-
};
|
|
4515
|
-
};
|
|
4516
|
-
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4517
|
-
return [
|
|
4518
|
-
//
|
|
4519
|
-
EditorState3.readOnly.of(readonly),
|
|
4520
|
-
EditorView15.editable.of(!readonly)
|
|
4521
|
-
];
|
|
4522
|
-
};
|
|
4523
|
-
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4524
|
-
return [
|
|
4525
|
-
//
|
|
4526
|
-
EditorView15.baseTheme(defaultTheme),
|
|
4527
|
-
theme && EditorView15.theme(theme),
|
|
4528
|
-
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4529
|
-
EditorView15.editorAttributes.of({
|
|
4530
|
-
class: slots?.editor?.className ?? ""
|
|
4531
|
-
}),
|
|
4532
|
-
EditorView15.contentAttributes.of({
|
|
4533
|
-
class: slots?.content?.className ?? ""
|
|
4534
|
-
})
|
|
4535
|
-
].filter(isNotFalsy5);
|
|
4536
|
-
};
|
|
4537
|
-
|
|
4538
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4539
|
-
import get5 from "lodash.get";
|
|
4540
|
-
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4541
|
-
import { generateName } from "@dxos/display-name";
|
|
4542
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
4543
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4544
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4545
|
-
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4546
|
-
import { hexToHue } from "@dxos/util";
|
|
4547
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4548
|
-
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4549
|
-
const extensions = [
|
|
4550
|
-
automerge(text)
|
|
4551
|
-
];
|
|
4552
|
-
const peerId = identity?.identityKey.toHex();
|
|
4553
|
-
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4554
|
-
if (space && identity) {
|
|
4555
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4556
|
-
space,
|
|
4557
|
-
channel: `awareness.${id}`,
|
|
4558
|
-
peerId: identity.identityKey.toHex(),
|
|
4559
|
-
info: {
|
|
4560
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4561
|
-
color: cursorDarkValue,
|
|
4562
|
-
lightColor: cursorLightValue
|
|
4563
|
-
}
|
|
4564
|
-
});
|
|
4565
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4566
|
-
}
|
|
4567
|
-
return extensions;
|
|
4568
|
-
};
|
|
4569
|
-
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4570
|
-
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4571
|
-
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4572
|
-
return {
|
|
4573
|
-
id,
|
|
4574
|
-
content,
|
|
4575
|
-
setContent,
|
|
4576
|
-
text: () => content
|
|
4577
|
-
};
|
|
4578
|
-
};
|
|
4579
|
-
var createModel = ({ space, identity, text }) => {
|
|
4580
|
-
if (!text) {
|
|
4581
|
-
return void 0;
|
|
4582
|
-
}
|
|
4583
|
-
invariant3(isAutomergeObject(text), void 0, {
|
|
4584
|
-
F: __dxlog_file7,
|
|
4585
|
-
L: 87,
|
|
4586
|
-
S: void 0,
|
|
4587
|
-
A: [
|
|
4588
|
-
"isAutomergeObject(text)",
|
|
4589
|
-
""
|
|
4590
|
-
]
|
|
4591
|
-
});
|
|
4592
|
-
const obj = text;
|
|
4593
|
-
const doc = getRawDoc(obj, [
|
|
4594
|
-
obj.field
|
|
4595
|
-
]);
|
|
4596
|
-
const peerId = identity?.identityKey.toHex();
|
|
4597
|
-
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4598
|
-
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4599
|
-
space,
|
|
4600
|
-
channel: `automerge.awareness.${obj.id}`,
|
|
4601
|
-
info: {
|
|
4602
|
-
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4603
|
-
color: cursorLightValue,
|
|
4604
|
-
lightColor: cursorDarkValue
|
|
4605
|
-
},
|
|
4606
|
-
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4607
|
-
});
|
|
4608
|
-
const extensions = [
|
|
4609
|
-
modelState.init(() => model),
|
|
4610
|
-
automerge({
|
|
4611
|
-
handle: doc.handle,
|
|
4612
|
-
path: doc.path
|
|
4613
|
-
})
|
|
4614
|
-
];
|
|
4615
|
-
if (awarenessProvider2) {
|
|
4616
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4617
|
-
}
|
|
4618
|
-
const model = {
|
|
4619
|
-
id: obj.id,
|
|
4620
|
-
content: doc,
|
|
4621
|
-
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4622
|
-
extension: extensions,
|
|
4623
|
-
peer: identity ? {
|
|
4624
|
-
id: identity.identityKey.toHex(),
|
|
4625
|
-
name: identity.profile?.displayName
|
|
4626
|
-
} : void 0
|
|
4627
|
-
};
|
|
4628
|
-
return model;
|
|
4629
|
-
};
|
|
4630
4901
|
export {
|
|
4631
4902
|
BaseTextEditor,
|
|
4632
4903
|
Cursor,
|
|
@@ -4655,11 +4926,11 @@ export {
|
|
|
4655
4926
|
blast,
|
|
4656
4927
|
callbackWrapper,
|
|
4657
4928
|
codeTheme,
|
|
4929
|
+
command,
|
|
4658
4930
|
comments,
|
|
4659
4931
|
compareFormatting,
|
|
4660
|
-
|
|
4932
|
+
createBasicExtensions,
|
|
4661
4933
|
createComment,
|
|
4662
|
-
createDataExtensions,
|
|
4663
4934
|
createMarkdownExtensions,
|
|
4664
4935
|
createThemeExtensions,
|
|
4665
4936
|
cursorLineMargin,
|
|
@@ -4670,6 +4941,7 @@ export {
|
|
|
4670
4941
|
defaultSlots,
|
|
4671
4942
|
defaultTextSlots,
|
|
4672
4943
|
defaultTheme,
|
|
4944
|
+
dnd,
|
|
4673
4945
|
editorFillLayoutEditor,
|
|
4674
4946
|
editorFillLayoutRoot,
|
|
4675
4947
|
editorMode,
|
|
@@ -4680,7 +4952,7 @@ export {
|
|
|
4680
4952
|
getToken,
|
|
4681
4953
|
image,
|
|
4682
4954
|
insertTable,
|
|
4683
|
-
|
|
4955
|
+
keymap9 as keymap,
|
|
4684
4956
|
linkTooltip,
|
|
4685
4957
|
listener,
|
|
4686
4958
|
logChanges,
|
|
@@ -4689,7 +4961,6 @@ export {
|
|
|
4689
4961
|
markdownTagsExtensions,
|
|
4690
4962
|
markdownTheme,
|
|
4691
4963
|
mention,
|
|
4692
|
-
modelState,
|
|
4693
4964
|
outliner,
|
|
4694
4965
|
removeBlockquote,
|
|
4695
4966
|
removeCodeblock,
|