@dxos/react-ui-editor 0.4.7-main.fd27392 → 0.4.7-next.76c1dea
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +976 -737
- 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/styles/index.d.ts +0 -1
- package/dist/types/src/styles/index.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +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/awareness.ts +3 -3
- package/src/extensions/command/command.ts +35 -0
- package/src/extensions/command/hint.ts +76 -0
- package/src/extensions/command/index.ts +5 -0
- package/src/extensions/command/state.ts +106 -0
- package/src/extensions/comments.ts +2 -1
- package/src/extensions/cursor-line-margin.ts +5 -2
- package/src/extensions/dnd.ts +17 -0
- package/src/extensions/index.ts +2 -1
- package/src/extensions/listener.ts +3 -3
- package/src/extensions/markdown/bundle.ts +4 -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 +20 -18
- package/src/index.ts +2 -0
- package/src/styles/index.ts +0 -1
- package/src/themes/default.ts +1 -0
- package/src/util.ts +1 -1
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/basic.d.ts +0 -9
- package/dist/types/src/extensions/basic.d.ts.map +0 -1
- package/dist/types/src/styles/cursors.d.ts +0 -5
- package/dist/types/src/styles/cursors.d.ts.map +0 -1
- package/src/extensions/basic.ts +0 -41
- package/src/styles/cursors.ts +0 -21
|
@@ -23,20 +23,19 @@ var translations_default = [
|
|
|
23
23
|
];
|
|
24
24
|
|
|
25
25
|
// packages/ui/react-ui-editor/src/index.ts
|
|
26
|
-
import { keymap as
|
|
26
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
|
27
|
+
import { tags as tags2 } from "@lezer/highlight";
|
|
27
28
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
28
29
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
29
30
|
|
|
30
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/index.ts
|
|
31
|
-
import { tags as tags2 } from "@lezer/highlight";
|
|
32
|
-
|
|
33
31
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
34
|
-
import { EditorState as
|
|
35
|
-
import { EditorView as
|
|
32
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
|
33
|
+
import { EditorView as EditorView17, scrollPastEnd as scrollPastEnd2 } from "@codemirror/view";
|
|
36
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
37
|
-
import
|
|
38
|
-
import React, { forwardRef, useCallback, useEffect as
|
|
39
|
-
import {
|
|
35
|
+
import defaultsDeep3 from "lodash.defaultsdeep";
|
|
36
|
+
import React, { forwardRef, useCallback, useEffect as useEffect3, useImperativeHandle, useRef as useRef3, useState as useState5, useMemo as useMemo3 } from "react";
|
|
37
|
+
import { DocAccessor } from "@dxos/echo-schema";
|
|
38
|
+
import { log as log9 } from "@dxos/log";
|
|
40
39
|
import { useThemeContext } from "@dxos/react-ui";
|
|
41
40
|
import { focusRing } from "@dxos/react-ui-theme";
|
|
42
41
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
@@ -596,7 +595,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
596
595
|
to: startLine.from + startLine.length,
|
|
597
596
|
value: Decoration2.mark({
|
|
598
597
|
attributes: {
|
|
599
|
-
style: `background-color: ${
|
|
598
|
+
style: `background-color: ${lightColor}`
|
|
600
599
|
},
|
|
601
600
|
class: "cm-collab-selection"
|
|
602
601
|
})
|
|
@@ -606,7 +605,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
606
605
|
to: end,
|
|
607
606
|
value: Decoration2.mark({
|
|
608
607
|
attributes: {
|
|
609
|
-
style: `background-color: ${
|
|
608
|
+
style: `background-color: ${lightColor}`
|
|
610
609
|
},
|
|
611
610
|
class: "cm-collab-selection"
|
|
612
611
|
})
|
|
@@ -618,7 +617,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
618
617
|
to: linePos,
|
|
619
618
|
value: Decoration2.line({
|
|
620
619
|
attributes: {
|
|
621
|
-
style: `background-color: ${
|
|
620
|
+
style: `background-color: ${lightColor}`,
|
|
622
621
|
class: "cm-collab-selectionLine"
|
|
623
622
|
}
|
|
624
623
|
})
|
|
@@ -733,28 +732,8 @@ var styles2 = EditorView3.baseTheme({
|
|
|
733
732
|
}
|
|
734
733
|
});
|
|
735
734
|
|
|
736
|
-
// packages/ui/react-ui-editor/src/extensions/basic.ts
|
|
737
|
-
import { closeBrackets } from "@codemirror/autocomplete";
|
|
738
|
-
import { history } from "@codemirror/commands";
|
|
739
|
-
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
740
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
741
|
-
import { drawSelection, EditorView as EditorView4, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
742
|
-
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
743
|
-
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true, bracketMatching: _bracketMatching = true } = {}) => [
|
|
744
|
-
lineWrapping && EditorView4.lineWrapping,
|
|
745
|
-
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
746
|
-
_bracketMatching && bracketMatching(),
|
|
747
|
-
closeBrackets(),
|
|
748
|
-
drawSelection(),
|
|
749
|
-
highlightActiveLine(),
|
|
750
|
-
history(),
|
|
751
|
-
_placeholder && placeholder(_placeholder),
|
|
752
|
-
// https://github.com/codemirror/theme-one-dark
|
|
753
|
-
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
754
|
-
].filter(isNotFalsy2);
|
|
755
|
-
|
|
756
735
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
757
|
-
import { EditorView as
|
|
736
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
758
737
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
759
738
|
import { invariant } from "@dxos/invariant";
|
|
760
739
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
@@ -802,7 +781,7 @@ var blast = (options = defaultOptions) => {
|
|
|
802
781
|
};
|
|
803
782
|
return [
|
|
804
783
|
// Cursor moved.
|
|
805
|
-
|
|
784
|
+
EditorView4.updateListener.of((update2) => {
|
|
806
785
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
807
786
|
if (blaster) {
|
|
808
787
|
blaster.destroy();
|
|
@@ -1063,52 +1042,232 @@ var random = (min, max) => {
|
|
|
1063
1042
|
return min + ~~(Math.random() * (max - min + 1));
|
|
1064
1043
|
};
|
|
1065
1044
|
|
|
1066
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1067
|
-
import {
|
|
1068
|
-
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
|
1069
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
|
|
1070
|
-
import sortBy from "lodash.sortby";
|
|
1071
|
-
import { useEffect } from "react";
|
|
1072
|
-
import { debounce } from "@dxos/async";
|
|
1073
|
-
import { nonNullable } from "@dxos/util";
|
|
1045
|
+
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1046
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1074
1047
|
|
|
1075
|
-
// packages/ui/react-ui-editor/src/
|
|
1076
|
-
import
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
{
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1048
|
+
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
|
1049
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
1050
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1051
|
+
|
|
1052
|
+
// packages/ui/react-ui-editor/src/extensions/command/state.ts
|
|
1053
|
+
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
|
1054
|
+
import { showTooltip } from "@codemirror/view";
|
|
1055
|
+
var commandConfig = Facet3.define({
|
|
1056
|
+
combine: (providers) => providers[0]
|
|
1057
|
+
});
|
|
1058
|
+
var commandState = StateField3.define({
|
|
1059
|
+
create: () => ({}),
|
|
1060
|
+
update: (state, tr) => {
|
|
1061
|
+
for (const effect of tr.effects) {
|
|
1062
|
+
if (effect.is(closeEffect)) {
|
|
1063
|
+
return {};
|
|
1064
|
+
}
|
|
1065
|
+
if (effect.is(openEffect)) {
|
|
1066
|
+
const options = tr.state.facet(commandConfig);
|
|
1067
|
+
const { pos, fullWidth } = effect.value;
|
|
1068
|
+
const tooltip = {
|
|
1069
|
+
pos,
|
|
1070
|
+
above: false,
|
|
1071
|
+
arrow: false,
|
|
1072
|
+
strictSide: true,
|
|
1073
|
+
create: (view) => {
|
|
1074
|
+
const dom = document.createElement("div");
|
|
1075
|
+
const tooltipView = {
|
|
1076
|
+
dom,
|
|
1077
|
+
mount: (view2) => {
|
|
1078
|
+
if (fullWidth) {
|
|
1079
|
+
const parent = dom.parentElement;
|
|
1080
|
+
const { paddingLeft, paddingRight } = window.getComputedStyle(parent);
|
|
1081
|
+
const widthWithoutPadding = parent.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
|
|
1082
|
+
dom.style.width = `${widthWithoutPadding}px`;
|
|
1083
|
+
}
|
|
1084
|
+
options.onRender(dom, (action) => {
|
|
1085
|
+
view2.dispatch({
|
|
1086
|
+
effects: closeEffect.of(null)
|
|
1087
|
+
});
|
|
1088
|
+
if (action?.insert?.length) {
|
|
1089
|
+
view2.dispatch({
|
|
1090
|
+
changes: {
|
|
1091
|
+
from: pos,
|
|
1092
|
+
insert: action.insert
|
|
1093
|
+
},
|
|
1094
|
+
selection: {
|
|
1095
|
+
anchor: pos + action.insert.length
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
setTimeout(() => view2.focus());
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
return tooltipView;
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
return {
|
|
1107
|
+
tooltip
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return state;
|
|
1101
1112
|
},
|
|
1113
|
+
provide: (f) => [
|
|
1114
|
+
showTooltip.from(f, (value) => value.tooltip ?? null)
|
|
1115
|
+
]
|
|
1116
|
+
});
|
|
1117
|
+
var openEffect = StateEffect2.define();
|
|
1118
|
+
var closeEffect = StateEffect2.define();
|
|
1119
|
+
var openCommand = (view) => {
|
|
1120
|
+
if (view.state.field(commandState, false)) {
|
|
1121
|
+
const selection = view.state.selection.main;
|
|
1122
|
+
const line = view.state.doc.lineAt(selection.from);
|
|
1123
|
+
if (line.from === selection.from && line.from === line.to) {
|
|
1124
|
+
view.dispatch({
|
|
1125
|
+
effects: openEffect.of({
|
|
1126
|
+
pos: selection.anchor,
|
|
1127
|
+
fullWidth: true
|
|
1128
|
+
})
|
|
1129
|
+
});
|
|
1130
|
+
return true;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
return false;
|
|
1134
|
+
};
|
|
1135
|
+
var closeCommand = (view) => {
|
|
1136
|
+
if (view.state.field(commandState, false)) {
|
|
1137
|
+
view.dispatch({
|
|
1138
|
+
effects: closeEffect.of(null)
|
|
1139
|
+
});
|
|
1140
|
+
return true;
|
|
1141
|
+
}
|
|
1142
|
+
return false;
|
|
1143
|
+
};
|
|
1144
|
+
var commandKeyBindings = [
|
|
1102
1145
|
{
|
|
1103
|
-
|
|
1104
|
-
|
|
1146
|
+
key: "/",
|
|
1147
|
+
run: openCommand
|
|
1105
1148
|
},
|
|
1106
1149
|
{
|
|
1107
|
-
|
|
1108
|
-
|
|
1150
|
+
key: "Escape",
|
|
1151
|
+
run: closeCommand
|
|
1109
1152
|
}
|
|
1110
1153
|
];
|
|
1111
|
-
|
|
1154
|
+
|
|
1155
|
+
// packages/ui/react-ui-editor/src/extensions/util/dom.ts
|
|
1156
|
+
var flattenRect = (rect, left) => {
|
|
1157
|
+
const x = left ? rect.left : rect.right;
|
|
1158
|
+
return {
|
|
1159
|
+
left: x,
|
|
1160
|
+
right: x,
|
|
1161
|
+
top: rect.top,
|
|
1162
|
+
bottom: rect.bottom
|
|
1163
|
+
};
|
|
1164
|
+
};
|
|
1165
|
+
var scratchRange;
|
|
1166
|
+
var textRange = (node, from, to = from) => {
|
|
1167
|
+
const range = scratchRange || (scratchRange = document.createRange());
|
|
1168
|
+
range.setEnd(node, to);
|
|
1169
|
+
range.setStart(node, from);
|
|
1170
|
+
return range;
|
|
1171
|
+
};
|
|
1172
|
+
var clientRectsFor = (dom) => {
|
|
1173
|
+
if (dom.nodeType === 3) {
|
|
1174
|
+
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
|
1175
|
+
} else if (dom.nodeType === 1) {
|
|
1176
|
+
return dom.getClientRects();
|
|
1177
|
+
} else {
|
|
1178
|
+
return [];
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
|
1183
|
+
var CommandHint = class extends WidgetType2 {
|
|
1184
|
+
constructor(content) {
|
|
1185
|
+
super();
|
|
1186
|
+
this.content = content;
|
|
1187
|
+
}
|
|
1188
|
+
toDOM() {
|
|
1189
|
+
const wrap = document.createElement("span");
|
|
1190
|
+
wrap.className = "cm-placeholder";
|
|
1191
|
+
wrap.style.pointerEvents = "none";
|
|
1192
|
+
wrap.appendChild(typeof this.content === "string" ? document.createTextNode(this.content) : this.content);
|
|
1193
|
+
if (typeof this.content === "string") {
|
|
1194
|
+
wrap.setAttribute("aria-label", "placeholder " + this.content);
|
|
1195
|
+
} else {
|
|
1196
|
+
wrap.setAttribute("aria-hidden", "true");
|
|
1197
|
+
}
|
|
1198
|
+
return wrap;
|
|
1199
|
+
}
|
|
1200
|
+
coordsAt(dom) {
|
|
1201
|
+
const rects = dom.firstChild ? clientRectsFor(dom.firstChild) : [];
|
|
1202
|
+
if (!rects.length) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
const style = window.getComputedStyle(dom.parentNode);
|
|
1206
|
+
const rect = flattenRect(rects[0], style.direction !== "rtl");
|
|
1207
|
+
const lineHeight = parseInt(style.lineHeight);
|
|
1208
|
+
if (rect.bottom - rect.top > lineHeight * 1.5) {
|
|
1209
|
+
return {
|
|
1210
|
+
left: rect.left,
|
|
1211
|
+
right: rect.right,
|
|
1212
|
+
top: rect.top,
|
|
1213
|
+
bottom: rect.top + lineHeight
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
return rect;
|
|
1217
|
+
}
|
|
1218
|
+
ignoreEvent() {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
1223
|
+
constructor() {
|
|
1224
|
+
this.deco = Decoration3.none;
|
|
1225
|
+
}
|
|
1226
|
+
update(update2) {
|
|
1227
|
+
const builder = new RangeSetBuilder();
|
|
1228
|
+
const cState = update2.view.state.field(commandState, false);
|
|
1229
|
+
if (!cState?.tooltip) {
|
|
1230
|
+
const selection = update2.view.state.selection.main;
|
|
1231
|
+
const line = update2.view.state.doc.lineAt(selection.from);
|
|
1232
|
+
if (selection.from === selection.to && line.from === line.to) {
|
|
1233
|
+
const hint = onHint();
|
|
1234
|
+
if (hint) {
|
|
1235
|
+
builder.add(selection.from, selection.to, Decoration3.widget({
|
|
1236
|
+
widget: new CommandHint(hint)
|
|
1237
|
+
}));
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
this.deco = builder.finish();
|
|
1242
|
+
}
|
|
1243
|
+
}, {
|
|
1244
|
+
provide: (plugin) => [
|
|
1245
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
|
1246
|
+
]
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1250
|
+
var command = (options) => {
|
|
1251
|
+
return [
|
|
1252
|
+
commandConfig.of(options),
|
|
1253
|
+
commandState,
|
|
1254
|
+
keymap3.of(commandKeyBindings),
|
|
1255
|
+
hintViewPlugin(options),
|
|
1256
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
|
1257
|
+
return focusing ? closeEffect.of(null) : null;
|
|
1258
|
+
})
|
|
1259
|
+
];
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1263
|
+
import { invertedEffects } from "@codemirror/commands";
|
|
1264
|
+
import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
|
1265
|
+
import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7 } from "@codemirror/view";
|
|
1266
|
+
import sortBy from "lodash.sortby";
|
|
1267
|
+
import { useEffect } from "react";
|
|
1268
|
+
import { debounce } from "@dxos/async";
|
|
1269
|
+
import { log as log3 } from "@dxos/log";
|
|
1270
|
+
import { nonNullable } from "@dxos/util";
|
|
1112
1271
|
|
|
1113
1272
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1114
1273
|
import { mx } from "@dxos/react-ui-theme";
|
|
@@ -1175,18 +1334,26 @@ var logChanges = (trs) => {
|
|
|
1175
1334
|
return changes2;
|
|
1176
1335
|
}).filter(Boolean);
|
|
1177
1336
|
if (changes.length) {
|
|
1178
|
-
|
|
1337
|
+
log2.info("changes", {
|
|
1338
|
+
changes
|
|
1339
|
+
}, {
|
|
1340
|
+
F: __dxlog_file3,
|
|
1341
|
+
L: 39,
|
|
1342
|
+
S: void 0,
|
|
1343
|
+
C: (f, a) => f(...a)
|
|
1344
|
+
});
|
|
1179
1345
|
}
|
|
1180
1346
|
};
|
|
1181
1347
|
|
|
1182
1348
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1183
|
-
var
|
|
1349
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1350
|
+
var documentId = Facet4.define({
|
|
1184
1351
|
combine: (values) => values[0]
|
|
1185
1352
|
});
|
|
1186
|
-
var setComments =
|
|
1187
|
-
var setSelection =
|
|
1188
|
-
var setCommentState =
|
|
1189
|
-
var commentsState =
|
|
1353
|
+
var setComments = StateEffect3.define();
|
|
1354
|
+
var setSelection = StateEffect3.define();
|
|
1355
|
+
var setCommentState = StateEffect3.define();
|
|
1356
|
+
var commentsState = StateField4.define({
|
|
1190
1357
|
create: (state) => ({
|
|
1191
1358
|
id: state.facet(documentId),
|
|
1192
1359
|
comments: [],
|
|
@@ -1224,7 +1391,7 @@ var commentsState = StateField3.define({
|
|
|
1224
1391
|
return value;
|
|
1225
1392
|
}
|
|
1226
1393
|
});
|
|
1227
|
-
var styles3 =
|
|
1394
|
+
var styles3 = EditorView7.baseTheme({
|
|
1228
1395
|
"&light .cm-comment, &light .cm-comment-current": {
|
|
1229
1396
|
mixBlendMode: "darken"
|
|
1230
1397
|
},
|
|
@@ -1246,26 +1413,31 @@ var styles3 = EditorView6.baseTheme({
|
|
|
1246
1413
|
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1247
1414
|
}
|
|
1248
1415
|
});
|
|
1249
|
-
var commentMark =
|
|
1416
|
+
var commentMark = Decoration4.mark({
|
|
1250
1417
|
class: "cm-comment",
|
|
1251
1418
|
attributes: {
|
|
1252
1419
|
"data-testid": "cm-comment"
|
|
1253
1420
|
}
|
|
1254
1421
|
});
|
|
1255
|
-
var commentCurrentMark =
|
|
1422
|
+
var commentCurrentMark = Decoration4.mark({
|
|
1256
1423
|
class: "cm-comment-current",
|
|
1257
1424
|
attributes: {
|
|
1258
1425
|
"data-testid": "cm-comment"
|
|
1259
1426
|
}
|
|
1260
1427
|
});
|
|
1261
|
-
var commentsDecorations =
|
|
1428
|
+
var commentsDecorations = EditorView7.decorations.compute([
|
|
1262
1429
|
commentsState
|
|
1263
1430
|
], (state) => {
|
|
1264
1431
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
1265
1432
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1266
1433
|
const range = comment.range;
|
|
1267
1434
|
if (!range || range.from === range.to) {
|
|
1268
|
-
|
|
1435
|
+
log3.warn("Invalid range:", range, {
|
|
1436
|
+
F: __dxlog_file4,
|
|
1437
|
+
L: 132,
|
|
1438
|
+
S: void 0,
|
|
1439
|
+
C: (f, a) => f(...a)
|
|
1440
|
+
});
|
|
1269
1441
|
return void 0;
|
|
1270
1442
|
}
|
|
1271
1443
|
if (comment.comment.id === current) {
|
|
@@ -1274,7 +1446,7 @@ var commentsDecorations = EditorView6.decorations.compute([
|
|
|
1274
1446
|
return commentMark.range(range.from, range.to);
|
|
1275
1447
|
}
|
|
1276
1448
|
}).filter(nonNullable);
|
|
1277
|
-
return
|
|
1449
|
+
return Decoration4.set(decorations);
|
|
1278
1450
|
});
|
|
1279
1451
|
var trackPastedComments = (onUpdate) => {
|
|
1280
1452
|
let tracked = null;
|
|
@@ -1296,7 +1468,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1296
1468
|
}
|
|
1297
1469
|
};
|
|
1298
1470
|
return [
|
|
1299
|
-
|
|
1471
|
+
EditorView7.domEventHandlers({
|
|
1300
1472
|
cut: handleTrack,
|
|
1301
1473
|
copy: handleTrack
|
|
1302
1474
|
}),
|
|
@@ -1318,7 +1490,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1318
1490
|
return effects;
|
|
1319
1491
|
}),
|
|
1320
1492
|
// Handle paste or the undo of comment deletion.
|
|
1321
|
-
|
|
1493
|
+
EditorView7.updateListener.of((update2) => {
|
|
1322
1494
|
const restore = [];
|
|
1323
1495
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1324
1496
|
const tr = update2.transactions[i];
|
|
@@ -1374,7 +1546,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
1374
1546
|
from: changes.mapPos(comment.from, 1),
|
|
1375
1547
|
to: changes.mapPos(comment.to, 1)
|
|
1376
1548
|
});
|
|
1377
|
-
var restoreCommentEffect =
|
|
1549
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
1378
1550
|
map: mapTrackedComment
|
|
1379
1551
|
});
|
|
1380
1552
|
var createComment = (view) => {
|
|
@@ -1415,7 +1587,7 @@ var createComment = (view) => {
|
|
|
1415
1587
|
}
|
|
1416
1588
|
return false;
|
|
1417
1589
|
};
|
|
1418
|
-
var optionsFacet =
|
|
1590
|
+
var optionsFacet = Facet4.define({
|
|
1419
1591
|
combine: (providers) => providers[0]
|
|
1420
1592
|
});
|
|
1421
1593
|
var comments = (options = {}) => {
|
|
@@ -1430,7 +1602,7 @@ var comments = (options = {}) => {
|
|
|
1430
1602
|
//
|
|
1431
1603
|
// Keymap.
|
|
1432
1604
|
//
|
|
1433
|
-
options.onCreate ?
|
|
1605
|
+
options.onCreate ? keymap4.of([
|
|
1434
1606
|
{
|
|
1435
1607
|
key: shortcut,
|
|
1436
1608
|
run: callbackWrapper(createComment)
|
|
@@ -1469,7 +1641,7 @@ var comments = (options = {}) => {
|
|
|
1469
1641
|
//
|
|
1470
1642
|
// Track deleted ranges and update ranges for decorations.
|
|
1471
1643
|
//
|
|
1472
|
-
|
|
1644
|
+
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1473
1645
|
let mod = false;
|
|
1474
1646
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1475
1647
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1501,7 +1673,7 @@ var comments = (options = {}) => {
|
|
|
1501
1673
|
//
|
|
1502
1674
|
// Track selection/proximity.
|
|
1503
1675
|
//
|
|
1504
|
-
|
|
1676
|
+
EditorView7.updateListener.of(({ view, state }) => {
|
|
1505
1677
|
let min = Infinity;
|
|
1506
1678
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1507
1679
|
const { head } = state.selection.main;
|
|
@@ -1550,7 +1722,7 @@ var focusComment = (view, id, center = true) => {
|
|
|
1550
1722
|
},
|
|
1551
1723
|
effects: [
|
|
1552
1724
|
//
|
|
1553
|
-
|
|
1725
|
+
EditorView7.scrollIntoView(range.from, center ? {
|
|
1554
1726
|
y: "center"
|
|
1555
1727
|
} : void 0),
|
|
1556
1728
|
setSelection.of({
|
|
@@ -1578,14 +1750,16 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1578
1750
|
};
|
|
1579
1751
|
|
|
1580
1752
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1581
|
-
import { Facet as
|
|
1582
|
-
import { EditorView as
|
|
1583
|
-
|
|
1753
|
+
import { Facet as Facet5, Transaction } from "@codemirror/state";
|
|
1754
|
+
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1755
|
+
import { log as log4 } from "@dxos/log";
|
|
1756
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts";
|
|
1757
|
+
var cursorLineMarginFacet = Facet5.define({
|
|
1584
1758
|
combine: (input) => input[0] ?? 3
|
|
1585
1759
|
});
|
|
1586
1760
|
var annotation = "cursorLineMargin";
|
|
1587
1761
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1588
|
-
var cursorLineMargin =
|
|
1762
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1589
1763
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1590
1764
|
return;
|
|
1591
1765
|
}
|
|
@@ -1603,7 +1777,12 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1603
1777
|
const needsScrollTop = false;
|
|
1604
1778
|
const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
|
|
1605
1779
|
if (needsScrollTop && needsScrollBot) {
|
|
1606
|
-
|
|
1780
|
+
log4.warn("is cursorScrollMargin too large for the editor size?", void 0, {
|
|
1781
|
+
F: __dxlog_file5,
|
|
1782
|
+
L: 66,
|
|
1783
|
+
S: void 0,
|
|
1784
|
+
C: (f, a) => f(...a)
|
|
1785
|
+
});
|
|
1607
1786
|
return;
|
|
1608
1787
|
}
|
|
1609
1788
|
if (!needsScrollTop && !needsScrollBot) {
|
|
@@ -1621,38 +1800,57 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1621
1800
|
}
|
|
1622
1801
|
view.dispatch({
|
|
1623
1802
|
annotations: Transaction.userEvent.of(annotation),
|
|
1624
|
-
effects:
|
|
1803
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1625
1804
|
y: needsScrollTop ? "start" : "end",
|
|
1626
1805
|
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1627
1806
|
})
|
|
1628
1807
|
});
|
|
1629
1808
|
});
|
|
1630
1809
|
|
|
1810
|
+
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1811
|
+
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1812
|
+
import { log as log5 } from "@dxos/log";
|
|
1813
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/dnd.ts";
|
|
1814
|
+
var dnd = () => {
|
|
1815
|
+
return EditorView9.domEventHandlers({
|
|
1816
|
+
drop: (event, view) => {
|
|
1817
|
+
log5.info("domEventHandlersDrop", {
|
|
1818
|
+
event
|
|
1819
|
+
}, {
|
|
1820
|
+
F: __dxlog_file6,
|
|
1821
|
+
L: 14,
|
|
1822
|
+
S: void 0,
|
|
1823
|
+
C: (f, a) => f(...a)
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
};
|
|
1828
|
+
|
|
1631
1829
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1632
|
-
import { EditorView as
|
|
1830
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1633
1831
|
var listener = ({ onFocus, onChange }) => {
|
|
1634
1832
|
const extensions = [];
|
|
1635
|
-
onFocus && extensions.push(
|
|
1636
|
-
onFocus(
|
|
1833
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1834
|
+
onFocus(focusing);
|
|
1637
1835
|
return null;
|
|
1638
1836
|
}));
|
|
1639
|
-
onChange && extensions.push(
|
|
1837
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1640
1838
|
onChange(update2.state.doc.toString());
|
|
1641
1839
|
}));
|
|
1642
1840
|
return extensions;
|
|
1643
1841
|
};
|
|
1644
1842
|
|
|
1645
1843
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1646
|
-
import { closeBrackets
|
|
1647
|
-
import { history
|
|
1844
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1845
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1648
1846
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1649
|
-
import { bracketMatching
|
|
1847
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1650
1848
|
import { languages } from "@codemirror/language-data";
|
|
1651
1849
|
import { searchKeymap } from "@codemirror/search";
|
|
1652
1850
|
import { EditorState } from "@codemirror/state";
|
|
1653
|
-
import { oneDarkHighlightStyle
|
|
1654
|
-
import {
|
|
1655
|
-
import { isNotFalsy as
|
|
1851
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1852
|
+
import { EditorView as EditorView11, drawSelection, dropCursor, keymap as keymap5, placeholder } from "@codemirror/view";
|
|
1853
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1656
1854
|
|
|
1657
1855
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1658
1856
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1845,19 +2043,17 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1845
2043
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1846
2044
|
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1847
2045
|
return [
|
|
1848
|
-
|
|
2046
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2047
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
1849
2048
|
EditorState.allowMultipleSelections.of(true),
|
|
1850
2049
|
EditorState.tabSize.of(2),
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
closeBrackets2(),
|
|
1854
|
-
crosshairCursor(),
|
|
2050
|
+
bracketMatching(),
|
|
2051
|
+
closeBrackets(),
|
|
1855
2052
|
dropCursor(),
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
history2(),
|
|
2053
|
+
drawSelection(),
|
|
2054
|
+
history(),
|
|
1859
2055
|
indentOnInput(),
|
|
1860
|
-
_placeholder &&
|
|
2056
|
+
_placeholder && placeholder(_placeholder),
|
|
1861
2057
|
// Main extension.
|
|
1862
2058
|
// https://github.com/codemirror/lang-markdown
|
|
1863
2059
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1877,10 +2073,10 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1877
2073
|
]
|
|
1878
2074
|
}),
|
|
1879
2075
|
// https://github.com/codemirror/theme-one-dark
|
|
1880
|
-
themeMode === "dark" ?
|
|
2076
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
1881
2077
|
// Custom styles.
|
|
1882
|
-
|
|
1883
|
-
|
|
2078
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
2079
|
+
keymap5.of([
|
|
1884
2080
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1885
2081
|
indentWithTab,
|
|
1886
2082
|
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
@@ -1892,22 +2088,22 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1892
2088
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1893
2089
|
...standardKeymap
|
|
1894
2090
|
])
|
|
1895
|
-
].filter(
|
|
2091
|
+
].filter(isNotFalsy2);
|
|
1896
2092
|
};
|
|
1897
2093
|
|
|
1898
2094
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
1899
2095
|
import { syntaxTree } from "@codemirror/language";
|
|
1900
|
-
import { RangeSetBuilder, StateEffect as
|
|
1901
|
-
import { EditorView as
|
|
2096
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2097
|
+
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1902
2098
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1903
|
-
var HorizontalRuleWidget = class extends
|
|
2099
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
1904
2100
|
toDOM() {
|
|
1905
2101
|
const el = document.createElement("span");
|
|
1906
2102
|
el.className = "cm-hr";
|
|
1907
2103
|
return el;
|
|
1908
2104
|
}
|
|
1909
2105
|
};
|
|
1910
|
-
var LinkButton = class extends
|
|
2106
|
+
var LinkButton = class extends WidgetType3 {
|
|
1911
2107
|
constructor(url, render) {
|
|
1912
2108
|
super();
|
|
1913
2109
|
this.url = url;
|
|
@@ -1922,7 +2118,7 @@ var LinkButton = class extends WidgetType2 {
|
|
|
1922
2118
|
return el;
|
|
1923
2119
|
}
|
|
1924
2120
|
};
|
|
1925
|
-
var CheckboxWidget = class extends
|
|
2121
|
+
var CheckboxWidget = class extends WidgetType3 {
|
|
1926
2122
|
constructor(_checked) {
|
|
1927
2123
|
super();
|
|
1928
2124
|
this._checked = _checked;
|
|
@@ -1959,28 +2155,28 @@ var CheckboxWidget = class extends WidgetType2 {
|
|
|
1959
2155
|
return false;
|
|
1960
2156
|
}
|
|
1961
2157
|
};
|
|
1962
|
-
var hide =
|
|
1963
|
-
var fencedCodeLine =
|
|
2158
|
+
var hide = Decoration5.replace({});
|
|
2159
|
+
var fencedCodeLine = Decoration5.line({
|
|
1964
2160
|
class: mx2("cm-code cm-codeblock-line")
|
|
1965
2161
|
});
|
|
1966
|
-
var fencedCodeLineFirst =
|
|
2162
|
+
var fencedCodeLineFirst = Decoration5.line({
|
|
1967
2163
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
1968
2164
|
});
|
|
1969
|
-
var fencedCodeLineLast =
|
|
2165
|
+
var fencedCodeLineLast = Decoration5.line({
|
|
1970
2166
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
1971
2167
|
});
|
|
1972
|
-
var horizontalRule =
|
|
2168
|
+
var horizontalRule = Decoration5.replace({
|
|
1973
2169
|
widget: new HorizontalRuleWidget()
|
|
1974
2170
|
});
|
|
1975
|
-
var checkedTask =
|
|
2171
|
+
var checkedTask = Decoration5.replace({
|
|
1976
2172
|
widget: new CheckboxWidget(true)
|
|
1977
2173
|
});
|
|
1978
|
-
var uncheckedTask =
|
|
2174
|
+
var uncheckedTask = Decoration5.replace({
|
|
1979
2175
|
widget: new CheckboxWidget(false)
|
|
1980
2176
|
});
|
|
1981
2177
|
var editingRange = (state, range, focus) => {
|
|
1982
2178
|
const { readOnly, selection: { main: { head } } } = state;
|
|
1983
|
-
return focus && !readOnly && head >= range.from && head
|
|
2179
|
+
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
1984
2180
|
};
|
|
1985
2181
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1986
2182
|
"CodeMark",
|
|
@@ -1990,8 +2186,8 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
1990
2186
|
"SuperscriptMark"
|
|
1991
2187
|
]);
|
|
1992
2188
|
var buildDecorations = (view, options, focus) => {
|
|
1993
|
-
const deco = new
|
|
1994
|
-
const atomicDeco = new
|
|
2189
|
+
const deco = new RangeSetBuilder2();
|
|
2190
|
+
const atomicDeco = new RangeSetBuilder2();
|
|
1995
2191
|
const { state } = view;
|
|
1996
2192
|
for (const { from, to } of view.visibleRanges) {
|
|
1997
2193
|
syntaxTree(state).iterate({
|
|
@@ -2008,7 +2204,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2008
2204
|
break;
|
|
2009
2205
|
}
|
|
2010
2206
|
const first = block.from <= node.from;
|
|
2011
|
-
const last = block.to >= node.to;
|
|
2207
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
|
2012
2208
|
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2013
2209
|
if (!editing && (first || last)) {
|
|
2014
2210
|
atomicDeco.add(block.from, block.to, hide);
|
|
@@ -2024,7 +2220,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2024
2220
|
if (!editing) {
|
|
2025
2221
|
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2026
2222
|
}
|
|
2027
|
-
deco.add(marks[0].to, marks[1].from,
|
|
2223
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
2028
2224
|
tagName: "a",
|
|
2029
2225
|
attributes: {
|
|
2030
2226
|
class: "cm-link",
|
|
@@ -2034,7 +2230,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2034
2230
|
}
|
|
2035
2231
|
}));
|
|
2036
2232
|
if (!editing) {
|
|
2037
|
-
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ?
|
|
2233
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
2038
2234
|
widget: new LinkButton(url, options.renderLinkButton)
|
|
2039
2235
|
}) : hide);
|
|
2040
2236
|
}
|
|
@@ -2052,7 +2248,7 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2052
2248
|
} else if (node.name === "TaskMarker") {
|
|
2053
2249
|
if (!editingRange(state, node, focus)) {
|
|
2054
2250
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2055
|
-
atomicDeco.add(node.from - 2, node.from - 1,
|
|
2251
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2056
2252
|
class: "cm-task"
|
|
2057
2253
|
}));
|
|
2058
2254
|
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
@@ -2070,50 +2266,51 @@ var buildDecorations = (view, options, focus) => {
|
|
|
2070
2266
|
atomicDeco: atomicDeco.finish()
|
|
2071
2267
|
};
|
|
2072
2268
|
};
|
|
2073
|
-
var forceUpdate =
|
|
2269
|
+
var forceUpdate = StateEffect4.define();
|
|
2074
2270
|
var decorateMarkdown = (options = {}) => {
|
|
2075
2271
|
return [
|
|
2076
|
-
|
|
2272
|
+
ViewPlugin4.fromClass(class {
|
|
2077
2273
|
constructor(view) {
|
|
2078
|
-
this.pendingUpdate = -1;
|
|
2079
2274
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2080
2275
|
}
|
|
2081
2276
|
update(update2) {
|
|
2082
|
-
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) {
|
|
2083
2278
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2084
2279
|
this.clearUpdate();
|
|
2085
2280
|
} else if (update2.selectionSet) {
|
|
2086
2281
|
this.scheduleUpdate(update2.view);
|
|
2087
2282
|
}
|
|
2088
2283
|
}
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
window.clearTimeout(this.pendingUpdate);
|
|
2092
|
-
this.pendingUpdate = -1;
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
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.
|
|
2095
2286
|
scheduleUpdate(view) {
|
|
2096
2287
|
this.clearUpdate();
|
|
2097
|
-
this.pendingUpdate =
|
|
2288
|
+
this.pendingUpdate = setTimeout(() => {
|
|
2098
2289
|
view.dispatch({
|
|
2099
2290
|
effects: forceUpdate.of(null)
|
|
2100
2291
|
});
|
|
2101
|
-
}, options.selectionChangeDelay
|
|
2292
|
+
}, options.selectionChangeDelay);
|
|
2293
|
+
}
|
|
2294
|
+
clearUpdate() {
|
|
2295
|
+
if (this.pendingUpdate) {
|
|
2296
|
+
clearTimeout(this.pendingUpdate);
|
|
2297
|
+
this.pendingUpdate = void 0;
|
|
2298
|
+
}
|
|
2102
2299
|
}
|
|
2103
2300
|
destroy() {
|
|
2104
2301
|
this.clearUpdate();
|
|
2105
2302
|
}
|
|
2106
2303
|
}, {
|
|
2107
2304
|
provide: (plugin) => [
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
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)
|
|
2111
2308
|
]
|
|
2112
2309
|
}),
|
|
2113
2310
|
formattingStyles
|
|
2114
2311
|
];
|
|
2115
2312
|
};
|
|
2116
|
-
var formattingStyles =
|
|
2313
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
2117
2314
|
"& .cm-code": {
|
|
2118
2315
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2119
2316
|
},
|
|
@@ -2166,7 +2363,7 @@ var formattingStyles = EditorView10.baseTheme({
|
|
|
2166
2363
|
import { snippet } from "@codemirror/autocomplete";
|
|
2167
2364
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2168
2365
|
import { EditorSelection } from "@codemirror/state";
|
|
2169
|
-
import { EditorView as
|
|
2366
|
+
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2170
2367
|
import { useState, useMemo } from "react";
|
|
2171
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;
|
|
2172
2369
|
var Inline;
|
|
@@ -3038,7 +3235,7 @@ var toggleCodeblock = (target) => {
|
|
|
3038
3235
|
};
|
|
3039
3236
|
var formatting = (options = {}) => {
|
|
3040
3237
|
return [
|
|
3041
|
-
|
|
3238
|
+
keymap6.of([
|
|
3042
3239
|
{
|
|
3043
3240
|
key: "meta-b",
|
|
3044
3241
|
run: toggleStrong
|
|
@@ -3236,7 +3433,7 @@ var getFormatting = (state) => {
|
|
|
3236
3433
|
};
|
|
3237
3434
|
var useFormattingState = () => {
|
|
3238
3435
|
const [state, setState] = useState(null);
|
|
3239
|
-
const observer = useMemo(() =>
|
|
3436
|
+
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3240
3437
|
if (update2.docChanged || update2.selectionSet) {
|
|
3241
3438
|
const newState = getFormatting(update2.state);
|
|
3242
3439
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3252,12 +3449,12 @@ var useFormattingState = () => {
|
|
|
3252
3449
|
|
|
3253
3450
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3254
3451
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3255
|
-
import { StateField as
|
|
3256
|
-
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";
|
|
3257
3454
|
var image = (options = {}) => {
|
|
3258
|
-
return
|
|
3455
|
+
return StateField5.define({
|
|
3259
3456
|
create: (state) => {
|
|
3260
|
-
return
|
|
3457
|
+
return Decoration6.set(buildDecorations2(0, state.doc.length, state));
|
|
3261
3458
|
},
|
|
3262
3459
|
update: (value, tr) => {
|
|
3263
3460
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3280,7 +3477,7 @@ var image = (options = {}) => {
|
|
|
3280
3477
|
add: buildDecorations2(from, to, tr.state)
|
|
3281
3478
|
});
|
|
3282
3479
|
},
|
|
3283
|
-
provide: (field) =>
|
|
3480
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3284
3481
|
});
|
|
3285
3482
|
};
|
|
3286
3483
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3302,7 +3499,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3302
3499
|
const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3303
3500
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3304
3501
|
preloadImage(url);
|
|
3305
|
-
decorations.push(
|
|
3502
|
+
decorations.push(Decoration6.replace({
|
|
3306
3503
|
block: true,
|
|
3307
3504
|
widget: new ImageWidget(url)
|
|
3308
3505
|
}).range(hide2 ? node.from : node.to, node.to));
|
|
@@ -3314,7 +3511,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3314
3511
|
});
|
|
3315
3512
|
return decorations;
|
|
3316
3513
|
};
|
|
3317
|
-
var ImageWidget = class extends
|
|
3514
|
+
var ImageWidget = class extends WidgetType4 {
|
|
3318
3515
|
constructor(_url) {
|
|
3319
3516
|
super();
|
|
3320
3517
|
this._url = _url;
|
|
@@ -3367,17 +3564,17 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3367
3564
|
|
|
3368
3565
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3369
3566
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3370
|
-
import { RangeSetBuilder as
|
|
3371
|
-
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";
|
|
3372
3569
|
var table = (options = {}) => {
|
|
3373
|
-
return
|
|
3570
|
+
return StateField6.define({
|
|
3374
3571
|
create: (state) => update(state, options),
|
|
3375
3572
|
update: (_, tr) => update(tr.state, options),
|
|
3376
|
-
provide: (field) =>
|
|
3573
|
+
provide: (field) => EditorView15.decorations.from(field)
|
|
3377
3574
|
});
|
|
3378
3575
|
};
|
|
3379
3576
|
var update = (state, options) => {
|
|
3380
|
-
const builder = new
|
|
3577
|
+
const builder = new RangeSetBuilder3();
|
|
3381
3578
|
const cursor = state.selection.main.head;
|
|
3382
3579
|
const tables = [];
|
|
3383
3580
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3417,16 +3614,16 @@ var update = (state, options) => {
|
|
|
3417
3614
|
});
|
|
3418
3615
|
tables.forEach((table2) => {
|
|
3419
3616
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3420
|
-
hide2 && builder.add(table2.from, table2.to,
|
|
3617
|
+
hide2 && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3421
3618
|
widget: new TableWidget(table2)
|
|
3422
3619
|
}));
|
|
3423
|
-
builder.add(table2.from, table2.to,
|
|
3620
|
+
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
3424
3621
|
class: "cm-table"
|
|
3425
3622
|
}));
|
|
3426
3623
|
});
|
|
3427
3624
|
return builder.finish();
|
|
3428
3625
|
};
|
|
3429
|
-
var TableWidget = class extends
|
|
3626
|
+
var TableWidget = class extends WidgetType5 {
|
|
3430
3627
|
constructor(_table) {
|
|
3431
3628
|
super();
|
|
3432
3629
|
this._table = _table;
|
|
@@ -3465,6 +3662,8 @@ var TableWidget = class extends WidgetType4 {
|
|
|
3465
3662
|
|
|
3466
3663
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3467
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";
|
|
3468
3667
|
var mention = ({ onSearch }) => {
|
|
3469
3668
|
return autocompletion2({
|
|
3470
3669
|
// TODO(burdon): Not working.
|
|
@@ -3476,7 +3675,14 @@ var mention = ({ onSearch }) => {
|
|
|
3476
3675
|
icons: false,
|
|
3477
3676
|
override: [
|
|
3478
3677
|
(context) => {
|
|
3479
|
-
|
|
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
|
+
});
|
|
3480
3686
|
const match = context.matchBefore(/@(\w+)?/);
|
|
3481
3687
|
if (!match || match.from === match.to && !context.explicit) {
|
|
3482
3688
|
return null;
|
|
@@ -3493,10 +3699,10 @@ var mention = ({ onSearch }) => {
|
|
|
3493
3699
|
};
|
|
3494
3700
|
|
|
3495
3701
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
3496
|
-
import { Facet as
|
|
3497
|
-
import { keymap as
|
|
3702
|
+
import { Facet as Facet6 } from "@codemirror/state";
|
|
3703
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
3498
3704
|
import { vim } from "@replit/codemirror-vim";
|
|
3499
|
-
var editorMode =
|
|
3705
|
+
var editorMode = Facet6.define({
|
|
3500
3706
|
combine: (modes) => modes[0] ?? {}
|
|
3501
3707
|
});
|
|
3502
3708
|
var EditorModes = {
|
|
@@ -3507,7 +3713,7 @@ var EditorModes = {
|
|
|
3507
3713
|
type: "vim",
|
|
3508
3714
|
noTabster: true
|
|
3509
3715
|
}),
|
|
3510
|
-
|
|
3716
|
+
keymap7.of([
|
|
3511
3717
|
{
|
|
3512
3718
|
key: "Alt-Escape",
|
|
3513
3719
|
run: (view) => {
|
|
@@ -3527,7 +3733,7 @@ var outliner = (options = {}) => {
|
|
|
3527
3733
|
};
|
|
3528
3734
|
|
|
3529
3735
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
3530
|
-
import { keymap as
|
|
3736
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
3531
3737
|
var defaultItems = [
|
|
3532
3738
|
"hello world!",
|
|
3533
3739
|
"this is a test.",
|
|
@@ -3537,7 +3743,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3537
3743
|
let t;
|
|
3538
3744
|
let idx = 0;
|
|
3539
3745
|
return [
|
|
3540
|
-
|
|
3746
|
+
keymap8.of([
|
|
3541
3747
|
{
|
|
3542
3748
|
// Reset.
|
|
3543
3749
|
key: "alt-meta-'",
|
|
@@ -3583,161 +3789,345 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3583
3789
|
];
|
|
3584
3790
|
};
|
|
3585
3791
|
|
|
3586
|
-
// packages/ui/react-ui-editor/src/
|
|
3587
|
-
import
|
|
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
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
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 = {
|
|
3694
3978
|
//
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
textDecorationLine: "underline",
|
|
3698
|
-
textDecorationThickness: "1px",
|
|
3699
|
-
textUnderlineOffset: "2px",
|
|
3700
|
-
borderRadius: ".125rem",
|
|
3701
|
-
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
3702
|
-
},
|
|
3979
|
+
// Main layout:
|
|
3980
|
+
// https://codemirror.net/examples/styling
|
|
3703
3981
|
//
|
|
3704
|
-
//
|
|
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>
|
|
3705
4000
|
//
|
|
3706
|
-
"
|
|
3707
|
-
|
|
4001
|
+
"&": {},
|
|
4002
|
+
"&.cm-focused": {
|
|
4003
|
+
outline: "none"
|
|
3708
4004
|
},
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
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
|
|
3716
4012
|
},
|
|
3717
|
-
".cm-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
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"
|
|
3721
4018
|
},
|
|
3722
|
-
".cm-
|
|
3723
|
-
|
|
4019
|
+
"&light .cm-content": {
|
|
4020
|
+
color: get4(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
4021
|
+
caretColor: "black"
|
|
3724
4022
|
},
|
|
3725
|
-
".cm-
|
|
3726
|
-
|
|
4023
|
+
"&dark .cm-content": {
|
|
4024
|
+
color: get4(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
4025
|
+
caretColor: "white"
|
|
3727
4026
|
},
|
|
3728
4027
|
//
|
|
3729
|
-
//
|
|
4028
|
+
// Cursor
|
|
3730
4029
|
//
|
|
3731
|
-
".cm-
|
|
3732
|
-
|
|
3733
|
-
textDecoration: "none !important"
|
|
4030
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
4031
|
+
borderLeft: "2px solid black"
|
|
3734
4032
|
},
|
|
3735
|
-
".cm-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
4033
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
4034
|
+
borderLeft: "2px solid white"
|
|
4035
|
+
},
|
|
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)")
|
|
4041
|
+
},
|
|
4042
|
+
//
|
|
4043
|
+
// line
|
|
4044
|
+
//
|
|
4045
|
+
".cm-line": {
|
|
4046
|
+
paddingInline: 0
|
|
4047
|
+
},
|
|
4048
|
+
".cm-activeLine": {
|
|
4049
|
+
background: "transparent"
|
|
4050
|
+
},
|
|
4051
|
+
//
|
|
4052
|
+
// gutter
|
|
4053
|
+
//
|
|
4054
|
+
".cm-gutterElement": {
|
|
4055
|
+
width: "48px"
|
|
4056
|
+
},
|
|
4057
|
+
//
|
|
4058
|
+
// Selection
|
|
4059
|
+
//
|
|
4060
|
+
"&light .cm-selectionBackground": {
|
|
4061
|
+
background: get4(tokens, "extend.colors.primary.100")
|
|
4062
|
+
},
|
|
4063
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4064
|
+
background: get4(tokens, "extend.colors.primary.200")
|
|
4065
|
+
},
|
|
4066
|
+
"&dark .cm-selectionBackground": {
|
|
4067
|
+
background: get4(tokens, "extend.colors.primary.700")
|
|
4068
|
+
},
|
|
4069
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4070
|
+
background: get4(tokens, "extend.colors.primary.600")
|
|
4071
|
+
},
|
|
4072
|
+
//
|
|
4073
|
+
// Search
|
|
4074
|
+
//
|
|
4075
|
+
"&light .cm-searchMatch": {
|
|
4076
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.100")
|
|
4077
|
+
},
|
|
4078
|
+
"&dark .cm-searchMatch": {
|
|
4079
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.700")
|
|
4080
|
+
},
|
|
4081
|
+
//
|
|
4082
|
+
// link
|
|
4083
|
+
//
|
|
4084
|
+
".cm-link": {
|
|
4085
|
+
color: get4(tokens, "extend.colors.primary.500"),
|
|
4086
|
+
textDecorationLine: "underline",
|
|
4087
|
+
textDecorationThickness: "1px",
|
|
4088
|
+
textUnderlineOffset: "2px",
|
|
4089
|
+
borderRadius: ".125rem",
|
|
4090
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4091
|
+
},
|
|
4092
|
+
//
|
|
4093
|
+
// tooltip
|
|
4094
|
+
//
|
|
4095
|
+
".cm-tooltip": {
|
|
4096
|
+
border: "none",
|
|
4097
|
+
background: "unset"
|
|
4098
|
+
},
|
|
4099
|
+
".cm-tooltip-below": {},
|
|
4100
|
+
//
|
|
4101
|
+
// autocomplete
|
|
4102
|
+
//
|
|
4103
|
+
".cm-tooltip-autocomplete": {
|
|
4104
|
+
marginTop: "4px",
|
|
4105
|
+
marginLeft: "-3px"
|
|
4106
|
+
},
|
|
4107
|
+
".cm-tooltip-autocomplete ul li": {},
|
|
4108
|
+
".cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
4109
|
+
".cm-completionIcon": {
|
|
4110
|
+
display: "none"
|
|
4111
|
+
},
|
|
4112
|
+
".cm-completionLabel": {
|
|
4113
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4114
|
+
},
|
|
4115
|
+
".cm-completionMatchedText": {
|
|
4116
|
+
textDecoration: "none"
|
|
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")
|
|
3741
4131
|
},
|
|
3742
4132
|
".cm-table-cell": {
|
|
3743
4133
|
padding: "2px 16px 2px 0px"
|
|
@@ -3833,19 +4223,238 @@ var codeTheme = {
|
|
|
3833
4223
|
}
|
|
3834
4224
|
};
|
|
3835
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
|
+
|
|
3836
4445
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3837
|
-
var
|
|
3838
|
-
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) => {
|
|
3839
4448
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
3840
4449
|
tabBehavior: "limited"
|
|
3841
4450
|
});
|
|
3842
4451
|
const { themeMode } = useThemeContext();
|
|
3843
|
-
const rootRef =
|
|
3844
|
-
const [view, setView] =
|
|
4452
|
+
const rootRef = useRef3(null);
|
|
4453
|
+
const [view, setView] = useState5(null);
|
|
3845
4454
|
useImperativeHandle(forwardedRef, () => view, [
|
|
3846
4455
|
view
|
|
3847
4456
|
]);
|
|
3848
|
-
|
|
4457
|
+
useEffect3(() => {
|
|
3849
4458
|
if (autoFocus) {
|
|
3850
4459
|
view?.focus();
|
|
3851
4460
|
}
|
|
@@ -3853,38 +4462,38 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3853
4462
|
view,
|
|
3854
4463
|
autoFocus
|
|
3855
4464
|
]);
|
|
3856
|
-
|
|
4465
|
+
useEffect3(() => {
|
|
3857
4466
|
if (!model || !rootRef.current) {
|
|
3858
4467
|
return;
|
|
3859
4468
|
}
|
|
3860
|
-
const state =
|
|
3861
|
-
doc: model.
|
|
4469
|
+
const state = EditorState3.create({
|
|
4470
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
3862
4471
|
selection,
|
|
3863
4472
|
extensions: [
|
|
3864
4473
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
F:
|
|
3868
|
-
L:
|
|
4474
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4475
|
+
log9.catch(err, void 0, {
|
|
4476
|
+
F: __dxlog_file11,
|
|
4477
|
+
L: 123,
|
|
3869
4478
|
S: void 0,
|
|
3870
4479
|
C: (f, a) => f(...a)
|
|
3871
4480
|
});
|
|
3872
4481
|
}),
|
|
3873
4482
|
// Theme.
|
|
3874
4483
|
// TODO(burdon): Make base theme configurable.
|
|
3875
|
-
|
|
3876
|
-
theme &&
|
|
3877
|
-
|
|
3878
|
-
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({
|
|
3879
4488
|
class: slots.editor.className
|
|
3880
4489
|
}),
|
|
3881
|
-
slots.content?.className &&
|
|
4490
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3882
4491
|
class: slots.content.className
|
|
3883
4492
|
}),
|
|
3884
4493
|
// NOTE: Assumes default line height.
|
|
3885
|
-
_scrollPastEnd &&
|
|
4494
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
3886
4495
|
// Focus.
|
|
3887
|
-
|
|
4496
|
+
EditorView17.updateListener.of((update2) => {
|
|
3888
4497
|
update2.transactions.forEach((transaction) => {
|
|
3889
4498
|
if (transaction.isUserEvent("focus.container")) {
|
|
3890
4499
|
rootRef.current?.focus();
|
|
@@ -3892,8 +4501,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3892
4501
|
});
|
|
3893
4502
|
}),
|
|
3894
4503
|
// State.
|
|
3895
|
-
|
|
3896
|
-
|
|
4504
|
+
EditorView17.editable.of(!readonly),
|
|
4505
|
+
EditorState3.readOnly.of(!!readonly),
|
|
3897
4506
|
// Storage and replication.
|
|
3898
4507
|
// NOTE: This must come before user extensions.
|
|
3899
4508
|
model.extension,
|
|
@@ -3901,7 +4510,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3901
4510
|
...extensions
|
|
3902
4511
|
].filter(isNotFalsy4)
|
|
3903
4512
|
});
|
|
3904
|
-
const view2 = new
|
|
4513
|
+
const view2 = new EditorView17({
|
|
3905
4514
|
state,
|
|
3906
4515
|
parent: rootRef.current,
|
|
3907
4516
|
scrollTo,
|
|
@@ -3958,14 +4567,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3958
4567
|
...tabsterDOMAttribute
|
|
3959
4568
|
});
|
|
3960
4569
|
});
|
|
3961
|
-
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) => {
|
|
3962
4571
|
const { themeMode } = useThemeContext();
|
|
3963
|
-
const updatedSlots =
|
|
3964
|
-
const extensions =
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
placeholder: placeholder3
|
|
3968
|
-
|
|
4572
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4573
|
+
const extensions = useMemo3(() => [
|
|
4574
|
+
createBasicExtensions({
|
|
4575
|
+
lineWrapping,
|
|
4576
|
+
placeholder: placeholder3
|
|
4577
|
+
}),
|
|
4578
|
+
createThemeExtensions({
|
|
4579
|
+
themeMode
|
|
3969
4580
|
}),
|
|
3970
4581
|
..._extensions ?? []
|
|
3971
4582
|
], [
|
|
@@ -3985,8 +4596,8 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
3985
4596
|
});
|
|
3986
4597
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3987
4598
|
const { themeMode } = useThemeContext();
|
|
3988
|
-
const updatedSlots =
|
|
3989
|
-
const extensions =
|
|
4599
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4600
|
+
const extensions = useMemo3(() => [
|
|
3990
4601
|
createMarkdownExtensions({
|
|
3991
4602
|
themeMode,
|
|
3992
4603
|
placeholder: placeholder3
|
|
@@ -4024,7 +4635,7 @@ var defaultMarkdownSlots = {
|
|
|
4024
4635
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4025
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";
|
|
4026
4637
|
import { createContext } from "@radix-ui/react-context";
|
|
4027
|
-
import React2, { useRef as
|
|
4638
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
4028
4639
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4029
4640
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4030
4641
|
var tooltipProps = {
|
|
@@ -4082,9 +4693,9 @@ var MarkdownHeading = () => {
|
|
|
4082
4693
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4083
4694
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4084
4695
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4085
|
-
const suppressNextTooltip =
|
|
4086
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4087
|
-
const [selectOpen, setSelectOpen] =
|
|
4696
|
+
const suppressNextTooltip = useRef4(false);
|
|
4697
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4698
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4088
4699
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4089
4700
|
open: tooltipOpen,
|
|
4090
4701
|
onOpenChange: (nextOpen) => {
|
|
@@ -4287,378 +4898,6 @@ var Toolbar = {
|
|
|
4287
4898
|
Markdown: MarkdownStandard,
|
|
4288
4899
|
Extended: MarkdownExtended
|
|
4289
4900
|
};
|
|
4290
|
-
|
|
4291
|
-
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4292
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4293
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4294
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
4295
|
-
import { log as log4 } from "@dxos/log";
|
|
4296
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4297
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
4298
|
-
var SpaceAwarenessProvider = class {
|
|
4299
|
-
constructor(params) {
|
|
4300
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4301
|
-
this.remoteStateChange = new Event2();
|
|
4302
|
-
this._space = params.space;
|
|
4303
|
-
this._channel = params.channel;
|
|
4304
|
-
this._peerId = params.peerId;
|
|
4305
|
-
this._info = params.info;
|
|
4306
|
-
}
|
|
4307
|
-
open() {
|
|
4308
|
-
this._ctx = new Context2();
|
|
4309
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4310
|
-
if (this._localState) {
|
|
4311
|
-
await this._space.postMessage(this._channel, {
|
|
4312
|
-
kind: "post",
|
|
4313
|
-
state: this._localState
|
|
4314
|
-
});
|
|
4315
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
4316
|
-
}
|
|
4317
|
-
});
|
|
4318
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4319
|
-
switch (message.payload.kind) {
|
|
4320
|
-
case "query": {
|
|
4321
|
-
this._handleQueryMessage();
|
|
4322
|
-
break;
|
|
4323
|
-
}
|
|
4324
|
-
case "post": {
|
|
4325
|
-
this._handlePostMessage(message.payload);
|
|
4326
|
-
break;
|
|
4327
|
-
}
|
|
4328
|
-
}
|
|
4329
|
-
}));
|
|
4330
|
-
void this._space.postMessage(this._channel, {
|
|
4331
|
-
kind: "query"
|
|
4332
|
-
}).catch((err) => {
|
|
4333
|
-
log4.debug("failed to query awareness", {
|
|
4334
|
-
err
|
|
4335
|
-
}, {
|
|
4336
|
-
F: __dxlog_file5,
|
|
4337
|
-
L: 89,
|
|
4338
|
-
S: this,
|
|
4339
|
-
C: (f, a) => f(...a)
|
|
4340
|
-
});
|
|
4341
|
-
});
|
|
4342
|
-
}
|
|
4343
|
-
close() {
|
|
4344
|
-
void this._ctx?.dispose();
|
|
4345
|
-
this._ctx = void 0;
|
|
4346
|
-
this._postTask = void 0;
|
|
4347
|
-
}
|
|
4348
|
-
getRemoteStates() {
|
|
4349
|
-
return Array.from(this._remoteStates.values());
|
|
4350
|
-
}
|
|
4351
|
-
update(position) {
|
|
4352
|
-
invariant2(this._postTask, void 0, {
|
|
4353
|
-
F: __dxlog_file5,
|
|
4354
|
-
L: 104,
|
|
4355
|
-
S: this,
|
|
4356
|
-
A: [
|
|
4357
|
-
"this._postTask",
|
|
4358
|
-
""
|
|
4359
|
-
]
|
|
4360
|
-
});
|
|
4361
|
-
this._localState = {
|
|
4362
|
-
peerId: this._peerId,
|
|
4363
|
-
position,
|
|
4364
|
-
info: this._info
|
|
4365
|
-
};
|
|
4366
|
-
this._postTask.schedule();
|
|
4367
|
-
}
|
|
4368
|
-
_handleQueryMessage() {
|
|
4369
|
-
invariant2(this._postTask, void 0, {
|
|
4370
|
-
F: __dxlog_file5,
|
|
4371
|
-
L: 115,
|
|
4372
|
-
S: this,
|
|
4373
|
-
A: [
|
|
4374
|
-
"this._postTask",
|
|
4375
|
-
""
|
|
4376
|
-
]
|
|
4377
|
-
});
|
|
4378
|
-
this._postTask.schedule();
|
|
4379
|
-
}
|
|
4380
|
-
_handlePostMessage(message) {
|
|
4381
|
-
invariant2(message.kind === "post", void 0, {
|
|
4382
|
-
F: __dxlog_file5,
|
|
4383
|
-
L: 120,
|
|
4384
|
-
S: this,
|
|
4385
|
-
A: [
|
|
4386
|
-
"message.kind === 'post'",
|
|
4387
|
-
""
|
|
4388
|
-
]
|
|
4389
|
-
});
|
|
4390
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
4391
|
-
this.remoteStateChange.emit();
|
|
4392
|
-
}
|
|
4393
|
-
};
|
|
4394
|
-
|
|
4395
|
-
// packages/ui/react-ui-editor/src/hooks/defs.ts
|
|
4396
|
-
import { StateField as StateField6 } from "@codemirror/state";
|
|
4397
|
-
var modelState = StateField6.define({
|
|
4398
|
-
create: () => void 0,
|
|
4399
|
-
update: (model) => model
|
|
4400
|
-
});
|
|
4401
|
-
|
|
4402
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4403
|
-
var useActionHandler = (view) => {
|
|
4404
|
-
return (action) => {
|
|
4405
|
-
if (!view) {
|
|
4406
|
-
return;
|
|
4407
|
-
}
|
|
4408
|
-
let inlineType, listType;
|
|
4409
|
-
switch (action.type) {
|
|
4410
|
-
case "heading":
|
|
4411
|
-
setHeading(parseInt(action.data))(view);
|
|
4412
|
-
break;
|
|
4413
|
-
case "strong":
|
|
4414
|
-
case "emphasis":
|
|
4415
|
-
case "strikethrough":
|
|
4416
|
-
case "code":
|
|
4417
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4418
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4419
|
-
break;
|
|
4420
|
-
case "list-ordered":
|
|
4421
|
-
case "list-bullet":
|
|
4422
|
-
case "list-task":
|
|
4423
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4424
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4425
|
-
break;
|
|
4426
|
-
case "blockquote":
|
|
4427
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4428
|
-
break;
|
|
4429
|
-
case "codeblock":
|
|
4430
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4431
|
-
break;
|
|
4432
|
-
case "table":
|
|
4433
|
-
insertTable(view);
|
|
4434
|
-
break;
|
|
4435
|
-
case "link":
|
|
4436
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4437
|
-
break;
|
|
4438
|
-
case "comment":
|
|
4439
|
-
createComment(view);
|
|
4440
|
-
break;
|
|
4441
|
-
}
|
|
4442
|
-
setTimeout(() => {
|
|
4443
|
-
if (!view.hasFocus) {
|
|
4444
|
-
view.focus();
|
|
4445
|
-
}
|
|
4446
|
-
});
|
|
4447
|
-
};
|
|
4448
|
-
};
|
|
4449
|
-
|
|
4450
|
-
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4451
|
-
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4452
|
-
var useEditorView = (id) => {
|
|
4453
|
-
const editorRef = useRef3(null);
|
|
4454
|
-
const [prev, setPrev] = useState4([
|
|
4455
|
-
null,
|
|
4456
|
-
""
|
|
4457
|
-
]);
|
|
4458
|
-
if (prev[0] !== editorRef.current) {
|
|
4459
|
-
setPrev([
|
|
4460
|
-
editorRef.current,
|
|
4461
|
-
id
|
|
4462
|
-
]);
|
|
4463
|
-
}
|
|
4464
|
-
return [
|
|
4465
|
-
editorRef,
|
|
4466
|
-
prev[1] !== id
|
|
4467
|
-
];
|
|
4468
|
-
};
|
|
4469
|
-
|
|
4470
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4471
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4472
|
-
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4473
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4474
|
-
import { log as log5 } from "@dxos/log";
|
|
4475
|
-
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4476
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4477
|
-
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps) => {
|
|
4478
|
-
const onUpdate = useRef4();
|
|
4479
|
-
const [view, setView] = useState5();
|
|
4480
|
-
const parentRef = useRef4(null);
|
|
4481
|
-
useEffect3(() => {
|
|
4482
|
-
let view2;
|
|
4483
|
-
if (parentRef.current) {
|
|
4484
|
-
const state = EditorState3.create({
|
|
4485
|
-
doc,
|
|
4486
|
-
selection,
|
|
4487
|
-
extensions: [
|
|
4488
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4489
|
-
EditorView15.exceptionSink.of((err) => {
|
|
4490
|
-
log5.catch(err, void 0, {
|
|
4491
|
-
F: __dxlog_file6,
|
|
4492
|
-
L: 57,
|
|
4493
|
-
S: void 0,
|
|
4494
|
-
C: (f, a) => f(...a)
|
|
4495
|
-
});
|
|
4496
|
-
}),
|
|
4497
|
-
extensions,
|
|
4498
|
-
EditorView15.updateListener.of(() => {
|
|
4499
|
-
onUpdate.current?.();
|
|
4500
|
-
})
|
|
4501
|
-
].filter(isNotFalsy5)
|
|
4502
|
-
});
|
|
4503
|
-
view2 = new EditorView15({
|
|
4504
|
-
parent: parentRef.current,
|
|
4505
|
-
scrollTo,
|
|
4506
|
-
state,
|
|
4507
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4508
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4509
|
-
dispatchTransactions: (trs, view3) => {
|
|
4510
|
-
if (debug) {
|
|
4511
|
-
logChanges(trs);
|
|
4512
|
-
}
|
|
4513
|
-
view3.update(trs);
|
|
4514
|
-
}
|
|
4515
|
-
});
|
|
4516
|
-
setView(view2);
|
|
4517
|
-
}
|
|
4518
|
-
return () => {
|
|
4519
|
-
view2?.destroy();
|
|
4520
|
-
};
|
|
4521
|
-
}, deps);
|
|
4522
|
-
useEffect3(() => {
|
|
4523
|
-
if (view) {
|
|
4524
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4525
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4526
|
-
}
|
|
4527
|
-
if (selection || scrollTo) {
|
|
4528
|
-
onUpdate.current = () => {
|
|
4529
|
-
onUpdate.current = void 0;
|
|
4530
|
-
view.dispatch({
|
|
4531
|
-
selection,
|
|
4532
|
-
effects: scrollTo && [
|
|
4533
|
-
scrollTo
|
|
4534
|
-
],
|
|
4535
|
-
scrollIntoView: !scrollTo
|
|
4536
|
-
});
|
|
4537
|
-
};
|
|
4538
|
-
}
|
|
4539
|
-
if (autoFocus) {
|
|
4540
|
-
view.focus();
|
|
4541
|
-
}
|
|
4542
|
-
}
|
|
4543
|
-
}, [
|
|
4544
|
-
view,
|
|
4545
|
-
autoFocus,
|
|
4546
|
-
selection,
|
|
4547
|
-
scrollTo
|
|
4548
|
-
]);
|
|
4549
|
-
return {
|
|
4550
|
-
parentRef,
|
|
4551
|
-
view
|
|
4552
|
-
};
|
|
4553
|
-
};
|
|
4554
|
-
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4555
|
-
return [
|
|
4556
|
-
//
|
|
4557
|
-
EditorState3.readOnly.of(readonly),
|
|
4558
|
-
EditorView15.editable.of(!readonly)
|
|
4559
|
-
];
|
|
4560
|
-
};
|
|
4561
|
-
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4562
|
-
return [
|
|
4563
|
-
//
|
|
4564
|
-
EditorView15.baseTheme(defaultTheme),
|
|
4565
|
-
theme && EditorView15.theme(theme),
|
|
4566
|
-
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4567
|
-
EditorView15.editorAttributes.of({
|
|
4568
|
-
class: slots?.editor?.className ?? ""
|
|
4569
|
-
}),
|
|
4570
|
-
EditorView15.contentAttributes.of({
|
|
4571
|
-
class: slots?.content?.className ?? ""
|
|
4572
|
-
})
|
|
4573
|
-
].filter(isNotFalsy5);
|
|
4574
|
-
};
|
|
4575
|
-
|
|
4576
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4577
|
-
import get5 from "lodash.get";
|
|
4578
|
-
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4579
|
-
import { generateName } from "@dxos/display-name";
|
|
4580
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
4581
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4582
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4583
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4584
|
-
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4585
|
-
const extensions = [
|
|
4586
|
-
automerge(text)
|
|
4587
|
-
];
|
|
4588
|
-
if (space && identity) {
|
|
4589
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4590
|
-
space,
|
|
4591
|
-
channel: `awareness.${id}`,
|
|
4592
|
-
peerId: identity.identityKey.toHex(),
|
|
4593
|
-
info: {
|
|
4594
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4595
|
-
color: cursorColor.color,
|
|
4596
|
-
lightColor: cursorColor.light
|
|
4597
|
-
}
|
|
4598
|
-
});
|
|
4599
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4600
|
-
}
|
|
4601
|
-
return extensions;
|
|
4602
|
-
};
|
|
4603
|
-
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4604
|
-
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4605
|
-
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4606
|
-
return {
|
|
4607
|
-
id,
|
|
4608
|
-
content,
|
|
4609
|
-
setContent,
|
|
4610
|
-
text: () => content
|
|
4611
|
-
};
|
|
4612
|
-
};
|
|
4613
|
-
var createModel = ({ space, identity, text }) => {
|
|
4614
|
-
if (!text) {
|
|
4615
|
-
return void 0;
|
|
4616
|
-
}
|
|
4617
|
-
invariant3(isAutomergeObject(text), void 0, {
|
|
4618
|
-
F: __dxlog_file7,
|
|
4619
|
-
L: 83,
|
|
4620
|
-
S: void 0,
|
|
4621
|
-
A: [
|
|
4622
|
-
"isAutomergeObject(text)",
|
|
4623
|
-
""
|
|
4624
|
-
]
|
|
4625
|
-
});
|
|
4626
|
-
const obj = text;
|
|
4627
|
-
const doc = getRawDoc(obj, [
|
|
4628
|
-
obj.field
|
|
4629
|
-
]);
|
|
4630
|
-
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4631
|
-
space,
|
|
4632
|
-
channel: `automerge.awareness.${obj.id}`,
|
|
4633
|
-
info: {
|
|
4634
|
-
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4635
|
-
color: cursorColor.color,
|
|
4636
|
-
lightColor: cursorColor.light
|
|
4637
|
-
},
|
|
4638
|
-
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4639
|
-
});
|
|
4640
|
-
const extensions = [
|
|
4641
|
-
modelState.init(() => model),
|
|
4642
|
-
automerge({
|
|
4643
|
-
handle: doc.handle,
|
|
4644
|
-
path: doc.path
|
|
4645
|
-
})
|
|
4646
|
-
];
|
|
4647
|
-
if (awarenessProvider2) {
|
|
4648
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4649
|
-
}
|
|
4650
|
-
const model = {
|
|
4651
|
-
id: obj.id,
|
|
4652
|
-
content: doc,
|
|
4653
|
-
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4654
|
-
extension: extensions,
|
|
4655
|
-
peer: identity ? {
|
|
4656
|
-
id: identity.identityKey.toHex(),
|
|
4657
|
-
name: identity.profile?.displayName
|
|
4658
|
-
} : void 0
|
|
4659
|
-
};
|
|
4660
|
-
return model;
|
|
4661
|
-
};
|
|
4662
4901
|
export {
|
|
4663
4902
|
BaseTextEditor,
|
|
4664
4903
|
Cursor,
|
|
@@ -4687,11 +4926,11 @@ export {
|
|
|
4687
4926
|
blast,
|
|
4688
4927
|
callbackWrapper,
|
|
4689
4928
|
codeTheme,
|
|
4929
|
+
command,
|
|
4690
4930
|
comments,
|
|
4691
4931
|
compareFormatting,
|
|
4692
|
-
|
|
4932
|
+
createBasicExtensions,
|
|
4693
4933
|
createComment,
|
|
4694
|
-
createDataExtensions,
|
|
4695
4934
|
createMarkdownExtensions,
|
|
4696
4935
|
createThemeExtensions,
|
|
4697
4936
|
cursorLineMargin,
|
|
@@ -4702,6 +4941,7 @@ export {
|
|
|
4702
4941
|
defaultSlots,
|
|
4703
4942
|
defaultTextSlots,
|
|
4704
4943
|
defaultTheme,
|
|
4944
|
+
dnd,
|
|
4705
4945
|
editorFillLayoutEditor,
|
|
4706
4946
|
editorFillLayoutRoot,
|
|
4707
4947
|
editorMode,
|
|
@@ -4712,7 +4952,7 @@ export {
|
|
|
4712
4952
|
getToken,
|
|
4713
4953
|
image,
|
|
4714
4954
|
insertTable,
|
|
4715
|
-
|
|
4955
|
+
keymap9 as keymap,
|
|
4716
4956
|
linkTooltip,
|
|
4717
4957
|
listener,
|
|
4718
4958
|
logChanges,
|
|
@@ -4721,7 +4961,6 @@ export {
|
|
|
4721
4961
|
markdownTagsExtensions,
|
|
4722
4962
|
markdownTheme,
|
|
4723
4963
|
mention,
|
|
4724
|
-
modelState,
|
|
4725
4964
|
outliner,
|
|
4726
4965
|
removeBlockquote,
|
|
4727
4966
|
removeCodeblock,
|