@dxos/react-ui-editor 0.8.2-main.f081794 → 0.8.2-main.fbd8ed0
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 +1664 -1359
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/node/index.cjs +2122 -1819
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs.map +2 -2
- package/dist/lib/node-esm/index.mjs +1664 -1359
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs.map +2 -2
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/{stories/InputMode.stories.d.ts → components/EditorToolbar/EditorToolbar.stories.d.ts} +3 -7
- package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/comment.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/image.d.ts +16 -0
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +11 -17
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/command/command.d.ts.map +1 -1
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
- package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/outliner.d.ts +12 -0
- package/dist/types/src/extensions/markdown/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +5 -5
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/typewriter.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/TextEditorBasic.stories.d.ts +3 -0
- package/dist/types/src/stories/TextEditorBasic.stories.d.ts.map +1 -1
- package/dist/types/src/stories/story-utils.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/testing/RefPopover.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -28
- package/src/components/EditorToolbar/EditorToolbar.stories.tsx +90 -0
- package/src/components/EditorToolbar/EditorToolbar.tsx +31 -32
- package/src/components/EditorToolbar/blocks.ts +27 -6
- package/src/components/EditorToolbar/comment.ts +11 -4
- package/src/components/EditorToolbar/formatting.ts +34 -7
- package/src/components/EditorToolbar/headings.ts +9 -8
- package/src/components/EditorToolbar/image.ts +16 -0
- package/src/components/EditorToolbar/lists.ts +26 -7
- package/src/components/EditorToolbar/search.ts +19 -0
- package/src/components/EditorToolbar/util.ts +14 -14
- package/src/components/EditorToolbar/view-mode.ts +9 -8
- package/src/defaults.ts +1 -1
- package/src/extensions/automerge/automerge.stories.tsx +9 -7
- package/src/extensions/automerge/automerge.test.tsx +4 -4
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/defs.ts +1 -2
- package/src/extensions/automerge/sync.ts +4 -4
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/automerge/update-codemirror.ts +3 -4
- package/src/extensions/markdown/changes.ts +3 -2
- package/src/extensions/markdown/decorate.ts +8 -7
- package/src/extensions/markdown/formatting.ts +4 -4
- package/src/extensions/markdown/index.ts +1 -0
- package/src/extensions/markdown/outliner.ts +235 -0
- package/src/extensions/markdown/styles.ts +2 -2
- package/src/extensions/modes.ts +5 -6
- package/src/extensions/preview/preview.ts +1 -1
- package/src/hooks/index.ts +0 -1
- package/src/stories/TextEditorBasic.stories.tsx +44 -0
- package/src/stories/story-utils.tsx +7 -9
- package/src/styles/theme.ts +3 -0
- package/src/testing/RefPopover.tsx +4 -4
- package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
- package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
- package/dist/types/src/stories/InputMode.stories.d.ts.map +0 -1
- package/src/hooks/useActionHandler.ts +0 -12
- package/src/stories/InputMode.stories.tsx +0 -124
@@ -36,13 +36,13 @@ var translations_default = [
|
|
36
36
|
];
|
37
37
|
|
38
38
|
// packages/ui/react-ui-editor/src/index.ts
|
39
|
-
import { EditorState as
|
40
|
-
import { EditorView as
|
39
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
40
|
+
import { EditorView as EditorView23, keymap as keymap11 } from "@codemirror/view";
|
41
41
|
import { tags as tags2 } from "@lezer/highlight";
|
42
42
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
43
43
|
|
44
44
|
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
45
|
-
import
|
45
|
+
import React3, { memo, useCallback } from "react";
|
46
46
|
import { ElevationProvider } from "@dxos/react-ui";
|
47
47
|
import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
|
48
48
|
import { textBlockWidth } from "@dxos/react-ui-theme";
|
@@ -54,692 +54,110 @@ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
|
|
54
54
|
var useEditorToolbarState = (initialState = {}) => {
|
55
55
|
return useMemo(() => live(initialState), []);
|
56
56
|
};
|
57
|
-
var createEditorAction = (
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
57
|
+
var createEditorAction = (id, invoke, properties) => {
|
58
|
+
const { label = [
|
59
|
+
`${id} label`,
|
60
|
+
{
|
61
|
+
ns: translationKey
|
62
|
+
}
|
63
|
+
], ...rest } = properties;
|
64
|
+
return createMenuAction(id, invoke, {
|
65
|
+
label,
|
66
|
+
...rest
|
67
|
+
});
|
68
|
+
};
|
67
69
|
var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
|
68
70
|
icon,
|
69
71
|
iconOnly: true,
|
70
72
|
...props
|
71
73
|
});
|
72
|
-
var editorToolbarSearch = createEditorAction({
|
73
|
-
type: "search"
|
74
|
-
}, "ph--magnifying-glass--regular");
|
75
74
|
|
76
|
-
// packages/ui/react-ui-editor/src/
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
value
|
81
|
-
});
|
82
|
-
var createBlockActions = (value, blankLine) => Object.entries({
|
83
|
-
blockquote: "ph--quotes--regular",
|
84
|
-
codeblock: "ph--code-block--regular",
|
85
|
-
table: "ph--table--regular"
|
86
|
-
}).map(([type, icon]) => {
|
87
|
-
return createEditorAction({
|
88
|
-
type,
|
89
|
-
checked: type === value,
|
90
|
-
...type === "table" && {
|
91
|
-
disabled: !!blankLine
|
92
|
-
}
|
93
|
-
}, icon);
|
94
|
-
});
|
95
|
-
var createBlocks = (state) => {
|
96
|
-
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
97
|
-
const blockGroupAction = createBlockGroupAction(value);
|
98
|
-
const blockActions = createBlockActions(value, state.blankLine);
|
99
|
-
return {
|
100
|
-
nodes: [
|
101
|
-
blockGroupAction,
|
102
|
-
...blockActions
|
103
|
-
],
|
104
|
-
edges: [
|
105
|
-
{
|
106
|
-
source: "root",
|
107
|
-
target: "block"
|
108
|
-
},
|
109
|
-
...blockActions.map(({ id }) => ({
|
110
|
-
source: blockGroupAction.id,
|
111
|
-
target: id
|
112
|
-
}))
|
113
|
-
]
|
114
|
-
};
|
115
|
-
};
|
75
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
76
|
+
import { StateField } from "@codemirror/state";
|
77
|
+
import { Decoration, EditorView } from "@codemirror/view";
|
78
|
+
import { isNotFalsy } from "@dxos/util";
|
116
79
|
|
117
|
-
// packages/ui/react-ui-editor/src/
|
118
|
-
|
119
|
-
var
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
nodes: [
|
125
|
-
createCommentAction([
|
126
|
-
commentLabel(state.comment, state.selection),
|
127
|
-
{
|
128
|
-
ns: translationKey
|
129
|
-
}
|
130
|
-
])
|
131
|
-
],
|
132
|
-
edges: [
|
133
|
-
{
|
134
|
-
source: "root",
|
135
|
-
target: "comment"
|
136
|
-
}
|
137
|
-
]
|
80
|
+
// packages/ui/react-ui-editor/src/util/facet.ts
|
81
|
+
import { Facet } from "@codemirror/state";
|
82
|
+
var singleValueFacet = (defaultValue) => Facet.define({
|
83
|
+
// Called immediately.
|
84
|
+
combine: (providers) => {
|
85
|
+
return providers[0] ?? defaultValue;
|
86
|
+
}
|
138
87
|
});
|
139
88
|
|
140
|
-
// packages/ui/react-ui-editor/src/
|
141
|
-
var
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
code: "ph--code--regular",
|
146
|
-
link: "ph--link--regular"
|
89
|
+
// packages/ui/react-ui-editor/src/util/cursor.ts
|
90
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
91
|
+
var defaultCursorConverter = {
|
92
|
+
toCursor: (position) => position.toString(),
|
93
|
+
fromCursor: (cursor) => parseInt(cursor)
|
147
94
|
};
|
148
|
-
var
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
};
|
95
|
+
var Cursor = class _Cursor {
|
96
|
+
static {
|
97
|
+
this.converter = singleValueFacet(defaultCursorConverter);
|
98
|
+
}
|
99
|
+
static {
|
100
|
+
this.getCursorFromRange = (state, range) => {
|
101
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
102
|
+
const from = cursorConverter2.toCursor(range.from);
|
103
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
104
|
+
return [
|
105
|
+
from,
|
106
|
+
to
|
107
|
+
].join(":");
|
108
|
+
};
|
109
|
+
}
|
110
|
+
static {
|
111
|
+
this.getRangeFromCursor = (state, cursor) => {
|
112
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
113
|
+
const parts = cursor.split(":");
|
114
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
115
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
116
|
+
return from !== void 0 && to !== void 0 ? {
|
117
|
+
from,
|
118
|
+
to
|
119
|
+
} : void 0;
|
120
|
+
};
|
121
|
+
}
|
176
122
|
};
|
177
123
|
|
178
|
-
// packages/ui/react-ui-editor/src/
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
"6": "ph--text-h-six--regular"
|
193
|
-
}).map(([levelStr, icon]) => {
|
194
|
-
const level = parseInt(levelStr);
|
195
|
-
return createEditorAction({
|
196
|
-
type: "heading",
|
197
|
-
data: level,
|
198
|
-
checked: value === levelStr
|
199
|
-
}, icon, [
|
200
|
-
"heading level label",
|
201
|
-
{
|
202
|
-
count: level,
|
203
|
-
ns: translationKey
|
124
|
+
// packages/ui/react-ui-editor/src/util/debug.ts
|
125
|
+
import { log } from "@dxos/log";
|
126
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
127
|
+
var wrapWithCatch = (fn) => {
|
128
|
+
return (...args) => {
|
129
|
+
try {
|
130
|
+
return fn(...args);
|
131
|
+
} catch (err) {
|
132
|
+
log.catch(err, void 0, {
|
133
|
+
F: __dxlog_file,
|
134
|
+
L: 15,
|
135
|
+
S: void 0,
|
136
|
+
C: (f, a) => f(...a)
|
137
|
+
});
|
204
138
|
}
|
205
|
-
], `heading--${levelStr}`);
|
206
|
-
});
|
207
|
-
var computeHeadingValue = (state) => {
|
208
|
-
const blockType = state ? state.blockType : "paragraph";
|
209
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
210
|
-
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
211
|
-
};
|
212
|
-
var createHeadings = (state) => {
|
213
|
-
const headingValue = computeHeadingValue(state);
|
214
|
-
const headingGroupAction = createHeadingGroupAction(headingValue);
|
215
|
-
const headingActions = createHeadingActions(headingValue);
|
216
|
-
return {
|
217
|
-
nodes: [
|
218
|
-
headingGroupAction,
|
219
|
-
...headingActions
|
220
|
-
],
|
221
|
-
edges: [
|
222
|
-
{
|
223
|
-
source: "root",
|
224
|
-
target: "heading"
|
225
|
-
},
|
226
|
-
...headingActions.map(({ id }) => ({
|
227
|
-
source: headingGroupAction.id,
|
228
|
-
target: id
|
229
|
-
}))
|
230
|
-
]
|
231
139
|
};
|
232
140
|
};
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
141
|
+
var callbackWrapper = (fn) => (...args) => {
|
142
|
+
try {
|
143
|
+
return fn(...args);
|
144
|
+
} catch (err) {
|
145
|
+
log.catch(err, void 0, {
|
146
|
+
F: __dxlog_file,
|
147
|
+
L: 29,
|
148
|
+
S: void 0,
|
149
|
+
C: (f, a) => f(...a)
|
150
|
+
});
|
151
|
+
}
|
239
152
|
};
|
240
|
-
var
|
241
|
-
|
242
|
-
|
243
|
-
value
|
244
|
-
});
|
245
|
-
var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
|
246
|
-
type: `list-${listStyle}`,
|
247
|
-
checked: value === listStyle
|
248
|
-
}, icon));
|
249
|
-
var createLists = (state) => {
|
250
|
-
const value = state.listStyle ?? "";
|
251
|
-
const listGroupAction = createListGroupAction(value);
|
252
|
-
const listActionsMap = createListActions(value);
|
253
|
-
return {
|
254
|
-
nodes: [
|
255
|
-
listGroupAction,
|
256
|
-
...listActionsMap
|
257
|
-
],
|
258
|
-
edges: [
|
259
|
-
{
|
260
|
-
source: "root",
|
261
|
-
target: "list"
|
262
|
-
},
|
263
|
-
...listActionsMap.map(({ id }) => ({
|
264
|
-
source: listGroupAction.id,
|
265
|
-
target: id
|
266
|
-
}))
|
267
|
-
]
|
268
|
-
};
|
153
|
+
var debugDispatcher = (trs, view) => {
|
154
|
+
logChanges(trs);
|
155
|
+
view.update(trs);
|
269
156
|
};
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
applyActive: true,
|
275
|
-
selectCardinality: "single",
|
276
|
-
value
|
277
|
-
}, "ph--eye--regular");
|
278
|
-
var createViewModeActions = (value) => Object.entries({
|
279
|
-
preview: "ph--eye--regular",
|
280
|
-
source: "ph--pencil-simple--regular",
|
281
|
-
readonly: "ph--pencil-slash--regular"
|
282
|
-
}).map(([viewMode, icon]) => {
|
283
|
-
return createEditorAction({
|
284
|
-
type: "view-mode",
|
285
|
-
data: viewMode,
|
286
|
-
checked: viewMode === value
|
287
|
-
}, icon, [
|
288
|
-
`${viewMode} mode label`,
|
289
|
-
{
|
290
|
-
ns: translationKey
|
291
|
-
}
|
292
|
-
], `view-mode--${viewMode}`);
|
293
|
-
});
|
294
|
-
var createViewMode = (state) => {
|
295
|
-
const value = state.viewMode ?? "source";
|
296
|
-
const viewModeGroupAction = createViewModeGroupAction(value);
|
297
|
-
const viewModeActions = createViewModeActions(value);
|
298
|
-
return {
|
299
|
-
nodes: [
|
300
|
-
viewModeGroupAction,
|
301
|
-
...viewModeActions
|
302
|
-
],
|
303
|
-
edges: [
|
304
|
-
{
|
305
|
-
source: "root",
|
306
|
-
target: "viewMode"
|
307
|
-
},
|
308
|
-
...viewModeActions.map(({ id }) => ({
|
309
|
-
source: viewModeGroupAction.id,
|
310
|
-
target: id
|
311
|
-
}))
|
312
|
-
]
|
313
|
-
};
|
314
|
-
};
|
315
|
-
|
316
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
317
|
-
import { EditorView } from "@codemirror/view";
|
318
|
-
import { mx as mx2 } from "@dxos/react-ui-theme";
|
319
|
-
|
320
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
321
|
-
import { mx } from "@dxos/react-ui-theme";
|
322
|
-
var headings = {
|
323
|
-
1: "text-4xl",
|
324
|
-
2: "text-3xl",
|
325
|
-
3: "text-2xl",
|
326
|
-
4: "text-xl",
|
327
|
-
5: "text-lg",
|
328
|
-
6: ""
|
329
|
-
};
|
330
|
-
var theme = {
|
331
|
-
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
332
|
-
codeMark: "font-mono text-primary-500",
|
333
|
-
mark: "opacity-50",
|
334
|
-
heading: (level) => {
|
335
|
-
return mx(headings[level], "dark:text-primary-400");
|
336
|
-
}
|
337
|
-
};
|
338
|
-
|
339
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
340
|
-
import get from "lodash.get";
|
341
|
-
import { tokens } from "@dxos/react-ui-theme";
|
342
|
-
var getToken = (path, defaultValue) => {
|
343
|
-
const value = get(tokens, path, defaultValue);
|
344
|
-
return value?.toString() ?? "";
|
345
|
-
};
|
346
|
-
var fontBody = getToken("fontFamily.body");
|
347
|
-
var fontMono = getToken("fontFamily.mono");
|
348
|
-
|
349
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
350
|
-
var defaultTheme = {
|
351
|
-
"&": {},
|
352
|
-
"&.cm-focused": {
|
353
|
-
outline: "none"
|
354
|
-
},
|
355
|
-
/**
|
356
|
-
* Scroller
|
357
|
-
*/
|
358
|
-
".cm-scroller": {
|
359
|
-
overflowY: "auto"
|
360
|
-
},
|
361
|
-
/**
|
362
|
-
* Content
|
363
|
-
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
364
|
-
*/
|
365
|
-
".cm-content": {
|
366
|
-
padding: "unset",
|
367
|
-
fontFamily: fontBody,
|
368
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
369
|
-
fontSize: "16px",
|
370
|
-
lineHeight: 1.5,
|
371
|
-
color: "unset"
|
372
|
-
},
|
373
|
-
/**
|
374
|
-
* Gutters
|
375
|
-
* NOTE: Gutters should have the same top margin as the content.
|
376
|
-
*/
|
377
|
-
".cm-gutters": {
|
378
|
-
borderRight: "none",
|
379
|
-
background: "transparent"
|
380
|
-
},
|
381
|
-
".cm-gutter": {},
|
382
|
-
".cm-gutter.cm-lineNumbers": {
|
383
|
-
paddingRight: "4px",
|
384
|
-
borderRight: "1px solid var(--dx-separator)"
|
385
|
-
},
|
386
|
-
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
387
|
-
minWidth: "40px",
|
388
|
-
alignContent: "center"
|
389
|
-
},
|
390
|
-
/**
|
391
|
-
* Height is set to match the corresponding line.
|
392
|
-
*/
|
393
|
-
".cm-gutterElement": {
|
394
|
-
alignItems: "center",
|
395
|
-
fontSize: "12px"
|
396
|
-
},
|
397
|
-
/**
|
398
|
-
* Line.
|
399
|
-
*/
|
400
|
-
".cm-line": {
|
401
|
-
paddingInline: 0
|
402
|
-
},
|
403
|
-
".cm-activeLine": {
|
404
|
-
background: "var(--dx-cmActiveLine)"
|
405
|
-
},
|
406
|
-
/**
|
407
|
-
* Cursor (layer).
|
408
|
-
*/
|
409
|
-
".cm-cursor, .cm-dropCursor": {
|
410
|
-
borderLeft: "2px solid var(--dx-cmCursor)"
|
411
|
-
},
|
412
|
-
".cm-placeholder": {
|
413
|
-
color: "var(--dx-subdued)"
|
414
|
-
},
|
415
|
-
/**
|
416
|
-
* Selection (layer).
|
417
|
-
*/
|
418
|
-
".cm-selectionBackground": {
|
419
|
-
background: "var(--dx-cmSelection)"
|
420
|
-
},
|
421
|
-
/**
|
422
|
-
* Search.
|
423
|
-
* NOTE: Matches comment.
|
424
|
-
*/
|
425
|
-
".cm-searchMatch": {
|
426
|
-
margin: "0 -3px",
|
427
|
-
padding: "3px",
|
428
|
-
borderRadius: "3px",
|
429
|
-
background: "var(--dx-cmHighlightSurface)",
|
430
|
-
color: "var(--dx-cmHighlight)"
|
431
|
-
},
|
432
|
-
".cm-searchMatch-selected": {
|
433
|
-
textDecoration: "underline"
|
434
|
-
},
|
435
|
-
/**
|
436
|
-
* Link.
|
437
|
-
*/
|
438
|
-
".cm-link": {
|
439
|
-
textDecorationLine: "underline",
|
440
|
-
textDecorationThickness: "1px",
|
441
|
-
textDecorationColor: "var(--dx-separator)",
|
442
|
-
textUnderlineOffset: "2px",
|
443
|
-
borderRadius: ".125rem"
|
444
|
-
},
|
445
|
-
".cm-link > span": {
|
446
|
-
color: "var(--dx-accentText)"
|
447
|
-
},
|
448
|
-
/**
|
449
|
-
* Tooltip.
|
450
|
-
*/
|
451
|
-
".cm-tooltip": {
|
452
|
-
background: "var(--dx-baseSurface)"
|
453
|
-
},
|
454
|
-
".cm-tooltip-below": {},
|
455
|
-
/**
|
456
|
-
* Autocomplete.
|
457
|
-
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
458
|
-
*/
|
459
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
460
|
-
marginTop: "4px",
|
461
|
-
marginLeft: "-3px"
|
462
|
-
},
|
463
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
464
|
-
maxHeight: "20em"
|
465
|
-
},
|
466
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
467
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
468
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
469
|
-
paddingLeft: "4px !important",
|
470
|
-
borderBottom: "none !important",
|
471
|
-
color: "var(--dx-accentText)"
|
472
|
-
},
|
473
|
-
".cm-tooltip.cm-completionInfo": {
|
474
|
-
width: "360px !important",
|
475
|
-
margin: "-10px 1px 0 1px",
|
476
|
-
padding: "8px !important",
|
477
|
-
borderColor: "var(--dx-separator)"
|
478
|
-
},
|
479
|
-
".cm-completionIcon": {
|
480
|
-
display: "none"
|
481
|
-
},
|
482
|
-
".cm-completionLabel": {
|
483
|
-
fontFamily: fontBody
|
484
|
-
},
|
485
|
-
".cm-completionMatchedText": {
|
486
|
-
textDecoration: "none !important",
|
487
|
-
opacity: 0.5
|
488
|
-
},
|
489
|
-
/**
|
490
|
-
* Panels
|
491
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
492
|
-
*
|
493
|
-
* Find/replace panel.
|
494
|
-
* <div class="cm-announced">...</div>
|
495
|
-
* <div class="cm-scroller">...</div>
|
496
|
-
* <div class="cm-panels cm-panels-bottom">
|
497
|
-
* <div class="cm-search cm-panel">
|
498
|
-
* <input class="cm-textfield" />
|
499
|
-
* <button class="cm-button">...</button>
|
500
|
-
* <label><input type="checkbox" />...</label>
|
501
|
-
* </div>
|
502
|
-
* </div
|
503
|
-
*/
|
504
|
-
// TODO(burdon): Implement custom panel (with icon buttons).
|
505
|
-
".cm-panels": {},
|
506
|
-
".cm-panel": {
|
507
|
-
fontFamily: fontBody,
|
508
|
-
backgroundColor: "var(--surface-bg)"
|
509
|
-
},
|
510
|
-
".cm-panel input, .cm-panel button, .cm-panel label": {
|
511
|
-
color: "var(--dx-subdued)",
|
512
|
-
fontFamily: fontBody,
|
513
|
-
fontSize: "14px",
|
514
|
-
all: "unset",
|
515
|
-
margin: "3px !important",
|
516
|
-
padding: "2px 6px !important",
|
517
|
-
outline: "1px solid transparent"
|
518
|
-
},
|
519
|
-
".cm-panel input, .cm-panel button": {
|
520
|
-
backgroundColor: "var(--dx-input)"
|
521
|
-
},
|
522
|
-
".cm-panel input:focus, .cm-panel button:focus": {
|
523
|
-
outline: "1px solid var(--dx-accentFocusIndicator)"
|
524
|
-
},
|
525
|
-
".cm-panel label": {
|
526
|
-
display: "inline-flex",
|
527
|
-
alignItems: "center",
|
528
|
-
cursor: "pointer"
|
529
|
-
},
|
530
|
-
".cm-panel input.cm-textfield": {},
|
531
|
-
".cm-panel input[type=checkbox]": {
|
532
|
-
width: "8px",
|
533
|
-
height: "8px",
|
534
|
-
marginRight: "6px !important",
|
535
|
-
padding: "2px !important",
|
536
|
-
color: "var(--dx-accentFocusIndicator)"
|
537
|
-
},
|
538
|
-
".cm-panel button": {
|
539
|
-
"&:hover": {
|
540
|
-
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
541
|
-
},
|
542
|
-
"&:active": {
|
543
|
-
backgroundColor: "var(--dx-accentSurfaceHover)"
|
544
|
-
}
|
545
|
-
},
|
546
|
-
".cm-panel.cm-search": {
|
547
|
-
padding: "4px",
|
548
|
-
borderTop: "1px solid var(--dx-separator)"
|
549
|
-
}
|
550
|
-
};
|
551
|
-
|
552
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
553
|
-
var margin = "!mt-[1rem]";
|
554
|
-
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
555
|
-
var editorContent = mx2(margin, editorWidth);
|
556
|
-
var editorFullWidth = mx2(margin);
|
557
|
-
var editorGutter = EditorView.theme({
|
558
|
-
// Match margin from content.
|
559
|
-
// Gutter = 2rem + 1rem margin.
|
560
|
-
".cm-gutters": {
|
561
|
-
marginTop: "1rem",
|
562
|
-
paddingRight: "1rem"
|
563
|
-
}
|
564
|
-
});
|
565
|
-
var editorMonospace = EditorView.theme({
|
566
|
-
".cm-content": {
|
567
|
-
fontFamily: fontMono
|
568
|
-
}
|
569
|
-
});
|
570
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
571
|
-
var stackItemContentEditorClassNames = (role) => mx2("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
572
|
-
var stackItemContentToolbarClassNames = (role) => mx2("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
|
573
|
-
|
574
|
-
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
575
|
-
var createToolbar = ({ state, customActions, ...features }) => {
|
576
|
-
const nodes = [];
|
577
|
-
const edges = [];
|
578
|
-
if (features.headings ?? true) {
|
579
|
-
const headings2 = createHeadings(state);
|
580
|
-
nodes.push(...headings2.nodes);
|
581
|
-
edges.push(...headings2.edges);
|
582
|
-
}
|
583
|
-
if (features.formatting ?? true) {
|
584
|
-
const formatting = createFormatting(state);
|
585
|
-
nodes.push(...formatting.nodes);
|
586
|
-
edges.push(...formatting.edges);
|
587
|
-
}
|
588
|
-
if (features.lists ?? true) {
|
589
|
-
const lists = createLists(state);
|
590
|
-
nodes.push(...lists.nodes);
|
591
|
-
edges.push(...lists.edges);
|
592
|
-
}
|
593
|
-
if (features.blocks ?? true) {
|
594
|
-
const blocks = createBlocks(state);
|
595
|
-
nodes.push(...blocks.nodes);
|
596
|
-
edges.push(...blocks.edges);
|
597
|
-
}
|
598
|
-
if (customActions) {
|
599
|
-
const custom = customActions();
|
600
|
-
nodes.push(...custom.nodes);
|
601
|
-
edges.push(...custom.edges);
|
602
|
-
}
|
603
|
-
const editorToolbarGap = createGapSeparator();
|
604
|
-
nodes.push(...editorToolbarGap.nodes);
|
605
|
-
edges.push(...editorToolbarGap.edges);
|
606
|
-
if (features.comment ?? true) {
|
607
|
-
const comment = createComment(state);
|
608
|
-
nodes.push(...comment.nodes);
|
609
|
-
edges.push(...comment.edges);
|
610
|
-
}
|
611
|
-
if (features.search ?? true) {
|
612
|
-
nodes.push(editorToolbarSearch);
|
613
|
-
edges.push({
|
614
|
-
source: "root",
|
615
|
-
target: editorToolbarSearch.id
|
616
|
-
});
|
617
|
-
}
|
618
|
-
if (features.viewMode ?? true) {
|
619
|
-
const viewMode = createViewMode(state);
|
620
|
-
nodes.push(...viewMode.nodes);
|
621
|
-
edges.push(...viewMode.edges);
|
622
|
-
}
|
623
|
-
return {
|
624
|
-
nodes,
|
625
|
-
edges
|
626
|
-
};
|
627
|
-
};
|
628
|
-
var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
|
629
|
-
const menuCreator = useCallback(() => createToolbar(props), [
|
630
|
-
props
|
631
|
-
]);
|
632
|
-
const { resolveGroupItems } = useMenuActions(menuCreator);
|
633
|
-
return {
|
634
|
-
resolveGroupItems,
|
635
|
-
onAction
|
636
|
-
};
|
637
|
-
};
|
638
|
-
var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
|
639
|
-
const menuProps = useEditorToolbarActionGraph(props);
|
640
|
-
return /* @__PURE__ */ React.createElement("div", {
|
641
|
-
role: "none",
|
642
|
-
className: stackItemContentToolbarClassNames(role)
|
643
|
-
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
644
|
-
elevation: role === "section" ? "positioned" : "base"
|
645
|
-
}, /* @__PURE__ */ React.createElement(MenuProvider, {
|
646
|
-
...menuProps,
|
647
|
-
attendableId
|
648
|
-
}, /* @__PURE__ */ React.createElement(ToolbarMenu, {
|
649
|
-
classNames: [
|
650
|
-
textBlockWidth,
|
651
|
-
"!bg-transparent",
|
652
|
-
classNames
|
653
|
-
]
|
654
|
-
}))));
|
655
|
-
};
|
656
|
-
|
657
|
-
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
658
|
-
import { StateField } from "@codemirror/state";
|
659
|
-
import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
|
660
|
-
import { isNotFalsy } from "@dxos/util";
|
661
|
-
|
662
|
-
// packages/ui/react-ui-editor/src/util/facet.ts
|
663
|
-
import { Facet } from "@codemirror/state";
|
664
|
-
var singleValueFacet = (defaultValue) => Facet.define({
|
665
|
-
// Called immediately.
|
666
|
-
combine: (providers) => {
|
667
|
-
return providers[0] ?? defaultValue;
|
668
|
-
}
|
669
|
-
});
|
670
|
-
|
671
|
-
// packages/ui/react-ui-editor/src/util/cursor.ts
|
672
|
-
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
673
|
-
var defaultCursorConverter = {
|
674
|
-
toCursor: (position) => position.toString(),
|
675
|
-
fromCursor: (cursor) => parseInt(cursor)
|
676
|
-
};
|
677
|
-
var Cursor = class _Cursor {
|
678
|
-
static {
|
679
|
-
this.converter = singleValueFacet(defaultCursorConverter);
|
680
|
-
}
|
681
|
-
static {
|
682
|
-
this.getCursorFromRange = (state, range) => {
|
683
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
684
|
-
const from = cursorConverter2.toCursor(range.from);
|
685
|
-
const to = cursorConverter2.toCursor(range.to, -1);
|
686
|
-
return [
|
687
|
-
from,
|
688
|
-
to
|
689
|
-
].join(":");
|
690
|
-
};
|
691
|
-
}
|
692
|
-
static {
|
693
|
-
this.getRangeFromCursor = (state, cursor) => {
|
694
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
695
|
-
const parts = cursor.split(":");
|
696
|
-
const from = cursorConverter2.fromCursor(parts[0]);
|
697
|
-
const to = cursorConverter2.fromCursor(parts[1]);
|
698
|
-
return from !== void 0 && to !== void 0 ? {
|
699
|
-
from,
|
700
|
-
to
|
701
|
-
} : void 0;
|
702
|
-
};
|
703
|
-
}
|
704
|
-
};
|
705
|
-
|
706
|
-
// packages/ui/react-ui-editor/src/util/debug.ts
|
707
|
-
import { log } from "@dxos/log";
|
708
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
709
|
-
var wrapWithCatch = (fn) => {
|
710
|
-
return (...args) => {
|
711
|
-
try {
|
712
|
-
return fn(...args);
|
713
|
-
} catch (err) {
|
714
|
-
log.catch(err, void 0, {
|
715
|
-
F: __dxlog_file,
|
716
|
-
L: 15,
|
717
|
-
S: void 0,
|
718
|
-
C: (f, a) => f(...a)
|
719
|
-
});
|
720
|
-
}
|
721
|
-
};
|
722
|
-
};
|
723
|
-
var callbackWrapper = (fn) => (...args) => {
|
724
|
-
try {
|
725
|
-
return fn(...args);
|
726
|
-
} catch (err) {
|
727
|
-
log.catch(err, void 0, {
|
728
|
-
F: __dxlog_file,
|
729
|
-
L: 29,
|
730
|
-
S: void 0,
|
731
|
-
C: (f, a) => f(...a)
|
732
|
-
});
|
733
|
-
}
|
734
|
-
};
|
735
|
-
var debugDispatcher = (trs, view) => {
|
736
|
-
logChanges(trs);
|
737
|
-
view.update(trs);
|
738
|
-
};
|
739
|
-
var logChanges = (trs) => {
|
740
|
-
const changes = trs.flatMap((tr) => {
|
741
|
-
if (tr.changes.empty) {
|
742
|
-
return void 0;
|
157
|
+
var logChanges = (trs) => {
|
158
|
+
const changes = trs.flatMap((tr) => {
|
159
|
+
if (tr.changes.empty) {
|
160
|
+
return void 0;
|
743
161
|
}
|
744
162
|
const changes2 = [];
|
745
163
|
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
@@ -791,7 +209,7 @@ var clientRectsFor = (dom) => {
|
|
791
209
|
};
|
792
210
|
|
793
211
|
// packages/ui/react-ui-editor/src/util/react.tsx
|
794
|
-
import
|
212
|
+
import React from "react";
|
795
213
|
import { createRoot } from "react-dom/client";
|
796
214
|
import { ThemeProvider, Tooltip } from "@dxos/react-ui";
|
797
215
|
import { defaultTx } from "@dxos/react-ui-theme";
|
@@ -808,15 +226,15 @@ var createElement = (tag, options, children) => {
|
|
808
226
|
return el;
|
809
227
|
};
|
810
228
|
var renderRoot = (root, node) => {
|
811
|
-
createRoot(root).render(/* @__PURE__ */
|
229
|
+
createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
|
812
230
|
tx: defaultTx
|
813
231
|
}, node));
|
814
232
|
return root;
|
815
233
|
};
|
816
234
|
var createRenderer = (Component) => (el, props) => {
|
817
|
-
renderRoot(el, /* @__PURE__ */
|
235
|
+
renderRoot(el, /* @__PURE__ */ React.createElement(ThemeProvider, {
|
818
236
|
tx: defaultTx
|
819
|
-
}, /* @__PURE__ */
|
237
|
+
}, /* @__PURE__ */ React.createElement(Tooltip.Provider, null, /* @__PURE__ */ React.createElement(Component, props))));
|
820
238
|
};
|
821
239
|
|
822
240
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
@@ -856,7 +274,7 @@ var annotations = (options = {}) => {
|
|
856
274
|
});
|
857
275
|
return [
|
858
276
|
annotationsState,
|
859
|
-
|
277
|
+
EditorView.decorations.compute([
|
860
278
|
annotationsState
|
861
279
|
], (state) => {
|
862
280
|
const annotations2 = state.field(annotationsState);
|
@@ -869,7 +287,7 @@ var annotations = (options = {}) => {
|
|
869
287
|
styles
|
870
288
|
];
|
871
289
|
};
|
872
|
-
var styles =
|
290
|
+
var styles = EditorView.theme({
|
873
291
|
".cm-annotation": {
|
874
292
|
textDecoration: "underline",
|
875
293
|
textDecorationStyle: "wavy",
|
@@ -917,9 +335,9 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
|
917
335
|
};
|
918
336
|
|
919
337
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
338
|
+
import { next as A3 } from "@automerge/automerge";
|
920
339
|
import { StateField as StateField2 } from "@codemirror/state";
|
921
|
-
import { EditorView as
|
922
|
-
import { next as A3 } from "@dxos/automerge/automerge";
|
340
|
+
import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
|
923
341
|
|
924
342
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
925
343
|
import { log as log2 } from "@dxos/log";
|
@@ -968,10 +386,10 @@ var isReconcile = (tr) => {
|
|
968
386
|
};
|
969
387
|
|
970
388
|
// packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
|
971
|
-
import { next as A2 } from "@
|
389
|
+
import { next as A2 } from "@automerge/automerge";
|
972
390
|
|
973
391
|
// packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
|
974
|
-
import { next as A } from "@
|
392
|
+
import { next as A } from "@automerge/automerge";
|
975
393
|
var updateAutomerge = (field, handle, transactions, state) => {
|
976
394
|
const { lastHeads, path } = state.field(field);
|
977
395
|
let hasChanges = false;
|
@@ -1140,8 +558,8 @@ var Syncer = class {
|
|
1140
558
|
}
|
1141
559
|
onAutomergeChange(view) {
|
1142
560
|
const oldHeads = getLastHeads(view.state, this._state);
|
1143
|
-
const newHeads = A2.getHeads(this._handle.
|
1144
|
-
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.
|
561
|
+
const newHeads = A2.getHeads(this._handle.doc());
|
562
|
+
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
1145
563
|
const selection = view.state.selection;
|
1146
564
|
const path = getPath(view.state, this._state);
|
1147
565
|
updateCodeMirror(view, selection, path, diff);
|
@@ -1157,7 +575,7 @@ var automerge = (accessor) => {
|
|
1157
575
|
const syncState = StateField2.define({
|
1158
576
|
create: () => ({
|
1159
577
|
path: accessor.path.slice(),
|
1160
|
-
lastHeads: A3.getHeads(accessor.handle.
|
578
|
+
lastHeads: A3.getHeads(accessor.handle.doc()),
|
1161
579
|
unreconciledTransactions: []
|
1162
580
|
}),
|
1163
581
|
update: (value, tr) => {
|
@@ -1202,7 +620,7 @@ var automerge = (accessor) => {
|
|
1202
620
|
}
|
1203
621
|
}),
|
1204
622
|
// Reconcile local updates.
|
1205
|
-
|
623
|
+
EditorView2.updateListener.of(({ view, changes }) => {
|
1206
624
|
if (!changes.empty) {
|
1207
625
|
syncer.reconcile(view, true);
|
1208
626
|
}
|
@@ -1212,7 +630,7 @@ var automerge = (accessor) => {
|
|
1212
630
|
|
1213
631
|
// packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
|
1214
632
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
1215
|
-
import { Decoration as Decoration2, EditorView as
|
633
|
+
import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
1216
634
|
import { Event } from "@dxos/async";
|
1217
635
|
import { Context } from "@dxos/context";
|
1218
636
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
|
@@ -1386,7 +804,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
1386
804
|
return true;
|
1387
805
|
}
|
1388
806
|
};
|
1389
|
-
var styles2 =
|
807
|
+
var styles2 = EditorView3.theme({
|
1390
808
|
".cm-collab-selection": {},
|
1391
809
|
".cm-collab-selectionLine": {
|
1392
810
|
padding: 0,
|
@@ -1552,7 +970,7 @@ var SpaceAwarenessProvider = class {
|
|
1552
970
|
};
|
1553
971
|
|
1554
972
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
1555
|
-
import { EditorView as
|
973
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
1556
974
|
import defaultsDeep from "lodash.defaultsdeep";
|
1557
975
|
import { invariant as invariant2 } from "@dxos/invariant";
|
1558
976
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
@@ -1600,7 +1018,7 @@ var blast = (options = defaultOptions) => {
|
|
1600
1018
|
};
|
1601
1019
|
return [
|
1602
1020
|
// Cursor moved.
|
1603
|
-
|
1021
|
+
EditorView4.updateListener.of((update2) => {
|
1604
1022
|
if (blaster?.node !== update2.view.scrollDOM) {
|
1605
1023
|
if (blaster) {
|
1606
1024
|
blaster.destroy();
|
@@ -1974,11 +1392,11 @@ var commandKeyBindings = [
|
|
1974
1392
|
];
|
1975
1393
|
|
1976
1394
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
1977
|
-
import { EditorView as
|
1395
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
1978
1396
|
|
1979
1397
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
1980
1398
|
import { RangeSetBuilder } from "@codemirror/state";
|
1981
|
-
import { Decoration as Decoration3, EditorView as
|
1399
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
1982
1400
|
var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
1983
1401
|
constructor() {
|
1984
1402
|
this.deco = Decoration3.none;
|
@@ -2002,7 +1420,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
2002
1420
|
}
|
2003
1421
|
}, {
|
2004
1422
|
provide: (plugin) => [
|
2005
|
-
|
1423
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
2006
1424
|
]
|
2007
1425
|
});
|
2008
1426
|
var CommandHint = class extends WidgetType2 {
|
@@ -2121,10 +1539,10 @@ var command = (options = {}) => {
|
|
2121
1539
|
options.onHint ? hintViewPlugin({
|
2122
1540
|
onHint: options.onHint
|
2123
1541
|
}) : [],
|
2124
|
-
|
1542
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
2125
1543
|
return focusing ? closeEffect.of(null) : null;
|
2126
1544
|
}),
|
2127
|
-
|
1545
|
+
EditorView6.theme({
|
2128
1546
|
".cm-tooltip": {
|
2129
1547
|
background: "transparent"
|
2130
1548
|
}
|
@@ -2135,7 +1553,7 @@ var command = (options = {}) => {
|
|
2135
1553
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
2136
1554
|
import { invertedEffects } from "@codemirror/commands";
|
2137
1555
|
import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
2138
|
-
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as
|
1556
|
+
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
2139
1557
|
import sortBy from "lodash.sortby";
|
2140
1558
|
import { useEffect, useMemo as useMemo2 } from "react";
|
2141
1559
|
import { debounce as debounce2 } from "@dxos/async";
|
@@ -2144,7 +1562,7 @@ import { isNonNullable } from "@dxos/util";
|
|
2144
1562
|
|
2145
1563
|
// packages/ui/react-ui-editor/src/extensions/selection.ts
|
2146
1564
|
import { Transaction } from "@codemirror/state";
|
2147
|
-
import { EditorView as
|
1565
|
+
import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
|
2148
1566
|
import { debounce } from "@dxos/async";
|
2149
1567
|
import { invariant as invariant3 } from "@dxos/invariant";
|
2150
1568
|
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
@@ -2155,7 +1573,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
2155
1573
|
return {
|
2156
1574
|
selection,
|
2157
1575
|
scrollIntoView: !scrollTo,
|
2158
|
-
effects: scrollTo ?
|
1576
|
+
effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
|
2159
1577
|
yMargin: 96
|
2160
1578
|
}) : void 0,
|
2161
1579
|
annotations: Transaction.userEvent.of(stateRestoreAnnotation)
|
@@ -2197,7 +1615,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
2197
1615
|
// setStateDebounced(id, {});
|
2198
1616
|
// },
|
2199
1617
|
// }),
|
2200
|
-
|
1618
|
+
EditorView7.updateListener.of(({ view, transactions }) => {
|
2201
1619
|
const id = view.state.facet(documentId);
|
2202
1620
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
2203
1621
|
return;
|
@@ -2278,7 +1696,7 @@ var commentsState = StateField4.define({
|
|
2278
1696
|
return value;
|
2279
1697
|
}
|
2280
1698
|
});
|
2281
|
-
var styles3 =
|
1699
|
+
var styles3 = EditorView8.theme({
|
2282
1700
|
".cm-comment, .cm-comment-current": {
|
2283
1701
|
margin: "0 -3px",
|
2284
1702
|
padding: "3px",
|
@@ -2298,7 +1716,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
2298
1716
|
"data-comment-id": id
|
2299
1717
|
}
|
2300
1718
|
});
|
2301
|
-
var commentsDecorations =
|
1719
|
+
var commentsDecorations = EditorView8.decorations.compute([
|
2302
1720
|
commentsState
|
2303
1721
|
], (state) => {
|
2304
1722
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
@@ -2321,7 +1739,7 @@ var commentsDecorations = EditorView9.decorations.compute([
|
|
2321
1739
|
return Decoration4.set(decorations);
|
2322
1740
|
});
|
2323
1741
|
var commentClickedEffect = StateEffect3.define();
|
2324
|
-
var handleCommentClick =
|
1742
|
+
var handleCommentClick = EditorView8.domEventHandlers({
|
2325
1743
|
click: (event, view) => {
|
2326
1744
|
let target = event.target;
|
2327
1745
|
const editorRoot = view.dom;
|
@@ -2360,7 +1778,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2360
1778
|
}
|
2361
1779
|
};
|
2362
1780
|
return [
|
2363
|
-
|
1781
|
+
EditorView8.domEventHandlers({
|
2364
1782
|
cut: handleTrack,
|
2365
1783
|
copy: handleTrack
|
2366
1784
|
}),
|
@@ -2382,7 +1800,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2382
1800
|
return effects;
|
2383
1801
|
}),
|
2384
1802
|
// Handle paste or the undo of comment deletion.
|
2385
|
-
|
1803
|
+
EditorView8.updateListener.of((update2) => {
|
2386
1804
|
const restore = [];
|
2387
1805
|
for (let i = 0; i < update2.transactions.length; i++) {
|
2388
1806
|
const tr = update2.transactions[i];
|
@@ -2441,7 +1859,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
2441
1859
|
var restoreCommentEffect = StateEffect3.define({
|
2442
1860
|
map: mapTrackedComment
|
2443
1861
|
});
|
2444
|
-
var
|
1862
|
+
var createComment = (view) => {
|
2445
1863
|
const options = view.state.facet(optionsFacet);
|
2446
1864
|
const { from, to } = view.state.selection.main;
|
2447
1865
|
if (from === to) {
|
@@ -2486,7 +1904,7 @@ var comments = (options = {}) => {
|
|
2486
1904
|
options.onCreate && keymap5.of([
|
2487
1905
|
{
|
2488
1906
|
key: shortcut,
|
2489
|
-
run: callbackWrapper(
|
1907
|
+
run: callbackWrapper(createComment)
|
2490
1908
|
}
|
2491
1909
|
]),
|
2492
1910
|
//
|
@@ -2524,7 +1942,7 @@ var comments = (options = {}) => {
|
|
2524
1942
|
//
|
2525
1943
|
// Track deleted ranges and update ranges for decorations.
|
2526
1944
|
//
|
2527
|
-
|
1945
|
+
EditorView8.updateListener.of(({ view, state, changes }) => {
|
2528
1946
|
let mod = false;
|
2529
1947
|
const { comments: comments2, ...value } = state.field(commentsState);
|
2530
1948
|
changes.iterChanges((from, to, from2, to2) => {
|
@@ -2556,7 +1974,7 @@ var comments = (options = {}) => {
|
|
2556
1974
|
//
|
2557
1975
|
// Track selection/proximity.
|
2558
1976
|
//
|
2559
|
-
|
1977
|
+
EditorView8.updateListener.of(({ view, state }) => {
|
2560
1978
|
let min = Infinity;
|
2561
1979
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
2562
1980
|
const { head } = state.selection.main;
|
@@ -2610,7 +2028,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
2610
2028
|
anchor: range.from
|
2611
2029
|
} : void 0,
|
2612
2030
|
effects: [
|
2613
|
-
needsScroll ?
|
2031
|
+
needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
|
2614
2032
|
y: "center"
|
2615
2033
|
} : void 0) : [],
|
2616
2034
|
needsSelectionUpdate ? setSelection.of({
|
@@ -2662,7 +2080,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
|
|
2662
2080
|
}
|
2663
2081
|
});
|
2664
2082
|
var useCommentState = (state) => {
|
2665
|
-
return useMemo2(() =>
|
2083
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2666
2084
|
if (update2.docChanged || update2.selectionSet) {
|
2667
2085
|
state.comment = selectionOverlapsComment(update2.state);
|
2668
2086
|
state.selection = hasActiveSelection(update2.state);
|
@@ -2686,7 +2104,7 @@ var useComments = (view, id, comments2) => {
|
|
2686
2104
|
});
|
2687
2105
|
};
|
2688
2106
|
var useCommentClickListener = (onCommentClick) => {
|
2689
|
-
return useMemo2(() =>
|
2107
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2690
2108
|
update2.transactions.forEach((transaction) => {
|
2691
2109
|
transaction.effects.forEach((effect) => {
|
2692
2110
|
if (effect.is(commentClickedEffect)) {
|
@@ -2702,9 +2120,9 @@ var useCommentClickListener = (onCommentClick) => {
|
|
2702
2120
|
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
2703
2121
|
import { syntaxTree } from "@codemirror/language";
|
2704
2122
|
import { StateField as StateField5 } from "@codemirror/state";
|
2705
|
-
var debugNodeLogger = (
|
2123
|
+
var debugNodeLogger = (log9 = console.log) => {
|
2706
2124
|
const logTokens = (state) => syntaxTree(state).iterate({
|
2707
|
-
enter: (node) =>
|
2125
|
+
enter: (node) => log9(node.type)
|
2708
2126
|
});
|
2709
2127
|
return StateField5.define({
|
2710
2128
|
create: (state) => logTokens(state),
|
@@ -2713,8 +2131,8 @@ var debugNodeLogger = (log8 = console.log) => {
|
|
2713
2131
|
};
|
2714
2132
|
|
2715
2133
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2716
|
-
import { dropCursor, EditorView as
|
2717
|
-
var styles4 =
|
2134
|
+
import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
|
2135
|
+
var styles4 = EditorView9.theme({
|
2718
2136
|
".cm-dropCursor": {
|
2719
2137
|
borderLeft: "2px solid var(--dx-accentText)",
|
2720
2138
|
color: "var(--dx-accentText)",
|
@@ -2728,7 +2146,7 @@ var dropFile = (options = {}) => {
|
|
2728
2146
|
return [
|
2729
2147
|
styles4,
|
2730
2148
|
dropCursor(),
|
2731
|
-
|
2149
|
+
EditorView9.domEventHandlers({
|
2732
2150
|
drop: (event, view) => {
|
2733
2151
|
event.preventDefault();
|
2734
2152
|
const files = event.dataTransfer?.files;
|
@@ -2755,7 +2173,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
|
|
2755
2173
|
import { searchKeymap } from "@codemirror/search";
|
2756
2174
|
import { EditorState } from "@codemirror/state";
|
2757
2175
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2758
|
-
import { EditorView as
|
2176
|
+
import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2759
2177
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
2760
2178
|
import merge from "lodash.merge";
|
2761
2179
|
import { generateName } from "@dxos/display-name";
|
@@ -2764,7 +2182,7 @@ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
2764
2182
|
|
2765
2183
|
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2766
2184
|
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2767
|
-
import { EditorView as
|
2185
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
2768
2186
|
var focusEffect = StateEffect4.define();
|
2769
2187
|
var focusField = StateField6.define({
|
2770
2188
|
create: () => false,
|
@@ -2779,7 +2197,7 @@ var focusField = StateField6.define({
|
|
2779
2197
|
});
|
2780
2198
|
var focus = [
|
2781
2199
|
focusField,
|
2782
|
-
|
2200
|
+
EditorView10.domEventHandlers({
|
2783
2201
|
focus: (event, view) => {
|
2784
2202
|
setTimeout(() => view.dispatch({
|
2785
2203
|
effects: focusEffect.of(true)
|
@@ -2793,6 +2211,241 @@ var focus = [
|
|
2793
2211
|
})
|
2794
2212
|
];
|
2795
2213
|
|
2214
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
2215
|
+
import { mx } from "@dxos/react-ui-theme";
|
2216
|
+
var headings = {
|
2217
|
+
1: "text-4xl",
|
2218
|
+
2: "text-3xl",
|
2219
|
+
3: "text-2xl",
|
2220
|
+
4: "text-xl",
|
2221
|
+
5: "text-lg",
|
2222
|
+
6: ""
|
2223
|
+
};
|
2224
|
+
var theme = {
|
2225
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
2226
|
+
codeMark: "font-mono text-primary-500",
|
2227
|
+
mark: "opacity-50",
|
2228
|
+
heading: (level) => {
|
2229
|
+
return mx(headings[level], "dark:text-primary-400");
|
2230
|
+
}
|
2231
|
+
};
|
2232
|
+
|
2233
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
2234
|
+
import get from "lodash.get";
|
2235
|
+
import { tokens } from "@dxos/react-ui-theme";
|
2236
|
+
var getToken = (path, defaultValue) => {
|
2237
|
+
const value = get(tokens, path, defaultValue);
|
2238
|
+
return value?.toString() ?? "";
|
2239
|
+
};
|
2240
|
+
var fontBody = getToken("fontFamily.body");
|
2241
|
+
var fontMono = getToken("fontFamily.mono");
|
2242
|
+
|
2243
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
2244
|
+
var defaultTheme = {
|
2245
|
+
"&": {},
|
2246
|
+
"&.cm-focused": {
|
2247
|
+
outline: "none"
|
2248
|
+
},
|
2249
|
+
/**
|
2250
|
+
* Scroller
|
2251
|
+
*/
|
2252
|
+
".cm-scroller": {
|
2253
|
+
overflowY: "auto"
|
2254
|
+
},
|
2255
|
+
/**
|
2256
|
+
* Content
|
2257
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
2258
|
+
*/
|
2259
|
+
".cm-content": {
|
2260
|
+
padding: "unset",
|
2261
|
+
fontFamily: fontBody,
|
2262
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
2263
|
+
fontSize: "16px",
|
2264
|
+
lineHeight: 1.5,
|
2265
|
+
color: "unset"
|
2266
|
+
},
|
2267
|
+
/**
|
2268
|
+
* Gutters
|
2269
|
+
* NOTE: Gutters should have the same top margin as the content.
|
2270
|
+
*/
|
2271
|
+
".cm-gutters": {
|
2272
|
+
borderRight: "none",
|
2273
|
+
background: "transparent"
|
2274
|
+
},
|
2275
|
+
".cm-gutter": {},
|
2276
|
+
".cm-gutter.cm-lineNumbers": {
|
2277
|
+
paddingRight: "4px",
|
2278
|
+
borderRight: "1px solid var(--dx-separator)"
|
2279
|
+
},
|
2280
|
+
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
2281
|
+
minWidth: "40px",
|
2282
|
+
alignContent: "center"
|
2283
|
+
},
|
2284
|
+
/**
|
2285
|
+
* Height is set to match the corresponding line.
|
2286
|
+
*/
|
2287
|
+
".cm-gutterElement": {
|
2288
|
+
alignItems: "center",
|
2289
|
+
fontSize: "12px"
|
2290
|
+
},
|
2291
|
+
/**
|
2292
|
+
* Line.
|
2293
|
+
*/
|
2294
|
+
".cm-line": {
|
2295
|
+
paddingInline: 0
|
2296
|
+
},
|
2297
|
+
".cm-activeLine": {
|
2298
|
+
background: "var(--dx-cmActiveLine)"
|
2299
|
+
},
|
2300
|
+
/**
|
2301
|
+
* Cursor (layer).
|
2302
|
+
*/
|
2303
|
+
".cm-cursor, .cm-dropCursor": {
|
2304
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
2305
|
+
},
|
2306
|
+
".cm-placeholder": {
|
2307
|
+
color: "var(--dx-subdued)"
|
2308
|
+
},
|
2309
|
+
/**
|
2310
|
+
* Selection (layer).
|
2311
|
+
*/
|
2312
|
+
".cm-selectionBackground": {
|
2313
|
+
background: "var(--dx-cmSelection)"
|
2314
|
+
},
|
2315
|
+
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
2316
|
+
background: "var(--dx-cmFocusedSelection)"
|
2317
|
+
},
|
2318
|
+
/**
|
2319
|
+
* Search.
|
2320
|
+
* NOTE: Matches comment.
|
2321
|
+
*/
|
2322
|
+
".cm-searchMatch": {
|
2323
|
+
margin: "0 -3px",
|
2324
|
+
padding: "3px",
|
2325
|
+
borderRadius: "3px",
|
2326
|
+
background: "var(--dx-cmHighlightSurface)",
|
2327
|
+
color: "var(--dx-cmHighlight)"
|
2328
|
+
},
|
2329
|
+
".cm-searchMatch-selected": {
|
2330
|
+
textDecoration: "underline"
|
2331
|
+
},
|
2332
|
+
/**
|
2333
|
+
* Link.
|
2334
|
+
*/
|
2335
|
+
".cm-link": {
|
2336
|
+
textDecorationLine: "underline",
|
2337
|
+
textDecorationThickness: "1px",
|
2338
|
+
textDecorationColor: "var(--dx-separator)",
|
2339
|
+
textUnderlineOffset: "2px",
|
2340
|
+
borderRadius: ".125rem"
|
2341
|
+
},
|
2342
|
+
".cm-link > span": {
|
2343
|
+
color: "var(--dx-accentText)"
|
2344
|
+
},
|
2345
|
+
/**
|
2346
|
+
* Tooltip.
|
2347
|
+
*/
|
2348
|
+
".cm-tooltip": {
|
2349
|
+
background: "var(--dx-baseSurface)"
|
2350
|
+
},
|
2351
|
+
".cm-tooltip-below": {},
|
2352
|
+
/**
|
2353
|
+
* Autocomplete.
|
2354
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
2355
|
+
*/
|
2356
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
2357
|
+
marginTop: "4px",
|
2358
|
+
marginLeft: "-3px"
|
2359
|
+
},
|
2360
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
2361
|
+
maxHeight: "20em"
|
2362
|
+
},
|
2363
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
2364
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
2365
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
2366
|
+
paddingLeft: "4px !important",
|
2367
|
+
borderBottom: "none !important",
|
2368
|
+
color: "var(--dx-accentText)"
|
2369
|
+
},
|
2370
|
+
".cm-tooltip.cm-completionInfo": {
|
2371
|
+
width: "360px !important",
|
2372
|
+
margin: "-10px 1px 0 1px",
|
2373
|
+
padding: "8px !important",
|
2374
|
+
borderColor: "var(--dx-separator)"
|
2375
|
+
},
|
2376
|
+
".cm-completionIcon": {
|
2377
|
+
display: "none"
|
2378
|
+
},
|
2379
|
+
".cm-completionLabel": {
|
2380
|
+
fontFamily: fontBody
|
2381
|
+
},
|
2382
|
+
".cm-completionMatchedText": {
|
2383
|
+
textDecoration: "none !important",
|
2384
|
+
opacity: 0.5
|
2385
|
+
},
|
2386
|
+
/**
|
2387
|
+
* Panels
|
2388
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
2389
|
+
*
|
2390
|
+
* Find/replace panel.
|
2391
|
+
* <div class="cm-announced">...</div>
|
2392
|
+
* <div class="cm-scroller">...</div>
|
2393
|
+
* <div class="cm-panels cm-panels-bottom">
|
2394
|
+
* <div class="cm-search cm-panel">
|
2395
|
+
* <input class="cm-textfield" />
|
2396
|
+
* <button class="cm-button">...</button>
|
2397
|
+
* <label><input type="checkbox" />...</label>
|
2398
|
+
* </div>
|
2399
|
+
* </div
|
2400
|
+
*/
|
2401
|
+
// TODO(burdon): Implement custom panel (with icon buttons).
|
2402
|
+
".cm-panels": {},
|
2403
|
+
".cm-panel": {
|
2404
|
+
fontFamily: fontBody,
|
2405
|
+
backgroundColor: "var(--surface-bg)"
|
2406
|
+
},
|
2407
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
2408
|
+
color: "var(--dx-subdued)",
|
2409
|
+
fontFamily: fontBody,
|
2410
|
+
fontSize: "14px",
|
2411
|
+
all: "unset",
|
2412
|
+
margin: "3px !important",
|
2413
|
+
padding: "2px 6px !important",
|
2414
|
+
outline: "1px solid transparent"
|
2415
|
+
},
|
2416
|
+
".cm-panel input, .cm-panel button": {
|
2417
|
+
backgroundColor: "var(--dx-input)"
|
2418
|
+
},
|
2419
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
2420
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
2421
|
+
},
|
2422
|
+
".cm-panel label": {
|
2423
|
+
display: "inline-flex",
|
2424
|
+
alignItems: "center",
|
2425
|
+
cursor: "pointer"
|
2426
|
+
},
|
2427
|
+
".cm-panel input.cm-textfield": {},
|
2428
|
+
".cm-panel input[type=checkbox]": {
|
2429
|
+
width: "8px",
|
2430
|
+
height: "8px",
|
2431
|
+
marginRight: "6px !important",
|
2432
|
+
padding: "2px !important",
|
2433
|
+
color: "var(--dx-accentFocusIndicator)"
|
2434
|
+
},
|
2435
|
+
".cm-panel button": {
|
2436
|
+
"&:hover": {
|
2437
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
2438
|
+
},
|
2439
|
+
"&:active": {
|
2440
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
2441
|
+
}
|
2442
|
+
},
|
2443
|
+
".cm-panel.cm-search": {
|
2444
|
+
padding: "4px",
|
2445
|
+
borderTop: "1px solid var(--dx-separator)"
|
2446
|
+
}
|
2447
|
+
};
|
2448
|
+
|
2796
2449
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2797
2450
|
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
2798
2451
|
var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
|
@@ -2817,7 +2470,7 @@ var createBasicExtensions = (_props) => {
|
|
2817
2470
|
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
2818
2471
|
return [
|
2819
2472
|
// NOTE: Doesn't catch errors in keymap functions.
|
2820
|
-
|
2473
|
+
EditorView11.exceptionSink.of((err) => {
|
2821
2474
|
log5.catch(err, void 0, {
|
2822
2475
|
F: __dxlog_file8,
|
2823
2476
|
L: 96,
|
@@ -2832,12 +2485,12 @@ var createBasicExtensions = (_props) => {
|
|
2832
2485
|
props.drawSelection && drawSelection({
|
2833
2486
|
cursorBlinkRate: 1200
|
2834
2487
|
}),
|
2835
|
-
props.editable !== void 0 &&
|
2488
|
+
props.editable !== void 0 && EditorView11.editable.of(props.editable),
|
2836
2489
|
props.focus && focus,
|
2837
2490
|
props.highlightActiveLine && highlightActiveLine(),
|
2838
2491
|
props.history && history(),
|
2839
2492
|
props.lineNumbers && lineNumbers(),
|
2840
|
-
props.lineWrapping &&
|
2493
|
+
props.lineWrapping && EditorView11.lineWrapping,
|
2841
2494
|
props.placeholder && placeholder(props.placeholder),
|
2842
2495
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
2843
2496
|
props.scrollPastEnd && scrollPastEnd(),
|
@@ -2874,14 +2527,14 @@ var defaultThemeSlots = {
|
|
2874
2527
|
var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
|
2875
2528
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
2876
2529
|
return [
|
2877
|
-
|
2878
|
-
|
2530
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
2531
|
+
EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
2879
2532
|
// https://github.com/codemirror/theme-one-dark
|
2880
2533
|
_syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
|
2881
|
-
slots.editor?.className &&
|
2534
|
+
slots.editor?.className && EditorView11.editorAttributes.of({
|
2882
2535
|
class: slots.editor.className
|
2883
2536
|
}),
|
2884
|
-
slots.content?.className &&
|
2537
|
+
slots.content?.className && EditorView11.contentAttributes.of({
|
2885
2538
|
class: slots.content.className
|
2886
2539
|
})
|
2887
2540
|
].filter(isNotFalsy3);
|
@@ -2910,8 +2563,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2910
2563
|
|
2911
2564
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
2912
2565
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
2913
|
-
import { EditorView as
|
2914
|
-
import
|
2566
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
2567
|
+
import React2 from "react";
|
2915
2568
|
import { Icon } from "@dxos/react-ui";
|
2916
2569
|
var folding = (_props = {}) => [
|
2917
2570
|
codeFolding({
|
@@ -2924,7 +2577,7 @@ var folding = (_props = {}) => [
|
|
2924
2577
|
const el = createElement("div", {
|
2925
2578
|
className: "flex h-full items-center"
|
2926
2579
|
});
|
2927
|
-
return renderRoot(el, /* @__PURE__ */
|
2580
|
+
return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
|
2928
2581
|
icon: "ph--caret-right--bold",
|
2929
2582
|
size: 3,
|
2930
2583
|
classNames: [
|
@@ -2934,7 +2587,7 @@ var folding = (_props = {}) => [
|
|
2934
2587
|
}));
|
2935
2588
|
}
|
2936
2589
|
}),
|
2937
|
-
|
2590
|
+
EditorView12.theme({
|
2938
2591
|
".cm-foldGutter": {
|
2939
2592
|
opacity: 0.3,
|
2940
2593
|
transition: "opacity 0.3s",
|
@@ -2947,14 +2600,14 @@ var folding = (_props = {}) => [
|
|
2947
2600
|
];
|
2948
2601
|
|
2949
2602
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
2950
|
-
import { EditorView as
|
2603
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
2951
2604
|
var listener = ({ onFocus, onChange }) => {
|
2952
2605
|
const extensions = [];
|
2953
|
-
onFocus && extensions.push(
|
2606
|
+
onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
|
2954
2607
|
onFocus(focusing);
|
2955
2608
|
return null;
|
2956
2609
|
}));
|
2957
|
-
onChange && extensions.push(
|
2610
|
+
onChange && extensions.push(EditorView13.updateListener.of((update2) => {
|
2958
2611
|
onChange(update2.state.doc.toString(), update2.state.facet(documentId));
|
2959
2612
|
}));
|
2960
2613
|
return extensions;
|
@@ -2964,7 +2617,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
2964
2617
|
import { snippet } from "@codemirror/autocomplete";
|
2965
2618
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
2966
2619
|
import { EditorSelection } from "@codemirror/state";
|
2967
|
-
import { EditorView as
|
2620
|
+
import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
|
2968
2621
|
import { useMemo as useMemo3 } from "react";
|
2969
2622
|
var formattingEquals = (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;
|
2970
2623
|
var Inline;
|
@@ -4053,7 +3706,7 @@ var getFormatting = (state) => {
|
|
4053
3706
|
};
|
4054
3707
|
};
|
4055
3708
|
var useFormattingState = (state) => {
|
4056
|
-
return useMemo3(() =>
|
3709
|
+
return useMemo3(() => EditorView14.updateListener.of((update2) => {
|
4057
3710
|
if (update2.docChanged || update2.selectionSet) {
|
4058
3711
|
Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
|
4059
3712
|
state[key] = active;
|
@@ -4101,7 +3754,7 @@ var processEditorPayload = (view, { type, data }) => {
|
|
4101
3754
|
})(view);
|
4102
3755
|
break;
|
4103
3756
|
case "comment":
|
4104
|
-
|
3757
|
+
createComment(view);
|
4105
3758
|
break;
|
4106
3759
|
}
|
4107
3760
|
requestAnimationFrame(() => {
|
@@ -4365,9 +4018,9 @@ var convertTreeToJson = (state) => {
|
|
4365
4018
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
4366
4019
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
4367
4020
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
|
4368
|
-
import { EditorView as
|
4021
|
+
import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
4369
4022
|
import { invariant as invariant4 } from "@dxos/invariant";
|
4370
|
-
import { mx as
|
4023
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
4371
4024
|
|
4372
4025
|
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
4373
4026
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
@@ -4417,11 +4070,11 @@ var adjustChanges = () => {
|
|
4417
4070
|
if (url) {
|
4418
4071
|
const node = tree.resolveInner(fromA, -1);
|
4419
4072
|
const invalidPositions = /* @__PURE__ */ new Set([
|
4420
|
-
"Link",
|
4421
|
-
"LinkMark",
|
4422
4073
|
"Code",
|
4423
4074
|
"CodeText",
|
4424
4075
|
"FencedCode",
|
4076
|
+
"Link",
|
4077
|
+
"LinkMark",
|
4425
4078
|
"URL"
|
4426
4079
|
]);
|
4427
4080
|
if (!invalidPositions.has(node?.name)) {
|
@@ -4516,7 +4169,7 @@ var getValidUrl = (str) => {
|
|
4516
4169
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
4517
4170
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
4518
4171
|
import { StateField as StateField8 } from "@codemirror/state";
|
4519
|
-
import { Decoration as Decoration5, EditorView as
|
4172
|
+
import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
|
4520
4173
|
var image = (_options = {}) => {
|
4521
4174
|
return [
|
4522
4175
|
StateField8.define({
|
@@ -4544,7 +4197,7 @@ var image = (_options = {}) => {
|
|
4544
4197
|
add: buildDecorations(from, to, tr.state)
|
4545
4198
|
});
|
4546
4199
|
},
|
4547
|
-
provide: (field) =>
|
4200
|
+
provide: (field) => EditorView15.decorations.from(field)
|
4548
4201
|
})
|
4549
4202
|
];
|
4550
4203
|
};
|
@@ -4604,10 +4257,10 @@ var ImageWidget = class extends WidgetType3 {
|
|
4604
4257
|
};
|
4605
4258
|
|
4606
4259
|
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
4607
|
-
import { EditorView as
|
4260
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
4608
4261
|
var bulletListIndentationWidth = 24;
|
4609
4262
|
var orderedListIndentationWidth = 36;
|
4610
|
-
var formattingStyles =
|
4263
|
+
var formattingStyles = EditorView16.theme({
|
4611
4264
|
/**
|
4612
4265
|
* Horizontal rule.
|
4613
4266
|
*/
|
@@ -4654,11 +4307,11 @@ var formattingStyles = EditorView17.theme({
|
|
4654
4307
|
background: "var(--dx-cmCodeblock)",
|
4655
4308
|
paddingInline: "1rem !important"
|
4656
4309
|
},
|
4657
|
-
"& .cm-codeblock-
|
4310
|
+
"& .cm-codeblock-start": {
|
4658
4311
|
borderTopLeftRadius: ".25rem",
|
4659
4312
|
borderTopRightRadius: ".25rem"
|
4660
4313
|
},
|
4661
|
-
"& .cm-codeblock-
|
4314
|
+
"& .cm-codeblock-end": {
|
4662
4315
|
borderBottomLeftRadius: ".25rem",
|
4663
4316
|
borderBottomRightRadius: ".25rem"
|
4664
4317
|
},
|
@@ -4728,12 +4381,12 @@ var formattingStyles = EditorView17.theme({
|
|
4728
4381
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
4729
4382
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
4730
4383
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
|
4731
|
-
import { Decoration as Decoration6, EditorView as
|
4384
|
+
import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
|
4732
4385
|
var table = (options = {}) => {
|
4733
4386
|
return StateField9.define({
|
4734
4387
|
create: (state) => update(state, options),
|
4735
4388
|
update: (_, tr) => update(tr.state, options),
|
4736
|
-
provide: (field) =>
|
4389
|
+
provide: (field) => EditorView17.decorations.from(field)
|
4737
4390
|
});
|
4738
4391
|
};
|
4739
4392
|
var update = (state, _options) => {
|
@@ -4919,16 +4572,16 @@ var TextWidget = class extends WidgetType5 {
|
|
4919
4572
|
};
|
4920
4573
|
var hide = Decoration7.replace({});
|
4921
4574
|
var blockQuote = Decoration7.line({
|
4922
|
-
class:
|
4575
|
+
class: "cm-blockquote"
|
4923
4576
|
});
|
4924
4577
|
var fencedCodeLine = Decoration7.line({
|
4925
|
-
class:
|
4578
|
+
class: "cm-code cm-codeblock-line"
|
4926
4579
|
});
|
4927
4580
|
var fencedCodeLineFirst = Decoration7.line({
|
4928
|
-
class:
|
4581
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-start")
|
4929
4582
|
});
|
4930
4583
|
var fencedCodeLineLast = Decoration7.line({
|
4931
|
-
class:
|
4584
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-end")
|
4932
4585
|
});
|
4933
4586
|
var commentBlockLine = fencedCodeLine;
|
4934
4587
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
@@ -4983,665 +4636,1317 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
4983
4636
|
} else {
|
4984
4637
|
headerLevels.splice(level);
|
4985
4638
|
}
|
4986
|
-
return headerLevels.slice(0, level);
|
4987
|
-
};
|
4988
|
-
const listLevels = [];
|
4989
|
-
const enterList = (node) => {
|
4990
|
-
listLevels.push({
|
4991
|
-
type: node.name,
|
4992
|
-
from: node.from,
|
4993
|
-
to: node.to,
|
4994
|
-
level: listLevels.length,
|
4995
|
-
number: 0
|
4639
|
+
return headerLevels.slice(0, level);
|
4640
|
+
};
|
4641
|
+
const listLevels = [];
|
4642
|
+
const enterList = (node) => {
|
4643
|
+
listLevels.push({
|
4644
|
+
type: node.name,
|
4645
|
+
from: node.from,
|
4646
|
+
to: node.to,
|
4647
|
+
level: listLevels.length,
|
4648
|
+
number: 0
|
4649
|
+
});
|
4650
|
+
};
|
4651
|
+
const leaveList = () => {
|
4652
|
+
listLevels.pop();
|
4653
|
+
};
|
4654
|
+
const getCurrentListLevel = () => {
|
4655
|
+
invariant4(listLevels.length, void 0, {
|
4656
|
+
F: __dxlog_file9,
|
4657
|
+
L: 201,
|
4658
|
+
S: void 0,
|
4659
|
+
A: [
|
4660
|
+
"listLevels.length",
|
4661
|
+
""
|
4662
|
+
]
|
4663
|
+
});
|
4664
|
+
return listLevels[listLevels.length - 1];
|
4665
|
+
};
|
4666
|
+
const enterNode = (node) => {
|
4667
|
+
switch (node.name) {
|
4668
|
+
// ATXHeading > HeaderMark > Paragraph
|
4669
|
+
// NOTE: Numbering requires processing the entire document since otherwise only the visible range will be
|
4670
|
+
// processed and the numbering will be incorrect.
|
4671
|
+
case "ATXHeading1":
|
4672
|
+
case "ATXHeading2":
|
4673
|
+
case "ATXHeading3":
|
4674
|
+
case "ATXHeading4":
|
4675
|
+
case "ATXHeading5":
|
4676
|
+
case "ATXHeading6": {
|
4677
|
+
const level = parseInt(node.name["ATXHeading".length]);
|
4678
|
+
const headers = getHeaderLevels(node, level);
|
4679
|
+
if (options.numberedHeadings?.from !== void 0) {
|
4680
|
+
const header = headers[level - 1];
|
4681
|
+
if (header) {
|
4682
|
+
header.number++;
|
4683
|
+
}
|
4684
|
+
}
|
4685
|
+
const editing = editingRange(state, node, focus2);
|
4686
|
+
if (editing) {
|
4687
|
+
break;
|
4688
|
+
}
|
4689
|
+
const mark = node.node.firstChild;
|
4690
|
+
if (mark?.name === "HeaderMark") {
|
4691
|
+
const { from, to = 6 } = options.numberedHeadings ?? {};
|
4692
|
+
const text = view.state.sliceDoc(node.from, node.to);
|
4693
|
+
const len = text.match(/[#\s]+/)[0].length;
|
4694
|
+
if (!from || level < from || level > to) {
|
4695
|
+
atomicDeco.add(mark.from, mark.from + len, hide);
|
4696
|
+
} else {
|
4697
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
4698
|
+
if (num.length) {
|
4699
|
+
atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
|
4700
|
+
widget: new TextWidget(num, theme.heading(level))
|
4701
|
+
}));
|
4702
|
+
}
|
4703
|
+
}
|
4704
|
+
}
|
4705
|
+
return false;
|
4706
|
+
}
|
4707
|
+
//
|
4708
|
+
// Lists.
|
4709
|
+
// [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?
|
4710
|
+
//
|
4711
|
+
case "BulletList":
|
4712
|
+
case "OrderedList": {
|
4713
|
+
enterList(node);
|
4714
|
+
break;
|
4715
|
+
}
|
4716
|
+
case "ListItem": {
|
4717
|
+
const line = state.doc.lineAt(node.from);
|
4718
|
+
const list = getCurrentListLevel();
|
4719
|
+
const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
|
4720
|
+
const offset = (options?.listPaddingLeft ?? 0) + ((list.level ?? 0) + 1) * width;
|
4721
|
+
if (node.from === line.to - 1) {
|
4722
|
+
return false;
|
4723
|
+
}
|
4724
|
+
deco.add(line.from, line.from, Decoration7.line({
|
4725
|
+
class: "cm-list-item",
|
4726
|
+
attributes: {
|
4727
|
+
style: `padding-left: ${offset}px; text-indent: -${width}px;`
|
4728
|
+
}
|
4729
|
+
}));
|
4730
|
+
break;
|
4731
|
+
}
|
4732
|
+
case "ListMark": {
|
4733
|
+
const list = getCurrentListLevel();
|
4734
|
+
const next = tree.resolve(node.to + 1, 1);
|
4735
|
+
if (next?.name === "TaskMarker") {
|
4736
|
+
break;
|
4737
|
+
}
|
4738
|
+
const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
|
4739
|
+
const line = state.doc.lineAt(node.from);
|
4740
|
+
const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
|
4741
|
+
atomicDeco.add(line.from, to, Decoration7.replace({
|
4742
|
+
widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
|
4743
|
+
}));
|
4744
|
+
break;
|
4745
|
+
}
|
4746
|
+
case "TaskMarker": {
|
4747
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
4748
|
+
const line = state.doc.lineAt(node.from);
|
4749
|
+
const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
|
4750
|
+
atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
|
4751
|
+
break;
|
4752
|
+
}
|
4753
|
+
//
|
4754
|
+
// Blockquote > QuoteMark > Paragraph
|
4755
|
+
//
|
4756
|
+
case "Blockquote": {
|
4757
|
+
const editing = editingRange(state, node, focus2);
|
4758
|
+
const quoteMark = node.node.getChild("QuoteMark");
|
4759
|
+
const paragraph = node.node.getChild("Paragraph");
|
4760
|
+
if (!editing && quoteMark && paragraph) {
|
4761
|
+
atomicDeco.add(quoteMark.from, paragraph.from, hide);
|
4762
|
+
}
|
4763
|
+
for (const block of view.viewportLineBlocks) {
|
4764
|
+
if (block.to < node.from) {
|
4765
|
+
continue;
|
4766
|
+
}
|
4767
|
+
if (block.from > node.to) {
|
4768
|
+
break;
|
4769
|
+
}
|
4770
|
+
deco.add(block.from, block.from, blockQuote);
|
4771
|
+
}
|
4772
|
+
break;
|
4773
|
+
}
|
4774
|
+
//
|
4775
|
+
// CommentBlock
|
4776
|
+
//
|
4777
|
+
case "CommentBlock": {
|
4778
|
+
const editing = editingRange(state, node, focus2);
|
4779
|
+
for (const block of view.viewportLineBlocks) {
|
4780
|
+
if (block.to < node.from) {
|
4781
|
+
continue;
|
4782
|
+
}
|
4783
|
+
if (block.from > node.to) {
|
4784
|
+
break;
|
4785
|
+
}
|
4786
|
+
const isFirst = block.from <= node.from;
|
4787
|
+
const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
|
4788
|
+
deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
|
4789
|
+
if (!editing && (isFirst || isLast)) {
|
4790
|
+
atomicDeco.add(block.from, block.to, hide);
|
4791
|
+
}
|
4792
|
+
}
|
4793
|
+
break;
|
4794
|
+
}
|
4795
|
+
//
|
4796
|
+
// FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
|
4797
|
+
//
|
4798
|
+
case "FencedCode": {
|
4799
|
+
for (const block of view.viewportLineBlocks) {
|
4800
|
+
if (block.to < node.from) {
|
4801
|
+
continue;
|
4802
|
+
}
|
4803
|
+
if (block.from > node.to) {
|
4804
|
+
break;
|
4805
|
+
}
|
4806
|
+
const first = block.from <= node.from;
|
4807
|
+
const last = block.to >= node.to && /```$/.test(state.doc.sliceString(block.from, block.to));
|
4808
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
4809
|
+
const editing = editingRange(state, node, focus2);
|
4810
|
+
if (!editing && (first || last)) {
|
4811
|
+
atomicDeco.add(block.from, block.to, hide);
|
4812
|
+
}
|
4813
|
+
}
|
4814
|
+
return false;
|
4815
|
+
}
|
4816
|
+
//
|
4817
|
+
// Link > [LinkMark, URL]
|
4818
|
+
//
|
4819
|
+
case "Link": {
|
4820
|
+
const marks = node.node.getChildren("LinkMark");
|
4821
|
+
const urlNode = node.node.getChild("URL");
|
4822
|
+
const editing = editingRange(state, node, focus2);
|
4823
|
+
if (urlNode && marks.length >= 2) {
|
4824
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
4825
|
+
if (!editing) {
|
4826
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
4827
|
+
}
|
4828
|
+
deco.add(marks[0].to, marks[1].from, Decoration7.mark({
|
4829
|
+
tagName: "a",
|
4830
|
+
attributes: {
|
4831
|
+
class: "cm-link",
|
4832
|
+
href: url,
|
4833
|
+
rel: "noreferrer",
|
4834
|
+
target: "_blank"
|
4835
|
+
}
|
4836
|
+
}));
|
4837
|
+
if (!editing) {
|
4838
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
|
4839
|
+
widget: new LinkButton(url, options.renderLinkButton)
|
4840
|
+
}) : hide);
|
4841
|
+
}
|
4842
|
+
}
|
4843
|
+
break;
|
4844
|
+
}
|
4845
|
+
//
|
4846
|
+
// HR
|
4847
|
+
//
|
4848
|
+
case "HorizontalRule": {
|
4849
|
+
if (!editingRange(state, node, focus2)) {
|
4850
|
+
deco.add(node.from, node.to, horizontalRule);
|
4851
|
+
}
|
4852
|
+
break;
|
4853
|
+
}
|
4854
|
+
default: {
|
4855
|
+
if (autoHideTags.has(node.name)) {
|
4856
|
+
if (!editingRange(state, node.node.parent, focus2)) {
|
4857
|
+
atomicDeco.add(node.from, node.to, hide);
|
4858
|
+
}
|
4859
|
+
}
|
4860
|
+
}
|
4861
|
+
}
|
4862
|
+
};
|
4863
|
+
const leaveNode = (node) => {
|
4864
|
+
switch (node.name) {
|
4865
|
+
case "BulletList":
|
4866
|
+
case "OrderedList": {
|
4867
|
+
leaveList();
|
4868
|
+
break;
|
4869
|
+
}
|
4870
|
+
}
|
4871
|
+
};
|
4872
|
+
const tree = syntaxTree7(state);
|
4873
|
+
if (options.numberedHeadings?.from === void 0) {
|
4874
|
+
for (const { from, to } of view.visibleRanges) {
|
4875
|
+
tree.iterate({
|
4876
|
+
from,
|
4877
|
+
to,
|
4878
|
+
enter: wrapWithCatch(enterNode),
|
4879
|
+
leave: wrapWithCatch(leaveNode)
|
4880
|
+
});
|
4881
|
+
}
|
4882
|
+
} else {
|
4883
|
+
tree.iterate({
|
4884
|
+
enter: wrapWithCatch(enterNode),
|
4885
|
+
leave: wrapWithCatch(leaveNode)
|
4996
4886
|
});
|
4887
|
+
}
|
4888
|
+
return {
|
4889
|
+
deco: deco.finish(),
|
4890
|
+
atomicDeco: atomicDeco.finish()
|
4997
4891
|
};
|
4998
|
-
|
4999
|
-
|
5000
|
-
|
5001
|
-
|
5002
|
-
|
5003
|
-
|
5004
|
-
|
5005
|
-
|
5006
|
-
|
5007
|
-
|
5008
|
-
|
4892
|
+
};
|
4893
|
+
var forceUpdate = StateEffect5.define();
|
4894
|
+
var decorateMarkdown = (options = {}) => {
|
4895
|
+
return [
|
4896
|
+
ViewPlugin7.fromClass(class {
|
4897
|
+
constructor(view) {
|
4898
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
|
4899
|
+
}
|
4900
|
+
update(update2) {
|
4901
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
4902
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
|
4903
|
+
this.clearUpdate();
|
4904
|
+
} else if (update2.selectionSet) {
|
4905
|
+
this.scheduleUpdate(update2.view);
|
4906
|
+
}
|
4907
|
+
}
|
4908
|
+
// Defer update in case moving through the document.
|
4909
|
+
scheduleUpdate(view) {
|
4910
|
+
this.clearUpdate();
|
4911
|
+
this.pendingUpdate = setTimeout(() => {
|
4912
|
+
view.dispatch({
|
4913
|
+
effects: forceUpdate.of(null)
|
4914
|
+
});
|
4915
|
+
}, options.selectionChangeDelay);
|
4916
|
+
}
|
4917
|
+
clearUpdate() {
|
4918
|
+
if (this.pendingUpdate) {
|
4919
|
+
clearTimeout(this.pendingUpdate);
|
4920
|
+
this.pendingUpdate = void 0;
|
4921
|
+
}
|
4922
|
+
}
|
4923
|
+
destroy() {
|
4924
|
+
this.clearUpdate();
|
4925
|
+
}
|
4926
|
+
}, {
|
4927
|
+
provide: (plugin) => [
|
4928
|
+
EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4929
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4930
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
5009
4931
|
]
|
5010
|
-
})
|
5011
|
-
|
4932
|
+
}),
|
4933
|
+
image(),
|
4934
|
+
table(),
|
4935
|
+
adjustChanges(),
|
4936
|
+
formattingStyles
|
4937
|
+
];
|
4938
|
+
};
|
4939
|
+
|
4940
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
4941
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
4942
|
+
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
4943
|
+
import { tooltipContent } from "@dxos/react-ui-theme";
|
4944
|
+
var linkTooltip = (renderTooltip) => {
|
4945
|
+
return hoverTooltip2((view, pos, side) => {
|
4946
|
+
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
4947
|
+
let link = null;
|
4948
|
+
for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
|
4949
|
+
link = node.name === "Link" ? node : null;
|
4950
|
+
}
|
4951
|
+
const url = link && link.getChild("URL");
|
4952
|
+
if (!url || !link) {
|
4953
|
+
return null;
|
4954
|
+
}
|
4955
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
4956
|
+
return {
|
4957
|
+
pos: link.from,
|
4958
|
+
end: link.to,
|
4959
|
+
// NOTE: Forcing above causes the tooltip to flicker.
|
4960
|
+
// above: true,
|
4961
|
+
create: () => {
|
4962
|
+
const el = document.createElement("div");
|
4963
|
+
el.className = tooltipContent({});
|
4964
|
+
renderTooltip(el, {
|
4965
|
+
url: urlText
|
4966
|
+
}, view);
|
4967
|
+
return {
|
4968
|
+
dom: el,
|
4969
|
+
offset: {
|
4970
|
+
x: 0,
|
4971
|
+
y: 4
|
4972
|
+
}
|
4973
|
+
};
|
4974
|
+
}
|
4975
|
+
};
|
4976
|
+
}, {
|
4977
|
+
// NOTE: 0 = default of 300ms.
|
4978
|
+
hoverTime: 1
|
4979
|
+
});
|
4980
|
+
};
|
4981
|
+
|
4982
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/outliner.ts
|
4983
|
+
import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
4984
|
+
import { StateField as StateField10, EditorState as EditorState2 } from "@codemirror/state";
|
4985
|
+
import { Decoration as Decoration8, EditorView as EditorView19 } from "@codemirror/view";
|
4986
|
+
import { log as log6 } from "@dxos/log";
|
4987
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
4988
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/markdown/outliner.ts";
|
4989
|
+
var indentLevel = 2;
|
4990
|
+
var matchTaskMarker = /^\s*- (\[ \]|\[x\])? /;
|
4991
|
+
var getLineInfo = (line) => {
|
4992
|
+
const match = line.text.match(matchTaskMarker);
|
4993
|
+
const start = line.from + (match?.[0]?.length ?? 0);
|
4994
|
+
return {
|
4995
|
+
match,
|
4996
|
+
start
|
5012
4997
|
};
|
5013
|
-
|
5014
|
-
|
5015
|
-
|
5016
|
-
|
5017
|
-
|
5018
|
-
|
5019
|
-
|
5020
|
-
|
5021
|
-
|
5022
|
-
|
5023
|
-
|
5024
|
-
|
5025
|
-
|
5026
|
-
|
5027
|
-
|
5028
|
-
|
5029
|
-
|
4998
|
+
};
|
4999
|
+
var outliner = () => [
|
5000
|
+
EditorState2.transactionFilter.of((tr) => {
|
5001
|
+
if (!tr.docChanged) {
|
5002
|
+
const pos = tr.selection?.ranges[tr.selection?.mainIndex]?.from;
|
5003
|
+
if (pos != null) {
|
5004
|
+
const { match, start } = getLineInfo(tr.startState.doc.lineAt(pos));
|
5005
|
+
if (match) {
|
5006
|
+
if (pos < start) {
|
5007
|
+
return [
|
5008
|
+
{
|
5009
|
+
selection: {
|
5010
|
+
anchor: start,
|
5011
|
+
head: start
|
5012
|
+
}
|
5013
|
+
}
|
5014
|
+
];
|
5030
5015
|
}
|
5031
5016
|
}
|
5032
|
-
|
5033
|
-
|
5034
|
-
|
5017
|
+
}
|
5018
|
+
return tr;
|
5019
|
+
}
|
5020
|
+
const changes = [];
|
5021
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, insert) => {
|
5022
|
+
const line = tr.startState.doc.lineAt(fromA);
|
5023
|
+
const isTaskMarker = line.text.match(matchTaskMarker);
|
5024
|
+
if (isTaskMarker) {
|
5025
|
+
const { start } = getLineInfo(line);
|
5026
|
+
const replace = start === toA && toA - fromA === insert.length;
|
5027
|
+
if (replace) {
|
5028
|
+
log6.info("delete line", void 0, {
|
5029
|
+
F: __dxlog_file10,
|
5030
|
+
L: 82,
|
5031
|
+
S: void 0,
|
5032
|
+
C: (f, a) => f(...a)
|
5033
|
+
});
|
5034
|
+
changes.push({
|
5035
|
+
from: line.from - 1,
|
5036
|
+
to: toA
|
5037
|
+
});
|
5038
|
+
return;
|
5035
5039
|
}
|
5036
|
-
|
5037
|
-
|
5038
|
-
|
5039
|
-
|
5040
|
-
|
5041
|
-
|
5042
|
-
|
5040
|
+
if (fromB === toB) {
|
5041
|
+
if (toA === line.to) {
|
5042
|
+
const line2 = tr.state.doc.lineAt(fromA);
|
5043
|
+
if (line2.text.match(/^\s*$/)) {
|
5044
|
+
if (line2.from === 0) {
|
5045
|
+
log6.info("skip", void 0, {
|
5046
|
+
F: __dxlog_file10,
|
5047
|
+
L: 94,
|
5048
|
+
S: void 0,
|
5049
|
+
C: (f, a) => f(...a)
|
5050
|
+
});
|
5051
|
+
changes.push({
|
5052
|
+
from: 0,
|
5053
|
+
to: 0
|
5054
|
+
});
|
5055
|
+
return;
|
5056
|
+
} else {
|
5057
|
+
log6.info("delete line", void 0, {
|
5058
|
+
F: __dxlog_file10,
|
5059
|
+
L: 99,
|
5060
|
+
S: void 0,
|
5061
|
+
C: (f, a) => f(...a)
|
5062
|
+
});
|
5063
|
+
changes.push({
|
5064
|
+
from: line2.from - 1,
|
5065
|
+
to: toA
|
5066
|
+
});
|
5067
|
+
return;
|
5068
|
+
}
|
5069
|
+
}
|
5070
|
+
}
|
5071
|
+
return;
|
5072
|
+
}
|
5073
|
+
if (insert.length === indentLevel) {
|
5074
|
+
if (line.number === 1) {
|
5075
|
+
log6.info("skip", void 0, {
|
5076
|
+
F: __dxlog_file10,
|
5077
|
+
L: 111,
|
5078
|
+
S: void 0,
|
5079
|
+
C: (f, a) => f(...a)
|
5080
|
+
});
|
5081
|
+
changes.push({
|
5082
|
+
from: 0,
|
5083
|
+
to: 0
|
5084
|
+
});
|
5085
|
+
return;
|
5043
5086
|
} else {
|
5044
|
-
const
|
5045
|
-
|
5046
|
-
|
5047
|
-
|
5048
|
-
|
5087
|
+
const getIndent = (text) => (text.match(/^\s*/)?.[0]?.length ?? 0) / indentLevel;
|
5088
|
+
const currentIndent = getIndent(line.text);
|
5089
|
+
const indentPrevious = getIndent(tr.state.doc.lineAt(fromA - 1).text);
|
5090
|
+
if (currentIndent > indentPrevious) {
|
5091
|
+
log6.info("skip", void 0, {
|
5092
|
+
F: __dxlog_file10,
|
5093
|
+
L: 119,
|
5094
|
+
S: void 0,
|
5095
|
+
C: (f, a) => f(...a)
|
5096
|
+
});
|
5097
|
+
changes.push({
|
5098
|
+
from: 0,
|
5099
|
+
to: 0
|
5100
|
+
});
|
5101
|
+
return;
|
5049
5102
|
}
|
5050
5103
|
}
|
5051
5104
|
}
|
5052
|
-
|
5105
|
+
log6.info("change", {
|
5106
|
+
line: {
|
5107
|
+
from: line.from,
|
5108
|
+
to: line.to
|
5109
|
+
},
|
5110
|
+
start,
|
5111
|
+
a: [
|
5112
|
+
fromA,
|
5113
|
+
toA
|
5114
|
+
],
|
5115
|
+
b: [
|
5116
|
+
fromB,
|
5117
|
+
toB
|
5118
|
+
],
|
5119
|
+
insert: {
|
5120
|
+
text: insert.toString(),
|
5121
|
+
length: insert.length
|
5122
|
+
}
|
5123
|
+
}, {
|
5124
|
+
F: __dxlog_file10,
|
5125
|
+
L: 134,
|
5126
|
+
S: void 0,
|
5127
|
+
C: (f, a) => f(...a)
|
5128
|
+
});
|
5053
5129
|
}
|
5054
|
-
|
5055
|
-
|
5056
|
-
|
5057
|
-
|
5058
|
-
|
5059
|
-
|
5060
|
-
|
5061
|
-
|
5130
|
+
});
|
5131
|
+
if (changes.length > 0) {
|
5132
|
+
return [
|
5133
|
+
{
|
5134
|
+
changes
|
5135
|
+
}
|
5136
|
+
];
|
5137
|
+
}
|
5138
|
+
return tr;
|
5139
|
+
}),
|
5140
|
+
StateField10.define({
|
5141
|
+
create: (state) => {
|
5142
|
+
return Decoration8.set(buildDecorations3(0, state.doc.length, state));
|
5143
|
+
},
|
5144
|
+
update: (value, tr) => {
|
5145
|
+
const from = 0;
|
5146
|
+
const to = tr.state.doc.length;
|
5147
|
+
return value.map(tr.changes).update({
|
5148
|
+
filterFrom: 0,
|
5149
|
+
filterTo: tr.state.doc.length,
|
5150
|
+
filter: () => false,
|
5151
|
+
add: buildDecorations3(from, to, tr.state)
|
5152
|
+
});
|
5153
|
+
},
|
5154
|
+
provide: (field) => EditorView19.decorations.from(field)
|
5155
|
+
}),
|
5156
|
+
// TODO(burdon): Increase indent padding by configuring decorate extension.
|
5157
|
+
// TODO(burdon): Hover to select entire group.
|
5158
|
+
EditorView19.theme({
|
5159
|
+
".cm-list-item-start": {
|
5160
|
+
borderTop: "1px solid var(--dx-separator)",
|
5161
|
+
borderLeft: "1px solid var(--dx-separator)",
|
5162
|
+
borderRight: "1px solid var(--dx-separator)",
|
5163
|
+
borderTopLeftRadius: "4px",
|
5164
|
+
borderTopRightRadius: "4px",
|
5165
|
+
paddingTop: "4px",
|
5166
|
+
marginTop: "8px"
|
5167
|
+
},
|
5168
|
+
".cm-list-item-end": {
|
5169
|
+
borderLeft: "1px solid var(--dx-separator)",
|
5170
|
+
borderRight: "1px solid var(--dx-separator)",
|
5171
|
+
borderBottom: "1px solid var(--dx-separator)",
|
5172
|
+
borderBottomLeftRadius: "4px",
|
5173
|
+
borderBottomRightRadius: "4px",
|
5174
|
+
paddingBottom: "4px",
|
5175
|
+
marginBottom: "8px"
|
5176
|
+
},
|
5177
|
+
".cm-list-item-continuation": {
|
5178
|
+
borderLeft: "1px solid var(--dx-separator)",
|
5179
|
+
borderRight: "1px solid var(--dx-separator)",
|
5180
|
+
// TODO(burdon): Should match parent indentation.
|
5181
|
+
paddingLeft: "24px"
|
5182
|
+
},
|
5183
|
+
// TODO(burdon): Set via options to decorate extension.
|
5184
|
+
".cm-list-item-continuation.cm-codeblock-start": {
|
5185
|
+
borderRadius: "0"
|
5186
|
+
}
|
5187
|
+
})
|
5188
|
+
];
|
5189
|
+
var buildDecorations3 = (from, to, state) => {
|
5190
|
+
const decorations = [];
|
5191
|
+
syntaxTree9(state).iterate({
|
5192
|
+
enter: (node) => {
|
5193
|
+
if (node.name === "ListItem") {
|
5194
|
+
const sub = node.node.getChild("BulletList");
|
5195
|
+
const lineStart = state.doc.lineAt(node.from);
|
5196
|
+
const lineEnd = sub ? state.doc.lineAt(state.doc.lineAt(sub.from).from - 1) : state.doc.lineAt(node.to);
|
5197
|
+
decorations.push(Decoration8.line({
|
5198
|
+
class: mx3("cm-list-item-start", lineStart.number === lineEnd.number && "cm-list-item-end")
|
5199
|
+
}).range(lineStart.from, lineStart.from));
|
5200
|
+
for (let i = lineStart.from + 1; i < lineEnd.from; i++) {
|
5201
|
+
decorations.push(Decoration8.line({
|
5202
|
+
class: mx3("cm-list-item-continuation")
|
5203
|
+
}).range(i, i));
|
5204
|
+
}
|
5205
|
+
if (lineStart.number !== lineEnd.number) {
|
5206
|
+
decorations.push(Decoration8.line({
|
5207
|
+
class: mx3("cm-list-item-end")
|
5208
|
+
}).range(lineEnd.from, lineEnd.from));
|
5209
|
+
}
|
5062
5210
|
}
|
5063
|
-
|
5064
|
-
|
5065
|
-
|
5066
|
-
|
5067
|
-
|
5068
|
-
|
5069
|
-
|
5211
|
+
}
|
5212
|
+
});
|
5213
|
+
return decorations;
|
5214
|
+
};
|
5215
|
+
|
5216
|
+
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
5217
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
5218
|
+
import { log as log7 } from "@dxos/log";
|
5219
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
5220
|
+
var mention = ({ debug, onSearch }) => {
|
5221
|
+
return autocompletion2({
|
5222
|
+
// TODO(burdon): Not working.
|
5223
|
+
activateOnTyping: true,
|
5224
|
+
// activateOnTypingDelay: 100,
|
5225
|
+
// selectOnOpen: true,
|
5226
|
+
closeOnBlur: !debug,
|
5227
|
+
// defaultKeymap: false,
|
5228
|
+
icons: false,
|
5229
|
+
override: [
|
5230
|
+
(context) => {
|
5231
|
+
log7.info("completion context", {
|
5232
|
+
context
|
5233
|
+
}, {
|
5234
|
+
F: __dxlog_file11,
|
5235
|
+
L: 27,
|
5236
|
+
S: void 0,
|
5237
|
+
C: (f, a) => f(...a)
|
5238
|
+
});
|
5239
|
+
const match = context.matchBefore(/@(\w+)?/);
|
5240
|
+
if (!match || match.from === match.to && !context.explicit) {
|
5241
|
+
return null;
|
5070
5242
|
}
|
5071
|
-
|
5072
|
-
|
5073
|
-
|
5074
|
-
|
5075
|
-
}
|
5076
|
-
}
|
5077
|
-
break;
|
5243
|
+
return {
|
5244
|
+
from: match.from,
|
5245
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5246
|
+
label: `@${value}`
|
5247
|
+
}))
|
5248
|
+
};
|
5078
5249
|
}
|
5079
|
-
|
5080
|
-
|
5081
|
-
|
5082
|
-
|
5083
|
-
|
5250
|
+
]
|
5251
|
+
});
|
5252
|
+
};
|
5253
|
+
|
5254
|
+
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
5255
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
5256
|
+
import { vim } from "@replit/codemirror-vim";
|
5257
|
+
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
5258
|
+
import { Schema } from "effect";
|
5259
|
+
var EditorViewModes = [
|
5260
|
+
"preview",
|
5261
|
+
"readonly",
|
5262
|
+
"source"
|
5263
|
+
];
|
5264
|
+
var EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
|
5265
|
+
var EditorInputModes = [
|
5266
|
+
"default",
|
5267
|
+
"vim",
|
5268
|
+
"vscode"
|
5269
|
+
];
|
5270
|
+
var EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
|
5271
|
+
var editorInputMode = singleValueFacet({});
|
5272
|
+
var InputModeExtensions = {
|
5273
|
+
default: [],
|
5274
|
+
vscode: [
|
5275
|
+
// https://github.com/replit/codemirror-vscode-keymap
|
5276
|
+
editorInputMode.of({
|
5277
|
+
type: "vscode"
|
5278
|
+
}),
|
5279
|
+
keymap9.of(vscodeKeymap)
|
5280
|
+
],
|
5281
|
+
vim: [
|
5282
|
+
// https://github.com/replit/codemirror-vim
|
5283
|
+
vim(),
|
5284
|
+
editorInputMode.of({
|
5285
|
+
type: "vim",
|
5286
|
+
noTabster: true
|
5287
|
+
}),
|
5288
|
+
keymap9.of([
|
5289
|
+
{
|
5290
|
+
key: "Alt-Escape",
|
5291
|
+
run: (view) => {
|
5292
|
+
view.dom.parentElement?.focus();
|
5293
|
+
return true;
|
5084
5294
|
}
|
5085
|
-
const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
|
5086
|
-
const line = state.doc.lineAt(node.from);
|
5087
|
-
const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
|
5088
|
-
atomicDeco.add(line.from, to, Decoration7.replace({
|
5089
|
-
widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
|
5090
|
-
}));
|
5091
|
-
break;
|
5092
5295
|
}
|
5093
|
-
|
5094
|
-
|
5095
|
-
|
5096
|
-
|
5097
|
-
|
5098
|
-
|
5296
|
+
])
|
5297
|
+
]
|
5298
|
+
};
|
5299
|
+
|
5300
|
+
// packages/ui/react-ui-editor/src/extensions/preview/preview.ts
|
5301
|
+
import "@dxos/lit-ui/dx-ref-tag.pcss";
|
5302
|
+
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
5303
|
+
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField11 } from "@codemirror/state";
|
5304
|
+
import { Decoration as Decoration9, EditorView as EditorView20, WidgetType as WidgetType6 } from "@codemirror/view";
|
5305
|
+
var preview = (options = {}) => {
|
5306
|
+
return [
|
5307
|
+
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5308
|
+
// "Block decorations may not be specified via plugins"
|
5309
|
+
StateField11.define({
|
5310
|
+
create: (state) => buildDecorations4(state, options),
|
5311
|
+
update: (_, tr) => buildDecorations4(tr.state, options),
|
5312
|
+
provide: (field) => [
|
5313
|
+
EditorView20.decorations.from(field),
|
5314
|
+
EditorView20.atomicRanges.of((view) => view.state.field(field))
|
5315
|
+
]
|
5316
|
+
}),
|
5317
|
+
EditorView20.theme({
|
5318
|
+
".cm-preview-block": {
|
5319
|
+
marginLeft: "-1rem",
|
5320
|
+
marginRight: "-1rem",
|
5321
|
+
padding: "1rem",
|
5322
|
+
borderRadius: "0.5rem",
|
5323
|
+
background: "var(--dx-modalSurface)",
|
5324
|
+
border: "1px solid var(--dx-separator)"
|
5099
5325
|
}
|
5100
|
-
|
5101
|
-
|
5102
|
-
|
5103
|
-
|
5104
|
-
|
5105
|
-
|
5106
|
-
|
5107
|
-
|
5108
|
-
|
5109
|
-
|
5110
|
-
|
5111
|
-
|
5112
|
-
|
5113
|
-
|
5114
|
-
|
5115
|
-
|
5326
|
+
})
|
5327
|
+
];
|
5328
|
+
};
|
5329
|
+
var getLinkRef = (state, node) => {
|
5330
|
+
const mark = node.getChild("LinkMark");
|
5331
|
+
const label = node.getChild("LinkLabel");
|
5332
|
+
if (mark && label) {
|
5333
|
+
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5334
|
+
return {
|
5335
|
+
suggest: ref.startsWith("?"),
|
5336
|
+
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5337
|
+
label: state.sliceDoc(mark.to, label.from - 1),
|
5338
|
+
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5339
|
+
};
|
5340
|
+
}
|
5341
|
+
};
|
5342
|
+
var buildDecorations4 = (state, options) => {
|
5343
|
+
const builder = new RangeSetBuilder4();
|
5344
|
+
syntaxTree10(state).iterate({
|
5345
|
+
enter: (node) => {
|
5346
|
+
switch (node.name) {
|
5347
|
+
//
|
5348
|
+
// Decoration.
|
5349
|
+
// [Label][dxn:echo:123]
|
5350
|
+
//
|
5351
|
+
case "Link": {
|
5352
|
+
const link = getLinkRef(state, node.node);
|
5353
|
+
if (link) {
|
5354
|
+
builder.add(node.from, node.to, Decoration9.replace({
|
5355
|
+
widget: new PreviewInlineWidget(options, link)
|
5356
|
+
}));
|
5116
5357
|
}
|
5117
|
-
|
5358
|
+
break;
|
5118
5359
|
}
|
5119
|
-
|
5120
|
-
|
5121
|
-
|
5122
|
-
|
5123
|
-
|
5124
|
-
|
5125
|
-
|
5126
|
-
|
5127
|
-
|
5128
|
-
|
5129
|
-
|
5130
|
-
|
5131
|
-
break;
|
5132
|
-
}
|
5133
|
-
const isFirst = block.from <= node.from;
|
5134
|
-
const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
|
5135
|
-
deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
|
5136
|
-
if (!editing && (isFirst || isLast)) {
|
5137
|
-
atomicDeco.add(block.from, block.to, hide);
|
5360
|
+
//
|
5361
|
+
// Block widget.
|
5362
|
+
// ![Label][dxn:echo:123]
|
5363
|
+
//
|
5364
|
+
case "Image": {
|
5365
|
+
const link = getLinkRef(state, node.node);
|
5366
|
+
if (options.renderBlock && link) {
|
5367
|
+
builder.add(node.from, node.to, Decoration9.replace({
|
5368
|
+
block: true,
|
5369
|
+
// atomic: true,
|
5370
|
+
widget: new PreviewBlockWidget(options, link)
|
5371
|
+
}));
|
5138
5372
|
}
|
5373
|
+
break;
|
5139
5374
|
}
|
5140
|
-
break;
|
5141
5375
|
}
|
5142
|
-
|
5143
|
-
|
5144
|
-
|
5145
|
-
|
5146
|
-
|
5147
|
-
|
5148
|
-
|
5149
|
-
|
5150
|
-
|
5151
|
-
|
5152
|
-
|
5153
|
-
|
5154
|
-
|
5155
|
-
|
5156
|
-
|
5157
|
-
|
5158
|
-
|
5159
|
-
|
5376
|
+
}
|
5377
|
+
});
|
5378
|
+
return builder.finish();
|
5379
|
+
};
|
5380
|
+
var PreviewInlineWidget = class extends WidgetType6 {
|
5381
|
+
constructor(_options, _link) {
|
5382
|
+
super();
|
5383
|
+
this._options = _options;
|
5384
|
+
this._link = _link;
|
5385
|
+
}
|
5386
|
+
// override ignoreEvent() {
|
5387
|
+
// return false;
|
5388
|
+
// }
|
5389
|
+
eq(other) {
|
5390
|
+
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5391
|
+
}
|
5392
|
+
toDOM(view) {
|
5393
|
+
const root = document.createElement("dx-ref-tag");
|
5394
|
+
root.textContent = this._link.label;
|
5395
|
+
root.setAttribute("ref", this._link.ref);
|
5396
|
+
return root;
|
5397
|
+
}
|
5398
|
+
};
|
5399
|
+
var PreviewBlockWidget = class extends WidgetType6 {
|
5400
|
+
constructor(_options, _link) {
|
5401
|
+
super();
|
5402
|
+
this._options = _options;
|
5403
|
+
this._link = _link;
|
5404
|
+
}
|
5405
|
+
// override ignoreEvent() {
|
5406
|
+
// return true;
|
5407
|
+
// }
|
5408
|
+
eq(other) {
|
5409
|
+
return this._link.ref === other._link.ref;
|
5410
|
+
}
|
5411
|
+
toDOM(view) {
|
5412
|
+
const root = document.createElement("div");
|
5413
|
+
root.classList.add("cm-preview-block");
|
5414
|
+
const handleAction = (action) => {
|
5415
|
+
const pos = view.posAtDOM(root);
|
5416
|
+
const node = syntaxTree10(view.state).resolve(pos + 1).node.parent;
|
5417
|
+
if (!node) {
|
5418
|
+
return;
|
5419
|
+
}
|
5420
|
+
const link = getLinkRef(view.state, node);
|
5421
|
+
if (link?.ref !== action.link.ref) {
|
5422
|
+
return;
|
5423
|
+
}
|
5424
|
+
switch (action.type) {
|
5425
|
+
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5426
|
+
// Insert ref text.
|
5427
|
+
case "insert": {
|
5428
|
+
view.dispatch({
|
5429
|
+
changes: {
|
5430
|
+
from: node.from,
|
5431
|
+
to: node.to,
|
5432
|
+
insert: action.target.text
|
5433
|
+
}
|
5434
|
+
});
|
5435
|
+
break;
|
5160
5436
|
}
|
5161
|
-
|
5162
|
-
|
5163
|
-
|
5164
|
-
|
5165
|
-
|
5166
|
-
|
5167
|
-
const marks = node.node.getChildren("LinkMark");
|
5168
|
-
const urlNode = node.node.getChild("URL");
|
5169
|
-
const editing = editingRange(state, node, focus2);
|
5170
|
-
if (urlNode && marks.length >= 2) {
|
5171
|
-
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
5172
|
-
if (!editing) {
|
5173
|
-
atomicDeco.add(node.from, marks[0].to, hide);
|
5174
|
-
}
|
5175
|
-
deco.add(marks[0].to, marks[1].from, Decoration7.mark({
|
5176
|
-
tagName: "a",
|
5177
|
-
attributes: {
|
5178
|
-
class: "cm-link",
|
5179
|
-
href: url,
|
5180
|
-
rel: "noreferrer",
|
5181
|
-
target: "_blank"
|
5437
|
+
// Remove ref.
|
5438
|
+
case "delete": {
|
5439
|
+
view.dispatch({
|
5440
|
+
changes: {
|
5441
|
+
from: node.from,
|
5442
|
+
to: node.to
|
5182
5443
|
}
|
5183
|
-
})
|
5184
|
-
|
5185
|
-
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
|
5186
|
-
widget: new LinkButton(url, options.renderLinkButton)
|
5187
|
-
}) : hide);
|
5188
|
-
}
|
5444
|
+
});
|
5445
|
+
break;
|
5189
5446
|
}
|
5190
|
-
break;
|
5191
5447
|
}
|
5192
|
-
|
5193
|
-
|
5194
|
-
|
5195
|
-
|
5196
|
-
|
5197
|
-
|
5448
|
+
};
|
5449
|
+
this._options.renderBlock(root, {
|
5450
|
+
readonly: view.state.readOnly,
|
5451
|
+
link: this._link,
|
5452
|
+
onAction: handleAction,
|
5453
|
+
onLookup: this._options.onLookup
|
5454
|
+
}, view);
|
5455
|
+
return root;
|
5456
|
+
}
|
5457
|
+
};
|
5458
|
+
|
5459
|
+
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
5460
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
5461
|
+
var defaultItems = [
|
5462
|
+
"hello world!",
|
5463
|
+
"this is a test.",
|
5464
|
+
"this is [DXOS](https://dxos.org)"
|
5465
|
+
];
|
5466
|
+
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5467
|
+
let t;
|
5468
|
+
let idx = 0;
|
5469
|
+
return [
|
5470
|
+
keymap10.of([
|
5471
|
+
{
|
5472
|
+
// Reset.
|
5473
|
+
key: "alt-meta-'",
|
5474
|
+
run: (view) => {
|
5475
|
+
clearTimeout(t);
|
5476
|
+
idx = 0;
|
5477
|
+
return true;
|
5198
5478
|
}
|
5199
|
-
|
5200
|
-
|
5201
|
-
|
5202
|
-
|
5203
|
-
|
5204
|
-
|
5479
|
+
},
|
5480
|
+
{
|
5481
|
+
// Next prompt.
|
5482
|
+
// TODO(burdon): Press 1-9 to select prompt?
|
5483
|
+
key: "shift-meta-'",
|
5484
|
+
run: (view) => {
|
5485
|
+
clearTimeout(t);
|
5486
|
+
const text = items[idx++];
|
5487
|
+
if (idx === items?.length) {
|
5488
|
+
idx = 0;
|
5205
5489
|
}
|
5490
|
+
let i = 0;
|
5491
|
+
const insert = (d = 0) => {
|
5492
|
+
t = setTimeout(() => {
|
5493
|
+
const pos = view.state.selection.main.head;
|
5494
|
+
view.dispatch({
|
5495
|
+
changes: {
|
5496
|
+
from: pos,
|
5497
|
+
insert: text[i++]
|
5498
|
+
},
|
5499
|
+
selection: {
|
5500
|
+
anchor: pos + 1
|
5501
|
+
}
|
5502
|
+
});
|
5503
|
+
if (i < text.length) {
|
5504
|
+
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5505
|
+
}
|
5506
|
+
}, d);
|
5507
|
+
};
|
5508
|
+
insert();
|
5509
|
+
return true;
|
5206
5510
|
}
|
5207
5511
|
}
|
5512
|
+
])
|
5513
|
+
];
|
5514
|
+
};
|
5515
|
+
|
5516
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
|
5517
|
+
var createBlockGroupAction = (value) => createEditorActionGroup("block", {
|
5518
|
+
variant: "toggleGroup",
|
5519
|
+
selectCardinality: "single",
|
5520
|
+
value
|
5521
|
+
});
|
5522
|
+
var createBlockActions = (value, getView, blankLine) => Object.entries({
|
5523
|
+
blockquote: "ph--quotes--regular",
|
5524
|
+
codeblock: "ph--code-block--regular",
|
5525
|
+
table: "ph--table--regular"
|
5526
|
+
}).map(([type, icon]) => {
|
5527
|
+
const checked = type === value;
|
5528
|
+
return createEditorAction(type, () => {
|
5529
|
+
const view = getView();
|
5530
|
+
if (!view) {
|
5531
|
+
return;
|
5208
5532
|
}
|
5209
|
-
|
5210
|
-
|
5211
|
-
|
5212
|
-
|
5213
|
-
case "
|
5214
|
-
|
5533
|
+
switch (type) {
|
5534
|
+
case "blockquote":
|
5535
|
+
checked ? removeBlockquote(view) : addBlockquote(view);
|
5536
|
+
break;
|
5537
|
+
case "codeblock":
|
5538
|
+
checked ? removeCodeblock(view) : addCodeblock(view);
|
5539
|
+
break;
|
5540
|
+
case "table":
|
5541
|
+
insertTable(view);
|
5215
5542
|
break;
|
5216
|
-
}
|
5217
|
-
}
|
5218
|
-
};
|
5219
|
-
const tree = syntaxTree7(state);
|
5220
|
-
if (options.numberedHeadings?.from === void 0) {
|
5221
|
-
for (const { from, to } of view.visibleRanges) {
|
5222
|
-
tree.iterate({
|
5223
|
-
from,
|
5224
|
-
to,
|
5225
|
-
enter: wrapWithCatch(enterNode),
|
5226
|
-
leave: wrapWithCatch(leaveNode)
|
5227
|
-
});
|
5228
5543
|
}
|
5229
|
-
}
|
5230
|
-
|
5231
|
-
|
5232
|
-
|
5233
|
-
}
|
5234
|
-
|
5544
|
+
}, {
|
5545
|
+
checked,
|
5546
|
+
...type === "table" && {
|
5547
|
+
disabled: !!blankLine
|
5548
|
+
},
|
5549
|
+
icon
|
5550
|
+
});
|
5551
|
+
});
|
5552
|
+
var createBlocks = (state, getView) => {
|
5553
|
+
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
5554
|
+
const blockGroupAction = createBlockGroupAction(value);
|
5555
|
+
const blockActions = createBlockActions(value, getView, state.blankLine);
|
5235
5556
|
return {
|
5236
|
-
|
5237
|
-
|
5557
|
+
nodes: [
|
5558
|
+
blockGroupAction,
|
5559
|
+
...blockActions
|
5560
|
+
],
|
5561
|
+
edges: [
|
5562
|
+
{
|
5563
|
+
source: "root",
|
5564
|
+
target: "block"
|
5565
|
+
},
|
5566
|
+
...blockActions.map(({ id }) => ({
|
5567
|
+
source: blockGroupAction.id,
|
5568
|
+
target: id
|
5569
|
+
}))
|
5570
|
+
]
|
5238
5571
|
};
|
5239
5572
|
};
|
5240
|
-
|
5241
|
-
|
5242
|
-
|
5243
|
-
|
5244
|
-
|
5245
|
-
|
5246
|
-
|
5247
|
-
|
5248
|
-
|
5249
|
-
|
5250
|
-
|
5251
|
-
|
5252
|
-
|
5253
|
-
|
5254
|
-
}
|
5255
|
-
// Defer update in case moving through the document.
|
5256
|
-
scheduleUpdate(view) {
|
5257
|
-
this.clearUpdate();
|
5258
|
-
this.pendingUpdate = setTimeout(() => {
|
5259
|
-
view.dispatch({
|
5260
|
-
effects: forceUpdate.of(null)
|
5261
|
-
});
|
5262
|
-
}, options.selectionChangeDelay);
|
5263
|
-
}
|
5264
|
-
clearUpdate() {
|
5265
|
-
if (this.pendingUpdate) {
|
5266
|
-
clearTimeout(this.pendingUpdate);
|
5267
|
-
this.pendingUpdate = void 0;
|
5268
|
-
}
|
5269
|
-
}
|
5270
|
-
destroy() {
|
5271
|
-
this.clearUpdate();
|
5573
|
+
|
5574
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
|
5575
|
+
var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
|
5576
|
+
var createCommentAction = (label, getView) => createEditorAction("comment", () => createComment(getView()), {
|
5577
|
+
testId: "editor.toolbar.comment",
|
5578
|
+
icon: "ph--chat-text--regular",
|
5579
|
+
label
|
5580
|
+
});
|
5581
|
+
var createComment2 = (state, getView) => ({
|
5582
|
+
nodes: [
|
5583
|
+
createCommentAction([
|
5584
|
+
commentLabel(state.comment, state.selection),
|
5585
|
+
{
|
5586
|
+
ns: translationKey
|
5272
5587
|
}
|
5273
|
-
|
5274
|
-
|
5275
|
-
|
5276
|
-
|
5277
|
-
|
5278
|
-
|
5279
|
-
}
|
5280
|
-
|
5281
|
-
|
5282
|
-
adjustChanges(),
|
5283
|
-
formattingStyles
|
5284
|
-
];
|
5285
|
-
};
|
5588
|
+
], getView)
|
5589
|
+
],
|
5590
|
+
edges: [
|
5591
|
+
{
|
5592
|
+
source: "root",
|
5593
|
+
target: "comment"
|
5594
|
+
}
|
5595
|
+
]
|
5596
|
+
});
|
5286
5597
|
|
5287
|
-
// packages/ui/react-ui-editor/src/
|
5288
|
-
|
5289
|
-
|
5290
|
-
|
5291
|
-
|
5292
|
-
|
5293
|
-
|
5294
|
-
|
5295
|
-
|
5296
|
-
|
5598
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
|
5599
|
+
var formats = {
|
5600
|
+
strong: "ph--text-b--regular",
|
5601
|
+
emphasis: "ph--text-italic--regular",
|
5602
|
+
strikethrough: "ph--text-strikethrough--regular",
|
5603
|
+
code: "ph--code--regular",
|
5604
|
+
link: "ph--link--regular"
|
5605
|
+
};
|
5606
|
+
var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
|
5607
|
+
variant: "toggleGroup",
|
5608
|
+
selectCardinality: "multiple",
|
5609
|
+
value: Object.keys(formats).filter((key) => !!formatting[key])
|
5610
|
+
});
|
5611
|
+
var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
|
5612
|
+
const checked = !!formatting[type];
|
5613
|
+
return createEditorAction(type, () => {
|
5614
|
+
const view = getView();
|
5615
|
+
if (!view) {
|
5616
|
+
return;
|
5297
5617
|
}
|
5298
|
-
|
5299
|
-
|
5300
|
-
return
|
5618
|
+
if (type === "link") {
|
5619
|
+
checked ? removeLink(view) : addLink()(view);
|
5620
|
+
return;
|
5301
5621
|
}
|
5302
|
-
const
|
5303
|
-
|
5304
|
-
pos: link.from,
|
5305
|
-
end: link.to,
|
5306
|
-
// NOTE: Forcing above causes the tooltip to flicker.
|
5307
|
-
// above: true,
|
5308
|
-
create: () => {
|
5309
|
-
const el = document.createElement("div");
|
5310
|
-
el.className = tooltipContent({});
|
5311
|
-
renderTooltip(el, {
|
5312
|
-
url: urlText
|
5313
|
-
}, view);
|
5314
|
-
return {
|
5315
|
-
dom: el,
|
5316
|
-
offset: {
|
5317
|
-
x: 0,
|
5318
|
-
y: 4
|
5319
|
-
}
|
5320
|
-
};
|
5321
|
-
}
|
5322
|
-
};
|
5622
|
+
const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
5623
|
+
setStyle(inlineType, !checked)(view);
|
5323
5624
|
}, {
|
5324
|
-
|
5325
|
-
|
5625
|
+
checked,
|
5626
|
+
icon
|
5326
5627
|
});
|
5628
|
+
});
|
5629
|
+
var createFormatting = (state, getView) => {
|
5630
|
+
const formattingGroupAction = createFormattingGroup(state);
|
5631
|
+
const formattingActions = createFormattingActions(state, getView);
|
5632
|
+
return {
|
5633
|
+
nodes: [
|
5634
|
+
formattingGroupAction,
|
5635
|
+
...formattingActions
|
5636
|
+
],
|
5637
|
+
edges: [
|
5638
|
+
{
|
5639
|
+
source: "root",
|
5640
|
+
target: "formatting"
|
5641
|
+
},
|
5642
|
+
...formattingActions.map(({ id }) => ({
|
5643
|
+
source: formattingGroupAction.id,
|
5644
|
+
target: id
|
5645
|
+
}))
|
5646
|
+
]
|
5647
|
+
};
|
5327
5648
|
};
|
5328
5649
|
|
5329
|
-
// packages/ui/react-ui-editor/src/
|
5330
|
-
|
5331
|
-
|
5332
|
-
|
5333
|
-
|
5334
|
-
|
5335
|
-
|
5336
|
-
|
5337
|
-
|
5338
|
-
|
5339
|
-
|
5340
|
-
|
5341
|
-
|
5342
|
-
|
5343
|
-
|
5344
|
-
|
5345
|
-
|
5346
|
-
|
5347
|
-
|
5348
|
-
|
5349
|
-
|
5350
|
-
|
5351
|
-
|
5352
|
-
const match = context.matchBefore(/@(\w+)?/);
|
5353
|
-
if (!match || match.from === match.to && !context.explicit) {
|
5354
|
-
return null;
|
5355
|
-
}
|
5356
|
-
return {
|
5357
|
-
from: match.from,
|
5358
|
-
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5359
|
-
label: `@${value}`
|
5360
|
-
}))
|
5361
|
-
};
|
5650
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
|
5651
|
+
var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
|
5652
|
+
variant: "dropdownMenu",
|
5653
|
+
applyActive: true,
|
5654
|
+
selectCardinality: "single",
|
5655
|
+
value
|
5656
|
+
}, "ph--text-h--regular");
|
5657
|
+
var createHeadingActions = (getView) => Object.entries({
|
5658
|
+
"0": "ph--paragraph--regular",
|
5659
|
+
"1": "ph--text-h-one--regular",
|
5660
|
+
"2": "ph--text-h-two--regular",
|
5661
|
+
"3": "ph--text-h-three--regular",
|
5662
|
+
"4": "ph--text-h-four--regular",
|
5663
|
+
"5": "ph--text-h-five--regular",
|
5664
|
+
"6": "ph--text-h-six--regular"
|
5665
|
+
}).map(([levelStr, icon]) => {
|
5666
|
+
const level = parseInt(levelStr);
|
5667
|
+
return createEditorAction(`heading--${levelStr}`, () => setHeading(level)(getView()), {
|
5668
|
+
label: [
|
5669
|
+
"heading level label",
|
5670
|
+
{
|
5671
|
+
count: level,
|
5672
|
+
ns: translationKey
|
5362
5673
|
}
|
5363
|
-
]
|
5674
|
+
],
|
5675
|
+
icon
|
5364
5676
|
});
|
5677
|
+
});
|
5678
|
+
var computeHeadingValue = (state) => {
|
5679
|
+
const blockType = state ? state.blockType : "paragraph";
|
5680
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
5681
|
+
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
5682
|
+
};
|
5683
|
+
var createHeadings = (state, getView) => {
|
5684
|
+
const headingValue = computeHeadingValue(state);
|
5685
|
+
const headingGroupAction = createHeadingGroupAction(headingValue);
|
5686
|
+
const headingActions = createHeadingActions(getView);
|
5687
|
+
return {
|
5688
|
+
nodes: [
|
5689
|
+
headingGroupAction,
|
5690
|
+
...headingActions
|
5691
|
+
],
|
5692
|
+
edges: [
|
5693
|
+
{
|
5694
|
+
source: "root",
|
5695
|
+
target: "heading"
|
5696
|
+
},
|
5697
|
+
...headingActions.map(({ id }) => ({
|
5698
|
+
source: headingGroupAction.id,
|
5699
|
+
target: id
|
5700
|
+
}))
|
5701
|
+
]
|
5702
|
+
};
|
5365
5703
|
};
|
5366
5704
|
|
5367
|
-
// packages/ui/react-ui-editor/src/
|
5368
|
-
|
5369
|
-
|
5370
|
-
|
5371
|
-
|
5372
|
-
var
|
5373
|
-
|
5374
|
-
|
5375
|
-
"source"
|
5376
|
-
];
|
5377
|
-
var EditorViewMode = S.Union(...EditorViewModes.map((mode) => S.Literal(mode)));
|
5378
|
-
var EditorInputModes = [
|
5379
|
-
"default",
|
5380
|
-
"vim",
|
5381
|
-
"vscode"
|
5382
|
-
];
|
5383
|
-
var EditorInputMode = S.Union(...EditorInputModes.map((mode) => S.Literal(mode)));
|
5384
|
-
var editorInputMode = singleValueFacet({});
|
5385
|
-
var InputModeExtensions = {
|
5386
|
-
default: [],
|
5387
|
-
vscode: [
|
5388
|
-
// https://github.com/replit/codemirror-vscode-keymap
|
5389
|
-
editorInputMode.of({
|
5390
|
-
type: "vscode"
|
5391
|
-
}),
|
5392
|
-
keymap9.of(vscodeKeymap)
|
5705
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/image.ts
|
5706
|
+
var createImageUploadAction = (onImageUpload) => createEditorAction("image", onImageUpload, {
|
5707
|
+
testId: "editor.toolbar.image",
|
5708
|
+
icon: "ph--image-square--regular"
|
5709
|
+
});
|
5710
|
+
var createImageUpload = (onImageUpload) => ({
|
5711
|
+
nodes: [
|
5712
|
+
createImageUploadAction(onImageUpload)
|
5393
5713
|
],
|
5394
|
-
|
5395
|
-
|
5396
|
-
|
5397
|
-
|
5398
|
-
|
5399
|
-
noTabster: true
|
5400
|
-
}),
|
5401
|
-
keymap9.of([
|
5402
|
-
{
|
5403
|
-
key: "Alt-Escape",
|
5404
|
-
run: (view) => {
|
5405
|
-
view.dom.parentElement?.focus();
|
5406
|
-
return true;
|
5407
|
-
}
|
5408
|
-
}
|
5409
|
-
])
|
5714
|
+
edges: [
|
5715
|
+
{
|
5716
|
+
source: "root",
|
5717
|
+
target: "image"
|
5718
|
+
}
|
5410
5719
|
]
|
5411
|
-
};
|
5720
|
+
});
|
5412
5721
|
|
5413
|
-
// packages/ui/react-ui-editor/src/
|
5414
|
-
|
5415
|
-
|
5416
|
-
|
5417
|
-
|
5418
|
-
var preview = (options = {}) => {
|
5419
|
-
return [
|
5420
|
-
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5421
|
-
// "Block decorations may not be specified via plugins"
|
5422
|
-
StateField10.define({
|
5423
|
-
create: (state) => buildDecorations3(state, options),
|
5424
|
-
update: (_, tr) => buildDecorations3(tr.state, options),
|
5425
|
-
provide: (field) => [
|
5426
|
-
EditorView20.decorations.from(field),
|
5427
|
-
EditorView20.atomicRanges.of((view) => view.state.field(field))
|
5428
|
-
]
|
5429
|
-
}),
|
5430
|
-
EditorView20.theme({
|
5431
|
-
".cm-preview-block": {
|
5432
|
-
marginLeft: "-1rem",
|
5433
|
-
marginRight: "-1rem",
|
5434
|
-
padding: "1rem",
|
5435
|
-
borderRadius: "0.5rem",
|
5436
|
-
background: "var(--dx-modalSurface)",
|
5437
|
-
border: "1px solid var(--dx-separator)"
|
5438
|
-
}
|
5439
|
-
})
|
5440
|
-
];
|
5441
|
-
};
|
5442
|
-
var getLinkRef = (state, node) => {
|
5443
|
-
const mark = node.getChild("LinkMark");
|
5444
|
-
const label = node.getChild("LinkLabel");
|
5445
|
-
if (mark && label) {
|
5446
|
-
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5447
|
-
return {
|
5448
|
-
suggest: ref.startsWith("?"),
|
5449
|
-
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5450
|
-
label: state.sliceDoc(mark.to, label.from - 1),
|
5451
|
-
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5452
|
-
};
|
5453
|
-
}
|
5722
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
|
5723
|
+
var listStyles = {
|
5724
|
+
bullet: "ph--list-bullets--regular",
|
5725
|
+
ordered: "ph--list-numbers--regular",
|
5726
|
+
task: "ph--list-checks--regular"
|
5454
5727
|
};
|
5455
|
-
var
|
5456
|
-
|
5457
|
-
|
5458
|
-
|
5459
|
-
|
5460
|
-
|
5461
|
-
|
5462
|
-
|
5463
|
-
|
5464
|
-
|
5465
|
-
|
5466
|
-
|
5467
|
-
|
5468
|
-
|
5469
|
-
|
5470
|
-
|
5471
|
-
|
5472
|
-
|
5473
|
-
|
5474
|
-
|
5475
|
-
|
5476
|
-
|
5477
|
-
|
5478
|
-
|
5479
|
-
|
5480
|
-
|
5481
|
-
|
5482
|
-
|
5483
|
-
|
5484
|
-
|
5485
|
-
|
5486
|
-
|
5487
|
-
|
5488
|
-
|
5728
|
+
var createListGroupAction = (value) => createEditorActionGroup("list", {
|
5729
|
+
variant: "toggleGroup",
|
5730
|
+
selectCardinality: "single",
|
5731
|
+
value
|
5732
|
+
});
|
5733
|
+
var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
|
5734
|
+
const checked = value === listStyle;
|
5735
|
+
return createEditorAction(`list-${listStyle}`, () => {
|
5736
|
+
const view = getView();
|
5737
|
+
if (!view) {
|
5738
|
+
return;
|
5739
|
+
}
|
5740
|
+
const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
|
5741
|
+
if (checked) {
|
5742
|
+
removeList(listType)(view);
|
5743
|
+
} else {
|
5744
|
+
addList(listType)(view);
|
5745
|
+
}
|
5746
|
+
}, {
|
5747
|
+
checked,
|
5748
|
+
icon
|
5749
|
+
});
|
5750
|
+
});
|
5751
|
+
var createLists = (state, getView) => {
|
5752
|
+
const value = state.listStyle ?? "";
|
5753
|
+
const listGroupAction = createListGroupAction(value);
|
5754
|
+
const listActionsMap = createListActions(value, getView);
|
5755
|
+
return {
|
5756
|
+
nodes: [
|
5757
|
+
listGroupAction,
|
5758
|
+
...listActionsMap
|
5759
|
+
],
|
5760
|
+
edges: [
|
5761
|
+
{
|
5762
|
+
source: "root",
|
5763
|
+
target: "list"
|
5764
|
+
},
|
5765
|
+
...listActionsMap.map(({ id }) => ({
|
5766
|
+
source: listGroupAction.id,
|
5767
|
+
target: id
|
5768
|
+
}))
|
5769
|
+
]
|
5770
|
+
};
|
5771
|
+
};
|
5772
|
+
|
5773
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/search.ts
|
5774
|
+
import { openSearchPanel } from "@codemirror/search";
|
5775
|
+
var createSearchAction = (getView) => createEditorAction("search", () => openSearchPanel(getView()), {
|
5776
|
+
testId: "editor.toolbar.search",
|
5777
|
+
icon: "ph--magnifying-glass--regular"
|
5778
|
+
});
|
5779
|
+
var createSearch = (getView) => ({
|
5780
|
+
nodes: [
|
5781
|
+
createSearchAction(getView)
|
5782
|
+
],
|
5783
|
+
edges: [
|
5784
|
+
{
|
5785
|
+
source: "root",
|
5786
|
+
target: "search"
|
5489
5787
|
}
|
5788
|
+
]
|
5789
|
+
});
|
5790
|
+
|
5791
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
|
5792
|
+
var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
|
5793
|
+
variant: "dropdownMenu",
|
5794
|
+
applyActive: true,
|
5795
|
+
selectCardinality: "single",
|
5796
|
+
value
|
5797
|
+
}, "ph--eye--regular");
|
5798
|
+
var createViewModeActions = (value, onViewModeChange) => Object.entries({
|
5799
|
+
preview: "ph--eye--regular",
|
5800
|
+
source: "ph--pencil-simple--regular",
|
5801
|
+
readonly: "ph--pencil-slash--regular"
|
5802
|
+
}).map(([viewMode, icon]) => {
|
5803
|
+
const checked = viewMode === value;
|
5804
|
+
return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode), {
|
5805
|
+
label: [
|
5806
|
+
`${viewMode} mode label`,
|
5807
|
+
{
|
5808
|
+
ns: translationKey
|
5809
|
+
}
|
5810
|
+
],
|
5811
|
+
checked,
|
5812
|
+
icon
|
5490
5813
|
});
|
5491
|
-
|
5814
|
+
});
|
5815
|
+
var createViewMode = (state, onViewModeChange) => {
|
5816
|
+
const value = state.viewMode ?? "source";
|
5817
|
+
const viewModeGroupAction = createViewModeGroupAction(value);
|
5818
|
+
const viewModeActions = createViewModeActions(value, onViewModeChange);
|
5819
|
+
return {
|
5820
|
+
nodes: [
|
5821
|
+
viewModeGroupAction,
|
5822
|
+
...viewModeActions
|
5823
|
+
],
|
5824
|
+
edges: [
|
5825
|
+
{
|
5826
|
+
source: "root",
|
5827
|
+
target: "viewMode"
|
5828
|
+
},
|
5829
|
+
...viewModeActions.map(({ id }) => ({
|
5830
|
+
source: viewModeGroupAction.id,
|
5831
|
+
target: id
|
5832
|
+
}))
|
5833
|
+
]
|
5834
|
+
};
|
5492
5835
|
};
|
5493
|
-
|
5494
|
-
|
5495
|
-
|
5496
|
-
|
5497
|
-
|
5836
|
+
|
5837
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
5838
|
+
import { EditorView as EditorView21 } from "@codemirror/view";
|
5839
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
5840
|
+
var margin = "!mt-[1rem]";
|
5841
|
+
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
5842
|
+
var editorContent = mx4(margin, editorWidth);
|
5843
|
+
var editorFullWidth = mx4(margin);
|
5844
|
+
var editorGutter = EditorView21.theme({
|
5845
|
+
// Match margin from content.
|
5846
|
+
// Gutter = 2rem + 1rem margin.
|
5847
|
+
".cm-gutters": {
|
5848
|
+
marginTop: "1rem",
|
5849
|
+
paddingRight: "1rem"
|
5498
5850
|
}
|
5499
|
-
|
5500
|
-
|
5501
|
-
|
5502
|
-
|
5503
|
-
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5851
|
+
});
|
5852
|
+
var editorMonospace = EditorView21.theme({
|
5853
|
+
".cm-content": {
|
5854
|
+
fontFamily: fontMono
|
5504
5855
|
}
|
5505
|
-
|
5506
|
-
|
5507
|
-
|
5508
|
-
|
5509
|
-
|
5856
|
+
});
|
5857
|
+
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
5858
|
+
var stackItemContentEditorClassNames = (role) => mx4("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
5859
|
+
var stackItemContentToolbarClassNames = (role) => mx4("relative z-[1] flex is-full bg-toolbarSurface border-be border-separator", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
|
5860
|
+
|
5861
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
5862
|
+
var createToolbar = ({ getView, state, customActions, ...features }) => {
|
5863
|
+
const nodes = [];
|
5864
|
+
const edges = [];
|
5865
|
+
if (features.headings ?? true) {
|
5866
|
+
const headings2 = createHeadings(state, getView);
|
5867
|
+
nodes.push(...headings2.nodes);
|
5868
|
+
edges.push(...headings2.edges);
|
5510
5869
|
}
|
5511
|
-
|
5512
|
-
|
5513
|
-
|
5514
|
-
|
5515
|
-
this._options = _options;
|
5516
|
-
this._link = _link;
|
5870
|
+
if (features.formatting ?? true) {
|
5871
|
+
const formatting = createFormatting(state, getView);
|
5872
|
+
nodes.push(...formatting.nodes);
|
5873
|
+
edges.push(...formatting.edges);
|
5517
5874
|
}
|
5518
|
-
|
5519
|
-
|
5520
|
-
|
5521
|
-
|
5522
|
-
return this._link.ref === other._link.ref;
|
5875
|
+
if (features.lists ?? true) {
|
5876
|
+
const lists = createLists(state, getView);
|
5877
|
+
nodes.push(...lists.nodes);
|
5878
|
+
edges.push(...lists.edges);
|
5523
5879
|
}
|
5524
|
-
|
5525
|
-
const
|
5526
|
-
|
5527
|
-
|
5528
|
-
const pos = view.posAtDOM(root);
|
5529
|
-
const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
|
5530
|
-
if (!node) {
|
5531
|
-
return;
|
5532
|
-
}
|
5533
|
-
const link = getLinkRef(view.state, node);
|
5534
|
-
if (link?.ref !== action.link.ref) {
|
5535
|
-
return;
|
5536
|
-
}
|
5537
|
-
switch (action.type) {
|
5538
|
-
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5539
|
-
// Insert ref text.
|
5540
|
-
case "insert": {
|
5541
|
-
view.dispatch({
|
5542
|
-
changes: {
|
5543
|
-
from: node.from,
|
5544
|
-
to: node.to,
|
5545
|
-
insert: action.target.text
|
5546
|
-
}
|
5547
|
-
});
|
5548
|
-
break;
|
5549
|
-
}
|
5550
|
-
// Remove ref.
|
5551
|
-
case "delete": {
|
5552
|
-
view.dispatch({
|
5553
|
-
changes: {
|
5554
|
-
from: node.from,
|
5555
|
-
to: node.to
|
5556
|
-
}
|
5557
|
-
});
|
5558
|
-
break;
|
5559
|
-
}
|
5560
|
-
}
|
5561
|
-
};
|
5562
|
-
this._options.renderBlock(root, {
|
5563
|
-
readonly: view.state.readOnly,
|
5564
|
-
link: this._link,
|
5565
|
-
onAction: handleAction,
|
5566
|
-
onLookup: this._options.onLookup
|
5567
|
-
}, view);
|
5568
|
-
return root;
|
5880
|
+
if (features.blocks ?? true) {
|
5881
|
+
const blocks = createBlocks(state, getView);
|
5882
|
+
nodes.push(...blocks.nodes);
|
5883
|
+
edges.push(...blocks.edges);
|
5569
5884
|
}
|
5885
|
+
if (features.image) {
|
5886
|
+
const image2 = createImageUpload(features.image);
|
5887
|
+
nodes.push(...image2.nodes);
|
5888
|
+
edges.push(...image2.edges);
|
5889
|
+
}
|
5890
|
+
if (customActions) {
|
5891
|
+
const custom = customActions();
|
5892
|
+
nodes.push(...custom.nodes);
|
5893
|
+
edges.push(...custom.edges);
|
5894
|
+
}
|
5895
|
+
const editorToolbarGap = createGapSeparator();
|
5896
|
+
nodes.push(...editorToolbarGap.nodes);
|
5897
|
+
edges.push(...editorToolbarGap.edges);
|
5898
|
+
if (features.comment) {
|
5899
|
+
const comment = createComment2(state, getView);
|
5900
|
+
nodes.push(...comment.nodes);
|
5901
|
+
edges.push(...comment.edges);
|
5902
|
+
}
|
5903
|
+
if (features.search ?? true) {
|
5904
|
+
const search = createSearch(getView);
|
5905
|
+
nodes.push(...search.nodes);
|
5906
|
+
edges.push(...search.edges);
|
5907
|
+
}
|
5908
|
+
if (features.viewMode) {
|
5909
|
+
const viewMode = createViewMode(state, features.viewMode);
|
5910
|
+
nodes.push(...viewMode.nodes);
|
5911
|
+
edges.push(...viewMode.edges);
|
5912
|
+
}
|
5913
|
+
return {
|
5914
|
+
nodes,
|
5915
|
+
edges
|
5916
|
+
};
|
5570
5917
|
};
|
5571
|
-
|
5572
|
-
|
5573
|
-
|
5574
|
-
var defaultItems = [
|
5575
|
-
"hello world!",
|
5576
|
-
"this is a test.",
|
5577
|
-
"this is [DXOS](https://dxos.org)"
|
5578
|
-
];
|
5579
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5580
|
-
let t;
|
5581
|
-
let idx = 0;
|
5582
|
-
return [
|
5583
|
-
keymap10.of([
|
5584
|
-
{
|
5585
|
-
// Reset.
|
5586
|
-
key: "alt-meta-'",
|
5587
|
-
run: (view) => {
|
5588
|
-
clearTimeout(t);
|
5589
|
-
idx = 0;
|
5590
|
-
return true;
|
5591
|
-
}
|
5592
|
-
},
|
5593
|
-
{
|
5594
|
-
// Next prompt.
|
5595
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
5596
|
-
key: "shift-meta-'",
|
5597
|
-
run: (view) => {
|
5598
|
-
clearTimeout(t);
|
5599
|
-
const text = items[idx++];
|
5600
|
-
if (idx === items?.length) {
|
5601
|
-
idx = 0;
|
5602
|
-
}
|
5603
|
-
let i = 0;
|
5604
|
-
const insert = (d = 0) => {
|
5605
|
-
t = setTimeout(() => {
|
5606
|
-
const pos = view.state.selection.main.head;
|
5607
|
-
view.dispatch({
|
5608
|
-
changes: {
|
5609
|
-
from: pos,
|
5610
|
-
insert: text[i++]
|
5611
|
-
},
|
5612
|
-
selection: {
|
5613
|
-
anchor: pos + 1
|
5614
|
-
}
|
5615
|
-
});
|
5616
|
-
if (i < text.length) {
|
5617
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5618
|
-
}
|
5619
|
-
}, d);
|
5620
|
-
};
|
5621
|
-
insert();
|
5622
|
-
return true;
|
5623
|
-
}
|
5624
|
-
}
|
5625
|
-
])
|
5626
|
-
];
|
5627
|
-
};
|
5628
|
-
|
5629
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
5630
|
-
import { useCallback as useCallback2 } from "react";
|
5631
|
-
var useActionHandler = (view) => {
|
5632
|
-
return useCallback2((action) => view && processEditorPayload(view, action.properties), [
|
5633
|
-
view
|
5918
|
+
var useEditorToolbarActionGraph = (props) => {
|
5919
|
+
const menuCreator = useCallback(() => createToolbar(props), [
|
5920
|
+
props
|
5634
5921
|
]);
|
5922
|
+
return useMenuActions(menuCreator);
|
5635
5923
|
};
|
5924
|
+
var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...props }) => {
|
5925
|
+
const menuProps = useEditorToolbarActionGraph(props);
|
5926
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
5927
|
+
role: "none",
|
5928
|
+
className: stackItemContentToolbarClassNames(role)
|
5929
|
+
}, /* @__PURE__ */ React3.createElement(ElevationProvider, {
|
5930
|
+
elevation: role === "section" ? "positioned" : "base"
|
5931
|
+
}, /* @__PURE__ */ React3.createElement(MenuProvider, {
|
5932
|
+
...menuProps,
|
5933
|
+
attendableId
|
5934
|
+
}, /* @__PURE__ */ React3.createElement(ToolbarMenu, {
|
5935
|
+
classNames: [
|
5936
|
+
textBlockWidth,
|
5937
|
+
classNames
|
5938
|
+
]
|
5939
|
+
}))));
|
5940
|
+
});
|
5636
5941
|
|
5637
5942
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
5638
|
-
import { EditorState as
|
5639
|
-
import { EditorView as
|
5943
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
5944
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
5640
5945
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
5641
|
-
import { useCallback as
|
5642
|
-
import { log as
|
5946
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
|
5947
|
+
import { log as log8 } from "@dxos/log";
|
5643
5948
|
import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
5644
|
-
var
|
5949
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
5645
5950
|
var instanceCount = 0;
|
5646
5951
|
var useTextEditor = (props = {}, deps = []) => {
|
5647
5952
|
const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
|
@@ -5651,12 +5956,12 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5651
5956
|
useEffect2(() => {
|
5652
5957
|
let view2;
|
5653
5958
|
if (parentRef.current) {
|
5654
|
-
|
5959
|
+
log8("create", {
|
5655
5960
|
id,
|
5656
5961
|
instanceId,
|
5657
5962
|
doc: initialValue?.length ?? 0
|
5658
5963
|
}, {
|
5659
|
-
F:
|
5964
|
+
F: __dxlog_file12,
|
5660
5965
|
L: 76,
|
5661
5966
|
S: void 0,
|
5662
5967
|
C: (f, a) => f(...a)
|
@@ -5673,16 +5978,16 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5673
5978
|
anchor
|
5674
5979
|
};
|
5675
5980
|
}
|
5676
|
-
const state =
|
5981
|
+
const state = EditorState3.create({
|
5677
5982
|
doc: doc ?? initialValue,
|
5678
5983
|
// selection: initialSelection,
|
5679
5984
|
extensions: [
|
5680
5985
|
id && documentId.of(id),
|
5681
5986
|
extensions,
|
5682
5987
|
// NOTE: This doesn't catch errors in keymap functions.
|
5683
|
-
|
5684
|
-
|
5685
|
-
F:
|
5988
|
+
EditorView22.exceptionSink.of((err) => {
|
5989
|
+
log8.catch(err, void 0, {
|
5990
|
+
F: __dxlog_file12,
|
5686
5991
|
L: 98,
|
5687
5992
|
S: void 0,
|
5688
5993
|
C: (f, a) => f(...a)
|
@@ -5690,10 +5995,10 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5690
5995
|
})
|
5691
5996
|
].filter(isNotFalsy4)
|
5692
5997
|
});
|
5693
|
-
view2 = new
|
5998
|
+
view2 = new EditorView22({
|
5694
5999
|
parent: parentRef.current,
|
5695
6000
|
state,
|
5696
|
-
scrollTo: scrollTo ?
|
6001
|
+
scrollTo: scrollTo ? EditorView22.scrollIntoView(scrollTo, {
|
5697
6002
|
yMargin: 96
|
5698
6003
|
}) : void 0,
|
5699
6004
|
dispatchTransactions: debug ? debugDispatcher : void 0
|
@@ -5711,10 +6016,10 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5711
6016
|
setView(view2);
|
5712
6017
|
}
|
5713
6018
|
return () => {
|
5714
|
-
|
6019
|
+
log8("destroy", {
|
5715
6020
|
id
|
5716
6021
|
}, {
|
5717
|
-
F:
|
6022
|
+
F: __dxlog_file12,
|
5718
6023
|
L: 135,
|
5719
6024
|
S: void 0,
|
5720
6025
|
C: (f, a) => f(...a)
|
@@ -5726,12 +6031,12 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5726
6031
|
if (view) {
|
5727
6032
|
if (scrollTo || selection) {
|
5728
6033
|
if (selection && selection.anchor > view.state.doc.length) {
|
5729
|
-
|
6034
|
+
log8.warn("invalid selection", {
|
5730
6035
|
length: view.state.doc.length,
|
5731
6036
|
scrollTo,
|
5732
6037
|
selection
|
5733
6038
|
}, {
|
5734
|
-
F:
|
6039
|
+
F: __dxlog_file12,
|
5735
6040
|
L: 144,
|
5736
6041
|
S: void 0,
|
5737
6042
|
C: (f, a) => f(...a)
|
@@ -5763,7 +6068,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5763
6068
|
Escape: view?.state.facet(editorInputMode).noTabster
|
5764
6069
|
}
|
5765
6070
|
});
|
5766
|
-
const handleKeyUp =
|
6071
|
+
const handleKeyUp = useCallback2((event) => {
|
5767
6072
|
const { key, target, currentTarget } = event;
|
5768
6073
|
if (target === currentTarget) {
|
5769
6074
|
switch (key) {
|
@@ -5790,9 +6095,9 @@ export {
|
|
5790
6095
|
Cursor,
|
5791
6096
|
EditorInputMode,
|
5792
6097
|
EditorInputModes,
|
5793
|
-
|
6098
|
+
EditorState4 as EditorState,
|
5794
6099
|
EditorToolbar,
|
5795
|
-
|
6100
|
+
EditorView23 as EditorView,
|
5796
6101
|
EditorViewMode,
|
5797
6102
|
EditorViewModes,
|
5798
6103
|
Inline,
|
@@ -5822,7 +6127,7 @@ export {
|
|
5822
6127
|
commentsState,
|
5823
6128
|
convertTreeToJson,
|
5824
6129
|
createBasicExtensions,
|
5825
|
-
|
6130
|
+
createComment,
|
5826
6131
|
createDataExtensions,
|
5827
6132
|
createEditorAction,
|
5828
6133
|
createEditorActionGroup,
|
@@ -5866,6 +6171,7 @@ export {
|
|
5866
6171
|
mention,
|
5867
6172
|
openCommand,
|
5868
6173
|
openEffect,
|
6174
|
+
outliner,
|
5869
6175
|
overlap,
|
5870
6176
|
preventNewline,
|
5871
6177
|
preview,
|
@@ -5900,7 +6206,6 @@ export {
|
|
5900
6206
|
toggleStyle,
|
5901
6207
|
translations_default as translations,
|
5902
6208
|
typewriter,
|
5903
|
-
useActionHandler,
|
5904
6209
|
useCommentClickListener,
|
5905
6210
|
useCommentState,
|
5906
6211
|
useComments,
|