@dxos/react-ui-editor 0.4.7-main.e015b9e → 0.4.7-main.e0789ae
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 +971 -741
- 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.map +1 -1
- package/dist/types/src/{components/TextEditor → extensions/automerge}/automerge.stories.d.ts +4 -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/cursor-line-margin.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts +3 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +4 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/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} +1 -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 +25 -25
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +95 -8
- package/src/components/TextEditor/TextEditor.stories.tsx +0 -15
- package/src/components/TextEditor/TextEditor.tsx +13 -6
- package/src/components/TextEditor/index.ts +0 -3
- package/src/components/Toolbar/Toolbar.stories.tsx +2 -1
- package/src/{components/TextEditor → extensions/automerge}/automerge.stories.tsx +32 -37
- package/src/extensions/awareness.ts +3 -3
- package/src/extensions/command/command.ts +35 -0
- package/src/extensions/command/hint.ts +76 -0
- package/src/extensions/command/index.ts +5 -0
- package/src/extensions/command/state.ts +106 -0
- package/src/extensions/cursor-line-margin.ts +2 -1
- package/src/extensions/dnd.ts +15 -0
- package/src/extensions/index.ts +2 -1
- package/src/extensions/listener.ts +3 -3
- package/src/extensions/markdown/bundle.ts +4 -15
- package/src/extensions/markdown/decorate.ts +76 -32
- package/src/extensions/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 +18 -18
- package/src/index.ts +2 -0
- package/src/styles/index.ts +0 -1
- package/src/themes/default.ts +1 -0
- 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 log5 } 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,231 @@ 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 { nonNullable } from "@dxos/util";
|
|
1112
1270
|
|
|
1113
1271
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1114
1272
|
import { mx } from "@dxos/react-ui-theme";
|
|
@@ -1180,13 +1338,13 @@ var logChanges = (trs) => {
|
|
|
1180
1338
|
};
|
|
1181
1339
|
|
|
1182
1340
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1183
|
-
var documentId =
|
|
1341
|
+
var documentId = Facet4.define({
|
|
1184
1342
|
combine: (values) => values[0]
|
|
1185
1343
|
});
|
|
1186
|
-
var setComments =
|
|
1187
|
-
var setSelection =
|
|
1188
|
-
var setCommentState =
|
|
1189
|
-
var commentsState =
|
|
1344
|
+
var setComments = StateEffect3.define();
|
|
1345
|
+
var setSelection = StateEffect3.define();
|
|
1346
|
+
var setCommentState = StateEffect3.define();
|
|
1347
|
+
var commentsState = StateField4.define({
|
|
1190
1348
|
create: (state) => ({
|
|
1191
1349
|
id: state.facet(documentId),
|
|
1192
1350
|
comments: [],
|
|
@@ -1224,7 +1382,7 @@ var commentsState = StateField3.define({
|
|
|
1224
1382
|
return value;
|
|
1225
1383
|
}
|
|
1226
1384
|
});
|
|
1227
|
-
var styles3 =
|
|
1385
|
+
var styles3 = EditorView7.baseTheme({
|
|
1228
1386
|
"&light .cm-comment, &light .cm-comment-current": {
|
|
1229
1387
|
mixBlendMode: "darken"
|
|
1230
1388
|
},
|
|
@@ -1246,19 +1404,19 @@ var styles3 = EditorView6.baseTheme({
|
|
|
1246
1404
|
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1247
1405
|
}
|
|
1248
1406
|
});
|
|
1249
|
-
var commentMark =
|
|
1407
|
+
var commentMark = Decoration4.mark({
|
|
1250
1408
|
class: "cm-comment",
|
|
1251
1409
|
attributes: {
|
|
1252
1410
|
"data-testid": "cm-comment"
|
|
1253
1411
|
}
|
|
1254
1412
|
});
|
|
1255
|
-
var commentCurrentMark =
|
|
1413
|
+
var commentCurrentMark = Decoration4.mark({
|
|
1256
1414
|
class: "cm-comment-current",
|
|
1257
1415
|
attributes: {
|
|
1258
1416
|
"data-testid": "cm-comment"
|
|
1259
1417
|
}
|
|
1260
1418
|
});
|
|
1261
|
-
var commentsDecorations =
|
|
1419
|
+
var commentsDecorations = EditorView7.decorations.compute([
|
|
1262
1420
|
commentsState
|
|
1263
1421
|
], (state) => {
|
|
1264
1422
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1274,7 +1432,7 @@ var commentsDecorations = EditorView6.decorations.compute([
|
|
|
1274
1432
|
return commentMark.range(range.from, range.to);
|
|
1275
1433
|
}
|
|
1276
1434
|
}).filter(nonNullable);
|
|
1277
|
-
return
|
|
1435
|
+
return Decoration4.set(decorations);
|
|
1278
1436
|
});
|
|
1279
1437
|
var trackPastedComments = (onUpdate) => {
|
|
1280
1438
|
let tracked = null;
|
|
@@ -1296,7 +1454,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1296
1454
|
}
|
|
1297
1455
|
};
|
|
1298
1456
|
return [
|
|
1299
|
-
|
|
1457
|
+
EditorView7.domEventHandlers({
|
|
1300
1458
|
cut: handleTrack,
|
|
1301
1459
|
copy: handleTrack
|
|
1302
1460
|
}),
|
|
@@ -1318,7 +1476,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1318
1476
|
return effects;
|
|
1319
1477
|
}),
|
|
1320
1478
|
// Handle paste or the undo of comment deletion.
|
|
1321
|
-
|
|
1479
|
+
EditorView7.updateListener.of((update2) => {
|
|
1322
1480
|
const restore = [];
|
|
1323
1481
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1324
1482
|
const tr = update2.transactions[i];
|
|
@@ -1374,7 +1532,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
1374
1532
|
from: changes.mapPos(comment.from, 1),
|
|
1375
1533
|
to: changes.mapPos(comment.to, 1)
|
|
1376
1534
|
});
|
|
1377
|
-
var restoreCommentEffect =
|
|
1535
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
1378
1536
|
map: mapTrackedComment
|
|
1379
1537
|
});
|
|
1380
1538
|
var createComment = (view) => {
|
|
@@ -1415,7 +1573,7 @@ var createComment = (view) => {
|
|
|
1415
1573
|
}
|
|
1416
1574
|
return false;
|
|
1417
1575
|
};
|
|
1418
|
-
var optionsFacet =
|
|
1576
|
+
var optionsFacet = Facet4.define({
|
|
1419
1577
|
combine: (providers) => providers[0]
|
|
1420
1578
|
});
|
|
1421
1579
|
var comments = (options = {}) => {
|
|
@@ -1430,7 +1588,7 @@ var comments = (options = {}) => {
|
|
|
1430
1588
|
//
|
|
1431
1589
|
// Keymap.
|
|
1432
1590
|
//
|
|
1433
|
-
options.onCreate ?
|
|
1591
|
+
options.onCreate ? keymap4.of([
|
|
1434
1592
|
{
|
|
1435
1593
|
key: shortcut,
|
|
1436
1594
|
run: callbackWrapper(createComment)
|
|
@@ -1469,7 +1627,7 @@ var comments = (options = {}) => {
|
|
|
1469
1627
|
//
|
|
1470
1628
|
// Track deleted ranges and update ranges for decorations.
|
|
1471
1629
|
//
|
|
1472
|
-
|
|
1630
|
+
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1473
1631
|
let mod = false;
|
|
1474
1632
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1475
1633
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1501,7 +1659,7 @@ var comments = (options = {}) => {
|
|
|
1501
1659
|
//
|
|
1502
1660
|
// Track selection/proximity.
|
|
1503
1661
|
//
|
|
1504
|
-
|
|
1662
|
+
EditorView7.updateListener.of(({ view, state }) => {
|
|
1505
1663
|
let min = Infinity;
|
|
1506
1664
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1507
1665
|
const { head } = state.selection.main;
|
|
@@ -1550,7 +1708,7 @@ var focusComment = (view, id, center = true) => {
|
|
|
1550
1708
|
},
|
|
1551
1709
|
effects: [
|
|
1552
1710
|
//
|
|
1553
|
-
|
|
1711
|
+
EditorView7.scrollIntoView(range.from, center ? {
|
|
1554
1712
|
y: "center"
|
|
1555
1713
|
} : void 0),
|
|
1556
1714
|
setSelection.of({
|
|
@@ -1578,14 +1736,14 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1578
1736
|
};
|
|
1579
1737
|
|
|
1580
1738
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1581
|
-
import { Facet as
|
|
1582
|
-
import { EditorView as
|
|
1583
|
-
var cursorLineMarginFacet =
|
|
1739
|
+
import { Facet as Facet5, Transaction } from "@codemirror/state";
|
|
1740
|
+
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1741
|
+
var cursorLineMarginFacet = Facet5.define({
|
|
1584
1742
|
combine: (input) => input[0] ?? 3
|
|
1585
1743
|
});
|
|
1586
1744
|
var annotation = "cursorLineMargin";
|
|
1587
1745
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1588
|
-
var cursorLineMargin =
|
|
1746
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1589
1747
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1590
1748
|
return;
|
|
1591
1749
|
}
|
|
@@ -1621,38 +1779,48 @@ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, sel
|
|
|
1621
1779
|
}
|
|
1622
1780
|
view.dispatch({
|
|
1623
1781
|
annotations: Transaction.userEvent.of(annotation),
|
|
1624
|
-
effects:
|
|
1782
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1625
1783
|
y: needsScrollTop ? "start" : "end",
|
|
1626
1784
|
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1627
1785
|
})
|
|
1628
1786
|
});
|
|
1629
1787
|
});
|
|
1630
1788
|
|
|
1789
|
+
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1790
|
+
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1791
|
+
var dnd = () => {
|
|
1792
|
+
return EditorView9.domEventHandlers({
|
|
1793
|
+
drop: (event, view) => {
|
|
1794
|
+
console.log(event);
|
|
1795
|
+
}
|
|
1796
|
+
});
|
|
1797
|
+
};
|
|
1798
|
+
|
|
1631
1799
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1632
|
-
import { EditorView as
|
|
1800
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1633
1801
|
var listener = ({ onFocus, onChange }) => {
|
|
1634
1802
|
const extensions = [];
|
|
1635
|
-
onFocus && extensions.push(
|
|
1636
|
-
onFocus(
|
|
1803
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1804
|
+
onFocus(focusing);
|
|
1637
1805
|
return null;
|
|
1638
1806
|
}));
|
|
1639
|
-
onChange && extensions.push(
|
|
1807
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1640
1808
|
onChange(update2.state.doc.toString());
|
|
1641
1809
|
}));
|
|
1642
1810
|
return extensions;
|
|
1643
1811
|
};
|
|
1644
1812
|
|
|
1645
1813
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1646
|
-
import { closeBrackets
|
|
1647
|
-
import { history
|
|
1814
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1815
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1648
1816
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1649
|
-
import { bracketMatching
|
|
1817
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1650
1818
|
import { languages } from "@codemirror/language-data";
|
|
1651
1819
|
import { searchKeymap } from "@codemirror/search";
|
|
1652
1820
|
import { EditorState } from "@codemirror/state";
|
|
1653
|
-
import { oneDarkHighlightStyle
|
|
1654
|
-
import {
|
|
1655
|
-
import { isNotFalsy as
|
|
1821
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1822
|
+
import { EditorView as EditorView11, drawSelection, dropCursor, keymap as keymap5, placeholder } from "@codemirror/view";
|
|
1823
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1656
1824
|
|
|
1657
1825
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1658
1826
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1845,19 +2013,17 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1845
2013
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1846
2014
|
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1847
2015
|
return [
|
|
1848
|
-
|
|
2016
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2017
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
1849
2018
|
EditorState.allowMultipleSelections.of(true),
|
|
1850
2019
|
EditorState.tabSize.of(2),
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
closeBrackets2(),
|
|
1854
|
-
crosshairCursor(),
|
|
2020
|
+
bracketMatching(),
|
|
2021
|
+
closeBrackets(),
|
|
1855
2022
|
dropCursor(),
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
history2(),
|
|
2023
|
+
drawSelection(),
|
|
2024
|
+
history(),
|
|
1859
2025
|
indentOnInput(),
|
|
1860
|
-
_placeholder &&
|
|
2026
|
+
_placeholder && placeholder(_placeholder),
|
|
1861
2027
|
// Main extension.
|
|
1862
2028
|
// https://github.com/codemirror/lang-markdown
|
|
1863
2029
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1877,10 +2043,10 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1877
2043
|
]
|
|
1878
2044
|
}),
|
|
1879
2045
|
// https://github.com/codemirror/theme-one-dark
|
|
1880
|
-
themeMode === "dark" ?
|
|
2046
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
1881
2047
|
// Custom styles.
|
|
1882
|
-
|
|
1883
|
-
|
|
2048
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
2049
|
+
keymap5.of([
|
|
1884
2050
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1885
2051
|
indentWithTab,
|
|
1886
2052
|
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
@@ -1892,22 +2058,22 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1892
2058
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1893
2059
|
...standardKeymap
|
|
1894
2060
|
])
|
|
1895
|
-
].filter(
|
|
2061
|
+
].filter(isNotFalsy2);
|
|
1896
2062
|
};
|
|
1897
2063
|
|
|
1898
2064
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
1899
2065
|
import { syntaxTree } from "@codemirror/language";
|
|
1900
|
-
import { RangeSetBuilder } from "@codemirror/state";
|
|
1901
|
-
import { EditorView as
|
|
2066
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2067
|
+
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1902
2068
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1903
|
-
var HorizontalRuleWidget = class extends
|
|
2069
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
1904
2070
|
toDOM() {
|
|
1905
2071
|
const el = document.createElement("span");
|
|
1906
2072
|
el.className = "cm-hr";
|
|
1907
2073
|
return el;
|
|
1908
2074
|
}
|
|
1909
2075
|
};
|
|
1910
|
-
var LinkButton = class extends
|
|
2076
|
+
var LinkButton = class extends WidgetType3 {
|
|
1911
2077
|
constructor(url, render) {
|
|
1912
2078
|
super();
|
|
1913
2079
|
this.url = url;
|
|
@@ -1922,7 +2088,7 @@ var LinkButton = class extends WidgetType2 {
|
|
|
1922
2088
|
return el;
|
|
1923
2089
|
}
|
|
1924
2090
|
};
|
|
1925
|
-
var CheckboxWidget = class extends
|
|
2091
|
+
var CheckboxWidget = class extends WidgetType3 {
|
|
1926
2092
|
constructor(_checked) {
|
|
1927
2093
|
super();
|
|
1928
2094
|
this._checked = _checked;
|
|
@@ -1959,28 +2125,28 @@ var CheckboxWidget = class extends WidgetType2 {
|
|
|
1959
2125
|
return false;
|
|
1960
2126
|
}
|
|
1961
2127
|
};
|
|
1962
|
-
var hide =
|
|
1963
|
-
var fencedCodeLine =
|
|
2128
|
+
var hide = Decoration5.replace({});
|
|
2129
|
+
var fencedCodeLine = Decoration5.line({
|
|
1964
2130
|
class: mx2("cm-code cm-codeblock-line")
|
|
1965
2131
|
});
|
|
1966
|
-
var fencedCodeLineFirst =
|
|
2132
|
+
var fencedCodeLineFirst = Decoration5.line({
|
|
1967
2133
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
1968
2134
|
});
|
|
1969
|
-
var fencedCodeLineLast =
|
|
2135
|
+
var fencedCodeLineLast = Decoration5.line({
|
|
1970
2136
|
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
1971
2137
|
});
|
|
1972
|
-
var horizontalRule =
|
|
2138
|
+
var horizontalRule = Decoration5.replace({
|
|
1973
2139
|
widget: new HorizontalRuleWidget()
|
|
1974
2140
|
});
|
|
1975
|
-
var checkedTask =
|
|
2141
|
+
var checkedTask = Decoration5.replace({
|
|
1976
2142
|
widget: new CheckboxWidget(true)
|
|
1977
2143
|
});
|
|
1978
|
-
var uncheckedTask =
|
|
2144
|
+
var uncheckedTask = Decoration5.replace({
|
|
1979
2145
|
widget: new CheckboxWidget(false)
|
|
1980
2146
|
});
|
|
1981
|
-
var editingRange = (state, range) => {
|
|
2147
|
+
var editingRange = (state, range, focus) => {
|
|
1982
2148
|
const { readOnly, selection: { main: { head } } } = state;
|
|
1983
|
-
return !readOnly && head >= range.from && head
|
|
2149
|
+
return focus && !readOnly && head >= range.from && head < range.to;
|
|
1984
2150
|
};
|
|
1985
2151
|
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1986
2152
|
"CodeMark",
|
|
@@ -1989,8 +2155,9 @@ var MarksByParent = /* @__PURE__ */ new Set([
|
|
|
1989
2155
|
"SubscriptMark",
|
|
1990
2156
|
"SuperscriptMark"
|
|
1991
2157
|
]);
|
|
1992
|
-
var buildDecorations = (view, options) => {
|
|
1993
|
-
const
|
|
2158
|
+
var buildDecorations = (view, options, focus) => {
|
|
2159
|
+
const deco = new RangeSetBuilder2();
|
|
2160
|
+
const atomicDeco = new RangeSetBuilder2();
|
|
1994
2161
|
const { state } = view;
|
|
1995
2162
|
for (const { from, to } of view.visibleRanges) {
|
|
1996
2163
|
syntaxTree(state).iterate({
|
|
@@ -1998,7 +2165,7 @@ var buildDecorations = (view, options) => {
|
|
|
1998
2165
|
to,
|
|
1999
2166
|
enter: (node) => {
|
|
2000
2167
|
if (node.name === "FencedCode") {
|
|
2001
|
-
const editing = editingRange(state, node);
|
|
2168
|
+
const editing = editingRange(state, node, focus);
|
|
2002
2169
|
for (const block of view.viewportLineBlocks) {
|
|
2003
2170
|
if (block.to < node.from) {
|
|
2004
2171
|
continue;
|
|
@@ -2007,23 +2174,23 @@ var buildDecorations = (view, options) => {
|
|
|
2007
2174
|
break;
|
|
2008
2175
|
}
|
|
2009
2176
|
const first = block.from <= node.from;
|
|
2010
|
-
const last = block.to >= node.to;
|
|
2011
|
-
|
|
2177
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
|
2178
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2012
2179
|
if (!editing && (first || last)) {
|
|
2013
|
-
|
|
2180
|
+
atomicDeco.add(block.from, block.to, hide);
|
|
2014
2181
|
}
|
|
2015
2182
|
}
|
|
2016
2183
|
return false;
|
|
2017
2184
|
} else if (node.name === "Link") {
|
|
2018
2185
|
const marks = node.node.getChildren("LinkMark");
|
|
2019
2186
|
const urlNode = node.node.getChild("URL");
|
|
2020
|
-
const editing = editingRange(state, node);
|
|
2187
|
+
const editing = editingRange(state, node, focus);
|
|
2021
2188
|
if (urlNode && marks.length >= 2) {
|
|
2022
2189
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
2023
2190
|
if (!editing) {
|
|
2024
|
-
|
|
2191
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2025
2192
|
}
|
|
2026
|
-
|
|
2193
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
2027
2194
|
tagName: "a",
|
|
2028
2195
|
attributes: {
|
|
2029
2196
|
class: "cm-link",
|
|
@@ -2033,57 +2200,87 @@ var buildDecorations = (view, options) => {
|
|
|
2033
2200
|
}
|
|
2034
2201
|
}));
|
|
2035
2202
|
if (!editing) {
|
|
2036
|
-
|
|
2203
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
2037
2204
|
widget: new LinkButton(url, options.renderLinkButton)
|
|
2038
2205
|
}) : hide);
|
|
2039
2206
|
}
|
|
2040
2207
|
}
|
|
2041
2208
|
} else if (node.name === "HeaderMark") {
|
|
2042
2209
|
const parent = node.node.parent;
|
|
2043
|
-
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
|
|
2210
|
+
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from), focus)) {
|
|
2044
2211
|
const next = state.doc.sliceString(node.to, node.to + 1);
|
|
2045
|
-
|
|
2212
|
+
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2046
2213
|
}
|
|
2047
2214
|
} else if (node.name === "HorizontalRule") {
|
|
2048
|
-
if (!editingRange(state, node)) {
|
|
2049
|
-
|
|
2215
|
+
if (!editingRange(state, node, focus)) {
|
|
2216
|
+
deco.add(node.from, node.to, horizontalRule);
|
|
2050
2217
|
}
|
|
2051
2218
|
} else if (node.name === "TaskMarker") {
|
|
2052
|
-
if (!editingRange(state, node)) {
|
|
2219
|
+
if (!editingRange(state, node, focus)) {
|
|
2053
2220
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2054
|
-
|
|
2221
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2055
2222
|
class: "cm-task"
|
|
2056
2223
|
}));
|
|
2057
|
-
|
|
2224
|
+
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2058
2225
|
}
|
|
2059
2226
|
} else if (MarksByParent.has(node.name)) {
|
|
2060
|
-
if (!editingRange(state, node.node.parent)) {
|
|
2061
|
-
|
|
2227
|
+
if (!editingRange(state, node.node.parent, focus)) {
|
|
2228
|
+
atomicDeco.add(node.from, node.to, hide);
|
|
2062
2229
|
}
|
|
2063
2230
|
}
|
|
2064
2231
|
}
|
|
2065
2232
|
});
|
|
2066
2233
|
}
|
|
2067
|
-
return
|
|
2234
|
+
return {
|
|
2235
|
+
deco: deco.finish(),
|
|
2236
|
+
atomicDeco: atomicDeco.finish()
|
|
2237
|
+
};
|
|
2068
2238
|
};
|
|
2239
|
+
var forceUpdate = StateEffect4.define();
|
|
2069
2240
|
var decorateMarkdown = (options = {}) => {
|
|
2070
2241
|
return [
|
|
2071
|
-
|
|
2242
|
+
ViewPlugin4.fromClass(class {
|
|
2072
2243
|
constructor(view) {
|
|
2073
|
-
this.
|
|
2244
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2074
2245
|
}
|
|
2075
2246
|
update(update2) {
|
|
2076
|
-
if (update2.docChanged || update2.
|
|
2077
|
-
this.
|
|
2247
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
2248
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2249
|
+
this.clearUpdate();
|
|
2250
|
+
} else if (update2.selectionSet) {
|
|
2251
|
+
this.scheduleUpdate(update2.view);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
2255
|
+
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
2256
|
+
scheduleUpdate(view) {
|
|
2257
|
+
this.clearUpdate();
|
|
2258
|
+
this.pendingUpdate = setTimeout(() => {
|
|
2259
|
+
view.dispatch({
|
|
2260
|
+
effects: forceUpdate.of(null)
|
|
2261
|
+
});
|
|
2262
|
+
}, options.selectionChangeDelay);
|
|
2263
|
+
}
|
|
2264
|
+
clearUpdate() {
|
|
2265
|
+
if (this.pendingUpdate) {
|
|
2266
|
+
clearTimeout(this.pendingUpdate);
|
|
2267
|
+
this.pendingUpdate = void 0;
|
|
2078
2268
|
}
|
|
2079
2269
|
}
|
|
2270
|
+
destroy() {
|
|
2271
|
+
this.clearUpdate();
|
|
2272
|
+
}
|
|
2080
2273
|
}, {
|
|
2081
|
-
|
|
2274
|
+
provide: (plugin) => [
|
|
2275
|
+
EditorView12.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2276
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2277
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
2278
|
+
]
|
|
2082
2279
|
}),
|
|
2083
2280
|
formattingStyles
|
|
2084
2281
|
];
|
|
2085
2282
|
};
|
|
2086
|
-
var formattingStyles =
|
|
2283
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
2087
2284
|
"& .cm-code": {
|
|
2088
2285
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2089
2286
|
},
|
|
@@ -2136,7 +2333,7 @@ var formattingStyles = EditorView10.baseTheme({
|
|
|
2136
2333
|
import { snippet } from "@codemirror/autocomplete";
|
|
2137
2334
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2138
2335
|
import { EditorSelection } from "@codemirror/state";
|
|
2139
|
-
import { EditorView as
|
|
2336
|
+
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2140
2337
|
import { useState, useMemo } from "react";
|
|
2141
2338
|
var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
2142
2339
|
var Inline;
|
|
@@ -3008,7 +3205,7 @@ var toggleCodeblock = (target) => {
|
|
|
3008
3205
|
};
|
|
3009
3206
|
var formatting = (options = {}) => {
|
|
3010
3207
|
return [
|
|
3011
|
-
|
|
3208
|
+
keymap6.of([
|
|
3012
3209
|
{
|
|
3013
3210
|
key: "meta-b",
|
|
3014
3211
|
run: toggleStrong
|
|
@@ -3206,7 +3403,7 @@ var getFormatting = (state) => {
|
|
|
3206
3403
|
};
|
|
3207
3404
|
var useFormattingState = () => {
|
|
3208
3405
|
const [state, setState] = useState(null);
|
|
3209
|
-
const observer = useMemo(() =>
|
|
3406
|
+
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3210
3407
|
if (update2.docChanged || update2.selectionSet) {
|
|
3211
3408
|
const newState = getFormatting(update2.state);
|
|
3212
3409
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3222,12 +3419,12 @@ var useFormattingState = () => {
|
|
|
3222
3419
|
|
|
3223
3420
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3224
3421
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3225
|
-
import { StateField as
|
|
3226
|
-
import { Decoration as
|
|
3422
|
+
import { StateField as StateField5 } from "@codemirror/state";
|
|
3423
|
+
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3227
3424
|
var image = (options = {}) => {
|
|
3228
|
-
return
|
|
3425
|
+
return StateField5.define({
|
|
3229
3426
|
create: (state) => {
|
|
3230
|
-
return
|
|
3427
|
+
return Decoration6.set(buildDecorations2(0, state.doc.length, state));
|
|
3231
3428
|
},
|
|
3232
3429
|
update: (value, tr) => {
|
|
3233
3430
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3250,7 +3447,7 @@ var image = (options = {}) => {
|
|
|
3250
3447
|
add: buildDecorations2(from, to, tr.state)
|
|
3251
3448
|
});
|
|
3252
3449
|
},
|
|
3253
|
-
provide: (field) =>
|
|
3450
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3254
3451
|
});
|
|
3255
3452
|
};
|
|
3256
3453
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3272,7 +3469,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3272
3469
|
const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3273
3470
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3274
3471
|
preloadImage(url);
|
|
3275
|
-
decorations.push(
|
|
3472
|
+
decorations.push(Decoration6.replace({
|
|
3276
3473
|
block: true,
|
|
3277
3474
|
widget: new ImageWidget(url)
|
|
3278
3475
|
}).range(hide2 ? node.from : node.to, node.to));
|
|
@@ -3284,7 +3481,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3284
3481
|
});
|
|
3285
3482
|
return decorations;
|
|
3286
3483
|
};
|
|
3287
|
-
var ImageWidget = class extends
|
|
3484
|
+
var ImageWidget = class extends WidgetType4 {
|
|
3288
3485
|
constructor(_url) {
|
|
3289
3486
|
super();
|
|
3290
3487
|
this._url = _url;
|
|
@@ -3337,17 +3534,17 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3337
3534
|
|
|
3338
3535
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3339
3536
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3340
|
-
import { RangeSetBuilder as
|
|
3341
|
-
import { Decoration as
|
|
3537
|
+
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
|
|
3538
|
+
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3342
3539
|
var table = (options = {}) => {
|
|
3343
|
-
return
|
|
3540
|
+
return StateField6.define({
|
|
3344
3541
|
create: (state) => update(state, options),
|
|
3345
3542
|
update: (_, tr) => update(tr.state, options),
|
|
3346
|
-
provide: (field) =>
|
|
3543
|
+
provide: (field) => EditorView15.decorations.from(field)
|
|
3347
3544
|
});
|
|
3348
3545
|
};
|
|
3349
3546
|
var update = (state, options) => {
|
|
3350
|
-
const builder = new
|
|
3547
|
+
const builder = new RangeSetBuilder3();
|
|
3351
3548
|
const cursor = state.selection.main.head;
|
|
3352
3549
|
const tables = [];
|
|
3353
3550
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3387,16 +3584,16 @@ var update = (state, options) => {
|
|
|
3387
3584
|
});
|
|
3388
3585
|
tables.forEach((table2) => {
|
|
3389
3586
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3390
|
-
hide2 && builder.add(table2.from, table2.to,
|
|
3587
|
+
hide2 && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3391
3588
|
widget: new TableWidget(table2)
|
|
3392
3589
|
}));
|
|
3393
|
-
builder.add(table2.from, table2.to,
|
|
3590
|
+
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
3394
3591
|
class: "cm-table"
|
|
3395
3592
|
}));
|
|
3396
3593
|
});
|
|
3397
3594
|
return builder.finish();
|
|
3398
3595
|
};
|
|
3399
|
-
var TableWidget = class extends
|
|
3596
|
+
var TableWidget = class extends WidgetType5 {
|
|
3400
3597
|
constructor(_table) {
|
|
3401
3598
|
super();
|
|
3402
3599
|
this._table = _table;
|
|
@@ -3463,10 +3660,10 @@ var mention = ({ onSearch }) => {
|
|
|
3463
3660
|
};
|
|
3464
3661
|
|
|
3465
3662
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
3466
|
-
import { Facet as
|
|
3467
|
-
import { keymap as
|
|
3663
|
+
import { Facet as Facet6 } from "@codemirror/state";
|
|
3664
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
3468
3665
|
import { vim } from "@replit/codemirror-vim";
|
|
3469
|
-
var editorMode =
|
|
3666
|
+
var editorMode = Facet6.define({
|
|
3470
3667
|
combine: (modes) => modes[0] ?? {}
|
|
3471
3668
|
});
|
|
3472
3669
|
var EditorModes = {
|
|
@@ -3477,7 +3674,7 @@ var EditorModes = {
|
|
|
3477
3674
|
type: "vim",
|
|
3478
3675
|
noTabster: true
|
|
3479
3676
|
}),
|
|
3480
|
-
|
|
3677
|
+
keymap7.of([
|
|
3481
3678
|
{
|
|
3482
3679
|
key: "Alt-Escape",
|
|
3483
3680
|
run: (view) => {
|
|
@@ -3497,7 +3694,7 @@ var outliner = (options = {}) => {
|
|
|
3497
3694
|
};
|
|
3498
3695
|
|
|
3499
3696
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
3500
|
-
import { keymap as
|
|
3697
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
3501
3698
|
var defaultItems = [
|
|
3502
3699
|
"hello world!",
|
|
3503
3700
|
"this is a test.",
|
|
@@ -3507,7 +3704,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3507
3704
|
let t;
|
|
3508
3705
|
let idx = 0;
|
|
3509
3706
|
return [
|
|
3510
|
-
|
|
3707
|
+
keymap8.of([
|
|
3511
3708
|
{
|
|
3512
3709
|
// Reset.
|
|
3513
3710
|
key: "alt-meta-'",
|
|
@@ -3553,164 +3750,348 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3553
3750
|
];
|
|
3554
3751
|
};
|
|
3555
3752
|
|
|
3556
|
-
// packages/ui/react-ui-editor/src/
|
|
3557
|
-
import
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3753
|
+
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
3754
|
+
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
3755
|
+
import { Context as Context2 } from "@dxos/context";
|
|
3756
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
3757
|
+
import { log as log3 } from "@dxos/log";
|
|
3758
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
3759
|
+
var DEBOUNCE_INTERVAL = 100;
|
|
3760
|
+
var SpaceAwarenessProvider = class {
|
|
3761
|
+
constructor(params) {
|
|
3762
|
+
this._remoteStates = /* @__PURE__ */ new Map();
|
|
3763
|
+
this.remoteStateChange = new Event2();
|
|
3764
|
+
this._space = params.space;
|
|
3765
|
+
this._channel = params.channel;
|
|
3766
|
+
this._peerId = params.peerId;
|
|
3767
|
+
this._info = params.info;
|
|
3768
|
+
}
|
|
3769
|
+
open() {
|
|
3770
|
+
this._ctx = new Context2();
|
|
3771
|
+
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
3772
|
+
if (this._localState) {
|
|
3773
|
+
await this._space.postMessage(this._channel, {
|
|
3774
|
+
kind: "post",
|
|
3775
|
+
state: this._localState
|
|
3776
|
+
});
|
|
3777
|
+
await sleep(DEBOUNCE_INTERVAL);
|
|
3778
|
+
}
|
|
3779
|
+
});
|
|
3780
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
3781
|
+
switch (message.payload.kind) {
|
|
3782
|
+
case "query": {
|
|
3783
|
+
this._handleQueryMessage();
|
|
3784
|
+
break;
|
|
3785
|
+
}
|
|
3786
|
+
case "post": {
|
|
3787
|
+
this._handlePostMessage(message.payload);
|
|
3788
|
+
break;
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
}));
|
|
3792
|
+
void this._space.postMessage(this._channel, {
|
|
3793
|
+
kind: "query"
|
|
3794
|
+
}).catch((err) => {
|
|
3795
|
+
log3.debug("failed to query awareness", {
|
|
3796
|
+
err
|
|
3797
|
+
}, {
|
|
3798
|
+
F: __dxlog_file4,
|
|
3799
|
+
L: 89,
|
|
3800
|
+
S: this,
|
|
3801
|
+
C: (f, a) => f(...a)
|
|
3802
|
+
});
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3805
|
+
close() {
|
|
3806
|
+
void this._ctx?.dispose();
|
|
3807
|
+
this._ctx = void 0;
|
|
3808
|
+
this._postTask = void 0;
|
|
3809
|
+
}
|
|
3810
|
+
getRemoteStates() {
|
|
3811
|
+
return Array.from(this._remoteStates.values());
|
|
3812
|
+
}
|
|
3813
|
+
update(position) {
|
|
3814
|
+
invariant2(this._postTask, void 0, {
|
|
3815
|
+
F: __dxlog_file4,
|
|
3816
|
+
L: 104,
|
|
3817
|
+
S: this,
|
|
3818
|
+
A: [
|
|
3819
|
+
"this._postTask",
|
|
3820
|
+
""
|
|
3821
|
+
]
|
|
3822
|
+
});
|
|
3823
|
+
this._localState = {
|
|
3824
|
+
peerId: this._peerId,
|
|
3825
|
+
position,
|
|
3826
|
+
info: this._info
|
|
3827
|
+
};
|
|
3828
|
+
this._postTask.schedule();
|
|
3829
|
+
}
|
|
3830
|
+
_handleQueryMessage() {
|
|
3831
|
+
invariant2(this._postTask, void 0, {
|
|
3832
|
+
F: __dxlog_file4,
|
|
3833
|
+
L: 115,
|
|
3834
|
+
S: this,
|
|
3835
|
+
A: [
|
|
3836
|
+
"this._postTask",
|
|
3837
|
+
""
|
|
3838
|
+
]
|
|
3839
|
+
});
|
|
3840
|
+
this._postTask.schedule();
|
|
3841
|
+
}
|
|
3842
|
+
_handlePostMessage(message) {
|
|
3843
|
+
invariant2(message.kind === "post", void 0, {
|
|
3844
|
+
F: __dxlog_file4,
|
|
3845
|
+
L: 120,
|
|
3846
|
+
S: this,
|
|
3847
|
+
A: [
|
|
3848
|
+
"message.kind === 'post'",
|
|
3849
|
+
""
|
|
3850
|
+
]
|
|
3851
|
+
});
|
|
3852
|
+
this._remoteStates.set(message.state.peerId, message.state);
|
|
3853
|
+
this.remoteStateChange.emit();
|
|
3854
|
+
}
|
|
3855
|
+
};
|
|
3856
|
+
|
|
3857
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3858
|
+
var useActionHandler = (view) => {
|
|
3859
|
+
return (action) => {
|
|
3860
|
+
if (!view) {
|
|
3861
|
+
return;
|
|
3862
|
+
}
|
|
3863
|
+
let inlineType, listType;
|
|
3864
|
+
switch (action.type) {
|
|
3865
|
+
case "heading":
|
|
3866
|
+
setHeading(parseInt(action.data))(view);
|
|
3867
|
+
break;
|
|
3868
|
+
case "strong":
|
|
3869
|
+
case "emphasis":
|
|
3870
|
+
case "strikethrough":
|
|
3871
|
+
case "code":
|
|
3872
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
3873
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3874
|
+
break;
|
|
3875
|
+
case "list-ordered":
|
|
3876
|
+
case "list-bullet":
|
|
3877
|
+
case "list-task":
|
|
3878
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
3879
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3880
|
+
break;
|
|
3881
|
+
case "blockquote":
|
|
3882
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3883
|
+
break;
|
|
3884
|
+
case "codeblock":
|
|
3885
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3886
|
+
break;
|
|
3887
|
+
case "table":
|
|
3888
|
+
insertTable(view);
|
|
3889
|
+
break;
|
|
3890
|
+
case "link":
|
|
3891
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
3892
|
+
break;
|
|
3893
|
+
case "comment":
|
|
3894
|
+
createComment(view);
|
|
3895
|
+
break;
|
|
3896
|
+
}
|
|
3897
|
+
setTimeout(() => {
|
|
3898
|
+
if (!view.hasFocus) {
|
|
3899
|
+
view.focus();
|
|
3900
|
+
}
|
|
3901
|
+
});
|
|
3902
|
+
};
|
|
3903
|
+
};
|
|
3904
|
+
|
|
3905
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3906
|
+
import { useRef, useState as useState2 } from "react";
|
|
3907
|
+
var useEditorView = (id) => {
|
|
3908
|
+
const editorRef = useRef(null);
|
|
3909
|
+
const [prev, setPrev] = useState2([
|
|
3910
|
+
null,
|
|
3911
|
+
""
|
|
3912
|
+
]);
|
|
3913
|
+
if (prev[0] !== editorRef.current) {
|
|
3914
|
+
setPrev([
|
|
3915
|
+
editorRef.current,
|
|
3916
|
+
id
|
|
3917
|
+
]);
|
|
3918
|
+
}
|
|
3919
|
+
return [
|
|
3920
|
+
editorRef,
|
|
3921
|
+
prev[1] !== id
|
|
3922
|
+
];
|
|
3923
|
+
};
|
|
3924
|
+
|
|
3925
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3926
|
+
import { closeBrackets as closeBrackets2 } from "@codemirror/autocomplete";
|
|
3927
|
+
import { history as history2 } from "@codemirror/commands";
|
|
3928
|
+
import { bracketMatching as bracketMatching2 } from "@codemirror/language";
|
|
3929
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState2 } from "@codemirror/state";
|
|
3930
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor as dropCursor2, EditorView as EditorView16, highlightActiveLine, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
|
|
3931
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
3932
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
3933
|
+
import { log as log4 } from "@dxos/log";
|
|
3934
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
3935
|
+
|
|
3936
|
+
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
3937
|
+
import get4 from "lodash.get";
|
|
3938
|
+
var defaultTheme = {
|
|
3675
3939
|
//
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
},
|
|
3679
|
-
".cm-tooltip-below": {},
|
|
3940
|
+
// Main layout:
|
|
3941
|
+
// https://codemirror.net/examples/styling
|
|
3680
3942
|
//
|
|
3681
|
-
//
|
|
3943
|
+
// <div class="cm-editor [cm-focused] [generated classes]">
|
|
3944
|
+
// <div class="cm-scroller">
|
|
3945
|
+
// <div class="cm-gutters">
|
|
3946
|
+
// <div class="cm-gutter [...]">
|
|
3947
|
+
// <div class="cm-gutterElement">...</div>
|
|
3948
|
+
// </div>
|
|
3949
|
+
// </div>
|
|
3950
|
+
// <div class="cm-content" role="textbox" contenteditable="true">
|
|
3951
|
+
// <div class="cm-line"></div>
|
|
3952
|
+
// </div>
|
|
3953
|
+
// <div class="cm-selectionLayer">
|
|
3954
|
+
// <div class="cm-selectionBackground"></div>
|
|
3955
|
+
// </div>
|
|
3956
|
+
// <div class="cm-cursorLayer">
|
|
3957
|
+
// <div class="cm-cursor"></div>
|
|
3958
|
+
// </div>
|
|
3959
|
+
// </div>
|
|
3960
|
+
// </div>
|
|
3682
3961
|
//
|
|
3683
|
-
"
|
|
3684
|
-
|
|
3685
|
-
|
|
3962
|
+
"&": {},
|
|
3963
|
+
"&.cm-focused": {
|
|
3964
|
+
outline: "none"
|
|
3686
3965
|
},
|
|
3687
|
-
|
|
3688
|
-
".cm-
|
|
3689
|
-
|
|
3690
|
-
|
|
3966
|
+
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
3967
|
+
".cm-scroller": {
|
|
3968
|
+
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
3969
|
+
// 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.
|
|
3970
|
+
overflowY: "auto",
|
|
3971
|
+
fontFamily: get4(tokens, "fontFamily.mono", []).join(","),
|
|
3972
|
+
lineHeight: 1.5
|
|
3691
3973
|
},
|
|
3692
|
-
".cm-
|
|
3693
|
-
|
|
3974
|
+
".cm-content": {
|
|
3975
|
+
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
3976
|
+
// padding: 'unset',
|
|
3977
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
3978
|
+
fontSize: "16px"
|
|
3694
3979
|
},
|
|
3695
|
-
".cm-
|
|
3696
|
-
|
|
3980
|
+
"&light .cm-content": {
|
|
3981
|
+
color: get4(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
3982
|
+
caretColor: "black"
|
|
3983
|
+
},
|
|
3984
|
+
"&dark .cm-content": {
|
|
3985
|
+
color: get4(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
3986
|
+
caretColor: "white"
|
|
3697
3987
|
},
|
|
3698
3988
|
//
|
|
3699
|
-
//
|
|
3989
|
+
// Cursor
|
|
3700
3990
|
//
|
|
3701
|
-
".cm-
|
|
3702
|
-
|
|
3703
|
-
textDecoration: "none !important"
|
|
3991
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
3992
|
+
borderLeft: "2px solid black"
|
|
3704
3993
|
},
|
|
3705
|
-
".cm-
|
|
3706
|
-
|
|
3707
|
-
borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.500")}`,
|
|
3708
|
-
fontWeight: 100,
|
|
3709
|
-
textAlign: "left",
|
|
3710
|
-
color: get4(tokens, "extend.colors.neutral.500")
|
|
3994
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
3995
|
+
borderLeft: "2px solid white"
|
|
3711
3996
|
},
|
|
3712
|
-
".cm-
|
|
3713
|
-
|
|
3997
|
+
"&light .cm-placeholder": {
|
|
3998
|
+
color: get4(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
3999
|
+
},
|
|
4000
|
+
"&dark .cm-placeholder": {
|
|
4001
|
+
color: get4(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
4002
|
+
},
|
|
4003
|
+
//
|
|
4004
|
+
// line
|
|
4005
|
+
//
|
|
4006
|
+
".cm-line": {
|
|
4007
|
+
paddingInline: 0
|
|
4008
|
+
},
|
|
4009
|
+
".cm-activeLine": {
|
|
4010
|
+
background: "transparent"
|
|
4011
|
+
},
|
|
4012
|
+
//
|
|
4013
|
+
// gutter
|
|
4014
|
+
//
|
|
4015
|
+
".cm-gutterElement": {
|
|
4016
|
+
width: "48px"
|
|
4017
|
+
},
|
|
4018
|
+
//
|
|
4019
|
+
// Selection
|
|
4020
|
+
//
|
|
4021
|
+
"&light .cm-selectionBackground": {
|
|
4022
|
+
background: get4(tokens, "extend.colors.primary.100")
|
|
4023
|
+
},
|
|
4024
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4025
|
+
background: get4(tokens, "extend.colors.primary.200")
|
|
4026
|
+
},
|
|
4027
|
+
"&dark .cm-selectionBackground": {
|
|
4028
|
+
background: get4(tokens, "extend.colors.primary.700")
|
|
4029
|
+
},
|
|
4030
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4031
|
+
background: get4(tokens, "extend.colors.primary.600")
|
|
4032
|
+
},
|
|
4033
|
+
//
|
|
4034
|
+
// Search
|
|
4035
|
+
//
|
|
4036
|
+
"&light .cm-searchMatch": {
|
|
4037
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.100")
|
|
4038
|
+
},
|
|
4039
|
+
"&dark .cm-searchMatch": {
|
|
4040
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.700")
|
|
4041
|
+
},
|
|
4042
|
+
//
|
|
4043
|
+
// link
|
|
4044
|
+
//
|
|
4045
|
+
".cm-link": {
|
|
4046
|
+
color: get4(tokens, "extend.colors.primary.500"),
|
|
4047
|
+
textDecorationLine: "underline",
|
|
4048
|
+
textDecorationThickness: "1px",
|
|
4049
|
+
textUnderlineOffset: "2px",
|
|
4050
|
+
borderRadius: ".125rem",
|
|
4051
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4052
|
+
},
|
|
4053
|
+
//
|
|
4054
|
+
// tooltip
|
|
4055
|
+
//
|
|
4056
|
+
".cm-tooltip": {
|
|
4057
|
+
border: "none",
|
|
4058
|
+
background: "unset"
|
|
4059
|
+
},
|
|
4060
|
+
".cm-tooltip-below": {},
|
|
4061
|
+
//
|
|
4062
|
+
// autocomplete
|
|
4063
|
+
//
|
|
4064
|
+
".cm-tooltip-autocomplete": {
|
|
4065
|
+
marginTop: "4px",
|
|
4066
|
+
marginLeft: "-3px"
|
|
4067
|
+
},
|
|
4068
|
+
".cm-tooltip-autocomplete ul li": {},
|
|
4069
|
+
".cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
4070
|
+
".cm-completionIcon": {
|
|
4071
|
+
display: "none"
|
|
4072
|
+
},
|
|
4073
|
+
".cm-completionLabel": {
|
|
4074
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4075
|
+
},
|
|
4076
|
+
".cm-completionMatchedText": {
|
|
4077
|
+
textDecoration: "none"
|
|
4078
|
+
},
|
|
4079
|
+
//
|
|
4080
|
+
// table
|
|
4081
|
+
//
|
|
4082
|
+
".cm-table *": {
|
|
4083
|
+
fontFamily: `${get4(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
4084
|
+
textDecoration: "none !important"
|
|
4085
|
+
},
|
|
4086
|
+
".cm-table-head": {
|
|
4087
|
+
padding: "2px 16px 2px 0px",
|
|
4088
|
+
borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.500")}`,
|
|
4089
|
+
fontWeight: 100,
|
|
4090
|
+
textAlign: "left",
|
|
4091
|
+
color: get4(tokens, "extend.colors.neutral.500")
|
|
4092
|
+
},
|
|
4093
|
+
".cm-table-cell": {
|
|
4094
|
+
padding: "2px 16px 2px 0px"
|
|
3714
4095
|
},
|
|
3715
4096
|
//
|
|
3716
4097
|
// image
|
|
@@ -3803,19 +4184,238 @@ var codeTheme = {
|
|
|
3803
4184
|
}
|
|
3804
4185
|
};
|
|
3805
4186
|
|
|
4187
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4188
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4189
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps = []) => {
|
|
4190
|
+
const onUpdate = useRef2();
|
|
4191
|
+
const [view, setView] = useState3();
|
|
4192
|
+
const parentRef = useRef2(null);
|
|
4193
|
+
useEffect2(() => {
|
|
4194
|
+
let view2;
|
|
4195
|
+
if (parentRef.current) {
|
|
4196
|
+
const state = EditorState2.create({
|
|
4197
|
+
doc,
|
|
4198
|
+
selection,
|
|
4199
|
+
extensions: [
|
|
4200
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4201
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4202
|
+
log4.catch(err, void 0, {
|
|
4203
|
+
F: __dxlog_file5,
|
|
4204
|
+
L: 70,
|
|
4205
|
+
S: void 0,
|
|
4206
|
+
C: (f, a) => f(...a)
|
|
4207
|
+
});
|
|
4208
|
+
}),
|
|
4209
|
+
extensions,
|
|
4210
|
+
EditorView16.updateListener.of(() => {
|
|
4211
|
+
onUpdate.current?.();
|
|
4212
|
+
})
|
|
4213
|
+
].filter(isNotFalsy3)
|
|
4214
|
+
});
|
|
4215
|
+
view2 = new EditorView16({
|
|
4216
|
+
parent: parentRef.current,
|
|
4217
|
+
scrollTo,
|
|
4218
|
+
state,
|
|
4219
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4220
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4221
|
+
dispatchTransactions: (trs, view3) => {
|
|
4222
|
+
if (debug) {
|
|
4223
|
+
logChanges(trs);
|
|
4224
|
+
}
|
|
4225
|
+
view3.update(trs);
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
setView(view2);
|
|
4229
|
+
}
|
|
4230
|
+
return () => {
|
|
4231
|
+
view2?.destroy();
|
|
4232
|
+
};
|
|
4233
|
+
}, deps);
|
|
4234
|
+
useEffect2(() => {
|
|
4235
|
+
if (view) {
|
|
4236
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4237
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4238
|
+
}
|
|
4239
|
+
if (selection || scrollTo) {
|
|
4240
|
+
onUpdate.current = () => {
|
|
4241
|
+
onUpdate.current = void 0;
|
|
4242
|
+
view.dispatch({
|
|
4243
|
+
selection,
|
|
4244
|
+
effects: scrollTo && [
|
|
4245
|
+
scrollTo
|
|
4246
|
+
],
|
|
4247
|
+
scrollIntoView: !scrollTo
|
|
4248
|
+
});
|
|
4249
|
+
};
|
|
4250
|
+
}
|
|
4251
|
+
if (autoFocus) {
|
|
4252
|
+
view.focus();
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
}, [
|
|
4256
|
+
view,
|
|
4257
|
+
autoFocus,
|
|
4258
|
+
selection,
|
|
4259
|
+
scrollTo
|
|
4260
|
+
]);
|
|
4261
|
+
return {
|
|
4262
|
+
parentRef,
|
|
4263
|
+
view
|
|
4264
|
+
};
|
|
4265
|
+
};
|
|
4266
|
+
var defaults = {
|
|
4267
|
+
bracketMatching: true,
|
|
4268
|
+
closeBrackets: true,
|
|
4269
|
+
drawSelection: true,
|
|
4270
|
+
editable: true,
|
|
4271
|
+
history: true,
|
|
4272
|
+
lineWrapping: true
|
|
4273
|
+
};
|
|
4274
|
+
var createBasicExtensions = (_props) => {
|
|
4275
|
+
const props = defaultsDeep2({}, _props, defaults);
|
|
4276
|
+
return [
|
|
4277
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4278
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4279
|
+
log4.catch(err, void 0, {
|
|
4280
|
+
F: __dxlog_file5,
|
|
4281
|
+
L: 167,
|
|
4282
|
+
S: void 0,
|
|
4283
|
+
C: (f, a) => f(...a)
|
|
4284
|
+
});
|
|
4285
|
+
}),
|
|
4286
|
+
props.allowMultipleSelections && EditorState2.allowMultipleSelections.of(true),
|
|
4287
|
+
props.bracketMatching && bracketMatching2(),
|
|
4288
|
+
props.closeBrackets && closeBrackets2(),
|
|
4289
|
+
props.crosshairCursor && crosshairCursor(),
|
|
4290
|
+
props.dropCursor && dropCursor2(),
|
|
4291
|
+
props.drawSelection && drawSelection2(),
|
|
4292
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
4293
|
+
props.history && history2(),
|
|
4294
|
+
props.lineNumbers && lineNumbers(),
|
|
4295
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
4296
|
+
props.placeholder && placeholder2(props.placeholder),
|
|
4297
|
+
props.readonly && [
|
|
4298
|
+
EditorState2.readOnly.of(true),
|
|
4299
|
+
EditorView16.editable.of(false)
|
|
4300
|
+
],
|
|
4301
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
4302
|
+
props.tabSize && EditorState2.tabSize.of(props.tabSize)
|
|
4303
|
+
].filter(isNotFalsy3);
|
|
4304
|
+
};
|
|
4305
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4306
|
+
return [
|
|
4307
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4308
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4309
|
+
theme && EditorView16.theme(theme),
|
|
4310
|
+
slots?.editor?.className && EditorView16.editorAttributes.of({
|
|
4311
|
+
class: slots.editor.className
|
|
4312
|
+
}),
|
|
4313
|
+
slots?.content?.className && EditorView16.contentAttributes.of({
|
|
4314
|
+
class: slots.content.className
|
|
4315
|
+
})
|
|
4316
|
+
].filter(isNotFalsy3);
|
|
4317
|
+
};
|
|
4318
|
+
|
|
4319
|
+
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4320
|
+
import get5 from "lodash.get";
|
|
4321
|
+
import { useState as useState4, useMemo as useMemo2 } from "react";
|
|
4322
|
+
import { generateName } from "@dxos/display-name";
|
|
4323
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
4324
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4325
|
+
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4326
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4327
|
+
import { hexToHue } from "@dxos/util";
|
|
4328
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4329
|
+
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4330
|
+
const extensions = [
|
|
4331
|
+
automerge(text)
|
|
4332
|
+
];
|
|
4333
|
+
const peerId = identity?.identityKey.toHex();
|
|
4334
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4335
|
+
if (space && identity) {
|
|
4336
|
+
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4337
|
+
space,
|
|
4338
|
+
channel: `awareness.${id}`,
|
|
4339
|
+
peerId: identity.identityKey.toHex(),
|
|
4340
|
+
info: {
|
|
4341
|
+
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4342
|
+
color: cursorDarkValue,
|
|
4343
|
+
lightColor: cursorLightValue
|
|
4344
|
+
}
|
|
4345
|
+
});
|
|
4346
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4347
|
+
}
|
|
4348
|
+
return extensions;
|
|
4349
|
+
};
|
|
4350
|
+
var useTextModel = (props) => useMemo2(() => createModel(props), Object.values(props));
|
|
4351
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4352
|
+
const [content, setContent] = useState4(defaultContent ?? "");
|
|
4353
|
+
return {
|
|
4354
|
+
id,
|
|
4355
|
+
content,
|
|
4356
|
+
text: () => content,
|
|
4357
|
+
setContent
|
|
4358
|
+
};
|
|
4359
|
+
};
|
|
4360
|
+
var createModel = ({ space, identity, text }) => {
|
|
4361
|
+
if (!text) {
|
|
4362
|
+
return void 0;
|
|
4363
|
+
}
|
|
4364
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
4365
|
+
F: __dxlog_file6,
|
|
4366
|
+
L: 88,
|
|
4367
|
+
S: void 0,
|
|
4368
|
+
A: [
|
|
4369
|
+
"isAutomergeObject(text)",
|
|
4370
|
+
""
|
|
4371
|
+
]
|
|
4372
|
+
});
|
|
4373
|
+
const obj = text;
|
|
4374
|
+
const doc = getRawDoc(obj, [
|
|
4375
|
+
obj.field
|
|
4376
|
+
]);
|
|
4377
|
+
const peerId = identity?.identityKey.toHex();
|
|
4378
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4379
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4380
|
+
space,
|
|
4381
|
+
channel: `automerge.awareness.${obj.id}`,
|
|
4382
|
+
info: {
|
|
4383
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4384
|
+
color: cursorLightValue,
|
|
4385
|
+
lightColor: cursorDarkValue
|
|
4386
|
+
},
|
|
4387
|
+
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4388
|
+
});
|
|
4389
|
+
const extensions = [
|
|
4390
|
+
automerge({
|
|
4391
|
+
handle: doc.handle,
|
|
4392
|
+
path: doc.path
|
|
4393
|
+
})
|
|
4394
|
+
];
|
|
4395
|
+
if (awarenessProvider2) {
|
|
4396
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4397
|
+
}
|
|
4398
|
+
return {
|
|
4399
|
+
id: obj.id,
|
|
4400
|
+
content: doc,
|
|
4401
|
+
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4402
|
+
extension: extensions
|
|
4403
|
+
};
|
|
4404
|
+
};
|
|
4405
|
+
|
|
3806
4406
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3807
|
-
var
|
|
3808
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo =
|
|
4407
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4408
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo = EditorView17.scrollIntoView(0), moveToEndOfLine, selection, theme, slots = defaultSlots, extensions = [], scrollPastEnd: _scrollPastEnd, debug }, forwardedRef) => {
|
|
3809
4409
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
3810
4410
|
tabBehavior: "limited"
|
|
3811
4411
|
});
|
|
3812
4412
|
const { themeMode } = useThemeContext();
|
|
3813
|
-
const rootRef =
|
|
3814
|
-
const [view, setView] =
|
|
4413
|
+
const rootRef = useRef3(null);
|
|
4414
|
+
const [view, setView] = useState5(null);
|
|
3815
4415
|
useImperativeHandle(forwardedRef, () => view, [
|
|
3816
4416
|
view
|
|
3817
4417
|
]);
|
|
3818
|
-
|
|
4418
|
+
useEffect3(() => {
|
|
3819
4419
|
if (autoFocus) {
|
|
3820
4420
|
view?.focus();
|
|
3821
4421
|
}
|
|
@@ -3823,38 +4423,38 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3823
4423
|
view,
|
|
3824
4424
|
autoFocus
|
|
3825
4425
|
]);
|
|
3826
|
-
|
|
4426
|
+
useEffect3(() => {
|
|
3827
4427
|
if (!model || !rootRef.current) {
|
|
3828
4428
|
return;
|
|
3829
4429
|
}
|
|
3830
|
-
const state =
|
|
3831
|
-
doc: model.
|
|
4430
|
+
const state = EditorState3.create({
|
|
4431
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
3832
4432
|
selection,
|
|
3833
4433
|
extensions: [
|
|
3834
4434
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
F:
|
|
3838
|
-
L:
|
|
4435
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4436
|
+
log5.catch(err, void 0, {
|
|
4437
|
+
F: __dxlog_file7,
|
|
4438
|
+
L: 123,
|
|
3839
4439
|
S: void 0,
|
|
3840
4440
|
C: (f, a) => f(...a)
|
|
3841
4441
|
});
|
|
3842
4442
|
}),
|
|
3843
4443
|
// Theme.
|
|
3844
4444
|
// TODO(burdon): Make base theme configurable.
|
|
3845
|
-
|
|
3846
|
-
theme &&
|
|
3847
|
-
|
|
3848
|
-
slots.editor?.className &&
|
|
4445
|
+
EditorView17.baseTheme(defaultTheme),
|
|
4446
|
+
theme && EditorView17.theme(theme),
|
|
4447
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
4448
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
3849
4449
|
class: slots.editor.className
|
|
3850
4450
|
}),
|
|
3851
|
-
slots.content?.className &&
|
|
4451
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3852
4452
|
class: slots.content.className
|
|
3853
4453
|
}),
|
|
3854
4454
|
// NOTE: Assumes default line height.
|
|
3855
|
-
_scrollPastEnd &&
|
|
4455
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
3856
4456
|
// Focus.
|
|
3857
|
-
|
|
4457
|
+
EditorView17.updateListener.of((update2) => {
|
|
3858
4458
|
update2.transactions.forEach((transaction) => {
|
|
3859
4459
|
if (transaction.isUserEvent("focus.container")) {
|
|
3860
4460
|
rootRef.current?.focus();
|
|
@@ -3862,8 +4462,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3862
4462
|
});
|
|
3863
4463
|
}),
|
|
3864
4464
|
// State.
|
|
3865
|
-
|
|
3866
|
-
|
|
4465
|
+
EditorView17.editable.of(!readonly),
|
|
4466
|
+
EditorState3.readOnly.of(!!readonly),
|
|
3867
4467
|
// Storage and replication.
|
|
3868
4468
|
// NOTE: This must come before user extensions.
|
|
3869
4469
|
model.extension,
|
|
@@ -3871,7 +4471,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3871
4471
|
...extensions
|
|
3872
4472
|
].filter(isNotFalsy4)
|
|
3873
4473
|
});
|
|
3874
|
-
const view2 = new
|
|
4474
|
+
const view2 = new EditorView17({
|
|
3875
4475
|
state,
|
|
3876
4476
|
parent: rootRef.current,
|
|
3877
4477
|
scrollTo,
|
|
@@ -3928,14 +4528,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3928
4528
|
...tabsterDOMAttribute
|
|
3929
4529
|
});
|
|
3930
4530
|
});
|
|
3931
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4531
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping = true, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3932
4532
|
const { themeMode } = useThemeContext();
|
|
3933
|
-
const updatedSlots =
|
|
3934
|
-
const extensions =
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
placeholder: placeholder3
|
|
3938
|
-
|
|
4533
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4534
|
+
const extensions = useMemo3(() => [
|
|
4535
|
+
createBasicExtensions({
|
|
4536
|
+
lineWrapping,
|
|
4537
|
+
placeholder: placeholder3
|
|
4538
|
+
}),
|
|
4539
|
+
createThemeExtensions({
|
|
4540
|
+
themeMode
|
|
3939
4541
|
}),
|
|
3940
4542
|
..._extensions ?? []
|
|
3941
4543
|
], [
|
|
@@ -3955,8 +4557,8 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
3955
4557
|
});
|
|
3956
4558
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
3957
4559
|
const { themeMode } = useThemeContext();
|
|
3958
|
-
const updatedSlots =
|
|
3959
|
-
const extensions =
|
|
4560
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4561
|
+
const extensions = useMemo3(() => [
|
|
3960
4562
|
createMarkdownExtensions({
|
|
3961
4563
|
themeMode,
|
|
3962
4564
|
placeholder: placeholder3
|
|
@@ -3994,7 +4596,7 @@ var defaultMarkdownSlots = {
|
|
|
3994
4596
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
3995
4597
|
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
3996
4598
|
import { createContext } from "@radix-ui/react-context";
|
|
3997
|
-
import React2, { useRef as
|
|
4599
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
3998
4600
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
3999
4601
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4000
4602
|
var tooltipProps = {
|
|
@@ -4052,9 +4654,9 @@ var MarkdownHeading = () => {
|
|
|
4052
4654
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4053
4655
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4054
4656
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4055
|
-
const suppressNextTooltip =
|
|
4056
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4057
|
-
const [selectOpen, setSelectOpen] =
|
|
4657
|
+
const suppressNextTooltip = useRef4(false);
|
|
4658
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4659
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4058
4660
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4059
4661
|
open: tooltipOpen,
|
|
4060
4662
|
onOpenChange: (nextOpen) => {
|
|
@@ -4257,378 +4859,6 @@ var Toolbar = {
|
|
|
4257
4859
|
Markdown: MarkdownStandard,
|
|
4258
4860
|
Extended: MarkdownExtended
|
|
4259
4861
|
};
|
|
4260
|
-
|
|
4261
|
-
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4262
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4263
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4264
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
4265
|
-
import { log as log4 } from "@dxos/log";
|
|
4266
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4267
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
4268
|
-
var SpaceAwarenessProvider = class {
|
|
4269
|
-
constructor(params) {
|
|
4270
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4271
|
-
this.remoteStateChange = new Event2();
|
|
4272
|
-
this._space = params.space;
|
|
4273
|
-
this._channel = params.channel;
|
|
4274
|
-
this._peerId = params.peerId;
|
|
4275
|
-
this._info = params.info;
|
|
4276
|
-
}
|
|
4277
|
-
open() {
|
|
4278
|
-
this._ctx = new Context2();
|
|
4279
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4280
|
-
if (this._localState) {
|
|
4281
|
-
await this._space.postMessage(this._channel, {
|
|
4282
|
-
kind: "post",
|
|
4283
|
-
state: this._localState
|
|
4284
|
-
});
|
|
4285
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
4286
|
-
}
|
|
4287
|
-
});
|
|
4288
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4289
|
-
switch (message.payload.kind) {
|
|
4290
|
-
case "query": {
|
|
4291
|
-
this._handleQueryMessage();
|
|
4292
|
-
break;
|
|
4293
|
-
}
|
|
4294
|
-
case "post": {
|
|
4295
|
-
this._handlePostMessage(message.payload);
|
|
4296
|
-
break;
|
|
4297
|
-
}
|
|
4298
|
-
}
|
|
4299
|
-
}));
|
|
4300
|
-
void this._space.postMessage(this._channel, {
|
|
4301
|
-
kind: "query"
|
|
4302
|
-
}).catch((err) => {
|
|
4303
|
-
log4.debug("failed to query awareness", {
|
|
4304
|
-
err
|
|
4305
|
-
}, {
|
|
4306
|
-
F: __dxlog_file5,
|
|
4307
|
-
L: 89,
|
|
4308
|
-
S: this,
|
|
4309
|
-
C: (f, a) => f(...a)
|
|
4310
|
-
});
|
|
4311
|
-
});
|
|
4312
|
-
}
|
|
4313
|
-
close() {
|
|
4314
|
-
void this._ctx?.dispose();
|
|
4315
|
-
this._ctx = void 0;
|
|
4316
|
-
this._postTask = void 0;
|
|
4317
|
-
}
|
|
4318
|
-
getRemoteStates() {
|
|
4319
|
-
return Array.from(this._remoteStates.values());
|
|
4320
|
-
}
|
|
4321
|
-
update(position) {
|
|
4322
|
-
invariant2(this._postTask, void 0, {
|
|
4323
|
-
F: __dxlog_file5,
|
|
4324
|
-
L: 104,
|
|
4325
|
-
S: this,
|
|
4326
|
-
A: [
|
|
4327
|
-
"this._postTask",
|
|
4328
|
-
""
|
|
4329
|
-
]
|
|
4330
|
-
});
|
|
4331
|
-
this._localState = {
|
|
4332
|
-
peerId: this._peerId,
|
|
4333
|
-
position,
|
|
4334
|
-
info: this._info
|
|
4335
|
-
};
|
|
4336
|
-
this._postTask.schedule();
|
|
4337
|
-
}
|
|
4338
|
-
_handleQueryMessage() {
|
|
4339
|
-
invariant2(this._postTask, void 0, {
|
|
4340
|
-
F: __dxlog_file5,
|
|
4341
|
-
L: 115,
|
|
4342
|
-
S: this,
|
|
4343
|
-
A: [
|
|
4344
|
-
"this._postTask",
|
|
4345
|
-
""
|
|
4346
|
-
]
|
|
4347
|
-
});
|
|
4348
|
-
this._postTask.schedule();
|
|
4349
|
-
}
|
|
4350
|
-
_handlePostMessage(message) {
|
|
4351
|
-
invariant2(message.kind === "post", void 0, {
|
|
4352
|
-
F: __dxlog_file5,
|
|
4353
|
-
L: 120,
|
|
4354
|
-
S: this,
|
|
4355
|
-
A: [
|
|
4356
|
-
"message.kind === 'post'",
|
|
4357
|
-
""
|
|
4358
|
-
]
|
|
4359
|
-
});
|
|
4360
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
4361
|
-
this.remoteStateChange.emit();
|
|
4362
|
-
}
|
|
4363
|
-
};
|
|
4364
|
-
|
|
4365
|
-
// packages/ui/react-ui-editor/src/hooks/defs.ts
|
|
4366
|
-
import { StateField as StateField6 } from "@codemirror/state";
|
|
4367
|
-
var modelState = StateField6.define({
|
|
4368
|
-
create: () => void 0,
|
|
4369
|
-
update: (model) => model
|
|
4370
|
-
});
|
|
4371
|
-
|
|
4372
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4373
|
-
var useActionHandler = (view) => {
|
|
4374
|
-
return (action) => {
|
|
4375
|
-
if (!view) {
|
|
4376
|
-
return;
|
|
4377
|
-
}
|
|
4378
|
-
let inlineType, listType;
|
|
4379
|
-
switch (action.type) {
|
|
4380
|
-
case "heading":
|
|
4381
|
-
setHeading(parseInt(action.data))(view);
|
|
4382
|
-
break;
|
|
4383
|
-
case "strong":
|
|
4384
|
-
case "emphasis":
|
|
4385
|
-
case "strikethrough":
|
|
4386
|
-
case "code":
|
|
4387
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4388
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4389
|
-
break;
|
|
4390
|
-
case "list-ordered":
|
|
4391
|
-
case "list-bullet":
|
|
4392
|
-
case "list-task":
|
|
4393
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4394
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4395
|
-
break;
|
|
4396
|
-
case "blockquote":
|
|
4397
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4398
|
-
break;
|
|
4399
|
-
case "codeblock":
|
|
4400
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4401
|
-
break;
|
|
4402
|
-
case "table":
|
|
4403
|
-
insertTable(view);
|
|
4404
|
-
break;
|
|
4405
|
-
case "link":
|
|
4406
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4407
|
-
break;
|
|
4408
|
-
case "comment":
|
|
4409
|
-
createComment(view);
|
|
4410
|
-
break;
|
|
4411
|
-
}
|
|
4412
|
-
setTimeout(() => {
|
|
4413
|
-
if (!view.hasFocus) {
|
|
4414
|
-
view.focus();
|
|
4415
|
-
}
|
|
4416
|
-
});
|
|
4417
|
-
};
|
|
4418
|
-
};
|
|
4419
|
-
|
|
4420
|
-
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4421
|
-
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4422
|
-
var useEditorView = (id) => {
|
|
4423
|
-
const editorRef = useRef3(null);
|
|
4424
|
-
const [prev, setPrev] = useState4([
|
|
4425
|
-
null,
|
|
4426
|
-
""
|
|
4427
|
-
]);
|
|
4428
|
-
if (prev[0] !== editorRef.current) {
|
|
4429
|
-
setPrev([
|
|
4430
|
-
editorRef.current,
|
|
4431
|
-
id
|
|
4432
|
-
]);
|
|
4433
|
-
}
|
|
4434
|
-
return [
|
|
4435
|
-
editorRef,
|
|
4436
|
-
prev[1] !== id
|
|
4437
|
-
];
|
|
4438
|
-
};
|
|
4439
|
-
|
|
4440
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4441
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4442
|
-
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4443
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4444
|
-
import { log as log5 } from "@dxos/log";
|
|
4445
|
-
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4446
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4447
|
-
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps) => {
|
|
4448
|
-
const onUpdate = useRef4();
|
|
4449
|
-
const [view, setView] = useState5();
|
|
4450
|
-
const parentRef = useRef4(null);
|
|
4451
|
-
useEffect3(() => {
|
|
4452
|
-
let view2;
|
|
4453
|
-
if (parentRef.current) {
|
|
4454
|
-
const state = EditorState3.create({
|
|
4455
|
-
doc,
|
|
4456
|
-
selection,
|
|
4457
|
-
extensions: [
|
|
4458
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4459
|
-
EditorView15.exceptionSink.of((err) => {
|
|
4460
|
-
log5.catch(err, void 0, {
|
|
4461
|
-
F: __dxlog_file6,
|
|
4462
|
-
L: 57,
|
|
4463
|
-
S: void 0,
|
|
4464
|
-
C: (f, a) => f(...a)
|
|
4465
|
-
});
|
|
4466
|
-
}),
|
|
4467
|
-
extensions,
|
|
4468
|
-
EditorView15.updateListener.of(() => {
|
|
4469
|
-
onUpdate.current?.();
|
|
4470
|
-
})
|
|
4471
|
-
].filter(isNotFalsy5)
|
|
4472
|
-
});
|
|
4473
|
-
view2 = new EditorView15({
|
|
4474
|
-
parent: parentRef.current,
|
|
4475
|
-
scrollTo,
|
|
4476
|
-
state,
|
|
4477
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4478
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4479
|
-
dispatchTransactions: (trs, view3) => {
|
|
4480
|
-
if (debug) {
|
|
4481
|
-
logChanges(trs);
|
|
4482
|
-
}
|
|
4483
|
-
view3.update(trs);
|
|
4484
|
-
}
|
|
4485
|
-
});
|
|
4486
|
-
setView(view2);
|
|
4487
|
-
}
|
|
4488
|
-
return () => {
|
|
4489
|
-
view2?.destroy();
|
|
4490
|
-
};
|
|
4491
|
-
}, deps);
|
|
4492
|
-
useEffect3(() => {
|
|
4493
|
-
if (view) {
|
|
4494
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4495
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4496
|
-
}
|
|
4497
|
-
if (selection || scrollTo) {
|
|
4498
|
-
onUpdate.current = () => {
|
|
4499
|
-
onUpdate.current = void 0;
|
|
4500
|
-
view.dispatch({
|
|
4501
|
-
selection,
|
|
4502
|
-
effects: scrollTo && [
|
|
4503
|
-
scrollTo
|
|
4504
|
-
],
|
|
4505
|
-
scrollIntoView: !scrollTo
|
|
4506
|
-
});
|
|
4507
|
-
};
|
|
4508
|
-
}
|
|
4509
|
-
if (autoFocus) {
|
|
4510
|
-
view.focus();
|
|
4511
|
-
}
|
|
4512
|
-
}
|
|
4513
|
-
}, [
|
|
4514
|
-
view,
|
|
4515
|
-
autoFocus,
|
|
4516
|
-
selection,
|
|
4517
|
-
scrollTo
|
|
4518
|
-
]);
|
|
4519
|
-
return {
|
|
4520
|
-
parentRef,
|
|
4521
|
-
view
|
|
4522
|
-
};
|
|
4523
|
-
};
|
|
4524
|
-
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4525
|
-
return [
|
|
4526
|
-
//
|
|
4527
|
-
EditorState3.readOnly.of(readonly),
|
|
4528
|
-
EditorView15.editable.of(!readonly)
|
|
4529
|
-
];
|
|
4530
|
-
};
|
|
4531
|
-
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4532
|
-
return [
|
|
4533
|
-
//
|
|
4534
|
-
EditorView15.baseTheme(defaultTheme),
|
|
4535
|
-
theme && EditorView15.theme(theme),
|
|
4536
|
-
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4537
|
-
EditorView15.editorAttributes.of({
|
|
4538
|
-
class: slots?.editor?.className ?? ""
|
|
4539
|
-
}),
|
|
4540
|
-
EditorView15.contentAttributes.of({
|
|
4541
|
-
class: slots?.content?.className ?? ""
|
|
4542
|
-
})
|
|
4543
|
-
].filter(isNotFalsy5);
|
|
4544
|
-
};
|
|
4545
|
-
|
|
4546
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4547
|
-
import get5 from "lodash.get";
|
|
4548
|
-
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4549
|
-
import { generateName } from "@dxos/display-name";
|
|
4550
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
4551
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4552
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4553
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4554
|
-
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4555
|
-
const extensions = [
|
|
4556
|
-
automerge(text)
|
|
4557
|
-
];
|
|
4558
|
-
if (space && identity) {
|
|
4559
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4560
|
-
space,
|
|
4561
|
-
channel: `awareness.${id}`,
|
|
4562
|
-
peerId: identity.identityKey.toHex(),
|
|
4563
|
-
info: {
|
|
4564
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4565
|
-
color: cursorColor.color,
|
|
4566
|
-
lightColor: cursorColor.light
|
|
4567
|
-
}
|
|
4568
|
-
});
|
|
4569
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4570
|
-
}
|
|
4571
|
-
return extensions;
|
|
4572
|
-
};
|
|
4573
|
-
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4574
|
-
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4575
|
-
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4576
|
-
return {
|
|
4577
|
-
id,
|
|
4578
|
-
content,
|
|
4579
|
-
setContent,
|
|
4580
|
-
text: () => content
|
|
4581
|
-
};
|
|
4582
|
-
};
|
|
4583
|
-
var createModel = ({ space, identity, text }) => {
|
|
4584
|
-
if (!text) {
|
|
4585
|
-
return void 0;
|
|
4586
|
-
}
|
|
4587
|
-
invariant3(isAutomergeObject(text), void 0, {
|
|
4588
|
-
F: __dxlog_file7,
|
|
4589
|
-
L: 83,
|
|
4590
|
-
S: void 0,
|
|
4591
|
-
A: [
|
|
4592
|
-
"isAutomergeObject(text)",
|
|
4593
|
-
""
|
|
4594
|
-
]
|
|
4595
|
-
});
|
|
4596
|
-
const obj = text;
|
|
4597
|
-
const doc = getRawDoc(obj, [
|
|
4598
|
-
obj.field
|
|
4599
|
-
]);
|
|
4600
|
-
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4601
|
-
space,
|
|
4602
|
-
channel: `automerge.awareness.${obj.id}`,
|
|
4603
|
-
info: {
|
|
4604
|
-
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4605
|
-
color: cursorColor.color,
|
|
4606
|
-
lightColor: cursorColor.light
|
|
4607
|
-
},
|
|
4608
|
-
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4609
|
-
});
|
|
4610
|
-
const extensions = [
|
|
4611
|
-
modelState.init(() => model),
|
|
4612
|
-
automerge({
|
|
4613
|
-
handle: doc.handle,
|
|
4614
|
-
path: doc.path
|
|
4615
|
-
})
|
|
4616
|
-
];
|
|
4617
|
-
if (awarenessProvider2) {
|
|
4618
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4619
|
-
}
|
|
4620
|
-
const model = {
|
|
4621
|
-
id: obj.id,
|
|
4622
|
-
content: doc,
|
|
4623
|
-
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4624
|
-
extension: extensions,
|
|
4625
|
-
peer: identity ? {
|
|
4626
|
-
id: identity.identityKey.toHex(),
|
|
4627
|
-
name: identity.profile?.displayName
|
|
4628
|
-
} : void 0
|
|
4629
|
-
};
|
|
4630
|
-
return model;
|
|
4631
|
-
};
|
|
4632
4862
|
export {
|
|
4633
4863
|
BaseTextEditor,
|
|
4634
4864
|
Cursor,
|
|
@@ -4657,11 +4887,11 @@ export {
|
|
|
4657
4887
|
blast,
|
|
4658
4888
|
callbackWrapper,
|
|
4659
4889
|
codeTheme,
|
|
4890
|
+
command,
|
|
4660
4891
|
comments,
|
|
4661
4892
|
compareFormatting,
|
|
4662
|
-
|
|
4893
|
+
createBasicExtensions,
|
|
4663
4894
|
createComment,
|
|
4664
|
-
createDataExtensions,
|
|
4665
4895
|
createMarkdownExtensions,
|
|
4666
4896
|
createThemeExtensions,
|
|
4667
4897
|
cursorLineMargin,
|
|
@@ -4672,6 +4902,7 @@ export {
|
|
|
4672
4902
|
defaultSlots,
|
|
4673
4903
|
defaultTextSlots,
|
|
4674
4904
|
defaultTheme,
|
|
4905
|
+
dnd,
|
|
4675
4906
|
editorFillLayoutEditor,
|
|
4676
4907
|
editorFillLayoutRoot,
|
|
4677
4908
|
editorMode,
|
|
@@ -4682,7 +4913,7 @@ export {
|
|
|
4682
4913
|
getToken,
|
|
4683
4914
|
image,
|
|
4684
4915
|
insertTable,
|
|
4685
|
-
|
|
4916
|
+
keymap9 as keymap,
|
|
4686
4917
|
linkTooltip,
|
|
4687
4918
|
listener,
|
|
4688
4919
|
logChanges,
|
|
@@ -4691,7 +4922,6 @@ export {
|
|
|
4691
4922
|
markdownTagsExtensions,
|
|
4692
4923
|
markdownTheme,
|
|
4693
4924
|
mention,
|
|
4694
|
-
modelState,
|
|
4695
4925
|
outliner,
|
|
4696
4926
|
removeBlockquote,
|
|
4697
4927
|
removeCodeblock,
|