@dxos/react-ui-editor 0.8.2-main.2f9c567 → 0.8.2-main.30e4dbb
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 +1591 -1523
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +1383 -1316
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1591 -1523
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- 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/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +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.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.map +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/link.d.ts.map +1 -1
- 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/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/story-utils.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 +28 -28
- package/src/components/EditorToolbar/EditorToolbar.stories.tsx +90 -0
- package/src/components/EditorToolbar/EditorToolbar.tsx +30 -31
- 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/hooks/index.ts +0 -1
- 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
@@ -40,7 +40,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
40
40
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
41
41
|
|
42
42
|
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
43
|
-
import
|
43
|
+
import React3, { memo, useCallback } from "react";
|
44
44
|
import { ElevationProvider } from "@dxos/react-ui";
|
45
45
|
import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
|
46
46
|
import { textBlockWidth } from "@dxos/react-ui-theme";
|
@@ -52,890 +52,308 @@ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
|
|
52
52
|
var useEditorToolbarState = (initialState = {}) => {
|
53
53
|
return useMemo(() => live(initialState), []);
|
54
54
|
};
|
55
|
-
var createEditorAction = (
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
55
|
+
var createEditorAction = (id, invoke, properties) => {
|
56
|
+
const { label = [
|
57
|
+
`${id} label`,
|
58
|
+
{
|
59
|
+
ns: translationKey
|
60
|
+
}
|
61
|
+
], ...rest } = properties;
|
62
|
+
return createMenuAction(id, invoke, {
|
63
|
+
label,
|
64
|
+
...rest
|
65
|
+
});
|
66
|
+
};
|
65
67
|
var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
|
66
68
|
icon,
|
67
69
|
iconOnly: true,
|
68
70
|
...props
|
69
71
|
});
|
70
|
-
var editorToolbarSearch = createEditorAction({
|
71
|
-
type: "search"
|
72
|
-
}, "ph--magnifying-glass--regular");
|
73
72
|
|
74
|
-
// packages/ui/react-ui-editor/src/
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
value
|
79
|
-
});
|
80
|
-
var createBlockActions = (value, blankLine) => Object.entries({
|
81
|
-
blockquote: "ph--quotes--regular",
|
82
|
-
codeblock: "ph--code-block--regular",
|
83
|
-
table: "ph--table--regular"
|
84
|
-
}).map(([type, icon]) => {
|
85
|
-
return createEditorAction({
|
86
|
-
type,
|
87
|
-
checked: type === value,
|
88
|
-
...type === "table" && {
|
89
|
-
disabled: !!blankLine
|
90
|
-
}
|
91
|
-
}, icon);
|
92
|
-
});
|
93
|
-
var createBlocks = (state) => {
|
94
|
-
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
95
|
-
const blockGroupAction = createBlockGroupAction(value);
|
96
|
-
const blockActions = createBlockActions(value, state.blankLine);
|
97
|
-
return {
|
98
|
-
nodes: [
|
99
|
-
blockGroupAction,
|
100
|
-
...blockActions
|
101
|
-
],
|
102
|
-
edges: [
|
103
|
-
{
|
104
|
-
source: "root",
|
105
|
-
target: "block"
|
106
|
-
},
|
107
|
-
...blockActions.map(({ id }) => ({
|
108
|
-
source: blockGroupAction.id,
|
109
|
-
target: id
|
110
|
-
}))
|
111
|
-
]
|
112
|
-
};
|
113
|
-
};
|
73
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
74
|
+
import { StateField } from "@codemirror/state";
|
75
|
+
import { Decoration, EditorView } from "@codemirror/view";
|
76
|
+
import { isNotFalsy } from "@dxos/util";
|
114
77
|
|
115
|
-
// packages/ui/react-ui-editor/src/
|
116
|
-
|
117
|
-
var
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
nodes: [
|
123
|
-
createCommentAction([
|
124
|
-
commentLabel(state.comment, state.selection),
|
125
|
-
{
|
126
|
-
ns: translationKey
|
127
|
-
}
|
128
|
-
])
|
129
|
-
],
|
130
|
-
edges: [
|
131
|
-
{
|
132
|
-
source: "root",
|
133
|
-
target: "comment"
|
134
|
-
}
|
135
|
-
]
|
78
|
+
// packages/ui/react-ui-editor/src/util/facet.ts
|
79
|
+
import { Facet } from "@codemirror/state";
|
80
|
+
var singleValueFacet = (defaultValue) => Facet.define({
|
81
|
+
// Called immediately.
|
82
|
+
combine: (providers) => {
|
83
|
+
return providers[0] ?? defaultValue;
|
84
|
+
}
|
136
85
|
});
|
137
86
|
|
138
|
-
// packages/ui/react-ui-editor/src/
|
139
|
-
var
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
code: "ph--code--regular",
|
144
|
-
link: "ph--link--regular"
|
87
|
+
// packages/ui/react-ui-editor/src/util/cursor.ts
|
88
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
89
|
+
var defaultCursorConverter = {
|
90
|
+
toCursor: (position) => position.toString(),
|
91
|
+
fromCursor: (cursor) => parseInt(cursor)
|
145
92
|
};
|
146
|
-
var
|
147
|
-
|
148
|
-
|
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
|
-
};
|
93
|
+
var Cursor = class _Cursor {
|
94
|
+
static {
|
95
|
+
this.converter = singleValueFacet(defaultCursorConverter);
|
96
|
+
}
|
97
|
+
static {
|
98
|
+
this.getCursorFromRange = (state, range) => {
|
99
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
100
|
+
const from = cursorConverter2.toCursor(range.from);
|
101
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
102
|
+
return [
|
103
|
+
from,
|
104
|
+
to
|
105
|
+
].join(":");
|
106
|
+
};
|
107
|
+
}
|
108
|
+
static {
|
109
|
+
this.getRangeFromCursor = (state, cursor) => {
|
110
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
111
|
+
const parts = cursor.split(":");
|
112
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
113
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
114
|
+
return from !== void 0 && to !== void 0 ? {
|
115
|
+
from,
|
116
|
+
to
|
117
|
+
} : void 0;
|
118
|
+
};
|
119
|
+
}
|
174
120
|
};
|
175
121
|
|
176
|
-
// packages/ui/react-ui-editor/src/
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
"6": "ph--text-h-six--regular"
|
191
|
-
}).map(([levelStr, icon]) => {
|
192
|
-
const level = parseInt(levelStr);
|
193
|
-
return createEditorAction({
|
194
|
-
type: "heading",
|
195
|
-
data: level,
|
196
|
-
checked: value === levelStr
|
197
|
-
}, icon, [
|
198
|
-
"heading level label",
|
199
|
-
{
|
200
|
-
count: level,
|
201
|
-
ns: translationKey
|
122
|
+
// packages/ui/react-ui-editor/src/util/debug.ts
|
123
|
+
import { log } from "@dxos/log";
|
124
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
125
|
+
var wrapWithCatch = (fn) => {
|
126
|
+
return (...args) => {
|
127
|
+
try {
|
128
|
+
return fn(...args);
|
129
|
+
} catch (err) {
|
130
|
+
log.catch(err, void 0, {
|
131
|
+
F: __dxlog_file,
|
132
|
+
L: 15,
|
133
|
+
S: void 0,
|
134
|
+
C: (f, a) => f(...a)
|
135
|
+
});
|
202
136
|
}
|
203
|
-
], `heading--${levelStr}`);
|
204
|
-
});
|
205
|
-
var computeHeadingValue = (state) => {
|
206
|
-
const blockType = state ? state.blockType : "paragraph";
|
207
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
208
|
-
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
209
|
-
};
|
210
|
-
var createHeadings = (state) => {
|
211
|
-
const headingValue = computeHeadingValue(state);
|
212
|
-
const headingGroupAction = createHeadingGroupAction(headingValue);
|
213
|
-
const headingActions = createHeadingActions(headingValue);
|
214
|
-
return {
|
215
|
-
nodes: [
|
216
|
-
headingGroupAction,
|
217
|
-
...headingActions
|
218
|
-
],
|
219
|
-
edges: [
|
220
|
-
{
|
221
|
-
source: "root",
|
222
|
-
target: "heading"
|
223
|
-
},
|
224
|
-
...headingActions.map(({ id }) => ({
|
225
|
-
source: headingGroupAction.id,
|
226
|
-
target: id
|
227
|
-
}))
|
228
|
-
]
|
229
137
|
};
|
230
138
|
};
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
139
|
+
var callbackWrapper = (fn) => (...args) => {
|
140
|
+
try {
|
141
|
+
return fn(...args);
|
142
|
+
} catch (err) {
|
143
|
+
log.catch(err, void 0, {
|
144
|
+
F: __dxlog_file,
|
145
|
+
L: 29,
|
146
|
+
S: void 0,
|
147
|
+
C: (f, a) => f(...a)
|
148
|
+
});
|
149
|
+
}
|
237
150
|
};
|
238
|
-
var
|
239
|
-
|
240
|
-
|
241
|
-
value
|
242
|
-
});
|
243
|
-
var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
|
244
|
-
type: `list-${listStyle}`,
|
245
|
-
checked: value === listStyle
|
246
|
-
}, icon));
|
247
|
-
var createLists = (state) => {
|
248
|
-
const value = state.listStyle ?? "";
|
249
|
-
const listGroupAction = createListGroupAction(value);
|
250
|
-
const listActionsMap = createListActions(value);
|
251
|
-
return {
|
252
|
-
nodes: [
|
253
|
-
listGroupAction,
|
254
|
-
...listActionsMap
|
255
|
-
],
|
256
|
-
edges: [
|
257
|
-
{
|
258
|
-
source: "root",
|
259
|
-
target: "list"
|
260
|
-
},
|
261
|
-
...listActionsMap.map(({ id }) => ({
|
262
|
-
source: listGroupAction.id,
|
263
|
-
target: id
|
264
|
-
}))
|
265
|
-
]
|
266
|
-
};
|
151
|
+
var debugDispatcher = (trs, view) => {
|
152
|
+
logChanges(trs);
|
153
|
+
view.update(trs);
|
267
154
|
};
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
applyActive: true,
|
273
|
-
selectCardinality: "single",
|
274
|
-
value
|
275
|
-
}, "ph--eye--regular");
|
276
|
-
var createViewModeActions = (value) => Object.entries({
|
277
|
-
preview: "ph--eye--regular",
|
278
|
-
source: "ph--pencil-simple--regular",
|
279
|
-
readonly: "ph--pencil-slash--regular"
|
280
|
-
}).map(([viewMode, icon]) => {
|
281
|
-
return createEditorAction({
|
282
|
-
type: "view-mode",
|
283
|
-
data: viewMode,
|
284
|
-
checked: viewMode === value
|
285
|
-
}, icon, [
|
286
|
-
`${viewMode} mode label`,
|
287
|
-
{
|
288
|
-
ns: translationKey
|
155
|
+
var logChanges = (trs) => {
|
156
|
+
const changes = trs.flatMap((tr) => {
|
157
|
+
if (tr.changes.empty) {
|
158
|
+
return void 0;
|
289
159
|
}
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
160
|
+
const changes2 = [];
|
161
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
162
|
+
fromA,
|
163
|
+
toA,
|
164
|
+
fromB,
|
165
|
+
toB,
|
166
|
+
inserted: inserted.toString()
|
167
|
+
})));
|
168
|
+
return changes2;
|
169
|
+
}).filter(Boolean);
|
170
|
+
if (changes.length) {
|
171
|
+
log("changes", {
|
172
|
+
changes
|
173
|
+
}, {
|
174
|
+
F: __dxlog_file,
|
175
|
+
L: 62,
|
176
|
+
S: void 0,
|
177
|
+
C: (f, a) => f(...a)
|
178
|
+
});
|
179
|
+
}
|
180
|
+
};
|
181
|
+
|
182
|
+
// packages/ui/react-ui-editor/src/util/dom.ts
|
183
|
+
var flattenRect = (rect, left) => {
|
184
|
+
const x = left ? rect.left : rect.right;
|
185
|
+
return {
|
186
|
+
left: x,
|
187
|
+
right: x,
|
188
|
+
top: rect.top,
|
189
|
+
bottom: rect.bottom
|
311
190
|
};
|
312
191
|
};
|
192
|
+
var scratchRange;
|
193
|
+
var textRange = (node, from, to = from) => {
|
194
|
+
const range = scratchRange || (scratchRange = document.createRange());
|
195
|
+
range.setEnd(node, to);
|
196
|
+
range.setStart(node, from);
|
197
|
+
return range;
|
198
|
+
};
|
199
|
+
var clientRectsFor = (dom) => {
|
200
|
+
if (dom.nodeType === 3) {
|
201
|
+
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
202
|
+
} else if (dom.nodeType === 1) {
|
203
|
+
return dom.getClientRects();
|
204
|
+
} else {
|
205
|
+
return [];
|
206
|
+
}
|
207
|
+
};
|
313
208
|
|
314
|
-
// packages/ui/react-ui-editor/src/
|
315
|
-
import
|
316
|
-
import {
|
209
|
+
// packages/ui/react-ui-editor/src/util/react.tsx
|
210
|
+
import React from "react";
|
211
|
+
import { createRoot } from "react-dom/client";
|
212
|
+
import { ThemeProvider, Tooltip } from "@dxos/react-ui";
|
213
|
+
import { defaultTx } from "@dxos/react-ui-theme";
|
214
|
+
var createElement = (tag, options, children) => {
|
215
|
+
const el = document.createElement(tag);
|
216
|
+
if (options?.className) {
|
217
|
+
el.className = options.className;
|
218
|
+
}
|
219
|
+
if (children) {
|
220
|
+
el.append(...Array.isArray(children) ? children : [
|
221
|
+
children
|
222
|
+
]);
|
223
|
+
}
|
224
|
+
return el;
|
225
|
+
};
|
226
|
+
var renderRoot = (root, node) => {
|
227
|
+
createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
|
228
|
+
tx: defaultTx
|
229
|
+
}, node));
|
230
|
+
return root;
|
231
|
+
};
|
232
|
+
var createRenderer = (Component) => (el, props) => {
|
233
|
+
renderRoot(el, /* @__PURE__ */ React.createElement(ThemeProvider, {
|
234
|
+
tx: defaultTx
|
235
|
+
}, /* @__PURE__ */ React.createElement(Tooltip.Provider, null, /* @__PURE__ */ React.createElement(Component, props))));
|
236
|
+
};
|
317
237
|
|
318
|
-
// packages/ui/react-ui-editor/src/
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
238
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
239
|
+
var annotationMark = Decoration.mark({
|
240
|
+
class: "cm-annotation"
|
241
|
+
});
|
242
|
+
var annotations = (options = {}) => {
|
243
|
+
const match = (state) => {
|
244
|
+
const annotations2 = [];
|
245
|
+
const text = state.doc.toString();
|
246
|
+
if (options.match) {
|
247
|
+
const matches = text.matchAll(options.match);
|
248
|
+
for (const match2 of matches) {
|
249
|
+
const from = match2.index;
|
250
|
+
const to = from + match2[0].length;
|
251
|
+
const cursor = Cursor.getCursorFromRange(state, {
|
252
|
+
from,
|
253
|
+
to
|
254
|
+
});
|
255
|
+
annotations2.push({
|
256
|
+
cursor
|
257
|
+
});
|
258
|
+
}
|
259
|
+
}
|
260
|
+
return annotations2;
|
261
|
+
};
|
262
|
+
const annotationsState = StateField.define({
|
263
|
+
create: (state) => {
|
264
|
+
return match(state);
|
265
|
+
},
|
266
|
+
update: (value, tr) => {
|
267
|
+
if (!tr.changes.empty) {
|
268
|
+
return match(tr.state);
|
269
|
+
}
|
270
|
+
return value;
|
271
|
+
}
|
272
|
+
});
|
273
|
+
return [
|
274
|
+
annotationsState,
|
275
|
+
EditorView.decorations.compute([
|
276
|
+
annotationsState
|
277
|
+
], (state) => {
|
278
|
+
const annotations2 = state.field(annotationsState);
|
279
|
+
const decorations = annotations2.map((annotation) => {
|
280
|
+
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
281
|
+
return range && annotationMark.range(range.from, range.to);
|
282
|
+
}).filter(isNotFalsy);
|
283
|
+
return Decoration.set(decorations);
|
284
|
+
}),
|
285
|
+
styles
|
286
|
+
];
|
327
287
|
};
|
328
|
-
var
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
return mx(headings[level], "dark:text-primary-400");
|
288
|
+
var styles = EditorView.theme({
|
289
|
+
".cm-annotation": {
|
290
|
+
textDecoration: "underline",
|
291
|
+
textDecorationStyle: "wavy",
|
292
|
+
textDecorationColor: "var(--dx-error)"
|
334
293
|
}
|
335
|
-
};
|
294
|
+
});
|
336
295
|
|
337
|
-
// packages/ui/react-ui-editor/src/
|
338
|
-
import
|
339
|
-
import {
|
340
|
-
|
341
|
-
|
342
|
-
|
296
|
+
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
297
|
+
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
298
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
299
|
+
import { keymap } from "@codemirror/view";
|
300
|
+
var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
301
|
+
const extensions = [
|
302
|
+
// https://codemirror.net/docs/ref/#view.keymap
|
303
|
+
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
304
|
+
// TODO(burdon): Set custom keymap.
|
305
|
+
keymap.of(completionKeymap),
|
306
|
+
// https://codemirror.net/examples/autocompletion
|
307
|
+
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
308
|
+
autocompletion({
|
309
|
+
activateOnTyping,
|
310
|
+
override,
|
311
|
+
closeOnBlur: !debug,
|
312
|
+
tooltipClass: () => "shadow rounded"
|
313
|
+
})
|
314
|
+
];
|
315
|
+
if (onSearch) {
|
316
|
+
extensions.push(
|
317
|
+
// TODO(burdon): Optional decoration via addToOptions
|
318
|
+
markdownLanguage.data.of({
|
319
|
+
autocomplete: (context) => {
|
320
|
+
const match = context.matchBefore(/\w*/);
|
321
|
+
if (!match || match.from === match.to && !context.explicit) {
|
322
|
+
return null;
|
323
|
+
}
|
324
|
+
return {
|
325
|
+
from: match.from,
|
326
|
+
options: onSearch(match.text.toLowerCase())
|
327
|
+
};
|
328
|
+
}
|
329
|
+
})
|
330
|
+
);
|
331
|
+
}
|
332
|
+
return extensions;
|
343
333
|
};
|
344
|
-
var fontBody = getToken("fontFamily.body");
|
345
|
-
var fontMono = getToken("fontFamily.mono");
|
346
334
|
|
347
|
-
// packages/ui/react-ui-editor/src/
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
color: "unset"
|
370
|
-
},
|
371
|
-
/**
|
372
|
-
* Gutters
|
373
|
-
* NOTE: Gutters should have the same top margin as the content.
|
374
|
-
*/
|
375
|
-
".cm-gutters": {
|
376
|
-
borderRight: "none",
|
377
|
-
background: "transparent"
|
378
|
-
},
|
379
|
-
".cm-gutter": {},
|
380
|
-
".cm-gutter.cm-lineNumbers": {
|
381
|
-
paddingRight: "4px",
|
382
|
-
borderRight: "1px solid var(--dx-separator)"
|
383
|
-
},
|
384
|
-
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
385
|
-
minWidth: "40px",
|
386
|
-
alignContent: "center"
|
387
|
-
},
|
388
|
-
/**
|
389
|
-
* Height is set to match the corresponding line.
|
390
|
-
*/
|
391
|
-
".cm-gutterElement": {
|
392
|
-
alignItems: "center",
|
393
|
-
fontSize: "12px"
|
394
|
-
},
|
395
|
-
/**
|
396
|
-
* Line.
|
397
|
-
*/
|
398
|
-
".cm-line": {
|
399
|
-
paddingInline: 0
|
400
|
-
},
|
401
|
-
".cm-activeLine": {
|
402
|
-
background: "var(--dx-cmActiveLine)"
|
403
|
-
},
|
404
|
-
/**
|
405
|
-
* Cursor (layer).
|
406
|
-
*/
|
407
|
-
".cm-cursor, .cm-dropCursor": {
|
408
|
-
borderLeft: "2px solid var(--dx-cmCursor)"
|
409
|
-
},
|
410
|
-
".cm-placeholder": {
|
411
|
-
color: "var(--dx-subdued)"
|
412
|
-
},
|
413
|
-
/**
|
414
|
-
* Selection (layer).
|
415
|
-
*/
|
416
|
-
".cm-selectionBackground": {
|
417
|
-
background: "var(--dx-cmSelection)"
|
418
|
-
},
|
419
|
-
/**
|
420
|
-
* Search.
|
421
|
-
* NOTE: Matches comment.
|
422
|
-
*/
|
423
|
-
".cm-searchMatch": {
|
424
|
-
margin: "0 -3px",
|
425
|
-
padding: "3px",
|
426
|
-
borderRadius: "3px",
|
427
|
-
background: "var(--dx-cmHighlightSurface)",
|
428
|
-
color: "var(--dx-cmHighlight)"
|
429
|
-
},
|
430
|
-
".cm-searchMatch-selected": {
|
431
|
-
textDecoration: "underline"
|
432
|
-
},
|
433
|
-
/**
|
434
|
-
* Link.
|
435
|
-
*/
|
436
|
-
".cm-link": {
|
437
|
-
textDecorationLine: "underline",
|
438
|
-
textDecorationThickness: "1px",
|
439
|
-
textDecorationColor: "var(--dx-separator)",
|
440
|
-
textUnderlineOffset: "2px",
|
441
|
-
borderRadius: ".125rem"
|
442
|
-
},
|
443
|
-
".cm-link > span": {
|
444
|
-
color: "var(--dx-accentText)"
|
445
|
-
},
|
446
|
-
/**
|
447
|
-
* Tooltip.
|
448
|
-
*/
|
449
|
-
".cm-tooltip": {
|
450
|
-
background: "var(--dx-baseSurface)"
|
451
|
-
},
|
452
|
-
".cm-tooltip-below": {},
|
453
|
-
/**
|
454
|
-
* Autocomplete.
|
455
|
-
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
456
|
-
*/
|
457
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
458
|
-
marginTop: "4px",
|
459
|
-
marginLeft: "-3px"
|
460
|
-
},
|
461
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
462
|
-
maxHeight: "20em"
|
463
|
-
},
|
464
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
465
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
466
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
467
|
-
paddingLeft: "4px !important",
|
468
|
-
borderBottom: "none !important",
|
469
|
-
color: "var(--dx-accentText)"
|
470
|
-
},
|
471
|
-
".cm-tooltip.cm-completionInfo": {
|
472
|
-
width: "360px !important",
|
473
|
-
margin: "-10px 1px 0 1px",
|
474
|
-
padding: "8px !important",
|
475
|
-
borderColor: "var(--dx-separator)"
|
476
|
-
},
|
477
|
-
".cm-completionIcon": {
|
478
|
-
display: "none"
|
479
|
-
},
|
480
|
-
".cm-completionLabel": {
|
481
|
-
fontFamily: fontBody
|
482
|
-
},
|
483
|
-
".cm-completionMatchedText": {
|
484
|
-
textDecoration: "none !important",
|
485
|
-
opacity: 0.5
|
486
|
-
},
|
487
|
-
/**
|
488
|
-
* Panels
|
489
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
490
|
-
*
|
491
|
-
* Find/replace panel.
|
492
|
-
* <div class="cm-announced">...</div>
|
493
|
-
* <div class="cm-scroller">...</div>
|
494
|
-
* <div class="cm-panels cm-panels-bottom">
|
495
|
-
* <div class="cm-search cm-panel">
|
496
|
-
* <input class="cm-textfield" />
|
497
|
-
* <button class="cm-button">...</button>
|
498
|
-
* <label><input type="checkbox" />...</label>
|
499
|
-
* </div>
|
500
|
-
* </div
|
501
|
-
*/
|
502
|
-
// TODO(burdon): Implement custom panel (with icon buttons).
|
503
|
-
".cm-panels": {},
|
504
|
-
".cm-panel": {
|
505
|
-
fontFamily: fontBody,
|
506
|
-
backgroundColor: "var(--surface-bg)"
|
507
|
-
},
|
508
|
-
".cm-panel input, .cm-panel button, .cm-panel label": {
|
509
|
-
color: "var(--dx-subdued)",
|
510
|
-
fontFamily: fontBody,
|
511
|
-
fontSize: "14px",
|
512
|
-
all: "unset",
|
513
|
-
margin: "3px !important",
|
514
|
-
padding: "2px 6px !important",
|
515
|
-
outline: "1px solid transparent"
|
516
|
-
},
|
517
|
-
".cm-panel input, .cm-panel button": {
|
518
|
-
backgroundColor: "var(--dx-input)"
|
519
|
-
},
|
520
|
-
".cm-panel input:focus, .cm-panel button:focus": {
|
521
|
-
outline: "1px solid var(--dx-accentFocusIndicator)"
|
522
|
-
},
|
523
|
-
".cm-panel label": {
|
524
|
-
display: "inline-flex",
|
525
|
-
alignItems: "center",
|
526
|
-
cursor: "pointer"
|
527
|
-
},
|
528
|
-
".cm-panel input.cm-textfield": {},
|
529
|
-
".cm-panel input[type=checkbox]": {
|
530
|
-
width: "8px",
|
531
|
-
height: "8px",
|
532
|
-
marginRight: "6px !important",
|
533
|
-
padding: "2px !important",
|
534
|
-
color: "var(--dx-accentFocusIndicator)"
|
535
|
-
},
|
536
|
-
".cm-panel button": {
|
537
|
-
"&:hover": {
|
538
|
-
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
539
|
-
},
|
540
|
-
"&:active": {
|
541
|
-
backgroundColor: "var(--dx-accentSurfaceHover)"
|
542
|
-
}
|
543
|
-
},
|
544
|
-
".cm-panel.cm-search": {
|
545
|
-
padding: "4px",
|
546
|
-
borderTop: "1px solid var(--dx-separator)"
|
547
|
-
}
|
548
|
-
};
|
549
|
-
|
550
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
551
|
-
var margin = "!mt-[1rem]";
|
552
|
-
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
553
|
-
var editorContent = mx2(margin, editorWidth);
|
554
|
-
var editorFullWidth = mx2(margin);
|
555
|
-
var editorGutter = EditorView.theme({
|
556
|
-
// Match margin from content.
|
557
|
-
// Gutter = 2rem + 1rem margin.
|
558
|
-
".cm-gutters": {
|
559
|
-
marginTop: "1rem",
|
560
|
-
paddingRight: "1rem"
|
561
|
-
}
|
562
|
-
});
|
563
|
-
var editorMonospace = EditorView.theme({
|
564
|
-
".cm-content": {
|
565
|
-
fontFamily: fontMono
|
566
|
-
}
|
567
|
-
});
|
568
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
569
|
-
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");
|
570
|
-
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");
|
571
|
-
|
572
|
-
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
573
|
-
var createToolbar = ({ state, customActions, ...features }) => {
|
574
|
-
const nodes = [];
|
575
|
-
const edges = [];
|
576
|
-
if (features.headings ?? true) {
|
577
|
-
const headings2 = createHeadings(state);
|
578
|
-
nodes.push(...headings2.nodes);
|
579
|
-
edges.push(...headings2.edges);
|
580
|
-
}
|
581
|
-
if (features.formatting ?? true) {
|
582
|
-
const formatting = createFormatting(state);
|
583
|
-
nodes.push(...formatting.nodes);
|
584
|
-
edges.push(...formatting.edges);
|
585
|
-
}
|
586
|
-
if (features.lists ?? true) {
|
587
|
-
const lists = createLists(state);
|
588
|
-
nodes.push(...lists.nodes);
|
589
|
-
edges.push(...lists.edges);
|
590
|
-
}
|
591
|
-
if (features.blocks ?? true) {
|
592
|
-
const blocks = createBlocks(state);
|
593
|
-
nodes.push(...blocks.nodes);
|
594
|
-
edges.push(...blocks.edges);
|
595
|
-
}
|
596
|
-
if (customActions) {
|
597
|
-
const custom = customActions();
|
598
|
-
nodes.push(...custom.nodes);
|
599
|
-
edges.push(...custom.edges);
|
600
|
-
}
|
601
|
-
const editorToolbarGap = createGapSeparator();
|
602
|
-
nodes.push(...editorToolbarGap.nodes);
|
603
|
-
edges.push(...editorToolbarGap.edges);
|
604
|
-
if (features.comment ?? true) {
|
605
|
-
const comment = createComment(state);
|
606
|
-
nodes.push(...comment.nodes);
|
607
|
-
edges.push(...comment.edges);
|
608
|
-
}
|
609
|
-
if (features.search ?? true) {
|
610
|
-
nodes.push(editorToolbarSearch);
|
611
|
-
edges.push({
|
612
|
-
source: "root",
|
613
|
-
target: editorToolbarSearch.id
|
614
|
-
});
|
615
|
-
}
|
616
|
-
if (features.viewMode ?? true) {
|
617
|
-
const viewMode = createViewMode(state);
|
618
|
-
nodes.push(...viewMode.nodes);
|
619
|
-
edges.push(...viewMode.edges);
|
620
|
-
}
|
621
|
-
return {
|
622
|
-
nodes,
|
623
|
-
edges
|
624
|
-
};
|
625
|
-
};
|
626
|
-
var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
|
627
|
-
const menuCreator = useCallback(() => createToolbar(props), [
|
628
|
-
props
|
629
|
-
]);
|
630
|
-
const { resolveGroupItems } = useMenuActions(menuCreator);
|
631
|
-
return {
|
632
|
-
resolveGroupItems,
|
633
|
-
onAction
|
634
|
-
};
|
635
|
-
};
|
636
|
-
var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
|
637
|
-
const menuProps = useEditorToolbarActionGraph(props);
|
638
|
-
return /* @__PURE__ */ React.createElement("div", {
|
639
|
-
role: "none",
|
640
|
-
className: stackItemContentToolbarClassNames(role)
|
641
|
-
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
642
|
-
elevation: role === "section" ? "positioned" : "base"
|
643
|
-
}, /* @__PURE__ */ React.createElement(MenuProvider, {
|
644
|
-
...menuProps,
|
645
|
-
attendableId
|
646
|
-
}, /* @__PURE__ */ React.createElement(ToolbarMenu, {
|
647
|
-
classNames: [
|
648
|
-
textBlockWidth,
|
649
|
-
"!bg-transparent",
|
650
|
-
classNames
|
651
|
-
]
|
652
|
-
}))));
|
653
|
-
};
|
654
|
-
|
655
|
-
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
656
|
-
import { StateField } from "@codemirror/state";
|
657
|
-
import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
|
658
|
-
import { isNotFalsy } from "@dxos/util";
|
659
|
-
|
660
|
-
// packages/ui/react-ui-editor/src/util/facet.ts
|
661
|
-
import { Facet } from "@codemirror/state";
|
662
|
-
var singleValueFacet = (defaultValue) => Facet.define({
|
663
|
-
// Called immediately.
|
664
|
-
combine: (providers) => {
|
665
|
-
return providers[0] ?? defaultValue;
|
666
|
-
}
|
667
|
-
});
|
668
|
-
|
669
|
-
// packages/ui/react-ui-editor/src/util/cursor.ts
|
670
|
-
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
671
|
-
var defaultCursorConverter = {
|
672
|
-
toCursor: (position) => position.toString(),
|
673
|
-
fromCursor: (cursor) => parseInt(cursor)
|
674
|
-
};
|
675
|
-
var Cursor = class _Cursor {
|
676
|
-
static {
|
677
|
-
this.converter = singleValueFacet(defaultCursorConverter);
|
678
|
-
}
|
679
|
-
static {
|
680
|
-
this.getCursorFromRange = (state, range) => {
|
681
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
682
|
-
const from = cursorConverter2.toCursor(range.from);
|
683
|
-
const to = cursorConverter2.toCursor(range.to, -1);
|
684
|
-
return [
|
685
|
-
from,
|
686
|
-
to
|
687
|
-
].join(":");
|
688
|
-
};
|
689
|
-
}
|
690
|
-
static {
|
691
|
-
this.getRangeFromCursor = (state, cursor) => {
|
692
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
693
|
-
const parts = cursor.split(":");
|
694
|
-
const from = cursorConverter2.fromCursor(parts[0]);
|
695
|
-
const to = cursorConverter2.fromCursor(parts[1]);
|
696
|
-
return from !== void 0 && to !== void 0 ? {
|
697
|
-
from,
|
698
|
-
to
|
699
|
-
} : void 0;
|
700
|
-
};
|
701
|
-
}
|
702
|
-
};
|
703
|
-
|
704
|
-
// packages/ui/react-ui-editor/src/util/debug.ts
|
705
|
-
import { log } from "@dxos/log";
|
706
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
707
|
-
var wrapWithCatch = (fn) => {
|
708
|
-
return (...args) => {
|
709
|
-
try {
|
710
|
-
return fn(...args);
|
711
|
-
} catch (err) {
|
712
|
-
log.catch(err, void 0, {
|
713
|
-
F: __dxlog_file,
|
714
|
-
L: 15,
|
715
|
-
S: void 0,
|
716
|
-
C: (f, a) => f(...a)
|
717
|
-
});
|
718
|
-
}
|
719
|
-
};
|
720
|
-
};
|
721
|
-
var callbackWrapper = (fn) => (...args) => {
|
722
|
-
try {
|
723
|
-
return fn(...args);
|
724
|
-
} catch (err) {
|
725
|
-
log.catch(err, void 0, {
|
726
|
-
F: __dxlog_file,
|
727
|
-
L: 29,
|
728
|
-
S: void 0,
|
729
|
-
C: (f, a) => f(...a)
|
730
|
-
});
|
731
|
-
}
|
732
|
-
};
|
733
|
-
var debugDispatcher = (trs, view) => {
|
734
|
-
logChanges(trs);
|
735
|
-
view.update(trs);
|
736
|
-
};
|
737
|
-
var logChanges = (trs) => {
|
738
|
-
const changes = trs.flatMap((tr) => {
|
739
|
-
if (tr.changes.empty) {
|
740
|
-
return void 0;
|
741
|
-
}
|
742
|
-
const changes2 = [];
|
743
|
-
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
744
|
-
fromA,
|
745
|
-
toA,
|
746
|
-
fromB,
|
747
|
-
toB,
|
748
|
-
inserted: inserted.toString()
|
749
|
-
})));
|
750
|
-
return changes2;
|
751
|
-
}).filter(Boolean);
|
752
|
-
if (changes.length) {
|
753
|
-
log("changes", {
|
754
|
-
changes
|
755
|
-
}, {
|
756
|
-
F: __dxlog_file,
|
757
|
-
L: 62,
|
758
|
-
S: void 0,
|
759
|
-
C: (f, a) => f(...a)
|
760
|
-
});
|
761
|
-
}
|
762
|
-
};
|
763
|
-
|
764
|
-
// packages/ui/react-ui-editor/src/util/dom.ts
|
765
|
-
var flattenRect = (rect, left) => {
|
766
|
-
const x = left ? rect.left : rect.right;
|
767
|
-
return {
|
768
|
-
left: x,
|
769
|
-
right: x,
|
770
|
-
top: rect.top,
|
771
|
-
bottom: rect.bottom
|
772
|
-
};
|
773
|
-
};
|
774
|
-
var scratchRange;
|
775
|
-
var textRange = (node, from, to = from) => {
|
776
|
-
const range = scratchRange || (scratchRange = document.createRange());
|
777
|
-
range.setEnd(node, to);
|
778
|
-
range.setStart(node, from);
|
779
|
-
return range;
|
780
|
-
};
|
781
|
-
var clientRectsFor = (dom) => {
|
782
|
-
if (dom.nodeType === 3) {
|
783
|
-
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
784
|
-
} else if (dom.nodeType === 1) {
|
785
|
-
return dom.getClientRects();
|
786
|
-
} else {
|
787
|
-
return [];
|
788
|
-
}
|
789
|
-
};
|
790
|
-
|
791
|
-
// packages/ui/react-ui-editor/src/util/react.tsx
|
792
|
-
import React2 from "react";
|
793
|
-
import { createRoot } from "react-dom/client";
|
794
|
-
import { ThemeProvider, Tooltip } from "@dxos/react-ui";
|
795
|
-
import { defaultTx } from "@dxos/react-ui-theme";
|
796
|
-
var createElement = (tag, options, children) => {
|
797
|
-
const el = document.createElement(tag);
|
798
|
-
if (options?.className) {
|
799
|
-
el.className = options.className;
|
800
|
-
}
|
801
|
-
if (children) {
|
802
|
-
el.append(...Array.isArray(children) ? children : [
|
803
|
-
children
|
804
|
-
]);
|
805
|
-
}
|
806
|
-
return el;
|
807
|
-
};
|
808
|
-
var renderRoot = (root, node) => {
|
809
|
-
createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
|
810
|
-
tx: defaultTx
|
811
|
-
}, node));
|
812
|
-
return root;
|
813
|
-
};
|
814
|
-
var createRenderer = (Component) => (el, props) => {
|
815
|
-
renderRoot(el, /* @__PURE__ */ React2.createElement(ThemeProvider, {
|
816
|
-
tx: defaultTx
|
817
|
-
}, /* @__PURE__ */ React2.createElement(Tooltip.Provider, null, /* @__PURE__ */ React2.createElement(Component, props))));
|
818
|
-
};
|
819
|
-
|
820
|
-
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
821
|
-
var annotationMark = Decoration.mark({
|
822
|
-
class: "cm-annotation"
|
823
|
-
});
|
824
|
-
var annotations = (options = {}) => {
|
825
|
-
const match = (state) => {
|
826
|
-
const annotations2 = [];
|
827
|
-
const text = state.doc.toString();
|
828
|
-
if (options.match) {
|
829
|
-
const matches = text.matchAll(options.match);
|
830
|
-
for (const match2 of matches) {
|
831
|
-
const from = match2.index;
|
832
|
-
const to = from + match2[0].length;
|
833
|
-
const cursor = Cursor.getCursorFromRange(state, {
|
834
|
-
from,
|
835
|
-
to
|
836
|
-
});
|
837
|
-
annotations2.push({
|
838
|
-
cursor
|
839
|
-
});
|
840
|
-
}
|
841
|
-
}
|
842
|
-
return annotations2;
|
843
|
-
};
|
844
|
-
const annotationsState = StateField.define({
|
845
|
-
create: (state) => {
|
846
|
-
return match(state);
|
847
|
-
},
|
848
|
-
update: (value, tr) => {
|
849
|
-
if (!tr.changes.empty) {
|
850
|
-
return match(tr.state);
|
851
|
-
}
|
852
|
-
return value;
|
853
|
-
}
|
854
|
-
});
|
855
|
-
return [
|
856
|
-
annotationsState,
|
857
|
-
EditorView2.decorations.compute([
|
858
|
-
annotationsState
|
859
|
-
], (state) => {
|
860
|
-
const annotations2 = state.field(annotationsState);
|
861
|
-
const decorations = annotations2.map((annotation) => {
|
862
|
-
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
863
|
-
return range && annotationMark.range(range.from, range.to);
|
864
|
-
}).filter(isNotFalsy);
|
865
|
-
return Decoration.set(decorations);
|
866
|
-
}),
|
867
|
-
styles
|
868
|
-
];
|
869
|
-
};
|
870
|
-
var styles = EditorView2.theme({
|
871
|
-
".cm-annotation": {
|
872
|
-
textDecoration: "underline",
|
873
|
-
textDecorationStyle: "wavy",
|
874
|
-
textDecorationColor: "var(--dx-error)"
|
875
|
-
}
|
876
|
-
});
|
877
|
-
|
878
|
-
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
879
|
-
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
880
|
-
import { markdownLanguage } from "@codemirror/lang-markdown";
|
881
|
-
import { keymap } from "@codemirror/view";
|
882
|
-
var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
883
|
-
const extensions = [
|
884
|
-
// https://codemirror.net/docs/ref/#view.keymap
|
885
|
-
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
886
|
-
// TODO(burdon): Set custom keymap.
|
887
|
-
keymap.of(completionKeymap),
|
888
|
-
// https://codemirror.net/examples/autocompletion
|
889
|
-
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
890
|
-
autocompletion({
|
891
|
-
activateOnTyping,
|
892
|
-
override,
|
893
|
-
closeOnBlur: !debug,
|
894
|
-
tooltipClass: () => "shadow rounded"
|
895
|
-
})
|
896
|
-
];
|
897
|
-
if (onSearch) {
|
898
|
-
extensions.push(
|
899
|
-
// TODO(burdon): Optional decoration via addToOptions
|
900
|
-
markdownLanguage.data.of({
|
901
|
-
autocomplete: (context) => {
|
902
|
-
const match = context.matchBefore(/\w*/);
|
903
|
-
if (!match || match.from === match.to && !context.explicit) {
|
904
|
-
return null;
|
905
|
-
}
|
906
|
-
return {
|
907
|
-
from: match.from,
|
908
|
-
options: onSearch(match.text.toLowerCase())
|
909
|
-
};
|
910
|
-
}
|
911
|
-
})
|
912
|
-
);
|
913
|
-
}
|
914
|
-
return extensions;
|
915
|
-
};
|
916
|
-
|
917
|
-
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
918
|
-
import { StateField as StateField2 } from "@codemirror/state";
|
919
|
-
import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
|
920
|
-
import { next as A3 } from "@dxos/automerge/automerge";
|
921
|
-
|
922
|
-
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
923
|
-
import { log as log2 } from "@dxos/log";
|
924
|
-
import { fromCursor, toCursor } from "@dxos/react-client/echo";
|
925
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
|
926
|
-
var cursorConverter = (accessor) => ({
|
927
|
-
toCursor: (pos, assoc) => {
|
928
|
-
try {
|
929
|
-
return toCursor(accessor, pos, assoc);
|
930
|
-
} catch (err) {
|
931
|
-
log2.catch(err, void 0, {
|
932
|
-
F: __dxlog_file2,
|
933
|
-
L: 15,
|
934
|
-
S: void 0,
|
935
|
-
C: (f, a) => f(...a)
|
936
|
-
});
|
937
|
-
return "";
|
938
|
-
}
|
335
|
+
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
336
|
+
import { StateField as StateField2 } from "@codemirror/state";
|
337
|
+
import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
|
338
|
+
import { next as A3 } from "@dxos/automerge/automerge";
|
339
|
+
|
340
|
+
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
341
|
+
import { log as log2 } from "@dxos/log";
|
342
|
+
import { fromCursor, toCursor } from "@dxos/react-client/echo";
|
343
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
|
344
|
+
var cursorConverter = (accessor) => ({
|
345
|
+
toCursor: (pos, assoc) => {
|
346
|
+
try {
|
347
|
+
return toCursor(accessor, pos, assoc);
|
348
|
+
} catch (err) {
|
349
|
+
log2.catch(err, void 0, {
|
350
|
+
F: __dxlog_file2,
|
351
|
+
L: 15,
|
352
|
+
S: void 0,
|
353
|
+
C: (f, a) => f(...a)
|
354
|
+
});
|
355
|
+
return "";
|
356
|
+
}
|
939
357
|
},
|
940
358
|
fromCursor: (cursor) => {
|
941
359
|
try {
|
@@ -1200,7 +618,7 @@ var automerge = (accessor) => {
|
|
1200
618
|
}
|
1201
619
|
}),
|
1202
620
|
// Reconcile local updates.
|
1203
|
-
|
621
|
+
EditorView2.updateListener.of(({ view, changes }) => {
|
1204
622
|
if (!changes.empty) {
|
1205
623
|
syncer.reconcile(view, true);
|
1206
624
|
}
|
@@ -1210,7 +628,7 @@ var automerge = (accessor) => {
|
|
1210
628
|
|
1211
629
|
// packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
|
1212
630
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
1213
|
-
import { Decoration as Decoration2, EditorView as
|
631
|
+
import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
1214
632
|
import { Event } from "@dxos/async";
|
1215
633
|
import { Context } from "@dxos/context";
|
1216
634
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
|
@@ -1384,7 +802,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
1384
802
|
return true;
|
1385
803
|
}
|
1386
804
|
};
|
1387
|
-
var styles2 =
|
805
|
+
var styles2 = EditorView3.theme({
|
1388
806
|
".cm-collab-selection": {},
|
1389
807
|
".cm-collab-selectionLine": {
|
1390
808
|
padding: 0,
|
@@ -1550,7 +968,7 @@ var SpaceAwarenessProvider = class {
|
|
1550
968
|
};
|
1551
969
|
|
1552
970
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
1553
|
-
import { EditorView as
|
971
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
1554
972
|
import defaultsDeep from "lodash.defaultsdeep";
|
1555
973
|
import { invariant as invariant2 } from "@dxos/invariant";
|
1556
974
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
@@ -1598,7 +1016,7 @@ var blast = (options = defaultOptions) => {
|
|
1598
1016
|
};
|
1599
1017
|
return [
|
1600
1018
|
// Cursor moved.
|
1601
|
-
|
1019
|
+
EditorView4.updateListener.of((update2) => {
|
1602
1020
|
if (blaster?.node !== update2.view.scrollDOM) {
|
1603
1021
|
if (blaster) {
|
1604
1022
|
blaster.destroy();
|
@@ -1972,11 +1390,11 @@ var commandKeyBindings = [
|
|
1972
1390
|
];
|
1973
1391
|
|
1974
1392
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
1975
|
-
import { EditorView as
|
1393
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
1976
1394
|
|
1977
1395
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
1978
1396
|
import { RangeSetBuilder } from "@codemirror/state";
|
1979
|
-
import { Decoration as Decoration3, EditorView as
|
1397
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
1980
1398
|
var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
1981
1399
|
constructor() {
|
1982
1400
|
this.deco = Decoration3.none;
|
@@ -2000,7 +1418,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
2000
1418
|
}
|
2001
1419
|
}, {
|
2002
1420
|
provide: (plugin) => [
|
2003
|
-
|
1421
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
2004
1422
|
]
|
2005
1423
|
});
|
2006
1424
|
var CommandHint = class extends WidgetType2 {
|
@@ -2119,10 +1537,10 @@ var command = (options = {}) => {
|
|
2119
1537
|
options.onHint ? hintViewPlugin({
|
2120
1538
|
onHint: options.onHint
|
2121
1539
|
}) : [],
|
2122
|
-
|
1540
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
2123
1541
|
return focusing ? closeEffect.of(null) : null;
|
2124
1542
|
}),
|
2125
|
-
|
1543
|
+
EditorView6.theme({
|
2126
1544
|
".cm-tooltip": {
|
2127
1545
|
background: "transparent"
|
2128
1546
|
}
|
@@ -2133,7 +1551,7 @@ var command = (options = {}) => {
|
|
2133
1551
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
2134
1552
|
import { invertedEffects } from "@codemirror/commands";
|
2135
1553
|
import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
2136
|
-
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as
|
1554
|
+
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
2137
1555
|
import sortBy from "lodash.sortby";
|
2138
1556
|
import { useEffect, useMemo as useMemo2 } from "react";
|
2139
1557
|
import { debounce as debounce2 } from "@dxos/async";
|
@@ -2142,7 +1560,7 @@ import { isNonNullable } from "@dxos/util";
|
|
2142
1560
|
|
2143
1561
|
// packages/ui/react-ui-editor/src/extensions/selection.ts
|
2144
1562
|
import { Transaction } from "@codemirror/state";
|
2145
|
-
import { EditorView as
|
1563
|
+
import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
|
2146
1564
|
import { debounce } from "@dxos/async";
|
2147
1565
|
import { invariant as invariant3 } from "@dxos/invariant";
|
2148
1566
|
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
@@ -2153,7 +1571,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
2153
1571
|
return {
|
2154
1572
|
selection,
|
2155
1573
|
scrollIntoView: !scrollTo,
|
2156
|
-
effects: scrollTo ?
|
1574
|
+
effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
|
2157
1575
|
yMargin: 96
|
2158
1576
|
}) : void 0,
|
2159
1577
|
annotations: Transaction.userEvent.of(stateRestoreAnnotation)
|
@@ -2195,7 +1613,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
2195
1613
|
// setStateDebounced(id, {});
|
2196
1614
|
// },
|
2197
1615
|
// }),
|
2198
|
-
|
1616
|
+
EditorView7.updateListener.of(({ view, transactions }) => {
|
2199
1617
|
const id = view.state.facet(documentId);
|
2200
1618
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
2201
1619
|
return;
|
@@ -2276,7 +1694,7 @@ var commentsState = StateField4.define({
|
|
2276
1694
|
return value;
|
2277
1695
|
}
|
2278
1696
|
});
|
2279
|
-
var styles3 =
|
1697
|
+
var styles3 = EditorView8.theme({
|
2280
1698
|
".cm-comment, .cm-comment-current": {
|
2281
1699
|
margin: "0 -3px",
|
2282
1700
|
padding: "3px",
|
@@ -2296,7 +1714,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
2296
1714
|
"data-comment-id": id
|
2297
1715
|
}
|
2298
1716
|
});
|
2299
|
-
var commentsDecorations =
|
1717
|
+
var commentsDecorations = EditorView8.decorations.compute([
|
2300
1718
|
commentsState
|
2301
1719
|
], (state) => {
|
2302
1720
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
@@ -2319,7 +1737,7 @@ var commentsDecorations = EditorView9.decorations.compute([
|
|
2319
1737
|
return Decoration4.set(decorations);
|
2320
1738
|
});
|
2321
1739
|
var commentClickedEffect = StateEffect3.define();
|
2322
|
-
var handleCommentClick =
|
1740
|
+
var handleCommentClick = EditorView8.domEventHandlers({
|
2323
1741
|
click: (event, view) => {
|
2324
1742
|
let target = event.target;
|
2325
1743
|
const editorRoot = view.dom;
|
@@ -2358,7 +1776,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2358
1776
|
}
|
2359
1777
|
};
|
2360
1778
|
return [
|
2361
|
-
|
1779
|
+
EditorView8.domEventHandlers({
|
2362
1780
|
cut: handleTrack,
|
2363
1781
|
copy: handleTrack
|
2364
1782
|
}),
|
@@ -2380,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2380
1798
|
return effects;
|
2381
1799
|
}),
|
2382
1800
|
// Handle paste or the undo of comment deletion.
|
2383
|
-
|
1801
|
+
EditorView8.updateListener.of((update2) => {
|
2384
1802
|
const restore = [];
|
2385
1803
|
for (let i = 0; i < update2.transactions.length; i++) {
|
2386
1804
|
const tr = update2.transactions[i];
|
@@ -2439,7 +1857,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
2439
1857
|
var restoreCommentEffect = StateEffect3.define({
|
2440
1858
|
map: mapTrackedComment
|
2441
1859
|
});
|
2442
|
-
var
|
1860
|
+
var createComment = (view) => {
|
2443
1861
|
const options = view.state.facet(optionsFacet);
|
2444
1862
|
const { from, to } = view.state.selection.main;
|
2445
1863
|
if (from === to) {
|
@@ -2484,7 +1902,7 @@ var comments = (options = {}) => {
|
|
2484
1902
|
options.onCreate && keymap5.of([
|
2485
1903
|
{
|
2486
1904
|
key: shortcut,
|
2487
|
-
run: callbackWrapper(
|
1905
|
+
run: callbackWrapper(createComment)
|
2488
1906
|
}
|
2489
1907
|
]),
|
2490
1908
|
//
|
@@ -2522,7 +1940,7 @@ var comments = (options = {}) => {
|
|
2522
1940
|
//
|
2523
1941
|
// Track deleted ranges and update ranges for decorations.
|
2524
1942
|
//
|
2525
|
-
|
1943
|
+
EditorView8.updateListener.of(({ view, state, changes }) => {
|
2526
1944
|
let mod = false;
|
2527
1945
|
const { comments: comments2, ...value } = state.field(commentsState);
|
2528
1946
|
changes.iterChanges((from, to, from2, to2) => {
|
@@ -2554,7 +1972,7 @@ var comments = (options = {}) => {
|
|
2554
1972
|
//
|
2555
1973
|
// Track selection/proximity.
|
2556
1974
|
//
|
2557
|
-
|
1975
|
+
EditorView8.updateListener.of(({ view, state }) => {
|
2558
1976
|
let min = Infinity;
|
2559
1977
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
2560
1978
|
const { head } = state.selection.main;
|
@@ -2608,7 +2026,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
2608
2026
|
anchor: range.from
|
2609
2027
|
} : void 0,
|
2610
2028
|
effects: [
|
2611
|
-
needsScroll ?
|
2029
|
+
needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
|
2612
2030
|
y: "center"
|
2613
2031
|
} : void 0) : [],
|
2614
2032
|
needsSelectionUpdate ? setSelection.of({
|
@@ -2660,7 +2078,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
|
|
2660
2078
|
}
|
2661
2079
|
});
|
2662
2080
|
var useCommentState = (state) => {
|
2663
|
-
return useMemo2(() =>
|
2081
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2664
2082
|
if (update2.docChanged || update2.selectionSet) {
|
2665
2083
|
state.comment = selectionOverlapsComment(update2.state);
|
2666
2084
|
state.selection = hasActiveSelection(update2.state);
|
@@ -2684,7 +2102,7 @@ var useComments = (view, id, comments2) => {
|
|
2684
2102
|
});
|
2685
2103
|
};
|
2686
2104
|
var useCommentClickListener = (onCommentClick) => {
|
2687
|
-
return useMemo2(() =>
|
2105
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2688
2106
|
update2.transactions.forEach((transaction) => {
|
2689
2107
|
transaction.effects.forEach((effect) => {
|
2690
2108
|
if (effect.is(commentClickedEffect)) {
|
@@ -2711,8 +2129,8 @@ var debugNodeLogger = (log8 = console.log) => {
|
|
2711
2129
|
};
|
2712
2130
|
|
2713
2131
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2714
|
-
import { dropCursor, EditorView as
|
2715
|
-
var styles4 =
|
2132
|
+
import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
|
2133
|
+
var styles4 = EditorView9.theme({
|
2716
2134
|
".cm-dropCursor": {
|
2717
2135
|
borderLeft: "2px solid var(--dx-accentText)",
|
2718
2136
|
color: "var(--dx-accentText)",
|
@@ -2726,7 +2144,7 @@ var dropFile = (options = {}) => {
|
|
2726
2144
|
return [
|
2727
2145
|
styles4,
|
2728
2146
|
dropCursor(),
|
2729
|
-
|
2147
|
+
EditorView9.domEventHandlers({
|
2730
2148
|
drop: (event, view) => {
|
2731
2149
|
event.preventDefault();
|
2732
2150
|
const files = event.dataTransfer?.files;
|
@@ -2753,7 +2171,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
|
|
2753
2171
|
import { searchKeymap } from "@codemirror/search";
|
2754
2172
|
import { EditorState } from "@codemirror/state";
|
2755
2173
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2756
|
-
import { EditorView as
|
2174
|
+
import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2757
2175
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
2758
2176
|
import merge from "lodash.merge";
|
2759
2177
|
import { generateName } from "@dxos/display-name";
|
@@ -2762,7 +2180,7 @@ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
2762
2180
|
|
2763
2181
|
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2764
2182
|
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2765
|
-
import { EditorView as
|
2183
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
2766
2184
|
var focusEffect = StateEffect4.define();
|
2767
2185
|
var focusField = StateField6.define({
|
2768
2186
|
create: () => false,
|
@@ -2777,19 +2195,251 @@ var focusField = StateField6.define({
|
|
2777
2195
|
});
|
2778
2196
|
var focus = [
|
2779
2197
|
focusField,
|
2780
|
-
|
2198
|
+
EditorView10.domEventHandlers({
|
2781
2199
|
focus: (event, view) => {
|
2782
2200
|
setTimeout(() => view.dispatch({
|
2783
2201
|
effects: focusEffect.of(true)
|
2784
2202
|
}));
|
2785
2203
|
},
|
2786
|
-
blur: (event, view) => {
|
2787
|
-
setTimeout(() => view.dispatch({
|
2788
|
-
effects: focusEffect.of(false)
|
2789
|
-
}));
|
2204
|
+
blur: (event, view) => {
|
2205
|
+
setTimeout(() => view.dispatch({
|
2206
|
+
effects: focusEffect.of(false)
|
2207
|
+
}));
|
2208
|
+
}
|
2209
|
+
})
|
2210
|
+
];
|
2211
|
+
|
2212
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
2213
|
+
import { mx } from "@dxos/react-ui-theme";
|
2214
|
+
var headings = {
|
2215
|
+
1: "text-4xl",
|
2216
|
+
2: "text-3xl",
|
2217
|
+
3: "text-2xl",
|
2218
|
+
4: "text-xl",
|
2219
|
+
5: "text-lg",
|
2220
|
+
6: ""
|
2221
|
+
};
|
2222
|
+
var theme = {
|
2223
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
2224
|
+
codeMark: "font-mono text-primary-500",
|
2225
|
+
mark: "opacity-50",
|
2226
|
+
heading: (level) => {
|
2227
|
+
return mx(headings[level], "dark:text-primary-400");
|
2228
|
+
}
|
2229
|
+
};
|
2230
|
+
|
2231
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
2232
|
+
import get from "lodash.get";
|
2233
|
+
import { tokens } from "@dxos/react-ui-theme";
|
2234
|
+
var getToken = (path, defaultValue) => {
|
2235
|
+
const value = get(tokens, path, defaultValue);
|
2236
|
+
return value?.toString() ?? "";
|
2237
|
+
};
|
2238
|
+
var fontBody = getToken("fontFamily.body");
|
2239
|
+
var fontMono = getToken("fontFamily.mono");
|
2240
|
+
|
2241
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
2242
|
+
var defaultTheme = {
|
2243
|
+
"&": {},
|
2244
|
+
"&.cm-focused": {
|
2245
|
+
outline: "none"
|
2246
|
+
},
|
2247
|
+
/**
|
2248
|
+
* Scroller
|
2249
|
+
*/
|
2250
|
+
".cm-scroller": {
|
2251
|
+
overflowY: "auto"
|
2252
|
+
},
|
2253
|
+
/**
|
2254
|
+
* Content
|
2255
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
2256
|
+
*/
|
2257
|
+
".cm-content": {
|
2258
|
+
padding: "unset",
|
2259
|
+
fontFamily: fontBody,
|
2260
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
2261
|
+
fontSize: "16px",
|
2262
|
+
lineHeight: 1.5,
|
2263
|
+
color: "unset"
|
2264
|
+
},
|
2265
|
+
/**
|
2266
|
+
* Gutters
|
2267
|
+
* NOTE: Gutters should have the same top margin as the content.
|
2268
|
+
*/
|
2269
|
+
".cm-gutters": {
|
2270
|
+
borderRight: "none",
|
2271
|
+
background: "transparent"
|
2272
|
+
},
|
2273
|
+
".cm-gutter": {},
|
2274
|
+
".cm-gutter.cm-lineNumbers": {
|
2275
|
+
paddingRight: "4px",
|
2276
|
+
borderRight: "1px solid var(--dx-separator)"
|
2277
|
+
},
|
2278
|
+
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
2279
|
+
minWidth: "40px",
|
2280
|
+
alignContent: "center"
|
2281
|
+
},
|
2282
|
+
/**
|
2283
|
+
* Height is set to match the corresponding line.
|
2284
|
+
*/
|
2285
|
+
".cm-gutterElement": {
|
2286
|
+
alignItems: "center",
|
2287
|
+
fontSize: "12px"
|
2288
|
+
},
|
2289
|
+
/**
|
2290
|
+
* Line.
|
2291
|
+
*/
|
2292
|
+
".cm-line": {
|
2293
|
+
paddingInline: 0
|
2294
|
+
},
|
2295
|
+
".cm-activeLine": {
|
2296
|
+
background: "var(--dx-cmActiveLine)"
|
2297
|
+
},
|
2298
|
+
/**
|
2299
|
+
* Cursor (layer).
|
2300
|
+
*/
|
2301
|
+
".cm-cursor, .cm-dropCursor": {
|
2302
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
2303
|
+
},
|
2304
|
+
".cm-placeholder": {
|
2305
|
+
color: "var(--dx-subdued)"
|
2306
|
+
},
|
2307
|
+
/**
|
2308
|
+
* Selection (layer).
|
2309
|
+
*/
|
2310
|
+
".cm-selectionBackground": {
|
2311
|
+
background: "var(--dx-cmSelection)"
|
2312
|
+
},
|
2313
|
+
/**
|
2314
|
+
* Search.
|
2315
|
+
* NOTE: Matches comment.
|
2316
|
+
*/
|
2317
|
+
".cm-searchMatch": {
|
2318
|
+
margin: "0 -3px",
|
2319
|
+
padding: "3px",
|
2320
|
+
borderRadius: "3px",
|
2321
|
+
background: "var(--dx-cmHighlightSurface)",
|
2322
|
+
color: "var(--dx-cmHighlight)"
|
2323
|
+
},
|
2324
|
+
".cm-searchMatch-selected": {
|
2325
|
+
textDecoration: "underline"
|
2326
|
+
},
|
2327
|
+
/**
|
2328
|
+
* Link.
|
2329
|
+
*/
|
2330
|
+
".cm-link": {
|
2331
|
+
textDecorationLine: "underline",
|
2332
|
+
textDecorationThickness: "1px",
|
2333
|
+
textDecorationColor: "var(--dx-separator)",
|
2334
|
+
textUnderlineOffset: "2px",
|
2335
|
+
borderRadius: ".125rem"
|
2336
|
+
},
|
2337
|
+
".cm-link > span": {
|
2338
|
+
color: "var(--dx-accentText)"
|
2339
|
+
},
|
2340
|
+
/**
|
2341
|
+
* Tooltip.
|
2342
|
+
*/
|
2343
|
+
".cm-tooltip": {
|
2344
|
+
background: "var(--dx-baseSurface)"
|
2345
|
+
},
|
2346
|
+
".cm-tooltip-below": {},
|
2347
|
+
/**
|
2348
|
+
* Autocomplete.
|
2349
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
2350
|
+
*/
|
2351
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
2352
|
+
marginTop: "4px",
|
2353
|
+
marginLeft: "-3px"
|
2354
|
+
},
|
2355
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
2356
|
+
maxHeight: "20em"
|
2357
|
+
},
|
2358
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
2359
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
2360
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
2361
|
+
paddingLeft: "4px !important",
|
2362
|
+
borderBottom: "none !important",
|
2363
|
+
color: "var(--dx-accentText)"
|
2364
|
+
},
|
2365
|
+
".cm-tooltip.cm-completionInfo": {
|
2366
|
+
width: "360px !important",
|
2367
|
+
margin: "-10px 1px 0 1px",
|
2368
|
+
padding: "8px !important",
|
2369
|
+
borderColor: "var(--dx-separator)"
|
2370
|
+
},
|
2371
|
+
".cm-completionIcon": {
|
2372
|
+
display: "none"
|
2373
|
+
},
|
2374
|
+
".cm-completionLabel": {
|
2375
|
+
fontFamily: fontBody
|
2376
|
+
},
|
2377
|
+
".cm-completionMatchedText": {
|
2378
|
+
textDecoration: "none !important",
|
2379
|
+
opacity: 0.5
|
2380
|
+
},
|
2381
|
+
/**
|
2382
|
+
* Panels
|
2383
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
2384
|
+
*
|
2385
|
+
* Find/replace panel.
|
2386
|
+
* <div class="cm-announced">...</div>
|
2387
|
+
* <div class="cm-scroller">...</div>
|
2388
|
+
* <div class="cm-panels cm-panels-bottom">
|
2389
|
+
* <div class="cm-search cm-panel">
|
2390
|
+
* <input class="cm-textfield" />
|
2391
|
+
* <button class="cm-button">...</button>
|
2392
|
+
* <label><input type="checkbox" />...</label>
|
2393
|
+
* </div>
|
2394
|
+
* </div
|
2395
|
+
*/
|
2396
|
+
// TODO(burdon): Implement custom panel (with icon buttons).
|
2397
|
+
".cm-panels": {},
|
2398
|
+
".cm-panel": {
|
2399
|
+
fontFamily: fontBody,
|
2400
|
+
backgroundColor: "var(--surface-bg)"
|
2401
|
+
},
|
2402
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
2403
|
+
color: "var(--dx-subdued)",
|
2404
|
+
fontFamily: fontBody,
|
2405
|
+
fontSize: "14px",
|
2406
|
+
all: "unset",
|
2407
|
+
margin: "3px !important",
|
2408
|
+
padding: "2px 6px !important",
|
2409
|
+
outline: "1px solid transparent"
|
2410
|
+
},
|
2411
|
+
".cm-panel input, .cm-panel button": {
|
2412
|
+
backgroundColor: "var(--dx-input)"
|
2413
|
+
},
|
2414
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
2415
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
2416
|
+
},
|
2417
|
+
".cm-panel label": {
|
2418
|
+
display: "inline-flex",
|
2419
|
+
alignItems: "center",
|
2420
|
+
cursor: "pointer"
|
2421
|
+
},
|
2422
|
+
".cm-panel input.cm-textfield": {},
|
2423
|
+
".cm-panel input[type=checkbox]": {
|
2424
|
+
width: "8px",
|
2425
|
+
height: "8px",
|
2426
|
+
marginRight: "6px !important",
|
2427
|
+
padding: "2px !important",
|
2428
|
+
color: "var(--dx-accentFocusIndicator)"
|
2429
|
+
},
|
2430
|
+
".cm-panel button": {
|
2431
|
+
"&:hover": {
|
2432
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
2433
|
+
},
|
2434
|
+
"&:active": {
|
2435
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
2790
2436
|
}
|
2791
|
-
}
|
2792
|
-
|
2437
|
+
},
|
2438
|
+
".cm-panel.cm-search": {
|
2439
|
+
padding: "4px",
|
2440
|
+
borderTop: "1px solid var(--dx-separator)"
|
2441
|
+
}
|
2442
|
+
};
|
2793
2443
|
|
2794
2444
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2795
2445
|
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
@@ -2815,7 +2465,7 @@ var createBasicExtensions = (_props) => {
|
|
2815
2465
|
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
2816
2466
|
return [
|
2817
2467
|
// NOTE: Doesn't catch errors in keymap functions.
|
2818
|
-
|
2468
|
+
EditorView11.exceptionSink.of((err) => {
|
2819
2469
|
log5.catch(err, void 0, {
|
2820
2470
|
F: __dxlog_file8,
|
2821
2471
|
L: 96,
|
@@ -2830,12 +2480,12 @@ var createBasicExtensions = (_props) => {
|
|
2830
2480
|
props.drawSelection && drawSelection({
|
2831
2481
|
cursorBlinkRate: 1200
|
2832
2482
|
}),
|
2833
|
-
props.editable !== void 0 &&
|
2483
|
+
props.editable !== void 0 && EditorView11.editable.of(props.editable),
|
2834
2484
|
props.focus && focus,
|
2835
2485
|
props.highlightActiveLine && highlightActiveLine(),
|
2836
2486
|
props.history && history(),
|
2837
2487
|
props.lineNumbers && lineNumbers(),
|
2838
|
-
props.lineWrapping &&
|
2488
|
+
props.lineWrapping && EditorView11.lineWrapping,
|
2839
2489
|
props.placeholder && placeholder(props.placeholder),
|
2840
2490
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
2841
2491
|
props.scrollPastEnd && scrollPastEnd(),
|
@@ -2872,14 +2522,14 @@ var defaultThemeSlots = {
|
|
2872
2522
|
var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
|
2873
2523
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
2874
2524
|
return [
|
2875
|
-
|
2876
|
-
|
2525
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
2526
|
+
EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
2877
2527
|
// https://github.com/codemirror/theme-one-dark
|
2878
2528
|
_syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
|
2879
|
-
slots.editor?.className &&
|
2529
|
+
slots.editor?.className && EditorView11.editorAttributes.of({
|
2880
2530
|
class: slots.editor.className
|
2881
2531
|
}),
|
2882
|
-
slots.content?.className &&
|
2532
|
+
slots.content?.className && EditorView11.contentAttributes.of({
|
2883
2533
|
class: slots.content.className
|
2884
2534
|
})
|
2885
2535
|
].filter(isNotFalsy3);
|
@@ -2908,8 +2558,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2908
2558
|
|
2909
2559
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
2910
2560
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
2911
|
-
import { EditorView as
|
2912
|
-
import
|
2561
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
2562
|
+
import React2 from "react";
|
2913
2563
|
import { Icon } from "@dxos/react-ui";
|
2914
2564
|
var folding = (_props = {}) => [
|
2915
2565
|
codeFolding({
|
@@ -2922,7 +2572,7 @@ var folding = (_props = {}) => [
|
|
2922
2572
|
const el = createElement("div", {
|
2923
2573
|
className: "flex h-full items-center"
|
2924
2574
|
});
|
2925
|
-
return renderRoot(el, /* @__PURE__ */
|
2575
|
+
return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
|
2926
2576
|
icon: "ph--caret-right--bold",
|
2927
2577
|
size: 3,
|
2928
2578
|
classNames: [
|
@@ -2932,7 +2582,7 @@ var folding = (_props = {}) => [
|
|
2932
2582
|
}));
|
2933
2583
|
}
|
2934
2584
|
}),
|
2935
|
-
|
2585
|
+
EditorView12.theme({
|
2936
2586
|
".cm-foldGutter": {
|
2937
2587
|
opacity: 0.3,
|
2938
2588
|
transition: "opacity 0.3s",
|
@@ -2945,14 +2595,14 @@ var folding = (_props = {}) => [
|
|
2945
2595
|
];
|
2946
2596
|
|
2947
2597
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
2948
|
-
import { EditorView as
|
2598
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
2949
2599
|
var listener = ({ onFocus, onChange }) => {
|
2950
2600
|
const extensions = [];
|
2951
|
-
onFocus && extensions.push(
|
2601
|
+
onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
|
2952
2602
|
onFocus(focusing);
|
2953
2603
|
return null;
|
2954
2604
|
}));
|
2955
|
-
onChange && extensions.push(
|
2605
|
+
onChange && extensions.push(EditorView13.updateListener.of((update2) => {
|
2956
2606
|
onChange(update2.state.doc.toString(), update2.state.facet(documentId));
|
2957
2607
|
}));
|
2958
2608
|
return extensions;
|
@@ -2962,7 +2612,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
2962
2612
|
import { snippet } from "@codemirror/autocomplete";
|
2963
2613
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
2964
2614
|
import { EditorSelection } from "@codemirror/state";
|
2965
|
-
import { EditorView as
|
2615
|
+
import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
|
2966
2616
|
import { useMemo as useMemo3 } from "react";
|
2967
2617
|
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;
|
2968
2618
|
var Inline;
|
@@ -4051,7 +3701,7 @@ var getFormatting = (state) => {
|
|
4051
3701
|
};
|
4052
3702
|
};
|
4053
3703
|
var useFormattingState = (state) => {
|
4054
|
-
return useMemo3(() =>
|
3704
|
+
return useMemo3(() => EditorView14.updateListener.of((update2) => {
|
4055
3705
|
if (update2.docChanged || update2.selectionSet) {
|
4056
3706
|
Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
|
4057
3707
|
state[key] = active;
|
@@ -4099,7 +3749,7 @@ var processEditorPayload = (view, { type, data }) => {
|
|
4099
3749
|
})(view);
|
4100
3750
|
break;
|
4101
3751
|
case "comment":
|
4102
|
-
|
3752
|
+
createComment(view);
|
4103
3753
|
break;
|
4104
3754
|
}
|
4105
3755
|
requestAnimationFrame(() => {
|
@@ -4363,9 +4013,9 @@ var convertTreeToJson = (state) => {
|
|
4363
4013
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
4364
4014
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
4365
4015
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
|
4366
|
-
import { EditorView as
|
4016
|
+
import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
4367
4017
|
import { invariant as invariant4 } from "@dxos/invariant";
|
4368
|
-
import { mx as
|
4018
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
4369
4019
|
|
4370
4020
|
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
4371
4021
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
@@ -4514,7 +4164,7 @@ var getValidUrl = (str) => {
|
|
4514
4164
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
4515
4165
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
4516
4166
|
import { StateField as StateField8 } from "@codemirror/state";
|
4517
|
-
import { Decoration as Decoration5, EditorView as
|
4167
|
+
import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
|
4518
4168
|
var image = (_options = {}) => {
|
4519
4169
|
return [
|
4520
4170
|
StateField8.define({
|
@@ -4542,7 +4192,7 @@ var image = (_options = {}) => {
|
|
4542
4192
|
add: buildDecorations(from, to, tr.state)
|
4543
4193
|
});
|
4544
4194
|
},
|
4545
|
-
provide: (field) =>
|
4195
|
+
provide: (field) => EditorView15.decorations.from(field)
|
4546
4196
|
})
|
4547
4197
|
];
|
4548
4198
|
};
|
@@ -4602,10 +4252,10 @@ var ImageWidget = class extends WidgetType3 {
|
|
4602
4252
|
};
|
4603
4253
|
|
4604
4254
|
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
4605
|
-
import { EditorView as
|
4255
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
4606
4256
|
var bulletListIndentationWidth = 24;
|
4607
4257
|
var orderedListIndentationWidth = 36;
|
4608
|
-
var formattingStyles =
|
4258
|
+
var formattingStyles = EditorView16.theme({
|
4609
4259
|
/**
|
4610
4260
|
* Horizontal rule.
|
4611
4261
|
*/
|
@@ -4726,12 +4376,12 @@ var formattingStyles = EditorView17.theme({
|
|
4726
4376
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
4727
4377
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
4728
4378
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
|
4729
|
-
import { Decoration as Decoration6, EditorView as
|
4379
|
+
import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
|
4730
4380
|
var table = (options = {}) => {
|
4731
4381
|
return StateField9.define({
|
4732
4382
|
create: (state) => update(state, options),
|
4733
4383
|
update: (_, tr) => update(tr.state, options),
|
4734
|
-
provide: (field) =>
|
4384
|
+
provide: (field) => EditorView17.decorations.from(field)
|
4735
4385
|
});
|
4736
4386
|
};
|
4737
4387
|
var update = (state, _options) => {
|
@@ -4917,16 +4567,16 @@ var TextWidget = class extends WidgetType5 {
|
|
4917
4567
|
};
|
4918
4568
|
var hide = Decoration7.replace({});
|
4919
4569
|
var blockQuote = Decoration7.line({
|
4920
|
-
class:
|
4570
|
+
class: mx2("cm-blockquote")
|
4921
4571
|
});
|
4922
4572
|
var fencedCodeLine = Decoration7.line({
|
4923
|
-
class:
|
4573
|
+
class: mx2("cm-code cm-codeblock-line")
|
4924
4574
|
});
|
4925
4575
|
var fencedCodeLineFirst = Decoration7.line({
|
4926
|
-
class:
|
4576
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
4927
4577
|
});
|
4928
4578
|
var fencedCodeLineLast = Decoration7.line({
|
4929
|
-
class:
|
4579
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
4930
4580
|
});
|
4931
4581
|
var commentBlockLine = fencedCodeLine;
|
4932
4582
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
@@ -4981,662 +4631,1081 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
4981
4631
|
} else {
|
4982
4632
|
headerLevels.splice(level);
|
4983
4633
|
}
|
4984
|
-
return headerLevels.slice(0, level);
|
4985
|
-
};
|
4986
|
-
const listLevels = [];
|
4987
|
-
const enterList = (node) => {
|
4988
|
-
listLevels.push({
|
4989
|
-
type: node.name,
|
4990
|
-
from: node.from,
|
4991
|
-
to: node.to,
|
4992
|
-
level: listLevels.length,
|
4993
|
-
number: 0
|
4994
|
-
});
|
4634
|
+
return headerLevels.slice(0, level);
|
4635
|
+
};
|
4636
|
+
const listLevels = [];
|
4637
|
+
const enterList = (node) => {
|
4638
|
+
listLevels.push({
|
4639
|
+
type: node.name,
|
4640
|
+
from: node.from,
|
4641
|
+
to: node.to,
|
4642
|
+
level: listLevels.length,
|
4643
|
+
number: 0
|
4644
|
+
});
|
4645
|
+
};
|
4646
|
+
const leaveList = () => {
|
4647
|
+
listLevels.pop();
|
4648
|
+
};
|
4649
|
+
const getCurrentListLevel = () => {
|
4650
|
+
invariant4(listLevels.length, void 0, {
|
4651
|
+
F: __dxlog_file9,
|
4652
|
+
L: 201,
|
4653
|
+
S: void 0,
|
4654
|
+
A: [
|
4655
|
+
"listLevels.length",
|
4656
|
+
""
|
4657
|
+
]
|
4658
|
+
});
|
4659
|
+
return listLevels[listLevels.length - 1];
|
4660
|
+
};
|
4661
|
+
const enterNode = (node) => {
|
4662
|
+
switch (node.name) {
|
4663
|
+
// ATXHeading > HeaderMark > Paragraph
|
4664
|
+
// NOTE: Numbering requires processing the entire document since otherwise only the visible range will be
|
4665
|
+
// processed and the numbering will be incorrect.
|
4666
|
+
case "ATXHeading1":
|
4667
|
+
case "ATXHeading2":
|
4668
|
+
case "ATXHeading3":
|
4669
|
+
case "ATXHeading4":
|
4670
|
+
case "ATXHeading5":
|
4671
|
+
case "ATXHeading6": {
|
4672
|
+
const level = parseInt(node.name["ATXHeading".length]);
|
4673
|
+
const headers = getHeaderLevels(node, level);
|
4674
|
+
if (options.numberedHeadings?.from !== void 0) {
|
4675
|
+
const header = headers[level - 1];
|
4676
|
+
if (header) {
|
4677
|
+
header.number++;
|
4678
|
+
}
|
4679
|
+
}
|
4680
|
+
const editing = editingRange(state, node, focus2);
|
4681
|
+
if (editing) {
|
4682
|
+
break;
|
4683
|
+
}
|
4684
|
+
const mark = node.node.firstChild;
|
4685
|
+
if (mark?.name === "HeaderMark") {
|
4686
|
+
const { from, to = 6 } = options.numberedHeadings ?? {};
|
4687
|
+
const text = view.state.sliceDoc(node.from, node.to);
|
4688
|
+
const len = text.match(/[#\s]+/)[0].length;
|
4689
|
+
if (!from || level < from || level > to) {
|
4690
|
+
atomicDeco.add(mark.from, mark.from + len, hide);
|
4691
|
+
} else {
|
4692
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
4693
|
+
if (num.length) {
|
4694
|
+
atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
|
4695
|
+
widget: new TextWidget(num, theme.heading(level))
|
4696
|
+
}));
|
4697
|
+
}
|
4698
|
+
}
|
4699
|
+
}
|
4700
|
+
return false;
|
4701
|
+
}
|
4702
|
+
//
|
4703
|
+
// Lists.
|
4704
|
+
// [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?
|
4705
|
+
//
|
4706
|
+
case "BulletList":
|
4707
|
+
case "OrderedList": {
|
4708
|
+
enterList(node);
|
4709
|
+
break;
|
4710
|
+
}
|
4711
|
+
case "ListItem": {
|
4712
|
+
const line = state.doc.lineAt(node.from);
|
4713
|
+
const list = getCurrentListLevel();
|
4714
|
+
const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
|
4715
|
+
const offset = ((list.level ?? 0) + 1) * width;
|
4716
|
+
if (node.from === line.to - 1) {
|
4717
|
+
return false;
|
4718
|
+
}
|
4719
|
+
deco.add(line.from, line.from, Decoration7.line({
|
4720
|
+
class: "cm-list-item",
|
4721
|
+
attributes: {
|
4722
|
+
style: `padding-left: ${offset}px; text-indent: -${width}px;`
|
4723
|
+
}
|
4724
|
+
}));
|
4725
|
+
break;
|
4726
|
+
}
|
4727
|
+
case "ListMark": {
|
4728
|
+
const list = getCurrentListLevel();
|
4729
|
+
const next = tree.resolve(node.to + 1, 1);
|
4730
|
+
if (next?.name === "TaskMarker") {
|
4731
|
+
break;
|
4732
|
+
}
|
4733
|
+
const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
|
4734
|
+
const line = state.doc.lineAt(node.from);
|
4735
|
+
const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
|
4736
|
+
atomicDeco.add(line.from, to, Decoration7.replace({
|
4737
|
+
widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
|
4738
|
+
}));
|
4739
|
+
break;
|
4740
|
+
}
|
4741
|
+
case "TaskMarker": {
|
4742
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
4743
|
+
const line = state.doc.lineAt(node.from);
|
4744
|
+
const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
|
4745
|
+
atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
|
4746
|
+
break;
|
4747
|
+
}
|
4748
|
+
//
|
4749
|
+
// Blockquote > QuoteMark > Paragraph
|
4750
|
+
//
|
4751
|
+
case "Blockquote": {
|
4752
|
+
const editing = editingRange(state, node, focus2);
|
4753
|
+
const quoteMark = node.node.getChild("QuoteMark");
|
4754
|
+
const paragraph = node.node.getChild("Paragraph");
|
4755
|
+
if (!editing && quoteMark && paragraph) {
|
4756
|
+
atomicDeco.add(quoteMark.from, paragraph.from, hide);
|
4757
|
+
}
|
4758
|
+
for (const block of view.viewportLineBlocks) {
|
4759
|
+
if (block.to < node.from) {
|
4760
|
+
continue;
|
4761
|
+
}
|
4762
|
+
if (block.from > node.to) {
|
4763
|
+
break;
|
4764
|
+
}
|
4765
|
+
deco.add(block.from, block.from, blockQuote);
|
4766
|
+
}
|
4767
|
+
break;
|
4768
|
+
}
|
4769
|
+
//
|
4770
|
+
// CommentBlock
|
4771
|
+
//
|
4772
|
+
case "CommentBlock": {
|
4773
|
+
const editing = editingRange(state, node, focus2);
|
4774
|
+
for (const block of view.viewportLineBlocks) {
|
4775
|
+
if (block.to < node.from) {
|
4776
|
+
continue;
|
4777
|
+
}
|
4778
|
+
if (block.from > node.to) {
|
4779
|
+
break;
|
4780
|
+
}
|
4781
|
+
const isFirst = block.from <= node.from;
|
4782
|
+
const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
|
4783
|
+
deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
|
4784
|
+
if (!editing && (isFirst || isLast)) {
|
4785
|
+
atomicDeco.add(block.from, block.to, hide);
|
4786
|
+
}
|
4787
|
+
}
|
4788
|
+
break;
|
4789
|
+
}
|
4790
|
+
//
|
4791
|
+
// FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
|
4792
|
+
//
|
4793
|
+
case "FencedCode": {
|
4794
|
+
for (const block of view.viewportLineBlocks) {
|
4795
|
+
if (block.to < node.from) {
|
4796
|
+
continue;
|
4797
|
+
}
|
4798
|
+
if (block.from > node.to) {
|
4799
|
+
break;
|
4800
|
+
}
|
4801
|
+
const first = block.from <= node.from;
|
4802
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
4803
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
4804
|
+
const editing = editingRange(state, node, focus2);
|
4805
|
+
if (!editing && (first || last)) {
|
4806
|
+
atomicDeco.add(block.from, block.to, hide);
|
4807
|
+
}
|
4808
|
+
}
|
4809
|
+
return false;
|
4810
|
+
}
|
4811
|
+
//
|
4812
|
+
// Link > [LinkMark, URL]
|
4813
|
+
//
|
4814
|
+
case "Link": {
|
4815
|
+
const marks = node.node.getChildren("LinkMark");
|
4816
|
+
const urlNode = node.node.getChild("URL");
|
4817
|
+
const editing = editingRange(state, node, focus2);
|
4818
|
+
if (urlNode && marks.length >= 2) {
|
4819
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
4820
|
+
if (!editing) {
|
4821
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
4822
|
+
}
|
4823
|
+
deco.add(marks[0].to, marks[1].from, Decoration7.mark({
|
4824
|
+
tagName: "a",
|
4825
|
+
attributes: {
|
4826
|
+
class: "cm-link",
|
4827
|
+
href: url,
|
4828
|
+
rel: "noreferrer",
|
4829
|
+
target: "_blank"
|
4830
|
+
}
|
4831
|
+
}));
|
4832
|
+
if (!editing) {
|
4833
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
|
4834
|
+
widget: new LinkButton(url, options.renderLinkButton)
|
4835
|
+
}) : hide);
|
4836
|
+
}
|
4837
|
+
}
|
4838
|
+
break;
|
4839
|
+
}
|
4840
|
+
//
|
4841
|
+
// HR
|
4842
|
+
//
|
4843
|
+
case "HorizontalRule": {
|
4844
|
+
if (!editingRange(state, node, focus2)) {
|
4845
|
+
deco.add(node.from, node.to, horizontalRule);
|
4846
|
+
}
|
4847
|
+
break;
|
4848
|
+
}
|
4849
|
+
default: {
|
4850
|
+
if (autoHideTags.has(node.name)) {
|
4851
|
+
if (!editingRange(state, node.node.parent, focus2)) {
|
4852
|
+
atomicDeco.add(node.from, node.to, hide);
|
4853
|
+
}
|
4854
|
+
}
|
4855
|
+
}
|
4856
|
+
}
|
4995
4857
|
};
|
4996
|
-
const
|
4997
|
-
|
4858
|
+
const leaveNode = (node) => {
|
4859
|
+
switch (node.name) {
|
4860
|
+
case "BulletList":
|
4861
|
+
case "OrderedList": {
|
4862
|
+
leaveList();
|
4863
|
+
break;
|
4864
|
+
}
|
4865
|
+
}
|
4998
4866
|
};
|
4999
|
-
const
|
5000
|
-
|
5001
|
-
|
5002
|
-
|
5003
|
-
|
5004
|
-
|
5005
|
-
|
5006
|
-
|
5007
|
-
|
4867
|
+
const tree = syntaxTree7(state);
|
4868
|
+
if (options.numberedHeadings?.from === void 0) {
|
4869
|
+
for (const { from, to } of view.visibleRanges) {
|
4870
|
+
tree.iterate({
|
4871
|
+
from,
|
4872
|
+
to,
|
4873
|
+
enter: wrapWithCatch(enterNode),
|
4874
|
+
leave: wrapWithCatch(leaveNode)
|
4875
|
+
});
|
4876
|
+
}
|
4877
|
+
} else {
|
4878
|
+
tree.iterate({
|
4879
|
+
enter: wrapWithCatch(enterNode),
|
4880
|
+
leave: wrapWithCatch(leaveNode)
|
5008
4881
|
});
|
5009
|
-
|
4882
|
+
}
|
4883
|
+
return {
|
4884
|
+
deco: deco.finish(),
|
4885
|
+
atomicDeco: atomicDeco.finish()
|
5010
4886
|
};
|
5011
|
-
|
5012
|
-
|
5013
|
-
|
5014
|
-
|
5015
|
-
|
5016
|
-
|
5017
|
-
|
5018
|
-
|
5019
|
-
|
5020
|
-
|
5021
|
-
|
5022
|
-
|
5023
|
-
|
5024
|
-
|
5025
|
-
const header = headers[level - 1];
|
5026
|
-
if (header) {
|
5027
|
-
header.number++;
|
5028
|
-
}
|
4887
|
+
};
|
4888
|
+
var forceUpdate = StateEffect5.define();
|
4889
|
+
var decorateMarkdown = (options = {}) => {
|
4890
|
+
return [
|
4891
|
+
ViewPlugin7.fromClass(class {
|
4892
|
+
constructor(view) {
|
4893
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
|
4894
|
+
}
|
4895
|
+
update(update2) {
|
4896
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
4897
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
|
4898
|
+
this.clearUpdate();
|
4899
|
+
} else if (update2.selectionSet) {
|
4900
|
+
this.scheduleUpdate(update2.view);
|
5029
4901
|
}
|
5030
|
-
|
5031
|
-
|
5032
|
-
|
4902
|
+
}
|
4903
|
+
// Defer update in case moving through the document.
|
4904
|
+
scheduleUpdate(view) {
|
4905
|
+
this.clearUpdate();
|
4906
|
+
this.pendingUpdate = setTimeout(() => {
|
4907
|
+
view.dispatch({
|
4908
|
+
effects: forceUpdate.of(null)
|
4909
|
+
});
|
4910
|
+
}, options.selectionChangeDelay);
|
4911
|
+
}
|
4912
|
+
clearUpdate() {
|
4913
|
+
if (this.pendingUpdate) {
|
4914
|
+
clearTimeout(this.pendingUpdate);
|
4915
|
+
this.pendingUpdate = void 0;
|
5033
4916
|
}
|
5034
|
-
|
5035
|
-
|
5036
|
-
|
5037
|
-
|
5038
|
-
|
5039
|
-
|
5040
|
-
|
5041
|
-
|
5042
|
-
|
5043
|
-
|
5044
|
-
|
5045
|
-
|
5046
|
-
|
5047
|
-
|
4917
|
+
}
|
4918
|
+
destroy() {
|
4919
|
+
this.clearUpdate();
|
4920
|
+
}
|
4921
|
+
}, {
|
4922
|
+
provide: (plugin) => [
|
4923
|
+
EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4924
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4925
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
4926
|
+
]
|
4927
|
+
}),
|
4928
|
+
image(),
|
4929
|
+
table(),
|
4930
|
+
adjustChanges(),
|
4931
|
+
formattingStyles
|
4932
|
+
];
|
4933
|
+
};
|
4934
|
+
|
4935
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
4936
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
4937
|
+
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
4938
|
+
import { tooltipContent } from "@dxos/react-ui-theme";
|
4939
|
+
var linkTooltip = (renderTooltip) => {
|
4940
|
+
return hoverTooltip2((view, pos, side) => {
|
4941
|
+
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
4942
|
+
let link = null;
|
4943
|
+
for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
|
4944
|
+
link = node.name === "Link" ? node : null;
|
4945
|
+
}
|
4946
|
+
const url = link && link.getChild("URL");
|
4947
|
+
if (!url || !link) {
|
4948
|
+
return null;
|
4949
|
+
}
|
4950
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
4951
|
+
return {
|
4952
|
+
pos: link.from,
|
4953
|
+
end: link.to,
|
4954
|
+
// NOTE: Forcing above causes the tooltip to flicker.
|
4955
|
+
// above: true,
|
4956
|
+
create: () => {
|
4957
|
+
const el = document.createElement("div");
|
4958
|
+
el.className = tooltipContent({});
|
4959
|
+
renderTooltip(el, {
|
4960
|
+
url: urlText
|
4961
|
+
}, view);
|
4962
|
+
return {
|
4963
|
+
dom: el,
|
4964
|
+
offset: {
|
4965
|
+
x: 0,
|
4966
|
+
y: 4
|
5048
4967
|
}
|
4968
|
+
};
|
4969
|
+
}
|
4970
|
+
};
|
4971
|
+
}, {
|
4972
|
+
// NOTE: 0 = default of 300ms.
|
4973
|
+
hoverTime: 1
|
4974
|
+
});
|
4975
|
+
};
|
4976
|
+
|
4977
|
+
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
4978
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
4979
|
+
import { log as log6 } from "@dxos/log";
|
4980
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
4981
|
+
var mention = ({ debug, onSearch }) => {
|
4982
|
+
return autocompletion2({
|
4983
|
+
// TODO(burdon): Not working.
|
4984
|
+
activateOnTyping: true,
|
4985
|
+
// activateOnTypingDelay: 100,
|
4986
|
+
// selectOnOpen: true,
|
4987
|
+
closeOnBlur: !debug,
|
4988
|
+
// defaultKeymap: false,
|
4989
|
+
icons: false,
|
4990
|
+
override: [
|
4991
|
+
(context) => {
|
4992
|
+
log6.info("completion context", {
|
4993
|
+
context
|
4994
|
+
}, {
|
4995
|
+
F: __dxlog_file10,
|
4996
|
+
L: 27,
|
4997
|
+
S: void 0,
|
4998
|
+
C: (f, a) => f(...a)
|
4999
|
+
});
|
5000
|
+
const match = context.matchBefore(/@(\w+)?/);
|
5001
|
+
if (!match || match.from === match.to && !context.explicit) {
|
5002
|
+
return null;
|
5003
|
+
}
|
5004
|
+
return {
|
5005
|
+
from: match.from,
|
5006
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5007
|
+
label: `@${value}`
|
5008
|
+
}))
|
5009
|
+
};
|
5010
|
+
}
|
5011
|
+
]
|
5012
|
+
});
|
5013
|
+
};
|
5014
|
+
|
5015
|
+
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
5016
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
5017
|
+
import { vim } from "@replit/codemirror-vim";
|
5018
|
+
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
5019
|
+
import { Schema } from "effect";
|
5020
|
+
var EditorViewModes = [
|
5021
|
+
"preview",
|
5022
|
+
"readonly",
|
5023
|
+
"source"
|
5024
|
+
];
|
5025
|
+
var EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
|
5026
|
+
var EditorInputModes = [
|
5027
|
+
"default",
|
5028
|
+
"vim",
|
5029
|
+
"vscode"
|
5030
|
+
];
|
5031
|
+
var EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
|
5032
|
+
var editorInputMode = singleValueFacet({});
|
5033
|
+
var InputModeExtensions = {
|
5034
|
+
default: [],
|
5035
|
+
vscode: [
|
5036
|
+
// https://github.com/replit/codemirror-vscode-keymap
|
5037
|
+
editorInputMode.of({
|
5038
|
+
type: "vscode"
|
5039
|
+
}),
|
5040
|
+
keymap9.of(vscodeKeymap)
|
5041
|
+
],
|
5042
|
+
vim: [
|
5043
|
+
// https://github.com/replit/codemirror-vim
|
5044
|
+
vim(),
|
5045
|
+
editorInputMode.of({
|
5046
|
+
type: "vim",
|
5047
|
+
noTabster: true
|
5048
|
+
}),
|
5049
|
+
keymap9.of([
|
5050
|
+
{
|
5051
|
+
key: "Alt-Escape",
|
5052
|
+
run: (view) => {
|
5053
|
+
view.dom.parentElement?.focus();
|
5054
|
+
return true;
|
5049
5055
|
}
|
5050
|
-
return false;
|
5051
5056
|
}
|
5052
|
-
|
5053
|
-
|
5054
|
-
|
5055
|
-
|
5056
|
-
|
5057
|
-
|
5058
|
-
|
5059
|
-
|
5057
|
+
])
|
5058
|
+
]
|
5059
|
+
};
|
5060
|
+
|
5061
|
+
// packages/ui/react-ui-editor/src/extensions/preview/preview.ts
|
5062
|
+
import "@dxos/lit-ui/dx-ref-tag.pcss";
|
5063
|
+
import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
5064
|
+
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
|
5065
|
+
import { Decoration as Decoration8, EditorView as EditorView19, WidgetType as WidgetType6 } from "@codemirror/view";
|
5066
|
+
var preview = (options = {}) => {
|
5067
|
+
return [
|
5068
|
+
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5069
|
+
// "Block decorations may not be specified via plugins"
|
5070
|
+
StateField10.define({
|
5071
|
+
create: (state) => buildDecorations3(state, options),
|
5072
|
+
update: (_, tr) => buildDecorations3(tr.state, options),
|
5073
|
+
provide: (field) => [
|
5074
|
+
EditorView19.decorations.from(field),
|
5075
|
+
EditorView19.atomicRanges.of((view) => view.state.field(field))
|
5076
|
+
]
|
5077
|
+
}),
|
5078
|
+
EditorView19.theme({
|
5079
|
+
".cm-preview-block": {
|
5080
|
+
marginLeft: "-1rem",
|
5081
|
+
marginRight: "-1rem",
|
5082
|
+
padding: "1rem",
|
5083
|
+
borderRadius: "0.5rem",
|
5084
|
+
background: "var(--dx-modalSurface)",
|
5085
|
+
border: "1px solid var(--dx-separator)"
|
5060
5086
|
}
|
5061
|
-
|
5062
|
-
|
5063
|
-
|
5064
|
-
|
5065
|
-
|
5066
|
-
|
5067
|
-
|
5068
|
-
|
5069
|
-
|
5070
|
-
|
5071
|
-
|
5072
|
-
|
5087
|
+
})
|
5088
|
+
];
|
5089
|
+
};
|
5090
|
+
var getLinkRef = (state, node) => {
|
5091
|
+
const mark = node.getChild("LinkMark");
|
5092
|
+
const label = node.getChild("LinkLabel");
|
5093
|
+
if (mark && label) {
|
5094
|
+
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5095
|
+
return {
|
5096
|
+
suggest: ref.startsWith("?"),
|
5097
|
+
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5098
|
+
label: state.sliceDoc(mark.to, label.from - 1),
|
5099
|
+
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5100
|
+
};
|
5101
|
+
}
|
5102
|
+
};
|
5103
|
+
var buildDecorations3 = (state, options) => {
|
5104
|
+
const builder = new RangeSetBuilder4();
|
5105
|
+
syntaxTree9(state).iterate({
|
5106
|
+
enter: (node) => {
|
5107
|
+
switch (node.name) {
|
5108
|
+
//
|
5109
|
+
// Decoration.
|
5110
|
+
// [Label][dxn:echo:123]
|
5111
|
+
//
|
5112
|
+
case "Link": {
|
5113
|
+
const link = getLinkRef(state, node.node);
|
5114
|
+
if (link) {
|
5115
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
5116
|
+
widget: new PreviewInlineWidget(options, link)
|
5117
|
+
}));
|
5073
5118
|
}
|
5074
|
-
}));
|
5075
|
-
break;
|
5076
|
-
}
|
5077
|
-
case "ListMark": {
|
5078
|
-
const list = getCurrentListLevel();
|
5079
|
-
const next = tree.resolve(node.to + 1, 1);
|
5080
|
-
if (next?.name === "TaskMarker") {
|
5081
5119
|
break;
|
5082
5120
|
}
|
5083
|
-
|
5084
|
-
|
5085
|
-
|
5086
|
-
|
5087
|
-
|
5088
|
-
|
5089
|
-
|
5090
|
-
|
5091
|
-
|
5092
|
-
|
5093
|
-
|
5094
|
-
|
5095
|
-
atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
|
5096
|
-
break;
|
5097
|
-
}
|
5098
|
-
//
|
5099
|
-
// Blockquote > QuoteMark > Paragraph
|
5100
|
-
//
|
5101
|
-
case "Blockquote": {
|
5102
|
-
const editing = editingRange(state, node, focus2);
|
5103
|
-
const quoteMark = node.node.getChild("QuoteMark");
|
5104
|
-
const paragraph = node.node.getChild("Paragraph");
|
5105
|
-
if (!editing && quoteMark && paragraph) {
|
5106
|
-
atomicDeco.add(quoteMark.from, paragraph.from, hide);
|
5107
|
-
}
|
5108
|
-
for (const block of view.viewportLineBlocks) {
|
5109
|
-
if (block.to < node.from) {
|
5110
|
-
continue;
|
5111
|
-
}
|
5112
|
-
if (block.from > node.to) {
|
5113
|
-
break;
|
5114
|
-
}
|
5115
|
-
deco.add(block.from, block.from, blockQuote);
|
5116
|
-
}
|
5117
|
-
break;
|
5118
|
-
}
|
5119
|
-
//
|
5120
|
-
// CommentBlock
|
5121
|
-
//
|
5122
|
-
case "CommentBlock": {
|
5123
|
-
const editing = editingRange(state, node, focus2);
|
5124
|
-
for (const block of view.viewportLineBlocks) {
|
5125
|
-
if (block.to < node.from) {
|
5126
|
-
continue;
|
5127
|
-
}
|
5128
|
-
if (block.from > node.to) {
|
5129
|
-
break;
|
5130
|
-
}
|
5131
|
-
const isFirst = block.from <= node.from;
|
5132
|
-
const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
|
5133
|
-
deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
|
5134
|
-
if (!editing && (isFirst || isLast)) {
|
5135
|
-
atomicDeco.add(block.from, block.to, hide);
|
5136
|
-
}
|
5137
|
-
}
|
5138
|
-
break;
|
5139
|
-
}
|
5140
|
-
//
|
5141
|
-
// FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
|
5142
|
-
//
|
5143
|
-
case "FencedCode": {
|
5144
|
-
for (const block of view.viewportLineBlocks) {
|
5145
|
-
if (block.to < node.from) {
|
5146
|
-
continue;
|
5147
|
-
}
|
5148
|
-
if (block.from > node.to) {
|
5149
|
-
break;
|
5150
|
-
}
|
5151
|
-
const first = block.from <= node.from;
|
5152
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
|
5153
|
-
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
5154
|
-
const editing = editingRange(state, node, focus2);
|
5155
|
-
if (!editing && (first || last)) {
|
5156
|
-
atomicDeco.add(block.from, block.to, hide);
|
5121
|
+
//
|
5122
|
+
// Block widget.
|
5123
|
+
// ![Label][dxn:echo:123]
|
5124
|
+
//
|
5125
|
+
case "Image": {
|
5126
|
+
const link = getLinkRef(state, node.node);
|
5127
|
+
if (options.renderBlock && link) {
|
5128
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
5129
|
+
block: true,
|
5130
|
+
// atomic: true,
|
5131
|
+
widget: new PreviewBlockWidget(options, link)
|
5132
|
+
}));
|
5157
5133
|
}
|
5134
|
+
break;
|
5158
5135
|
}
|
5159
|
-
return false;
|
5160
5136
|
}
|
5161
|
-
|
5162
|
-
|
5163
|
-
|
5164
|
-
|
5165
|
-
|
5166
|
-
|
5167
|
-
|
5168
|
-
|
5169
|
-
|
5170
|
-
|
5171
|
-
|
5172
|
-
|
5173
|
-
|
5174
|
-
|
5175
|
-
|
5176
|
-
|
5177
|
-
|
5178
|
-
|
5179
|
-
|
5180
|
-
|
5181
|
-
|
5182
|
-
|
5183
|
-
|
5184
|
-
|
5185
|
-
|
5186
|
-
|
5187
|
-
|
5188
|
-
|
5137
|
+
}
|
5138
|
+
});
|
5139
|
+
return builder.finish();
|
5140
|
+
};
|
5141
|
+
var PreviewInlineWidget = class extends WidgetType6 {
|
5142
|
+
constructor(_options, _link) {
|
5143
|
+
super();
|
5144
|
+
this._options = _options;
|
5145
|
+
this._link = _link;
|
5146
|
+
}
|
5147
|
+
// override ignoreEvent() {
|
5148
|
+
// return false;
|
5149
|
+
// }
|
5150
|
+
eq(other) {
|
5151
|
+
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5152
|
+
}
|
5153
|
+
toDOM(view) {
|
5154
|
+
const root = document.createElement("dx-ref-tag");
|
5155
|
+
root.textContent = this._link.label;
|
5156
|
+
root.setAttribute("ref", this._link.ref);
|
5157
|
+
return root;
|
5158
|
+
}
|
5159
|
+
};
|
5160
|
+
var PreviewBlockWidget = class extends WidgetType6 {
|
5161
|
+
constructor(_options, _link) {
|
5162
|
+
super();
|
5163
|
+
this._options = _options;
|
5164
|
+
this._link = _link;
|
5165
|
+
}
|
5166
|
+
// override ignoreEvent() {
|
5167
|
+
// return true;
|
5168
|
+
// }
|
5169
|
+
eq(other) {
|
5170
|
+
return this._link.ref === other._link.ref;
|
5171
|
+
}
|
5172
|
+
toDOM(view) {
|
5173
|
+
const root = document.createElement("div");
|
5174
|
+
root.classList.add("cm-preview-block");
|
5175
|
+
const handleAction = (action) => {
|
5176
|
+
const pos = view.posAtDOM(root);
|
5177
|
+
const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
|
5178
|
+
if (!node) {
|
5179
|
+
return;
|
5189
5180
|
}
|
5190
|
-
|
5191
|
-
|
5192
|
-
|
5193
|
-
case "HorizontalRule": {
|
5194
|
-
if (!editingRange(state, node, focus2)) {
|
5195
|
-
deco.add(node.from, node.to, horizontalRule);
|
5196
|
-
}
|
5197
|
-
break;
|
5181
|
+
const link = getLinkRef(view.state, node);
|
5182
|
+
if (link?.ref !== action.link.ref) {
|
5183
|
+
return;
|
5198
5184
|
}
|
5199
|
-
|
5200
|
-
|
5201
|
-
|
5202
|
-
|
5203
|
-
|
5185
|
+
switch (action.type) {
|
5186
|
+
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5187
|
+
// Insert ref text.
|
5188
|
+
case "insert": {
|
5189
|
+
view.dispatch({
|
5190
|
+
changes: {
|
5191
|
+
from: node.from,
|
5192
|
+
to: node.to,
|
5193
|
+
insert: action.target.text
|
5194
|
+
}
|
5195
|
+
});
|
5196
|
+
break;
|
5197
|
+
}
|
5198
|
+
// Remove ref.
|
5199
|
+
case "delete": {
|
5200
|
+
view.dispatch({
|
5201
|
+
changes: {
|
5202
|
+
from: node.from,
|
5203
|
+
to: node.to
|
5204
|
+
}
|
5205
|
+
});
|
5206
|
+
break;
|
5204
5207
|
}
|
5205
5208
|
}
|
5206
|
-
}
|
5207
|
-
|
5208
|
-
|
5209
|
-
|
5210
|
-
|
5211
|
-
|
5212
|
-
|
5213
|
-
|
5214
|
-
}
|
5215
|
-
}
|
5216
|
-
};
|
5217
|
-
const tree = syntaxTree7(state);
|
5218
|
-
if (options.numberedHeadings?.from === void 0) {
|
5219
|
-
for (const { from, to } of view.visibleRanges) {
|
5220
|
-
tree.iterate({
|
5221
|
-
from,
|
5222
|
-
to,
|
5223
|
-
enter: wrapWithCatch(enterNode),
|
5224
|
-
leave: wrapWithCatch(leaveNode)
|
5225
|
-
});
|
5226
|
-
}
|
5227
|
-
} else {
|
5228
|
-
tree.iterate({
|
5229
|
-
enter: wrapWithCatch(enterNode),
|
5230
|
-
leave: wrapWithCatch(leaveNode)
|
5231
|
-
});
|
5209
|
+
};
|
5210
|
+
this._options.renderBlock(root, {
|
5211
|
+
readonly: view.state.readOnly,
|
5212
|
+
link: this._link,
|
5213
|
+
onAction: handleAction,
|
5214
|
+
onLookup: this._options.onLookup
|
5215
|
+
}, view);
|
5216
|
+
return root;
|
5232
5217
|
}
|
5233
|
-
return {
|
5234
|
-
deco: deco.finish(),
|
5235
|
-
atomicDeco: atomicDeco.finish()
|
5236
|
-
};
|
5237
5218
|
};
|
5238
|
-
|
5239
|
-
|
5219
|
+
|
5220
|
+
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
5221
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
5222
|
+
var defaultItems = [
|
5223
|
+
"hello world!",
|
5224
|
+
"this is a test.",
|
5225
|
+
"this is [DXOS](https://dxos.org)"
|
5226
|
+
];
|
5227
|
+
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5228
|
+
let t;
|
5229
|
+
let idx = 0;
|
5240
5230
|
return [
|
5241
|
-
|
5242
|
-
|
5243
|
-
|
5244
|
-
|
5245
|
-
|
5246
|
-
|
5247
|
-
|
5248
|
-
|
5249
|
-
} else if (update2.selectionSet) {
|
5250
|
-
this.scheduleUpdate(update2.view);
|
5231
|
+
keymap10.of([
|
5232
|
+
{
|
5233
|
+
// Reset.
|
5234
|
+
key: "alt-meta-'",
|
5235
|
+
run: (view) => {
|
5236
|
+
clearTimeout(t);
|
5237
|
+
idx = 0;
|
5238
|
+
return true;
|
5251
5239
|
}
|
5252
|
-
}
|
5253
|
-
|
5254
|
-
|
5255
|
-
|
5256
|
-
|
5257
|
-
|
5258
|
-
|
5259
|
-
|
5260
|
-
|
5261
|
-
|
5262
|
-
|
5263
|
-
|
5264
|
-
|
5265
|
-
|
5240
|
+
},
|
5241
|
+
{
|
5242
|
+
// Next prompt.
|
5243
|
+
// TODO(burdon): Press 1-9 to select prompt?
|
5244
|
+
key: "shift-meta-'",
|
5245
|
+
run: (view) => {
|
5246
|
+
clearTimeout(t);
|
5247
|
+
const text = items[idx++];
|
5248
|
+
if (idx === items?.length) {
|
5249
|
+
idx = 0;
|
5250
|
+
}
|
5251
|
+
let i = 0;
|
5252
|
+
const insert = (d = 0) => {
|
5253
|
+
t = setTimeout(() => {
|
5254
|
+
const pos = view.state.selection.main.head;
|
5255
|
+
view.dispatch({
|
5256
|
+
changes: {
|
5257
|
+
from: pos,
|
5258
|
+
insert: text[i++]
|
5259
|
+
},
|
5260
|
+
selection: {
|
5261
|
+
anchor: pos + 1
|
5262
|
+
}
|
5263
|
+
});
|
5264
|
+
if (i < text.length) {
|
5265
|
+
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5266
|
+
}
|
5267
|
+
}, d);
|
5268
|
+
};
|
5269
|
+
insert();
|
5270
|
+
return true;
|
5266
5271
|
}
|
5267
5272
|
}
|
5268
|
-
|
5269
|
-
this.clearUpdate();
|
5270
|
-
}
|
5271
|
-
}, {
|
5272
|
-
provide: (plugin) => [
|
5273
|
-
EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5274
|
-
EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5275
|
-
EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
5276
|
-
]
|
5277
|
-
}),
|
5278
|
-
image(),
|
5279
|
-
table(),
|
5280
|
-
adjustChanges(),
|
5281
|
-
formattingStyles
|
5273
|
+
])
|
5282
5274
|
];
|
5283
5275
|
};
|
5284
5276
|
|
5285
|
-
// packages/ui/react-ui-editor/src/
|
5286
|
-
|
5287
|
-
|
5288
|
-
|
5289
|
-
|
5290
|
-
|
5291
|
-
|
5292
|
-
|
5293
|
-
|
5294
|
-
|
5277
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
|
5278
|
+
var createBlockGroupAction = (value) => createEditorActionGroup("block", {
|
5279
|
+
variant: "toggleGroup",
|
5280
|
+
selectCardinality: "single",
|
5281
|
+
value
|
5282
|
+
});
|
5283
|
+
var createBlockActions = (value, getView, blankLine) => Object.entries({
|
5284
|
+
blockquote: "ph--quotes--regular",
|
5285
|
+
codeblock: "ph--code-block--regular",
|
5286
|
+
table: "ph--table--regular"
|
5287
|
+
}).map(([type, icon]) => {
|
5288
|
+
const checked = type === value;
|
5289
|
+
return createEditorAction(type, () => {
|
5290
|
+
const view = getView();
|
5291
|
+
if (!view) {
|
5292
|
+
return;
|
5295
5293
|
}
|
5296
|
-
|
5297
|
-
|
5298
|
-
|
5294
|
+
switch (type) {
|
5295
|
+
case "blockquote":
|
5296
|
+
checked ? removeBlockquote(view) : addBlockquote(view);
|
5297
|
+
break;
|
5298
|
+
case "codeblock":
|
5299
|
+
checked ? removeCodeblock(view) : addCodeblock(view);
|
5300
|
+
break;
|
5301
|
+
case "table":
|
5302
|
+
insertTable(view);
|
5303
|
+
break;
|
5299
5304
|
}
|
5300
|
-
|
5301
|
-
|
5302
|
-
|
5303
|
-
|
5304
|
-
|
5305
|
-
|
5306
|
-
|
5307
|
-
|
5308
|
-
|
5309
|
-
|
5310
|
-
|
5311
|
-
|
5312
|
-
|
5313
|
-
|
5314
|
-
|
5315
|
-
|
5316
|
-
|
5317
|
-
|
5318
|
-
|
5305
|
+
}, {
|
5306
|
+
checked,
|
5307
|
+
...type === "table" && {
|
5308
|
+
disabled: !!blankLine
|
5309
|
+
},
|
5310
|
+
icon
|
5311
|
+
});
|
5312
|
+
});
|
5313
|
+
var createBlocks = (state, getView) => {
|
5314
|
+
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
5315
|
+
const blockGroupAction = createBlockGroupAction(value);
|
5316
|
+
const blockActions = createBlockActions(value, getView, state.blankLine);
|
5317
|
+
return {
|
5318
|
+
nodes: [
|
5319
|
+
blockGroupAction,
|
5320
|
+
...blockActions
|
5321
|
+
],
|
5322
|
+
edges: [
|
5323
|
+
{
|
5324
|
+
source: "root",
|
5325
|
+
target: "block"
|
5326
|
+
},
|
5327
|
+
...blockActions.map(({ id }) => ({
|
5328
|
+
source: blockGroupAction.id,
|
5329
|
+
target: id
|
5330
|
+
}))
|
5331
|
+
]
|
5332
|
+
};
|
5333
|
+
};
|
5334
|
+
|
5335
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
|
5336
|
+
var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
|
5337
|
+
var createCommentAction = (label, getView) => createEditorAction("comment", () => createComment(getView()), {
|
5338
|
+
testId: "editor.toolbar.comment",
|
5339
|
+
icon: "ph--chat-text--regular",
|
5340
|
+
label
|
5341
|
+
});
|
5342
|
+
var createComment2 = (state, getView) => ({
|
5343
|
+
nodes: [
|
5344
|
+
createCommentAction([
|
5345
|
+
commentLabel(state.comment, state.selection),
|
5346
|
+
{
|
5347
|
+
ns: translationKey
|
5319
5348
|
}
|
5320
|
-
|
5349
|
+
], getView)
|
5350
|
+
],
|
5351
|
+
edges: [
|
5352
|
+
{
|
5353
|
+
source: "root",
|
5354
|
+
target: "comment"
|
5355
|
+
}
|
5356
|
+
]
|
5357
|
+
});
|
5358
|
+
|
5359
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
|
5360
|
+
var formats = {
|
5361
|
+
strong: "ph--text-b--regular",
|
5362
|
+
emphasis: "ph--text-italic--regular",
|
5363
|
+
strikethrough: "ph--text-strikethrough--regular",
|
5364
|
+
code: "ph--code--regular",
|
5365
|
+
link: "ph--link--regular"
|
5366
|
+
};
|
5367
|
+
var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
|
5368
|
+
variant: "toggleGroup",
|
5369
|
+
selectCardinality: "multiple",
|
5370
|
+
value: Object.keys(formats).filter((key) => !!formatting[key])
|
5371
|
+
});
|
5372
|
+
var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
|
5373
|
+
const checked = !!formatting[type];
|
5374
|
+
return createEditorAction(type, () => {
|
5375
|
+
const view = getView();
|
5376
|
+
if (!view) {
|
5377
|
+
return;
|
5378
|
+
}
|
5379
|
+
if (type === "link") {
|
5380
|
+
checked ? removeLink(view) : addLink()(view);
|
5381
|
+
return;
|
5382
|
+
}
|
5383
|
+
const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
5384
|
+
setStyle(inlineType, !checked)(view);
|
5321
5385
|
}, {
|
5322
|
-
|
5323
|
-
|
5386
|
+
checked,
|
5387
|
+
icon
|
5324
5388
|
});
|
5389
|
+
});
|
5390
|
+
var createFormatting = (state, getView) => {
|
5391
|
+
const formattingGroupAction = createFormattingGroup(state);
|
5392
|
+
const formattingActions = createFormattingActions(state, getView);
|
5393
|
+
return {
|
5394
|
+
nodes: [
|
5395
|
+
formattingGroupAction,
|
5396
|
+
...formattingActions
|
5397
|
+
],
|
5398
|
+
edges: [
|
5399
|
+
{
|
5400
|
+
source: "root",
|
5401
|
+
target: "formatting"
|
5402
|
+
},
|
5403
|
+
...formattingActions.map(({ id }) => ({
|
5404
|
+
source: formattingGroupAction.id,
|
5405
|
+
target: id
|
5406
|
+
}))
|
5407
|
+
]
|
5408
|
+
};
|
5325
5409
|
};
|
5326
5410
|
|
5327
|
-
// packages/ui/react-ui-editor/src/
|
5328
|
-
|
5329
|
-
|
5330
|
-
|
5331
|
-
|
5332
|
-
|
5333
|
-
|
5334
|
-
|
5335
|
-
|
5336
|
-
|
5337
|
-
|
5338
|
-
|
5339
|
-
|
5340
|
-
|
5341
|
-
|
5342
|
-
|
5343
|
-
|
5344
|
-
|
5345
|
-
|
5346
|
-
|
5347
|
-
|
5348
|
-
|
5349
|
-
|
5350
|
-
const match = context.matchBefore(/@(\w+)?/);
|
5351
|
-
if (!match || match.from === match.to && !context.explicit) {
|
5352
|
-
return null;
|
5353
|
-
}
|
5354
|
-
return {
|
5355
|
-
from: match.from,
|
5356
|
-
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5357
|
-
label: `@${value}`
|
5358
|
-
}))
|
5359
|
-
};
|
5411
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
|
5412
|
+
var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
|
5413
|
+
variant: "dropdownMenu",
|
5414
|
+
applyActive: true,
|
5415
|
+
selectCardinality: "single",
|
5416
|
+
value
|
5417
|
+
}, "ph--text-h--regular");
|
5418
|
+
var createHeadingActions = (getView) => Object.entries({
|
5419
|
+
"0": "ph--paragraph--regular",
|
5420
|
+
"1": "ph--text-h-one--regular",
|
5421
|
+
"2": "ph--text-h-two--regular",
|
5422
|
+
"3": "ph--text-h-three--regular",
|
5423
|
+
"4": "ph--text-h-four--regular",
|
5424
|
+
"5": "ph--text-h-five--regular",
|
5425
|
+
"6": "ph--text-h-six--regular"
|
5426
|
+
}).map(([levelStr, icon]) => {
|
5427
|
+
const level = parseInt(levelStr);
|
5428
|
+
return createEditorAction(`heading--${levelStr}`, () => setHeading(level)(getView()), {
|
5429
|
+
label: [
|
5430
|
+
"heading level label",
|
5431
|
+
{
|
5432
|
+
count: level,
|
5433
|
+
ns: translationKey
|
5360
5434
|
}
|
5361
|
-
]
|
5435
|
+
],
|
5436
|
+
icon
|
5362
5437
|
});
|
5438
|
+
});
|
5439
|
+
var computeHeadingValue = (state) => {
|
5440
|
+
const blockType = state ? state.blockType : "paragraph";
|
5441
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
5442
|
+
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
5443
|
+
};
|
5444
|
+
var createHeadings = (state, getView) => {
|
5445
|
+
const headingValue = computeHeadingValue(state);
|
5446
|
+
const headingGroupAction = createHeadingGroupAction(headingValue);
|
5447
|
+
const headingActions = createHeadingActions(getView);
|
5448
|
+
return {
|
5449
|
+
nodes: [
|
5450
|
+
headingGroupAction,
|
5451
|
+
...headingActions
|
5452
|
+
],
|
5453
|
+
edges: [
|
5454
|
+
{
|
5455
|
+
source: "root",
|
5456
|
+
target: "heading"
|
5457
|
+
},
|
5458
|
+
...headingActions.map(({ id }) => ({
|
5459
|
+
source: headingGroupAction.id,
|
5460
|
+
target: id
|
5461
|
+
}))
|
5462
|
+
]
|
5463
|
+
};
|
5363
5464
|
};
|
5364
5465
|
|
5365
|
-
// packages/ui/react-ui-editor/src/
|
5366
|
-
|
5367
|
-
|
5368
|
-
|
5369
|
-
|
5370
|
-
var
|
5371
|
-
|
5372
|
-
|
5373
|
-
"source"
|
5374
|
-
];
|
5375
|
-
var EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
|
5376
|
-
var EditorInputModes = [
|
5377
|
-
"default",
|
5378
|
-
"vim",
|
5379
|
-
"vscode"
|
5380
|
-
];
|
5381
|
-
var EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
|
5382
|
-
var editorInputMode = singleValueFacet({});
|
5383
|
-
var InputModeExtensions = {
|
5384
|
-
default: [],
|
5385
|
-
vscode: [
|
5386
|
-
// https://github.com/replit/codemirror-vscode-keymap
|
5387
|
-
editorInputMode.of({
|
5388
|
-
type: "vscode"
|
5389
|
-
}),
|
5390
|
-
keymap9.of(vscodeKeymap)
|
5466
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/image.ts
|
5467
|
+
var createImageUploadAction = (onImageUpload) => createEditorAction("image", onImageUpload, {
|
5468
|
+
testId: "editor.toolbar.image",
|
5469
|
+
icon: "ph--image-square--regular"
|
5470
|
+
});
|
5471
|
+
var createImageUpload = (onImageUpload) => ({
|
5472
|
+
nodes: [
|
5473
|
+
createImageUploadAction(onImageUpload)
|
5391
5474
|
],
|
5392
|
-
|
5393
|
-
|
5394
|
-
|
5395
|
-
|
5396
|
-
|
5397
|
-
noTabster: true
|
5398
|
-
}),
|
5399
|
-
keymap9.of([
|
5400
|
-
{
|
5401
|
-
key: "Alt-Escape",
|
5402
|
-
run: (view) => {
|
5403
|
-
view.dom.parentElement?.focus();
|
5404
|
-
return true;
|
5405
|
-
}
|
5406
|
-
}
|
5407
|
-
])
|
5475
|
+
edges: [
|
5476
|
+
{
|
5477
|
+
source: "root",
|
5478
|
+
target: "image"
|
5479
|
+
}
|
5408
5480
|
]
|
5409
|
-
};
|
5481
|
+
});
|
5410
5482
|
|
5411
|
-
// packages/ui/react-ui-editor/src/
|
5412
|
-
|
5413
|
-
|
5414
|
-
|
5415
|
-
|
5416
|
-
var preview = (options = {}) => {
|
5417
|
-
return [
|
5418
|
-
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5419
|
-
// "Block decorations may not be specified via plugins"
|
5420
|
-
StateField10.define({
|
5421
|
-
create: (state) => buildDecorations3(state, options),
|
5422
|
-
update: (_, tr) => buildDecorations3(tr.state, options),
|
5423
|
-
provide: (field) => [
|
5424
|
-
EditorView20.decorations.from(field),
|
5425
|
-
EditorView20.atomicRanges.of((view) => view.state.field(field))
|
5426
|
-
]
|
5427
|
-
}),
|
5428
|
-
EditorView20.theme({
|
5429
|
-
".cm-preview-block": {
|
5430
|
-
marginLeft: "-1rem",
|
5431
|
-
marginRight: "-1rem",
|
5432
|
-
padding: "1rem",
|
5433
|
-
borderRadius: "0.5rem",
|
5434
|
-
background: "var(--dx-modalSurface)",
|
5435
|
-
border: "1px solid var(--dx-separator)"
|
5436
|
-
}
|
5437
|
-
})
|
5438
|
-
];
|
5439
|
-
};
|
5440
|
-
var getLinkRef = (state, node) => {
|
5441
|
-
const mark = node.getChild("LinkMark");
|
5442
|
-
const label = node.getChild("LinkLabel");
|
5443
|
-
if (mark && label) {
|
5444
|
-
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5445
|
-
return {
|
5446
|
-
suggest: ref.startsWith("?"),
|
5447
|
-
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5448
|
-
label: state.sliceDoc(mark.to, label.from - 1),
|
5449
|
-
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5450
|
-
};
|
5451
|
-
}
|
5483
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
|
5484
|
+
var listStyles = {
|
5485
|
+
bullet: "ph--list-bullets--regular",
|
5486
|
+
ordered: "ph--list-numbers--regular",
|
5487
|
+
task: "ph--list-checks--regular"
|
5452
5488
|
};
|
5453
|
-
var
|
5454
|
-
|
5455
|
-
|
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
|
-
|
5489
|
+
var createListGroupAction = (value) => createEditorActionGroup("list", {
|
5490
|
+
variant: "toggleGroup",
|
5491
|
+
selectCardinality: "single",
|
5492
|
+
value
|
5493
|
+
});
|
5494
|
+
var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
|
5495
|
+
const checked = value === listStyle;
|
5496
|
+
return createEditorAction(`list-${listStyle}`, () => {
|
5497
|
+
const view = getView();
|
5498
|
+
if (!view) {
|
5499
|
+
return;
|
5500
|
+
}
|
5501
|
+
const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
|
5502
|
+
if (checked) {
|
5503
|
+
removeList(listType)(view);
|
5504
|
+
} else {
|
5505
|
+
addList(listType)(view);
|
5506
|
+
}
|
5507
|
+
}, {
|
5508
|
+
checked,
|
5509
|
+
icon
|
5510
|
+
});
|
5511
|
+
});
|
5512
|
+
var createLists = (state, getView) => {
|
5513
|
+
const value = state.listStyle ?? "";
|
5514
|
+
const listGroupAction = createListGroupAction(value);
|
5515
|
+
const listActionsMap = createListActions(value, getView);
|
5516
|
+
return {
|
5517
|
+
nodes: [
|
5518
|
+
listGroupAction,
|
5519
|
+
...listActionsMap
|
5520
|
+
],
|
5521
|
+
edges: [
|
5522
|
+
{
|
5523
|
+
source: "root",
|
5524
|
+
target: "list"
|
5525
|
+
},
|
5526
|
+
...listActionsMap.map(({ id }) => ({
|
5527
|
+
source: listGroupAction.id,
|
5528
|
+
target: id
|
5529
|
+
}))
|
5530
|
+
]
|
5531
|
+
};
|
5532
|
+
};
|
5533
|
+
|
5534
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/search.ts
|
5535
|
+
import { openSearchPanel } from "@codemirror/search";
|
5536
|
+
var createSearchAction = (getView) => createEditorAction("search", () => openSearchPanel(getView()), {
|
5537
|
+
testId: "editor.toolbar.search",
|
5538
|
+
icon: "ph--magnifying-glass--regular"
|
5539
|
+
});
|
5540
|
+
var createSearch = (getView) => ({
|
5541
|
+
nodes: [
|
5542
|
+
createSearchAction(getView)
|
5543
|
+
],
|
5544
|
+
edges: [
|
5545
|
+
{
|
5546
|
+
source: "root",
|
5547
|
+
target: "search"
|
5487
5548
|
}
|
5549
|
+
]
|
5550
|
+
});
|
5551
|
+
|
5552
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
|
5553
|
+
var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
|
5554
|
+
variant: "dropdownMenu",
|
5555
|
+
applyActive: true,
|
5556
|
+
selectCardinality: "single",
|
5557
|
+
value
|
5558
|
+
}, "ph--eye--regular");
|
5559
|
+
var createViewModeActions = (value, onViewModeChange) => Object.entries({
|
5560
|
+
preview: "ph--eye--regular",
|
5561
|
+
source: "ph--pencil-simple--regular",
|
5562
|
+
readonly: "ph--pencil-slash--regular"
|
5563
|
+
}).map(([viewMode, icon]) => {
|
5564
|
+
const checked = viewMode === value;
|
5565
|
+
return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode), {
|
5566
|
+
label: [
|
5567
|
+
`${viewMode} mode label`,
|
5568
|
+
{
|
5569
|
+
ns: translationKey
|
5570
|
+
}
|
5571
|
+
],
|
5572
|
+
checked,
|
5573
|
+
icon
|
5488
5574
|
});
|
5489
|
-
|
5575
|
+
});
|
5576
|
+
var createViewMode = (state, onViewModeChange) => {
|
5577
|
+
const value = state.viewMode ?? "source";
|
5578
|
+
const viewModeGroupAction = createViewModeGroupAction(value);
|
5579
|
+
const viewModeActions = createViewModeActions(value, onViewModeChange);
|
5580
|
+
return {
|
5581
|
+
nodes: [
|
5582
|
+
viewModeGroupAction,
|
5583
|
+
...viewModeActions
|
5584
|
+
],
|
5585
|
+
edges: [
|
5586
|
+
{
|
5587
|
+
source: "root",
|
5588
|
+
target: "viewMode"
|
5589
|
+
},
|
5590
|
+
...viewModeActions.map(({ id }) => ({
|
5591
|
+
source: viewModeGroupAction.id,
|
5592
|
+
target: id
|
5593
|
+
}))
|
5594
|
+
]
|
5595
|
+
};
|
5490
5596
|
};
|
5491
|
-
|
5492
|
-
|
5493
|
-
|
5494
|
-
|
5495
|
-
|
5597
|
+
|
5598
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
5599
|
+
import { EditorView as EditorView20 } from "@codemirror/view";
|
5600
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
5601
|
+
var margin = "!mt-[1rem]";
|
5602
|
+
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
5603
|
+
var editorContent = mx3(margin, editorWidth);
|
5604
|
+
var editorFullWidth = mx3(margin);
|
5605
|
+
var editorGutter = EditorView20.theme({
|
5606
|
+
// Match margin from content.
|
5607
|
+
// Gutter = 2rem + 1rem margin.
|
5608
|
+
".cm-gutters": {
|
5609
|
+
marginTop: "1rem",
|
5610
|
+
paddingRight: "1rem"
|
5496
5611
|
}
|
5497
|
-
|
5498
|
-
|
5499
|
-
|
5500
|
-
|
5501
|
-
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5612
|
+
});
|
5613
|
+
var editorMonospace = EditorView20.theme({
|
5614
|
+
".cm-content": {
|
5615
|
+
fontFamily: fontMono
|
5502
5616
|
}
|
5503
|
-
|
5504
|
-
|
5505
|
-
|
5506
|
-
|
5507
|
-
|
5617
|
+
});
|
5618
|
+
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
5619
|
+
var stackItemContentEditorClassNames = (role) => mx3("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");
|
5620
|
+
var stackItemContentToolbarClassNames = (role) => mx3("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
|
5621
|
+
|
5622
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
5623
|
+
var createToolbar = ({ getView, state, customActions, ...features }) => {
|
5624
|
+
const nodes = [];
|
5625
|
+
const edges = [];
|
5626
|
+
if (features.headings ?? true) {
|
5627
|
+
const headings2 = createHeadings(state, getView);
|
5628
|
+
nodes.push(...headings2.nodes);
|
5629
|
+
edges.push(...headings2.edges);
|
5508
5630
|
}
|
5509
|
-
|
5510
|
-
|
5511
|
-
|
5512
|
-
|
5513
|
-
this._options = _options;
|
5514
|
-
this._link = _link;
|
5631
|
+
if (features.formatting ?? true) {
|
5632
|
+
const formatting = createFormatting(state, getView);
|
5633
|
+
nodes.push(...formatting.nodes);
|
5634
|
+
edges.push(...formatting.edges);
|
5515
5635
|
}
|
5516
|
-
|
5517
|
-
|
5518
|
-
|
5519
|
-
|
5520
|
-
return this._link.ref === other._link.ref;
|
5636
|
+
if (features.lists ?? true) {
|
5637
|
+
const lists = createLists(state, getView);
|
5638
|
+
nodes.push(...lists.nodes);
|
5639
|
+
edges.push(...lists.edges);
|
5521
5640
|
}
|
5522
|
-
|
5523
|
-
const
|
5524
|
-
|
5525
|
-
|
5526
|
-
const pos = view.posAtDOM(root);
|
5527
|
-
const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
|
5528
|
-
if (!node) {
|
5529
|
-
return;
|
5530
|
-
}
|
5531
|
-
const link = getLinkRef(view.state, node);
|
5532
|
-
if (link?.ref !== action.link.ref) {
|
5533
|
-
return;
|
5534
|
-
}
|
5535
|
-
switch (action.type) {
|
5536
|
-
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5537
|
-
// Insert ref text.
|
5538
|
-
case "insert": {
|
5539
|
-
view.dispatch({
|
5540
|
-
changes: {
|
5541
|
-
from: node.from,
|
5542
|
-
to: node.to,
|
5543
|
-
insert: action.target.text
|
5544
|
-
}
|
5545
|
-
});
|
5546
|
-
break;
|
5547
|
-
}
|
5548
|
-
// Remove ref.
|
5549
|
-
case "delete": {
|
5550
|
-
view.dispatch({
|
5551
|
-
changes: {
|
5552
|
-
from: node.from,
|
5553
|
-
to: node.to
|
5554
|
-
}
|
5555
|
-
});
|
5556
|
-
break;
|
5557
|
-
}
|
5558
|
-
}
|
5559
|
-
};
|
5560
|
-
this._options.renderBlock(root, {
|
5561
|
-
readonly: view.state.readOnly,
|
5562
|
-
link: this._link,
|
5563
|
-
onAction: handleAction,
|
5564
|
-
onLookup: this._options.onLookup
|
5565
|
-
}, view);
|
5566
|
-
return root;
|
5641
|
+
if (features.blocks ?? true) {
|
5642
|
+
const blocks = createBlocks(state, getView);
|
5643
|
+
nodes.push(...blocks.nodes);
|
5644
|
+
edges.push(...blocks.edges);
|
5567
5645
|
}
|
5646
|
+
if (features.image) {
|
5647
|
+
const image2 = createImageUpload(features.image);
|
5648
|
+
nodes.push(...image2.nodes);
|
5649
|
+
edges.push(...image2.edges);
|
5650
|
+
}
|
5651
|
+
if (customActions) {
|
5652
|
+
const custom = customActions();
|
5653
|
+
nodes.push(...custom.nodes);
|
5654
|
+
edges.push(...custom.edges);
|
5655
|
+
}
|
5656
|
+
const editorToolbarGap = createGapSeparator();
|
5657
|
+
nodes.push(...editorToolbarGap.nodes);
|
5658
|
+
edges.push(...editorToolbarGap.edges);
|
5659
|
+
if (features.comment) {
|
5660
|
+
const comment = createComment2(state, getView);
|
5661
|
+
nodes.push(...comment.nodes);
|
5662
|
+
edges.push(...comment.edges);
|
5663
|
+
}
|
5664
|
+
if (features.search ?? true) {
|
5665
|
+
const search = createSearch(getView);
|
5666
|
+
nodes.push(...search.nodes);
|
5667
|
+
edges.push(...search.edges);
|
5668
|
+
}
|
5669
|
+
if (features.viewMode) {
|
5670
|
+
const viewMode = createViewMode(state, features.viewMode);
|
5671
|
+
nodes.push(...viewMode.nodes);
|
5672
|
+
edges.push(...viewMode.edges);
|
5673
|
+
}
|
5674
|
+
return {
|
5675
|
+
nodes,
|
5676
|
+
edges
|
5677
|
+
};
|
5568
5678
|
};
|
5569
|
-
|
5570
|
-
|
5571
|
-
|
5572
|
-
var defaultItems = [
|
5573
|
-
"hello world!",
|
5574
|
-
"this is a test.",
|
5575
|
-
"this is [DXOS](https://dxos.org)"
|
5576
|
-
];
|
5577
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5578
|
-
let t;
|
5579
|
-
let idx = 0;
|
5580
|
-
return [
|
5581
|
-
keymap10.of([
|
5582
|
-
{
|
5583
|
-
// Reset.
|
5584
|
-
key: "alt-meta-'",
|
5585
|
-
run: (view) => {
|
5586
|
-
clearTimeout(t);
|
5587
|
-
idx = 0;
|
5588
|
-
return true;
|
5589
|
-
}
|
5590
|
-
},
|
5591
|
-
{
|
5592
|
-
// Next prompt.
|
5593
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
5594
|
-
key: "shift-meta-'",
|
5595
|
-
run: (view) => {
|
5596
|
-
clearTimeout(t);
|
5597
|
-
const text = items[idx++];
|
5598
|
-
if (idx === items?.length) {
|
5599
|
-
idx = 0;
|
5600
|
-
}
|
5601
|
-
let i = 0;
|
5602
|
-
const insert = (d = 0) => {
|
5603
|
-
t = setTimeout(() => {
|
5604
|
-
const pos = view.state.selection.main.head;
|
5605
|
-
view.dispatch({
|
5606
|
-
changes: {
|
5607
|
-
from: pos,
|
5608
|
-
insert: text[i++]
|
5609
|
-
},
|
5610
|
-
selection: {
|
5611
|
-
anchor: pos + 1
|
5612
|
-
}
|
5613
|
-
});
|
5614
|
-
if (i < text.length) {
|
5615
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5616
|
-
}
|
5617
|
-
}, d);
|
5618
|
-
};
|
5619
|
-
insert();
|
5620
|
-
return true;
|
5621
|
-
}
|
5622
|
-
}
|
5623
|
-
])
|
5624
|
-
];
|
5625
|
-
};
|
5626
|
-
|
5627
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
5628
|
-
import { useCallback as useCallback2 } from "react";
|
5629
|
-
var useActionHandler = (view) => {
|
5630
|
-
return useCallback2((action) => view && processEditorPayload(view, action.properties), [
|
5631
|
-
view
|
5679
|
+
var useEditorToolbarActionGraph = (props) => {
|
5680
|
+
const menuCreator = useCallback(() => createToolbar(props), [
|
5681
|
+
props
|
5632
5682
|
]);
|
5683
|
+
return useMenuActions(menuCreator);
|
5633
5684
|
};
|
5685
|
+
var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...props }) => {
|
5686
|
+
const menuProps = useEditorToolbarActionGraph(props);
|
5687
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
5688
|
+
role: "none",
|
5689
|
+
className: stackItemContentToolbarClassNames(role)
|
5690
|
+
}, /* @__PURE__ */ React3.createElement(ElevationProvider, {
|
5691
|
+
elevation: role === "section" ? "positioned" : "base"
|
5692
|
+
}, /* @__PURE__ */ React3.createElement(MenuProvider, {
|
5693
|
+
...menuProps,
|
5694
|
+
attendableId
|
5695
|
+
}, /* @__PURE__ */ React3.createElement(ToolbarMenu, {
|
5696
|
+
classNames: [
|
5697
|
+
textBlockWidth,
|
5698
|
+
"!bg-transparent",
|
5699
|
+
classNames
|
5700
|
+
]
|
5701
|
+
}))));
|
5702
|
+
});
|
5634
5703
|
|
5635
5704
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
5636
5705
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
5637
5706
|
import { EditorView as EditorView21 } from "@codemirror/view";
|
5638
5707
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
5639
|
-
import { useCallback as
|
5708
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
|
5640
5709
|
import { log as log7 } from "@dxos/log";
|
5641
5710
|
import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
5642
5711
|
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
@@ -5761,7 +5830,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5761
5830
|
Escape: view?.state.facet(editorInputMode).noTabster
|
5762
5831
|
}
|
5763
5832
|
});
|
5764
|
-
const handleKeyUp =
|
5833
|
+
const handleKeyUp = useCallback2((event) => {
|
5765
5834
|
const { key, target, currentTarget } = event;
|
5766
5835
|
if (target === currentTarget) {
|
5767
5836
|
switch (key) {
|
@@ -5820,7 +5889,7 @@ export {
|
|
5820
5889
|
commentsState,
|
5821
5890
|
convertTreeToJson,
|
5822
5891
|
createBasicExtensions,
|
5823
|
-
|
5892
|
+
createComment,
|
5824
5893
|
createDataExtensions,
|
5825
5894
|
createEditorAction,
|
5826
5895
|
createEditorActionGroup,
|
@@ -5898,7 +5967,6 @@ export {
|
|
5898
5967
|
toggleStyle,
|
5899
5968
|
translations_default as translations,
|
5900
5969
|
typewriter,
|
5901
|
-
useActionHandler,
|
5902
5970
|
useCommentClickListener,
|
5903
5971
|
useCommentState,
|
5904
5972
|
useComments,
|