@dxos/ui-editor 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +2033 -1155
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +26 -6
- package/dist/lib/browser/types/index.mjs.map +4 -4
- package/dist/lib/node-esm/index.mjs +2039 -1160
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +27 -6
- package/dist/lib/node-esm/types/index.mjs.map +4 -4
- package/dist/types/src/defaults.d.ts +4 -10
- 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/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +5 -2
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/typeahead.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/sync.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-provider.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/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 +4 -3
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -3
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +3 -0
- 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/styles.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/outliner/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts +2 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/replacer.d.ts.map +1 -1
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +75 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +5 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +4 -1
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +28 -8
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/index.d.ts +0 -2
- package/dist/types/src/styles/index.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +15 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +4 -4
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts +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/decorations.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/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -40
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +2 -3
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +55 -8
- package/src/extensions/scrolling/auto-scroll.ts +244 -0
- package/src/extensions/scrolling/crawler.ts +263 -0
- package/src/extensions/scrolling/index.ts +8 -0
- package/src/extensions/scrolling/scroll-past-end.ts +32 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +125 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/dist/lib/browser/chunk-HL3YF6WC.mjs +0 -22
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs +0 -24
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +0 -7
- package/dist/types/src/extensions/autoscroll.d.ts +0 -20
- package/dist/types/src/extensions/autoscroll.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling.d.ts +0 -78
- package/dist/types/src/extensions/scrolling.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/streamer.d.ts +0 -12
- package/dist/types/src/extensions/tags/streamer.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts +0 -10
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/dist/types/src/styles/markdown.d.ts +0 -8
- package/dist/types/src/styles/markdown.d.ts.map +0 -1
- package/dist/types/src/styles/tokens.d.ts +0 -3
- package/dist/types/src/styles/tokens.d.ts.map +0 -1
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -1,29 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
|
-
import { EditorState as
|
|
10
|
-
import { EditorView as
|
|
2
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
14
7
|
// src/defaults.ts
|
|
15
8
|
import { mx } from "@dxos/ui-theme";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
10
|
+
var documentSlots = {
|
|
11
|
+
content: {
|
|
12
|
+
/**
|
|
13
|
+
* CodeMirror content width.
|
|
14
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
15
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
16
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
17
|
+
*/
|
|
18
|
+
className: mx(
|
|
19
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
20
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
21
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
22
|
+
// scroll until a click forces a re-measure.
|
|
23
|
+
"dx-inline-size-container",
|
|
24
|
+
// Wider margin for web (vs. mobile).
|
|
25
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
26
|
+
"mx-auto! w-full"
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var compactSlots = {
|
|
31
|
+
content: {
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
21
36
|
content: {
|
|
22
|
-
className:
|
|
37
|
+
className: "mx-2!"
|
|
23
38
|
}
|
|
24
39
|
};
|
|
25
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
26
|
-
var stackItemContentEditorClassNames = (role) => mx("p-0.5 dx-focus-ring-inset attention-surface data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
|
27
40
|
|
|
28
41
|
// src/extensions/annotations.ts
|
|
29
42
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -58,7 +71,7 @@ var annotations = ({ match } = {}) => {
|
|
|
58
71
|
".cm-annotation": {
|
|
59
72
|
textDecoration: "underline",
|
|
60
73
|
textDecorationStyle: "wavy",
|
|
61
|
-
textDecorationColor: "var(--
|
|
74
|
+
textDecorationColor: "var(--color-error-text)"
|
|
62
75
|
}
|
|
63
76
|
})
|
|
64
77
|
];
|
|
@@ -207,7 +220,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
207
220
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
208
221
|
var defaultCursorConverter = {
|
|
209
222
|
toCursor: (position) => position.toString(),
|
|
210
|
-
fromCursor: (
|
|
223
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
211
224
|
};
|
|
212
225
|
var Cursor = class _Cursor {
|
|
213
226
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -220,9 +233,9 @@ var Cursor = class _Cursor {
|
|
|
220
233
|
to
|
|
221
234
|
].join(":");
|
|
222
235
|
};
|
|
223
|
-
static getRangeFromCursor = (state,
|
|
236
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
224
237
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
225
|
-
const parts =
|
|
238
|
+
const parts = cursor.split(":");
|
|
226
239
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
227
240
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
228
241
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -258,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
258
271
|
} catch (err) {
|
|
259
272
|
log.catch(err, {
|
|
260
273
|
label
|
|
261
|
-
}, {
|
|
262
|
-
F: __dxlog_file,
|
|
263
|
-
L: 20,
|
|
264
|
-
S: void 0,
|
|
265
|
-
C: (f, a) => f(...a)
|
|
266
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
};
|
|
@@ -289,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
289
297
|
if (changes.length) {
|
|
290
298
|
log("changes", {
|
|
291
299
|
changes
|
|
292
|
-
}, {
|
|
293
|
-
F: __dxlog_file,
|
|
294
|
-
L: 54,
|
|
295
|
-
S: void 0,
|
|
296
|
-
C: (f, a) => f(...a)
|
|
297
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
298
301
|
}
|
|
299
302
|
};
|
|
300
303
|
|
|
@@ -360,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
360
363
|
};
|
|
361
364
|
|
|
362
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
363
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
364
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
365
368
|
_timeout;
|
|
366
369
|
_decorations = Decoration3.none;
|
|
367
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
368
374
|
if (this._timeout) {
|
|
369
375
|
window.clearTimeout(this._timeout);
|
|
370
376
|
this._timeout = void 0;
|
|
371
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
372
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const lineStart = activeLine.from;
|
|
376
|
-
this._timeout = setTimeout(() => {
|
|
377
|
-
this._decorations = Decoration3.set([
|
|
378
|
-
Decoration3.widget({
|
|
379
|
-
widget: new PlaceholderWidget(content),
|
|
380
|
-
side: 1
|
|
381
|
-
}).range(lineStart)
|
|
382
|
-
]);
|
|
383
|
-
update2.view.update([]);
|
|
384
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
385
385
|
}
|
|
386
|
-
|
|
386
|
+
const lineStart = activeLine.from;
|
|
387
|
+
const view = update2.view;
|
|
388
|
+
this._timeout = setTimeout(() => {
|
|
389
|
+
this._decorations = Decoration3.set([
|
|
390
|
+
Decoration3.widget({
|
|
391
|
+
widget: new PlaceholderWidget(content),
|
|
392
|
+
side: 1
|
|
393
|
+
}).range(lineStart)
|
|
394
|
+
]);
|
|
395
|
+
view.update([]);
|
|
396
|
+
}, delay);
|
|
387
397
|
}
|
|
388
398
|
destroy() {
|
|
389
399
|
if (this._timeout) {
|
|
@@ -501,233 +511,10 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
501
511
|
];
|
|
502
512
|
};
|
|
503
513
|
|
|
504
|
-
// src/extensions/autoscroll.ts
|
|
505
|
-
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
506
|
-
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
507
|
-
import { debounce } from "@dxos/async";
|
|
508
|
-
import { Domino } from "@dxos/ui";
|
|
509
|
-
|
|
510
|
-
// src/extensions/scrolling.ts
|
|
511
|
-
import { StateEffect } from "@codemirror/state";
|
|
512
|
-
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
513
|
-
var scrollToLineEffect = StateEffect.define();
|
|
514
|
-
var smoothScroll = ({ offset = 0, position = "start" } = {}) => {
|
|
515
|
-
const scrollPlugin = ViewPlugin5.fromClass(class SmoothScrollPlugin {
|
|
516
|
-
view;
|
|
517
|
-
constructor(view) {
|
|
518
|
-
this.view = view;
|
|
519
|
-
}
|
|
520
|
-
// No-op.
|
|
521
|
-
destroy() {
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Perform smooth scroll to the specified line.
|
|
525
|
-
*/
|
|
526
|
-
scrollToLine(lineNumber, options) {
|
|
527
|
-
const { offset: animOffset = 0, position: animPosition, behavior } = options;
|
|
528
|
-
const doc = this.view.state.doc;
|
|
529
|
-
const scroller = this.view.scrollDOM;
|
|
530
|
-
const targetLine = Math.max(0, lineNumber - 1);
|
|
531
|
-
if (behavior === "instant") {
|
|
532
|
-
requestAnimationFrame(() => {
|
|
533
|
-
this.view.dispatch({
|
|
534
|
-
selection: {
|
|
535
|
-
anchor: doc.line(targetLine + 1).from
|
|
536
|
-
},
|
|
537
|
-
scrollIntoView: true
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
if (targetLine >= doc.lines) {
|
|
543
|
-
const targetScrollTop2 = scroller.scrollHeight - scroller.clientHeight + (animOffset || 0);
|
|
544
|
-
this.animateScroll(scroller, targetScrollTop2);
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
const lineStart = doc.line(targetLine + 1).from;
|
|
548
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
549
|
-
if (!coords) {
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
const currentScrollTop = scroller.scrollTop;
|
|
553
|
-
const scrollerRect = scroller.getBoundingClientRect();
|
|
554
|
-
const maxScrollTop = scroller.scrollHeight - scroller.clientHeight;
|
|
555
|
-
let targetScrollTop;
|
|
556
|
-
if (animPosition === "end") {
|
|
557
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + animOffset;
|
|
558
|
-
} else {
|
|
559
|
-
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + animOffset;
|
|
560
|
-
}
|
|
561
|
-
const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
562
|
-
this.animateScroll(scroller, clampedScrollTop);
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Animate scroll using browser's built-in smooth scrolling.
|
|
566
|
-
*/
|
|
567
|
-
animateScroll(element, targetScrollTop) {
|
|
568
|
-
if (Math.abs(targetScrollTop - element.scrollTop) < 1) {
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
element.scrollTo({
|
|
572
|
-
top: targetScrollTop,
|
|
573
|
-
behavior: "smooth"
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
return [
|
|
578
|
-
scrollPlugin,
|
|
579
|
-
// Update listener to handle scroll effects.
|
|
580
|
-
EditorView4.updateListener.of((update2) => {
|
|
581
|
-
update2.transactions.forEach((transaction) => {
|
|
582
|
-
for (const effect of transaction.effects) {
|
|
583
|
-
if (effect.is(scrollToLineEffect)) {
|
|
584
|
-
const { line, options = {} } = effect.value;
|
|
585
|
-
const plugin = update2.view.plugin(scrollPlugin);
|
|
586
|
-
if (plugin) {
|
|
587
|
-
plugin.scrollToLine(line, {
|
|
588
|
-
offset,
|
|
589
|
-
position,
|
|
590
|
-
...options
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
})
|
|
597
|
-
];
|
|
598
|
-
};
|
|
599
|
-
var scrollToLine = (view, line, options) => {
|
|
600
|
-
view.dispatch({
|
|
601
|
-
effects: scrollToLineEffect.of({
|
|
602
|
-
line,
|
|
603
|
-
options
|
|
604
|
-
})
|
|
605
|
-
});
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
// src/extensions/autoscroll.ts
|
|
609
|
-
var scrollToBottomEffect = StateEffect2.define();
|
|
610
|
-
var autoScroll = ({ autoScroll: autoScroll2 = true, threshold = 100, throttleDelay = 1e3, onAutoScroll } = {}) => {
|
|
611
|
-
let buttonContainer;
|
|
612
|
-
let hideTimeout;
|
|
613
|
-
let lastScrollTop = 0;
|
|
614
|
-
let isPinned = true;
|
|
615
|
-
const setPinned = (pin) => {
|
|
616
|
-
isPinned = pin;
|
|
617
|
-
buttonContainer?.classList.toggle("opacity-0", pin);
|
|
618
|
-
};
|
|
619
|
-
const hideScrollbar = (view) => {
|
|
620
|
-
view.scrollDOM.classList.add("cm-hide-scrollbar");
|
|
621
|
-
clearTimeout(hideTimeout);
|
|
622
|
-
hideTimeout = setTimeout(() => {
|
|
623
|
-
view.scrollDOM.classList.remove("cm-hide-scrollbar");
|
|
624
|
-
}, 1e3);
|
|
625
|
-
};
|
|
626
|
-
const scrollToBottom = (view, behavior) => {
|
|
627
|
-
setPinned(true);
|
|
628
|
-
hideScrollbar(view);
|
|
629
|
-
const line = view.state.doc.lineAt(view.state.doc.length);
|
|
630
|
-
view.dispatch({
|
|
631
|
-
selection: {
|
|
632
|
-
anchor: line.to,
|
|
633
|
-
head: line.to
|
|
634
|
-
},
|
|
635
|
-
effects: scrollToLineEffect.of({
|
|
636
|
-
line: line.number,
|
|
637
|
-
options: {
|
|
638
|
-
position: "end",
|
|
639
|
-
offset: threshold,
|
|
640
|
-
behavior
|
|
641
|
-
}
|
|
642
|
-
})
|
|
643
|
-
});
|
|
644
|
-
};
|
|
645
|
-
const checkDistance = debounce((view) => {
|
|
646
|
-
const scrollerRect = view.scrollDOM.getBoundingClientRect();
|
|
647
|
-
const coords = view.coordsAtPos(view.state.doc.length);
|
|
648
|
-
const distanceFromBottom = coords ? coords.bottom - scrollerRect.bottom : 0;
|
|
649
|
-
setPinned(distanceFromBottom < 0);
|
|
650
|
-
}, 1e3);
|
|
651
|
-
const triggerUpdate = debounce((view) => scrollToBottom(view), throttleDelay);
|
|
652
|
-
return [
|
|
653
|
-
// Update listener for logging when scrolling is needed.
|
|
654
|
-
EditorView5.updateListener.of(({ view, transactions, heightChanged }) => {
|
|
655
|
-
transactions.forEach((transaction) => {
|
|
656
|
-
for (const effect of transaction.effects) {
|
|
657
|
-
if (effect.is(scrollToBottomEffect)) {
|
|
658
|
-
scrollToBottom(view, effect.value);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
if (heightChanged && isPinned) {
|
|
663
|
-
const coords = view.coordsAtPos(view.state.doc.length);
|
|
664
|
-
const scrollerRect = view.scrollDOM.getBoundingClientRect();
|
|
665
|
-
const distanceFromBottom = coords ? scrollerRect.bottom - coords.bottom : 0;
|
|
666
|
-
if (autoScroll2 && distanceFromBottom < threshold) {
|
|
667
|
-
const shouldScroll = onAutoScroll?.({
|
|
668
|
-
view,
|
|
669
|
-
distanceFromBottom
|
|
670
|
-
}) ?? true;
|
|
671
|
-
if (shouldScroll) {
|
|
672
|
-
triggerUpdate(view);
|
|
673
|
-
}
|
|
674
|
-
} else if (distanceFromBottom < 0) {
|
|
675
|
-
setPinned(false);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
}),
|
|
679
|
-
// Detect user scroll.
|
|
680
|
-
EditorView5.domEventHandlers({
|
|
681
|
-
scroll: (event, view) => {
|
|
682
|
-
const currentScrollTop = view.scrollDOM.scrollTop;
|
|
683
|
-
const scrollingUp = currentScrollTop < lastScrollTop;
|
|
684
|
-
lastScrollTop = currentScrollTop;
|
|
685
|
-
if (scrollingUp) {
|
|
686
|
-
setPinned(false);
|
|
687
|
-
} else {
|
|
688
|
-
checkDistance(view);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}),
|
|
692
|
-
// Scroll button.
|
|
693
|
-
ViewPlugin6.fromClass(class {
|
|
694
|
-
constructor(view) {
|
|
695
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
696
|
-
icon: "ph--arrow-down--regular"
|
|
697
|
-
});
|
|
698
|
-
const button = Domino.of("button").classNames("dx-button bg-accentSurface").attributes({
|
|
699
|
-
"data-density": "fine"
|
|
700
|
-
}).children(icon).on("click", () => {
|
|
701
|
-
scrollToBottom(view);
|
|
702
|
-
});
|
|
703
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").children(button).root;
|
|
704
|
-
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
705
|
-
}
|
|
706
|
-
}),
|
|
707
|
-
// Styles.
|
|
708
|
-
EditorView5.theme({
|
|
709
|
-
".cm-scroller": {
|
|
710
|
-
scrollbarWidth: "thin"
|
|
711
|
-
},
|
|
712
|
-
".cm-scroller.cm-hide-scrollbar": {
|
|
713
|
-
scrollbarWidth: "none"
|
|
714
|
-
},
|
|
715
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
716
|
-
display: "none"
|
|
717
|
-
},
|
|
718
|
-
".cm-scroll-button": {
|
|
719
|
-
position: "absolute",
|
|
720
|
-
bottom: "0.5rem",
|
|
721
|
-
right: "1rem"
|
|
722
|
-
}
|
|
723
|
-
})
|
|
724
|
-
];
|
|
725
|
-
};
|
|
726
|
-
|
|
727
514
|
// src/extensions/automerge/automerge.ts
|
|
728
515
|
import { next as A3 } from "@automerge/automerge";
|
|
729
516
|
import { StateField, Transaction as Transaction2 } from "@codemirror/state";
|
|
730
|
-
import { EditorView as
|
|
517
|
+
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
731
518
|
import { DocAccessor } from "@dxos/echo-db";
|
|
732
519
|
|
|
733
520
|
// src/extensions/state.ts
|
|
@@ -743,35 +530,25 @@ var cursorConverter = (accessor) => ({
|
|
|
743
530
|
try {
|
|
744
531
|
return toCursor(accessor, pos, assoc);
|
|
745
532
|
} catch (err) {
|
|
746
|
-
log2.catch(err, void 0, {
|
|
747
|
-
F: __dxlog_file2,
|
|
748
|
-
L: 15,
|
|
749
|
-
S: void 0,
|
|
750
|
-
C: (f, a) => f(...a)
|
|
751
|
-
});
|
|
533
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
|
|
752
534
|
return "";
|
|
753
535
|
}
|
|
754
536
|
},
|
|
755
|
-
fromCursor: (
|
|
537
|
+
fromCursor: (cursor) => {
|
|
756
538
|
try {
|
|
757
|
-
return fromCursor(accessor,
|
|
539
|
+
return fromCursor(accessor, cursor);
|
|
758
540
|
} catch (err) {
|
|
759
|
-
log2.catch(err, void 0, {
|
|
760
|
-
F: __dxlog_file2,
|
|
761
|
-
L: 24,
|
|
762
|
-
S: void 0,
|
|
763
|
-
C: (f, a) => f(...a)
|
|
764
|
-
});
|
|
541
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
|
|
765
542
|
return 0;
|
|
766
543
|
}
|
|
767
544
|
}
|
|
768
545
|
});
|
|
769
546
|
|
|
770
547
|
// src/extensions/automerge/defs.ts
|
|
771
|
-
import { Annotation, StateEffect
|
|
548
|
+
import { Annotation, StateEffect } from "@codemirror/state";
|
|
772
549
|
var getPath = (state, field) => state.field(field).path;
|
|
773
550
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
774
|
-
var updateHeadsEffect =
|
|
551
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
775
552
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
776
553
|
newHeads
|
|
777
554
|
});
|
|
@@ -946,12 +723,7 @@ var Syncer = class {
|
|
|
946
723
|
this._pending = false;
|
|
947
724
|
}
|
|
948
725
|
onEditorChange(view) {
|
|
949
|
-
log3("onEditorChange", void 0, {
|
|
950
|
-
F: __dxlog_file3,
|
|
951
|
-
L: 45,
|
|
952
|
-
S: this,
|
|
953
|
-
C: (f, a) => f(...a)
|
|
954
|
-
});
|
|
726
|
+
log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
|
|
955
727
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
956
728
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
957
729
|
if (newHeads) {
|
|
@@ -962,12 +734,7 @@ var Syncer = class {
|
|
|
962
734
|
}
|
|
963
735
|
}
|
|
964
736
|
onAutomergeChange(view) {
|
|
965
|
-
log3("onAutomergeChange", void 0, {
|
|
966
|
-
F: __dxlog_file3,
|
|
967
|
-
L: 60,
|
|
968
|
-
S: this,
|
|
969
|
-
C: (f, a) => f(...a)
|
|
970
|
-
});
|
|
737
|
+
log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
|
|
971
738
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
972
739
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
973
740
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1020,7 +787,7 @@ var automerge = (accessor) => {
|
|
|
1020
787
|
// Track heads.
|
|
1021
788
|
syncState,
|
|
1022
789
|
// Reconcile external updates.
|
|
1023
|
-
|
|
790
|
+
ViewPlugin5.fromClass(class {
|
|
1024
791
|
_view;
|
|
1025
792
|
constructor(_view) {
|
|
1026
793
|
this._view = _view;
|
|
@@ -1029,6 +796,17 @@ var automerge = (accessor) => {
|
|
|
1029
796
|
const value = DocAccessor.getValue(accessor);
|
|
1030
797
|
const current = this._view.state.doc.toString();
|
|
1031
798
|
if (value !== current) {
|
|
799
|
+
this._view.dispatch({
|
|
800
|
+
changes: {
|
|
801
|
+
from: 0,
|
|
802
|
+
to: this._view.state.doc.length,
|
|
803
|
+
insert: value
|
|
804
|
+
},
|
|
805
|
+
annotations: [
|
|
806
|
+
initialSync,
|
|
807
|
+
reconcileAnnotation.of(true)
|
|
808
|
+
]
|
|
809
|
+
});
|
|
1032
810
|
}
|
|
1033
811
|
});
|
|
1034
812
|
}
|
|
@@ -1040,7 +818,7 @@ var automerge = (accessor) => {
|
|
|
1040
818
|
};
|
|
1041
819
|
}),
|
|
1042
820
|
// Reconcile local updates.
|
|
1043
|
-
|
|
821
|
+
EditorView4.updateListener.of(({ view, changes, transactions }) => {
|
|
1044
822
|
if (!changes.empty) {
|
|
1045
823
|
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
|
|
1046
824
|
if (!isInitialSync) {
|
|
@@ -1053,7 +831,7 @@ var automerge = (accessor) => {
|
|
|
1053
831
|
|
|
1054
832
|
// src/extensions/awareness/awareness.ts
|
|
1055
833
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
1056
|
-
import { Decoration as Decoration5, EditorView as
|
|
834
|
+
import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1057
835
|
import { Event } from "@dxos/async";
|
|
1058
836
|
import { Context } from "@dxos/context";
|
|
1059
837
|
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
@@ -1072,17 +850,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
|
1072
850
|
var awareness = (provider = dummyProvider) => {
|
|
1073
851
|
return [
|
|
1074
852
|
awarenessProvider.of(provider),
|
|
1075
|
-
|
|
853
|
+
ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
|
|
1076
854
|
decorations: (value) => value.decorations
|
|
1077
855
|
}),
|
|
1078
856
|
styles
|
|
1079
857
|
];
|
|
1080
858
|
};
|
|
1081
859
|
var RemoteSelectionsDecorator = class {
|
|
1082
|
-
_ctx = new Context(void 0, {
|
|
1083
|
-
F: __dxlog_file4,
|
|
1084
|
-
L: 80
|
|
1085
|
-
});
|
|
860
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
|
|
1086
861
|
_cursorConverter;
|
|
1087
862
|
_provider;
|
|
1088
863
|
_lastAnchor;
|
|
@@ -1231,7 +1006,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
|
|
|
1231
1006
|
return true;
|
|
1232
1007
|
}
|
|
1233
1008
|
};
|
|
1234
|
-
var styles =
|
|
1009
|
+
var styles = EditorView5.theme({
|
|
1235
1010
|
".cm-collab-selection": {},
|
|
1236
1011
|
".cm-collab-selectionLine": {
|
|
1237
1012
|
padding: 0,
|
|
@@ -1313,10 +1088,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1313
1088
|
this._info = info;
|
|
1314
1089
|
}
|
|
1315
1090
|
open() {
|
|
1316
|
-
this._ctx = new Context2(void 0, {
|
|
1317
|
-
F: __dxlog_file5,
|
|
1318
|
-
L: 57
|
|
1319
|
-
});
|
|
1091
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
|
|
1320
1092
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1321
1093
|
if (this._localState) {
|
|
1322
1094
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1343,12 +1115,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1343
1115
|
}).catch((err) => {
|
|
1344
1116
|
log4.debug("failed to query awareness", {
|
|
1345
1117
|
err
|
|
1346
|
-
}, {
|
|
1347
|
-
F: __dxlog_file5,
|
|
1348
|
-
L: 91,
|
|
1349
|
-
S: this,
|
|
1350
|
-
C: (f, a) => f(...a)
|
|
1351
|
-
});
|
|
1118
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
|
|
1352
1119
|
});
|
|
1353
1120
|
}
|
|
1354
1121
|
close() {
|
|
@@ -1360,15 +1127,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1360
1127
|
return Array.from(this._remoteStates.values());
|
|
1361
1128
|
}
|
|
1362
1129
|
update(position) {
|
|
1363
|
-
invariant(this._postTask, void 0, {
|
|
1364
|
-
F: __dxlog_file5,
|
|
1365
|
-
L: 106,
|
|
1366
|
-
S: this,
|
|
1367
|
-
A: [
|
|
1368
|
-
"this._postTask",
|
|
1369
|
-
""
|
|
1370
|
-
]
|
|
1371
|
-
});
|
|
1130
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1372
1131
|
this._localState = {
|
|
1373
1132
|
peerId: this._peerId,
|
|
1374
1133
|
position,
|
|
@@ -1377,34 +1136,18 @@ var SpaceAwarenessProvider = class {
|
|
|
1377
1136
|
this._postTask.schedule();
|
|
1378
1137
|
}
|
|
1379
1138
|
_handleQueryMessage() {
|
|
1380
|
-
invariant(this._postTask, void 0, {
|
|
1381
|
-
F: __dxlog_file5,
|
|
1382
|
-
L: 117,
|
|
1383
|
-
S: this,
|
|
1384
|
-
A: [
|
|
1385
|
-
"this._postTask",
|
|
1386
|
-
""
|
|
1387
|
-
]
|
|
1388
|
-
});
|
|
1139
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1389
1140
|
this._postTask.schedule();
|
|
1390
1141
|
}
|
|
1391
1142
|
_handlePostMessage(message) {
|
|
1392
|
-
invariant(message.kind === "post", void 0, {
|
|
1393
|
-
F: __dxlog_file5,
|
|
1394
|
-
L: 122,
|
|
1395
|
-
S: this,
|
|
1396
|
-
A: [
|
|
1397
|
-
"message.kind === 'post'",
|
|
1398
|
-
""
|
|
1399
|
-
]
|
|
1400
|
-
});
|
|
1143
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1401
1144
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1402
1145
|
this.remoteStateChange.emit();
|
|
1403
1146
|
}
|
|
1404
1147
|
};
|
|
1405
1148
|
|
|
1406
1149
|
// src/extensions/blast.ts
|
|
1407
|
-
import { EditorView as
|
|
1150
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1408
1151
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1409
1152
|
import { throttle } from "@dxos/async";
|
|
1410
1153
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
@@ -1453,7 +1196,7 @@ var blast = (options = defaultOptions) => {
|
|
|
1453
1196
|
};
|
|
1454
1197
|
return [
|
|
1455
1198
|
// Cursor moved.
|
|
1456
|
-
|
|
1199
|
+
EditorView6.updateListener.of((update2) => {
|
|
1457
1200
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
1458
1201
|
if (blaster) {
|
|
1459
1202
|
blaster.destroy();
|
|
@@ -1526,15 +1269,7 @@ var Blaster = class {
|
|
|
1526
1269
|
return this._node;
|
|
1527
1270
|
}
|
|
1528
1271
|
initialize() {
|
|
1529
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1530
|
-
F: __dxlog_file6,
|
|
1531
|
-
L: 142,
|
|
1532
|
-
S: this,
|
|
1533
|
-
A: [
|
|
1534
|
-
"!this._canvas && !this._ctx",
|
|
1535
|
-
""
|
|
1536
|
-
]
|
|
1537
|
-
});
|
|
1272
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1538
1273
|
this._canvas = document.createElement("canvas");
|
|
1539
1274
|
this._canvas.id = "code-blast-canvas";
|
|
1540
1275
|
this._canvas.style.position = "absolute";
|
|
@@ -1563,15 +1298,7 @@ var Blaster = class {
|
|
|
1563
1298
|
}
|
|
1564
1299
|
}
|
|
1565
1300
|
start() {
|
|
1566
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1567
|
-
F: __dxlog_file6,
|
|
1568
|
-
L: 181,
|
|
1569
|
-
S: this,
|
|
1570
|
-
A: [
|
|
1571
|
-
"this._canvas && this._ctx",
|
|
1572
|
-
""
|
|
1573
|
-
]
|
|
1574
|
-
});
|
|
1301
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1575
1302
|
this._running = true;
|
|
1576
1303
|
this.loop();
|
|
1577
1304
|
}
|
|
@@ -1711,9 +1438,9 @@ var random = (min, max) => {
|
|
|
1711
1438
|
|
|
1712
1439
|
// src/extensions/blocks.ts
|
|
1713
1440
|
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1714
|
-
import { Decoration as Decoration6, EditorView as
|
|
1441
|
+
import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
1715
1442
|
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1716
|
-
var paragraphBlockPlugin =
|
|
1443
|
+
var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
|
|
1717
1444
|
decorations;
|
|
1718
1445
|
constructor(view) {
|
|
1719
1446
|
this.decorations = this.build(view);
|
|
@@ -1772,15 +1499,15 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
|
|
|
1772
1499
|
});
|
|
1773
1500
|
var blocks = () => [
|
|
1774
1501
|
paragraphBlockPlugin,
|
|
1775
|
-
|
|
1502
|
+
EditorView7.baseTheme({
|
|
1776
1503
|
".cm-line.block-line": {
|
|
1777
1504
|
paddingLeft: "0.75rem",
|
|
1778
1505
|
paddingRight: "0.75rem",
|
|
1779
|
-
borderLeft: "1px solid var(--
|
|
1780
|
-
borderRight: "1px solid var(--
|
|
1506
|
+
borderLeft: "1px solid var(--color-subdued-separator)",
|
|
1507
|
+
borderRight: "1px solid var(--color-subdued-separator)"
|
|
1781
1508
|
},
|
|
1782
1509
|
".cm-line.block-single": {
|
|
1783
|
-
border: "1px solid var(--
|
|
1510
|
+
border: "1px solid var(--color-subdued-separator)",
|
|
1784
1511
|
borderRadius: "6px",
|
|
1785
1512
|
paddingTop: "0.5rem",
|
|
1786
1513
|
paddingBottom: "0.5rem",
|
|
@@ -1788,7 +1515,7 @@ var blocks = () => [
|
|
|
1788
1515
|
marginBottom: "0.5rem"
|
|
1789
1516
|
},
|
|
1790
1517
|
".cm-line.block-first": {
|
|
1791
|
-
borderTop: "1px solid var(--
|
|
1518
|
+
borderTop: "1px solid var(--color-subdued-separator)",
|
|
1792
1519
|
borderTopLeftRadius: "6px",
|
|
1793
1520
|
borderTopRightRadius: "6px",
|
|
1794
1521
|
paddingTop: "0.5rem",
|
|
@@ -1796,7 +1523,7 @@ var blocks = () => [
|
|
|
1796
1523
|
},
|
|
1797
1524
|
".cm-line.block-middle": {},
|
|
1798
1525
|
".cm-line.block-last": {
|
|
1799
|
-
borderBottom: "1px solid var(--
|
|
1526
|
+
borderBottom: "1px solid var(--color-subdued-separator)",
|
|
1800
1527
|
borderBottomLeftRadius: "6px",
|
|
1801
1528
|
borderBottomRightRadius: "6px",
|
|
1802
1529
|
paddingBottom: "0.5rem",
|
|
@@ -1806,13 +1533,13 @@ var blocks = () => [
|
|
|
1806
1533
|
];
|
|
1807
1534
|
|
|
1808
1535
|
// src/extensions/bookmarks.ts
|
|
1809
|
-
import { Prec as Prec3, StateEffect as
|
|
1536
|
+
import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1810
1537
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1811
1538
|
import { log as log5 } from "@dxos/log";
|
|
1812
1539
|
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1813
|
-
var addBookmark =
|
|
1814
|
-
var removeBookmark =
|
|
1815
|
-
var clearBookmarks =
|
|
1540
|
+
var addBookmark = StateEffect2.define();
|
|
1541
|
+
var removeBookmark = StateEffect2.define();
|
|
1542
|
+
var clearBookmarks = StateEffect2.define();
|
|
1816
1543
|
var bookmarks = () => {
|
|
1817
1544
|
return [
|
|
1818
1545
|
bookmarksField,
|
|
@@ -1821,12 +1548,7 @@ var bookmarks = () => {
|
|
|
1821
1548
|
key: "Mod-ArrowUp",
|
|
1822
1549
|
run: (view) => {
|
|
1823
1550
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1824
|
-
log5("up", bookmarks2, {
|
|
1825
|
-
F: __dxlog_file7,
|
|
1826
|
-
L: 29,
|
|
1827
|
-
S: void 0,
|
|
1828
|
-
C: (f, a) => f(...a)
|
|
1829
|
-
});
|
|
1551
|
+
log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
|
|
1830
1552
|
return true;
|
|
1831
1553
|
}
|
|
1832
1554
|
},
|
|
@@ -1834,12 +1556,7 @@ var bookmarks = () => {
|
|
|
1834
1556
|
key: "Mod-ArrowDown",
|
|
1835
1557
|
run: (view) => {
|
|
1836
1558
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1837
|
-
log5("down", bookmarks2, {
|
|
1838
|
-
F: __dxlog_file7,
|
|
1839
|
-
L: 37,
|
|
1840
|
-
S: void 0,
|
|
1841
|
-
C: (f, a) => f(...a)
|
|
1842
|
-
});
|
|
1559
|
+
log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
|
|
1843
1560
|
return true;
|
|
1844
1561
|
}
|
|
1845
1562
|
}
|
|
@@ -1876,27 +1593,27 @@ var bookmarksField = StateField2.define({
|
|
|
1876
1593
|
|
|
1877
1594
|
// src/extensions/comments.ts
|
|
1878
1595
|
import { invertedEffects } from "@codemirror/commands";
|
|
1879
|
-
import { StateEffect as
|
|
1880
|
-
import { Decoration as Decoration7, EditorView as
|
|
1596
|
+
import { StateEffect as StateEffect3, StateField as StateField3 } from "@codemirror/state";
|
|
1597
|
+
import { Decoration as Decoration7, EditorView as EditorView9, ViewPlugin as ViewPlugin8, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1881
1598
|
import sortBy from "lodash.sortby";
|
|
1882
|
-
import { debounce as
|
|
1599
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
1883
1600
|
import { log as log6 } from "@dxos/log";
|
|
1884
1601
|
import { isNonNullable } from "@dxos/util";
|
|
1885
1602
|
|
|
1886
1603
|
// src/extensions/selection.ts
|
|
1887
1604
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1888
|
-
import { EditorView as
|
|
1889
|
-
import { debounce
|
|
1605
|
+
import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
|
|
1606
|
+
import { debounce } from "@dxos/async";
|
|
1890
1607
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1891
1608
|
import { isTruthy } from "@dxos/util";
|
|
1892
1609
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1893
1610
|
var documentId = singleValueFacet();
|
|
1894
|
-
var stateRestoreAnnotation = "dxos.
|
|
1611
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1895
1612
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1896
1613
|
return {
|
|
1897
1614
|
selection,
|
|
1898
1615
|
scrollIntoView: !scrollTo,
|
|
1899
|
-
effects: scrollTo ?
|
|
1616
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
|
1900
1617
|
yMargin: 96
|
|
1901
1618
|
}) : void 0,
|
|
1902
1619
|
annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
|
|
@@ -1904,33 +1621,17 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1904
1621
|
};
|
|
1905
1622
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1906
1623
|
getState: (id) => {
|
|
1907
|
-
invariant3(id, void 0, {
|
|
1908
|
-
F: __dxlog_file8,
|
|
1909
|
-
L: 47,
|
|
1910
|
-
S: void 0,
|
|
1911
|
-
A: [
|
|
1912
|
-
"id",
|
|
1913
|
-
""
|
|
1914
|
-
]
|
|
1915
|
-
});
|
|
1624
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
|
|
1916
1625
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1917
1626
|
return state ? JSON.parse(state) : void 0;
|
|
1918
1627
|
},
|
|
1919
1628
|
setState: (id, state) => {
|
|
1920
|
-
invariant3(id, void 0, {
|
|
1921
|
-
F: __dxlog_file8,
|
|
1922
|
-
L: 53,
|
|
1923
|
-
S: void 0,
|
|
1924
|
-
A: [
|
|
1925
|
-
"id",
|
|
1926
|
-
""
|
|
1927
|
-
]
|
|
1928
|
-
});
|
|
1629
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
|
|
1929
1630
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1930
1631
|
}
|
|
1931
1632
|
});
|
|
1932
1633
|
var selectionState = ({ getState, setState } = {}) => {
|
|
1933
|
-
const setStateDebounced =
|
|
1634
|
+
const setStateDebounced = debounce(setState, 1e3);
|
|
1934
1635
|
return [
|
|
1935
1636
|
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
1936
1637
|
// EditorView.domEventHandlers({
|
|
@@ -1938,7 +1639,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1938
1639
|
// setStateDebounced(id, {});
|
|
1939
1640
|
// },
|
|
1940
1641
|
// }),
|
|
1941
|
-
|
|
1642
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
|
1942
1643
|
const id = view.state.facet(documentId);
|
|
1943
1644
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
1944
1645
|
return;
|
|
@@ -1978,9 +1679,9 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1978
1679
|
|
|
1979
1680
|
// src/extensions/comments.ts
|
|
1980
1681
|
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1981
|
-
var setComments =
|
|
1982
|
-
var setSelection =
|
|
1983
|
-
var setCommentState =
|
|
1682
|
+
var setComments = StateEffect3.define();
|
|
1683
|
+
var setSelection = StateEffect3.define();
|
|
1684
|
+
var setCommentState = StateEffect3.define();
|
|
1984
1685
|
var commentsState = StateField3.define({
|
|
1985
1686
|
create: (state) => ({
|
|
1986
1687
|
id: state.facet(documentId),
|
|
@@ -2019,17 +1720,17 @@ var commentsState = StateField3.define({
|
|
|
2019
1720
|
return value;
|
|
2020
1721
|
}
|
|
2021
1722
|
});
|
|
2022
|
-
var styles2 =
|
|
1723
|
+
var styles2 = EditorView9.theme({
|
|
2023
1724
|
".cm-comment, .cm-comment-current": {
|
|
2024
1725
|
padding: "3px 0",
|
|
2025
|
-
color: "var(--
|
|
2026
|
-
backgroundColor: "var(--
|
|
1726
|
+
color: "var(--color-cm-comment-text)",
|
|
1727
|
+
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2027
1728
|
},
|
|
2028
1729
|
".cm-comment > span, .cm-comment-current > span": {
|
|
2029
1730
|
boxDecorationBreak: "clone",
|
|
2030
|
-
boxShadow: "0 0 1px 3px var(--
|
|
2031
|
-
backgroundColor: "var(--
|
|
2032
|
-
color: "var(--
|
|
1731
|
+
boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
|
|
1732
|
+
backgroundColor: "var(--color-cm-comment-surface)",
|
|
1733
|
+
color: "var(--color-cm-comment-text)",
|
|
2033
1734
|
cursor: "pointer"
|
|
2034
1735
|
}
|
|
2035
1736
|
});
|
|
@@ -2040,19 +1741,14 @@ var createCommentMark = (id, isCurrent) => Decoration7.mark({
|
|
|
2040
1741
|
"data-comment-id": id
|
|
2041
1742
|
}
|
|
2042
1743
|
});
|
|
2043
|
-
var commentsDecorations =
|
|
1744
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
|
2044
1745
|
commentsState
|
|
2045
1746
|
], (state) => {
|
|
2046
1747
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
2047
1748
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2048
1749
|
const range = comment.range;
|
|
2049
1750
|
if (!range) {
|
|
2050
|
-
log6.warn("Invalid range:", range, {
|
|
2051
|
-
F: __dxlog_file9,
|
|
2052
|
-
L: 140,
|
|
2053
|
-
S: void 0,
|
|
2054
|
-
C: (f, a) => f(...a)
|
|
2055
|
-
});
|
|
1751
|
+
log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
|
|
2056
1752
|
return void 0;
|
|
2057
1753
|
} else if (range.from === range.to) {
|
|
2058
1754
|
return void 0;
|
|
@@ -2062,8 +1758,8 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2062
1758
|
}).filter(isNonNullable);
|
|
2063
1759
|
return Decoration7.set(decorations2);
|
|
2064
1760
|
});
|
|
2065
|
-
var commentClickedEffect =
|
|
2066
|
-
var handleCommentClick =
|
|
1761
|
+
var commentClickedEffect = StateEffect3.define();
|
|
1762
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
|
2067
1763
|
click: (event, view) => {
|
|
2068
1764
|
let target = event.target;
|
|
2069
1765
|
const editorRoot = view.dom;
|
|
@@ -2102,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2102
1798
|
}
|
|
2103
1799
|
};
|
|
2104
1800
|
return [
|
|
2105
|
-
|
|
1801
|
+
EditorView9.domEventHandlers({
|
|
2106
1802
|
cut: handleTrack,
|
|
2107
1803
|
copy: handleTrack
|
|
2108
1804
|
}),
|
|
@@ -2124,7 +1820,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2124
1820
|
return effects;
|
|
2125
1821
|
}),
|
|
2126
1822
|
// Handle paste or the undo of comment deletion.
|
|
2127
|
-
|
|
1823
|
+
EditorView9.updateListener.of((update2) => {
|
|
2128
1824
|
const restore = [];
|
|
2129
1825
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
2130
1826
|
const tr = update2.transactions[i];
|
|
@@ -2165,10 +1861,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2165
1861
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2166
1862
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2167
1863
|
if (!exists) {
|
|
2168
|
-
const
|
|
1864
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2169
1865
|
onUpdate({
|
|
2170
1866
|
id: comment.id,
|
|
2171
|
-
cursor
|
|
1867
|
+
cursor
|
|
2172
1868
|
});
|
|
2173
1869
|
}
|
|
2174
1870
|
}
|
|
@@ -2180,7 +1876,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2180
1876
|
from: changes.mapPos(comment.from, 1),
|
|
2181
1877
|
to: changes.mapPos(comment.to, 1)
|
|
2182
1878
|
});
|
|
2183
|
-
var restoreCommentEffect =
|
|
1879
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
2184
1880
|
map: mapTrackedComment
|
|
2185
1881
|
});
|
|
2186
1882
|
var createComment = (view) => {
|
|
@@ -2197,13 +1893,13 @@ var createComment = (view) => {
|
|
|
2197
1893
|
}
|
|
2198
1894
|
});
|
|
2199
1895
|
}
|
|
2200
|
-
const
|
|
1896
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2201
1897
|
from,
|
|
2202
1898
|
to
|
|
2203
1899
|
});
|
|
2204
|
-
if (
|
|
1900
|
+
if (cursor) {
|
|
2205
1901
|
options.onCreate?.({
|
|
2206
|
-
cursor
|
|
1902
|
+
cursor,
|
|
2207
1903
|
from,
|
|
2208
1904
|
location: view.coordsAtPos(from)
|
|
2209
1905
|
});
|
|
@@ -2214,7 +1910,7 @@ var createComment = (view) => {
|
|
|
2214
1910
|
var optionsFacet = singleValueFacet();
|
|
2215
1911
|
var comments = (options = {}) => {
|
|
2216
1912
|
const { key: shortcut = "meta-'" } = options;
|
|
2217
|
-
const handleSelect =
|
|
1913
|
+
const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
|
|
2218
1914
|
return [
|
|
2219
1915
|
optionsFacet.of(options),
|
|
2220
1916
|
options.id ? documentId.of(options.id) : void 0,
|
|
@@ -2266,7 +1962,7 @@ var comments = (options = {}) => {
|
|
|
2266
1962
|
//
|
|
2267
1963
|
// Track deleted ranges and update ranges for decorations.
|
|
2268
1964
|
//
|
|
2269
|
-
|
|
1965
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
|
2270
1966
|
let mod = false;
|
|
2271
1967
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
2272
1968
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -2298,7 +1994,7 @@ var comments = (options = {}) => {
|
|
|
2298
1994
|
//
|
|
2299
1995
|
// Track selection/proximity.
|
|
2300
1996
|
//
|
|
2301
|
-
|
|
1997
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
|
2302
1998
|
let min = Infinity;
|
|
2303
1999
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
2304
2000
|
const { head } = state.selection.main;
|
|
@@ -2352,7 +2048,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
|
2352
2048
|
anchor: range.from
|
|
2353
2049
|
} : void 0,
|
|
2354
2050
|
effects: [
|
|
2355
|
-
needsScroll ?
|
|
2051
|
+
needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
|
|
2356
2052
|
y: "center"
|
|
2357
2053
|
} : void 0) : [],
|
|
2358
2054
|
needsSelectionUpdate ? setSelection.of({
|
|
@@ -2383,7 +2079,7 @@ var ExternalCommentSync = class {
|
|
|
2383
2079
|
this.unsubscribe();
|
|
2384
2080
|
};
|
|
2385
2081
|
};
|
|
2386
|
-
var createExternalCommentSync = (id, subscribe, getComments) =>
|
|
2082
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
|
|
2387
2083
|
constructor(view) {
|
|
2388
2084
|
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
2389
2085
|
}
|
|
@@ -2392,9 +2088,9 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fro
|
|
|
2392
2088
|
// src/extensions/debug.ts
|
|
2393
2089
|
import { syntaxTree } from "@codemirror/language";
|
|
2394
2090
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
2395
|
-
var debugNodeLogger = (
|
|
2091
|
+
var debugNodeLogger = (log12 = console.log) => {
|
|
2396
2092
|
const logTokens = (state) => syntaxTree(state).iterate({
|
|
2397
|
-
enter: (node) =>
|
|
2093
|
+
enter: (node) => log12(node.type)
|
|
2398
2094
|
});
|
|
2399
2095
|
return StateField4.define({
|
|
2400
2096
|
create: (state) => logTokens(state),
|
|
@@ -2403,12 +2099,12 @@ var debugNodeLogger = (log11 = console.log) => {
|
|
|
2403
2099
|
};
|
|
2404
2100
|
|
|
2405
2101
|
// src/extensions/dnd.ts
|
|
2406
|
-
import { EditorView as
|
|
2102
|
+
import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
|
|
2407
2103
|
var dropFile = (options = {}) => {
|
|
2408
2104
|
return [
|
|
2409
2105
|
styles3,
|
|
2410
2106
|
dropCursor(),
|
|
2411
|
-
|
|
2107
|
+
EditorView10.domEventHandlers({
|
|
2412
2108
|
drop: (event, view) => {
|
|
2413
2109
|
event.preventDefault();
|
|
2414
2110
|
const files = event.dataTransfer?.files;
|
|
@@ -2427,10 +2123,10 @@ var dropFile = (options = {}) => {
|
|
|
2427
2123
|
})
|
|
2428
2124
|
];
|
|
2429
2125
|
};
|
|
2430
|
-
var styles3 =
|
|
2126
|
+
var styles3 = EditorView10.theme({
|
|
2431
2127
|
".cm-dropCursor": {
|
|
2432
|
-
borderLeft: "2px solid var(--
|
|
2433
|
-
color: "var(--
|
|
2128
|
+
borderLeft: "2px solid var(--color-accent-text)",
|
|
2129
|
+
color: "var(--color-accent-text)",
|
|
2434
2130
|
padding: "0 4px"
|
|
2435
2131
|
},
|
|
2436
2132
|
".cm-dropCursor:after": {
|
|
@@ -2444,47 +2140,66 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2444
2140
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2445
2141
|
import { searchKeymap } from "@codemirror/search";
|
|
2446
2142
|
import { EditorState } from "@codemirror/state";
|
|
2447
|
-
import { EditorView as
|
|
2143
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2448
2144
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2449
2145
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2450
2146
|
import { generateName } from "@dxos/display-name";
|
|
2451
|
-
import { log as
|
|
2452
|
-
import { hexToHue, isTruthy as
|
|
2147
|
+
import { log as log8 } from "@dxos/log";
|
|
2148
|
+
import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
|
|
2453
2149
|
|
|
2454
|
-
// src/styles/
|
|
2150
|
+
// src/styles/theme.ts
|
|
2151
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2455
2152
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2456
2153
|
var headings = {
|
|
2457
|
-
1:
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2154
|
+
1: {
|
|
2155
|
+
className: "text-3xl",
|
|
2156
|
+
fontSize: "var(--text-3xl)",
|
|
2157
|
+
lineHeight: "var(--text-4xl--line-height)"
|
|
2158
|
+
},
|
|
2159
|
+
2: {
|
|
2160
|
+
className: "text-2xl",
|
|
2161
|
+
fontSize: "var(--text-2xl)",
|
|
2162
|
+
lineHeight: "var(--text-3xl--line-height)"
|
|
2163
|
+
},
|
|
2164
|
+
3: {
|
|
2165
|
+
className: "text-xl",
|
|
2166
|
+
fontSize: "var(--text-xl)",
|
|
2167
|
+
lineHeight: "var(--text-2xl--line-height)"
|
|
2168
|
+
},
|
|
2169
|
+
4: {
|
|
2170
|
+
className: "text-lg",
|
|
2171
|
+
fontSize: "var(--text-lg)",
|
|
2172
|
+
lineHeight: "var(--text-xl--line-height)"
|
|
2173
|
+
},
|
|
2174
|
+
5: {
|
|
2175
|
+
className: "text-base",
|
|
2176
|
+
fontSize: "var(--text-base)",
|
|
2177
|
+
lineHeight: "var(--text-lg--line-height)"
|
|
2178
|
+
},
|
|
2179
|
+
6: {
|
|
2180
|
+
className: "text-base",
|
|
2181
|
+
fontSize: "var(--text-base)",
|
|
2182
|
+
lineHeight: "var(--text-base--line-height)"
|
|
2183
|
+
}
|
|
2463
2184
|
};
|
|
2185
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2186
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2464
2187
|
var markdownTheme = {
|
|
2465
|
-
code: "font-mono
|
|
2466
|
-
codeMark: "font-mono
|
|
2467
|
-
mark: "
|
|
2468
|
-
heading: (level) => {
|
|
2469
|
-
|
|
2470
|
-
|
|
2188
|
+
code: "font-mono! cm-code-inline",
|
|
2189
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2190
|
+
mark: "font-mono!",
|
|
2191
|
+
heading: (level) => ({
|
|
2192
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2193
|
+
color: "var(--color-cm-heading) !important",
|
|
2194
|
+
lineHeight: headings[level].lineHeight,
|
|
2195
|
+
fontSize: headings[level].fontSize,
|
|
2196
|
+
fontWeight: "100 !important"
|
|
2197
|
+
})
|
|
2471
2198
|
};
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
// src/styles/tokens.ts
|
|
2477
|
-
import { tokens } from "@dxos/ui-theme";
|
|
2478
|
-
import { get } from "@dxos/util";
|
|
2479
|
-
var getToken = (path, defaultValue) => {
|
|
2480
|
-
const value = get(tokens, path, defaultValue);
|
|
2481
|
-
return value?.toString() ?? "";
|
|
2482
|
-
};
|
|
2483
|
-
var fontBody = getToken("fontFamily.body");
|
|
2484
|
-
var fontMono = getToken("fontFamily.mono");
|
|
2485
|
-
|
|
2486
|
-
// src/styles/theme.ts
|
|
2487
|
-
var baseTheme = EditorView13.baseTheme({
|
|
2199
|
+
var baseTheme = EditorView11.baseTheme({
|
|
2200
|
+
/**
|
|
2201
|
+
* Outer frame.
|
|
2202
|
+
*/
|
|
2488
2203
|
"&": {},
|
|
2489
2204
|
"&.cm-focused": {
|
|
2490
2205
|
outline: "none"
|
|
@@ -2493,7 +2208,27 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2493
2208
|
* Scroller
|
|
2494
2209
|
*/
|
|
2495
2210
|
".cm-scroller": {
|
|
2496
|
-
|
|
2211
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
2212
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2213
|
+
// open/close) don't jump the user's view.
|
|
2214
|
+
overflowAnchor: "auto"
|
|
2215
|
+
},
|
|
2216
|
+
".cm-scroller::-webkit-scrollbar": {
|
|
2217
|
+
width: "var(--scrollbar-size,8px)",
|
|
2218
|
+
height: "var(--scrollbar-size,8px)"
|
|
2219
|
+
},
|
|
2220
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2221
|
+
background: "transparent"
|
|
2222
|
+
},
|
|
2223
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2224
|
+
background: "transparent"
|
|
2225
|
+
},
|
|
2226
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2227
|
+
background: "transparent",
|
|
2228
|
+
transition: "background 0.15s"
|
|
2229
|
+
},
|
|
2230
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2231
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2497
2232
|
},
|
|
2498
2233
|
/**
|
|
2499
2234
|
* Content
|
|
@@ -2501,7 +2236,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2501
2236
|
*/
|
|
2502
2237
|
".cm-content": {
|
|
2503
2238
|
padding: "unset",
|
|
2504
|
-
lineHeight: "24px",
|
|
2505
2239
|
color: "unset"
|
|
2506
2240
|
},
|
|
2507
2241
|
/**
|
|
@@ -2515,8 +2249,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2515
2249
|
".cm-gutter": {},
|
|
2516
2250
|
".cm-gutter.cm-lineNumbers": {
|
|
2517
2251
|
paddingRight: "4px",
|
|
2518
|
-
borderRight: "1px solid var(--
|
|
2519
|
-
color: "var(--
|
|
2252
|
+
borderRight: "1px solid var(--color-subdued-separator)",
|
|
2253
|
+
color: "var(--color-subdued)"
|
|
2520
2254
|
},
|
|
2521
2255
|
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
|
2522
2256
|
minWidth: "40px"
|
|
@@ -2532,29 +2266,36 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2532
2266
|
* Line.
|
|
2533
2267
|
*/
|
|
2534
2268
|
".cm-line": {
|
|
2535
|
-
lineHeight:
|
|
2269
|
+
lineHeight: 1.5,
|
|
2536
2270
|
paddingInline: 0
|
|
2537
2271
|
},
|
|
2272
|
+
/**
|
|
2273
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2274
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2275
|
+
*/
|
|
2276
|
+
".cm-line *": {
|
|
2277
|
+
lineHeight: "inherit"
|
|
2278
|
+
},
|
|
2538
2279
|
".cm-activeLine": {
|
|
2539
|
-
background: "var(--
|
|
2280
|
+
background: "var(--color-cm-active-line)"
|
|
2540
2281
|
},
|
|
2541
2282
|
/**
|
|
2542
2283
|
* Cursor (layer).
|
|
2543
2284
|
*/
|
|
2544
2285
|
".cm-cursor, .cm-dropCursor": {
|
|
2545
|
-
borderLeft: "2px solid var(--
|
|
2286
|
+
borderLeft: "2px solid var(--color-cm-cursor)"
|
|
2546
2287
|
},
|
|
2547
2288
|
".cm-placeholder": {
|
|
2548
|
-
color: "var(--
|
|
2289
|
+
color: "var(--color-placeholder)"
|
|
2549
2290
|
},
|
|
2550
2291
|
/**
|
|
2551
2292
|
* Selection (layer).
|
|
2552
2293
|
*/
|
|
2553
2294
|
".cm-selectionBackground": {
|
|
2554
|
-
background: "var(--
|
|
2295
|
+
background: "var(--color-cm-selection)"
|
|
2555
2296
|
},
|
|
2556
2297
|
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2557
|
-
background: "var(--
|
|
2298
|
+
background: "var(--color-cm-focused-selection)"
|
|
2558
2299
|
},
|
|
2559
2300
|
/**
|
|
2560
2301
|
* Search.
|
|
@@ -2564,8 +2305,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2564
2305
|
margin: "0 -3px",
|
|
2565
2306
|
padding: "3px",
|
|
2566
2307
|
borderRadius: "3px",
|
|
2567
|
-
background: "var(--
|
|
2568
|
-
color: "var(--
|
|
2308
|
+
background: "var(--color-cm-highlight-surface)",
|
|
2309
|
+
color: "var(--color-cm-highlight)"
|
|
2569
2310
|
},
|
|
2570
2311
|
".cm-searchMatch-selected": {
|
|
2571
2312
|
textDecoration: "underline"
|
|
@@ -2576,20 +2317,30 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2576
2317
|
".cm-link": {
|
|
2577
2318
|
textDecorationLine: "underline",
|
|
2578
2319
|
textDecorationThickness: "1px",
|
|
2579
|
-
textDecorationColor: "var(--
|
|
2320
|
+
textDecorationColor: "var(--color-separator)",
|
|
2580
2321
|
textUnderlineOffset: "2px",
|
|
2581
|
-
borderRadius: ".125rem"
|
|
2322
|
+
borderRadius: ".125rem",
|
|
2323
|
+
cursor: "pointer"
|
|
2582
2324
|
},
|
|
2583
2325
|
".cm-link > span": {
|
|
2584
|
-
color: "var(--
|
|
2326
|
+
color: "var(--color-accent-text)"
|
|
2327
|
+
},
|
|
2328
|
+
".cm-link > span:hover": {
|
|
2329
|
+
color: "var(--color-accent-text-hover)"
|
|
2585
2330
|
},
|
|
2586
2331
|
/**
|
|
2587
2332
|
* Tooltip.
|
|
2588
2333
|
*/
|
|
2589
2334
|
".cm-tooltip": {
|
|
2590
|
-
background: "var(--
|
|
2335
|
+
background: "var(--color-modal-surface)"
|
|
2591
2336
|
},
|
|
2592
2337
|
".cm-tooltip-below": {},
|
|
2338
|
+
".cm-tooltip-hover": {
|
|
2339
|
+
background: "var(--color-modal-surface)",
|
|
2340
|
+
border: "1px solid var(--color-separator)",
|
|
2341
|
+
borderRadius: "4px",
|
|
2342
|
+
overflow: "hidden"
|
|
2343
|
+
},
|
|
2593
2344
|
/**
|
|
2594
2345
|
* Autocomplete.
|
|
2595
2346
|
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
@@ -2597,7 +2348,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2597
2348
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
2598
2349
|
marginTop: "6px",
|
|
2599
2350
|
marginLeft: "-10px",
|
|
2600
|
-
border: "2px solid var(--
|
|
2351
|
+
border: "2px solid var(--color-separator)",
|
|
2601
2352
|
borderRadius: "4px"
|
|
2602
2353
|
},
|
|
2603
2354
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
@@ -2607,12 +2358,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2607
2358
|
padding: "4px"
|
|
2608
2359
|
},
|
|
2609
2360
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2610
|
-
background: "var(--
|
|
2611
|
-
color: "var(--
|
|
2361
|
+
background: "var(--color-current-surface)",
|
|
2362
|
+
color: "var(--color-base-foreground)"
|
|
2612
2363
|
},
|
|
2613
2364
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2614
2365
|
paddingLeft: "4px !important",
|
|
2615
|
-
color: "var(--
|
|
2366
|
+
color: "var(--color-base-foreground)"
|
|
2616
2367
|
},
|
|
2617
2368
|
/**
|
|
2618
2369
|
* Completion info.
|
|
@@ -2621,17 +2372,17 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2621
2372
|
width: "360px !important",
|
|
2622
2373
|
margin: "-10px 1px 0 1px",
|
|
2623
2374
|
padding: "8px !important",
|
|
2624
|
-
borderColor: "var(--
|
|
2375
|
+
borderColor: "var(--color-separator)"
|
|
2625
2376
|
},
|
|
2626
2377
|
".cm-completionIcon": {
|
|
2627
2378
|
display: "none"
|
|
2628
2379
|
},
|
|
2629
2380
|
".cm-completionLabel": {
|
|
2630
|
-
color: "var(--
|
|
2381
|
+
color: "var(--color-description)",
|
|
2631
2382
|
padding: "0 4px"
|
|
2632
2383
|
},
|
|
2633
2384
|
".cm-completionMatchedText": {
|
|
2634
|
-
color: "var(--
|
|
2385
|
+
color: "var(--color-base-foreground)",
|
|
2635
2386
|
textDecoration: "none !important"
|
|
2636
2387
|
},
|
|
2637
2388
|
/**
|
|
@@ -2655,7 +2406,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2655
2406
|
backgroundColor: "var(--surface-bg)"
|
|
2656
2407
|
},
|
|
2657
2408
|
".cm-panel input, .cm-panel button, .cm-panel label": {
|
|
2658
|
-
color: "var(--
|
|
2409
|
+
color: "var(--color-subdued)",
|
|
2659
2410
|
fontSize: "14px",
|
|
2660
2411
|
all: "unset",
|
|
2661
2412
|
margin: "3px !important",
|
|
@@ -2663,10 +2414,10 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2663
2414
|
outline: "1px solid transparent"
|
|
2664
2415
|
},
|
|
2665
2416
|
".cm-panel input, .cm-panel button": {
|
|
2666
|
-
backgroundColor: "var(--
|
|
2417
|
+
backgroundColor: "var(--color-input-surface)"
|
|
2667
2418
|
},
|
|
2668
2419
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2669
|
-
outline: "1px solid var(--
|
|
2420
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2670
2421
|
},
|
|
2671
2422
|
".cm-panel label": {
|
|
2672
2423
|
display: "inline-flex",
|
|
@@ -2679,33 +2430,33 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2679
2430
|
height: "8px",
|
|
2680
2431
|
marginRight: "6px !important",
|
|
2681
2432
|
padding: "2px !important",
|
|
2682
|
-
color: "var(--
|
|
2433
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2683
2434
|
},
|
|
2684
2435
|
".cm-panel button": {
|
|
2685
2436
|
"&:hover": {
|
|
2686
|
-
|
|
2437
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
|
|
2438
|
+
backgroundColor: "var(--color-accent-surface-hover) !important"
|
|
2687
2439
|
},
|
|
2688
2440
|
"&:active": {
|
|
2689
|
-
backgroundColor: "var(--
|
|
2441
|
+
backgroundColor: "var(--color-accent-surface-hover)"
|
|
2690
2442
|
}
|
|
2691
2443
|
},
|
|
2692
2444
|
".cm-panel.cm-search": {
|
|
2693
2445
|
padding: "4px",
|
|
2694
|
-
borderTop: "1px solid var(--
|
|
2446
|
+
borderTop: "1px solid var(--color-separator)"
|
|
2695
2447
|
}
|
|
2696
2448
|
});
|
|
2697
|
-
var editorGutter =
|
|
2449
|
+
var editorGutter = EditorView11.theme({
|
|
2698
2450
|
".cm-gutters": {
|
|
2699
2451
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2700
|
-
background: "var(--
|
|
2452
|
+
background: "var(--color-base-surface) !important",
|
|
2701
2453
|
paddingRight: "1rem"
|
|
2702
2454
|
}
|
|
2703
2455
|
});
|
|
2704
|
-
var createFontTheme = ({ monospace } = {}) =>
|
|
2705
|
-
//
|
|
2456
|
+
var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
|
|
2457
|
+
// Main content.
|
|
2706
2458
|
".cm-scroller": {
|
|
2707
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2708
|
-
fontSize: "16px"
|
|
2459
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2709
2460
|
},
|
|
2710
2461
|
// Maintain defaults for UI components.
|
|
2711
2462
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2715,9 +2466,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2715
2466
|
});
|
|
2716
2467
|
|
|
2717
2468
|
// src/extensions/focus.ts
|
|
2718
|
-
import { StateEffect as
|
|
2719
|
-
import { EditorView as
|
|
2720
|
-
var focusEffect =
|
|
2469
|
+
import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
|
|
2470
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
|
2471
|
+
var focusEffect = StateEffect4.define();
|
|
2721
2472
|
var focusField = StateField5.define({
|
|
2722
2473
|
create: () => false,
|
|
2723
2474
|
update: (value, tr) => {
|
|
@@ -2731,7 +2482,7 @@ var focusField = StateField5.define({
|
|
|
2731
2482
|
});
|
|
2732
2483
|
var focus = [
|
|
2733
2484
|
focusField,
|
|
2734
|
-
|
|
2485
|
+
EditorView12.domEventHandlers({
|
|
2735
2486
|
focus: (_event, view) => {
|
|
2736
2487
|
requestAnimationFrame(() => view.dispatch({
|
|
2737
2488
|
effects: focusEffect.of(true)
|
|
@@ -2745,77 +2496,451 @@ var focus = [
|
|
|
2745
2496
|
})
|
|
2746
2497
|
];
|
|
2747
2498
|
|
|
2748
|
-
// src/extensions/
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
}
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2499
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2500
|
+
import { StateEffect as StateEffect6 } from "@codemirror/state";
|
|
2501
|
+
import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
|
|
2502
|
+
import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
|
|
2503
|
+
import { Domino } from "@dxos/ui";
|
|
2504
|
+
import { getSize } from "@dxos/ui-theme";
|
|
2505
|
+
|
|
2506
|
+
// src/extensions/scrolling/crawler.ts
|
|
2507
|
+
import { StateEffect as StateEffect5 } from "@codemirror/state";
|
|
2508
|
+
import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
|
|
2509
|
+
import { log as log7 } from "@dxos/log";
|
|
2510
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
|
|
2511
|
+
var crawlerLineEffect = StateEffect5.define();
|
|
2512
|
+
var crawlerActiveEffect = StateEffect5.define();
|
|
2513
|
+
var scrollToLine = (view, options) => {
|
|
2514
|
+
view.dispatch({
|
|
2515
|
+
effects: crawlerLineEffect.of(options)
|
|
2516
|
+
});
|
|
2517
|
+
};
|
|
2518
|
+
var crawler = ({ overScroll = 0 } = {}) => {
|
|
2519
|
+
const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
|
|
2520
|
+
view;
|
|
2521
|
+
crawler;
|
|
2522
|
+
constructor(view) {
|
|
2523
|
+
this.view = view;
|
|
2524
|
+
this.crawler = createCrawler(this.view);
|
|
2757
2525
|
}
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2526
|
+
// No-op.
|
|
2527
|
+
destroy() {
|
|
2528
|
+
this.crawler.cancel();
|
|
2529
|
+
}
|
|
2530
|
+
cancel() {
|
|
2531
|
+
this.crawler.cancel();
|
|
2532
|
+
}
|
|
2533
|
+
crawl(start = false) {
|
|
2534
|
+
if (start) {
|
|
2535
|
+
this.crawler.scroll();
|
|
2536
|
+
} else {
|
|
2537
|
+
this.crawler.cancel();
|
|
2768
2538
|
}
|
|
2769
|
-
}
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2539
|
+
}
|
|
2540
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
2541
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
2542
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
2543
|
+
const doc = this.view.state.doc;
|
|
2544
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
2545
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
2546
|
+
const lineStart = doc.line(line + 1).from;
|
|
2547
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
2548
|
+
if (coords) {
|
|
2549
|
+
const currentScrollTop = scrollTop;
|
|
2550
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
2551
|
+
if (position === "end") {
|
|
2552
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
2553
|
+
} else {
|
|
2554
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
2555
|
+
}
|
|
2556
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
2776
2557
|
}
|
|
2777
|
-
|
|
2558
|
+
}
|
|
2559
|
+
requestAnimationFrame(() => {
|
|
2560
|
+
this.view.scrollDOM.scrollTo({
|
|
2561
|
+
top: targetScrollTop
|
|
2562
|
+
});
|
|
2563
|
+
});
|
|
2778
2564
|
}
|
|
2779
|
-
return transaction;
|
|
2780
2565
|
});
|
|
2781
|
-
};
|
|
2782
|
-
var defaultBasicOptions = {
|
|
2783
|
-
allowMultipleSelections: true,
|
|
2784
|
-
bracketMatching: true,
|
|
2785
|
-
closeBrackets: true,
|
|
2786
|
-
drawSelection: true,
|
|
2787
|
-
focus: true,
|
|
2788
|
-
history: true,
|
|
2789
|
-
keymap: "standard",
|
|
2790
|
-
lineWrapping: true,
|
|
2791
|
-
search: false
|
|
2792
|
-
};
|
|
2793
|
-
var keymaps = {
|
|
2794
|
-
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2795
|
-
standard: standardKeymap,
|
|
2796
|
-
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
2797
|
-
default: defaultKeymap
|
|
2798
|
-
};
|
|
2799
|
-
var createBasicExtensions = (propsProp) => {
|
|
2800
|
-
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2801
2566
|
return [
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2567
|
+
crawlerPlugin,
|
|
2568
|
+
// Listen for effect.
|
|
2569
|
+
EditorView13.updateListener.of((update2) => {
|
|
2570
|
+
update2.transactions.forEach((transaction) => {
|
|
2571
|
+
try {
|
|
2572
|
+
const plugin = update2.view.plugin(crawlerPlugin);
|
|
2573
|
+
if (plugin) {
|
|
2574
|
+
for (const effect of transaction.effects) {
|
|
2575
|
+
if (effect.is(crawlerActiveEffect)) {
|
|
2576
|
+
plugin.crawl(effect.value);
|
|
2577
|
+
} else if (effect.is(crawlerLineEffect)) {
|
|
2578
|
+
plugin.scroll(effect.value);
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
} catch (err) {
|
|
2583
|
+
log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 98, S: void 0 });
|
|
2584
|
+
}
|
|
2585
|
+
});
|
|
2586
|
+
}),
|
|
2587
|
+
// Styles.
|
|
2588
|
+
EditorView13.theme({
|
|
2589
|
+
".cm-scroller": {
|
|
2590
|
+
overflowY: "scroll",
|
|
2591
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
2592
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
2593
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
2594
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
2595
|
+
overflowAnchor: "auto"
|
|
2596
|
+
},
|
|
2597
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
2598
|
+
display: "none"
|
|
2599
|
+
},
|
|
2600
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2601
|
+
background: "transparent",
|
|
2602
|
+
transition: "background 0.15s"
|
|
2603
|
+
},
|
|
2604
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2605
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2606
|
+
},
|
|
2607
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
2608
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
2609
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
2610
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
2611
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
2612
|
+
".cm-content::after": {
|
|
2613
|
+
content: '""',
|
|
2614
|
+
display: "block",
|
|
2615
|
+
height: `${overScroll}px`
|
|
2616
|
+
},
|
|
2617
|
+
".cm-scroll-button": {
|
|
2618
|
+
position: "absolute",
|
|
2619
|
+
bottom: "0.5rem",
|
|
2620
|
+
right: "1rem"
|
|
2621
|
+
}
|
|
2622
|
+
})
|
|
2623
|
+
];
|
|
2624
|
+
};
|
|
2625
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
2626
|
+
const el = view.scrollDOM;
|
|
2627
|
+
let currentTop = 0;
|
|
2628
|
+
let velocity = 0;
|
|
2629
|
+
let rafId = null;
|
|
2630
|
+
let lastTime = 0;
|
|
2631
|
+
function frame(now) {
|
|
2632
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
2633
|
+
lastTime = now;
|
|
2634
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
2635
|
+
const delta = targetTop - currentTop;
|
|
2636
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
2637
|
+
el.scrollTop = targetTop;
|
|
2638
|
+
currentTop = targetTop;
|
|
2639
|
+
velocity = 0;
|
|
2640
|
+
rafId = null;
|
|
2641
|
+
lastTime = 0;
|
|
2642
|
+
return;
|
|
2643
|
+
}
|
|
2644
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
2645
|
+
velocity += accel * dt;
|
|
2646
|
+
currentTop += velocity * dt;
|
|
2647
|
+
el.scrollTop = currentTop;
|
|
2648
|
+
rafId = requestAnimationFrame(frame);
|
|
2649
|
+
}
|
|
2650
|
+
return {
|
|
2651
|
+
scroll: () => {
|
|
2652
|
+
if (rafId === null) {
|
|
2653
|
+
currentTop = el.scrollTop;
|
|
2654
|
+
lastTime = 0;
|
|
2655
|
+
rafId = requestAnimationFrame(frame);
|
|
2656
|
+
}
|
|
2657
|
+
},
|
|
2658
|
+
cancel: () => {
|
|
2659
|
+
if (rafId !== null) {
|
|
2660
|
+
cancelAnimationFrame(rafId);
|
|
2661
|
+
velocity = 0;
|
|
2662
|
+
lastTime = 0;
|
|
2663
|
+
rafId = null;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2670
|
+
var autoScrollEffect = StateEffect6.define();
|
|
2671
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
2672
|
+
let buttonContainer;
|
|
2673
|
+
let isPinned = true;
|
|
2674
|
+
let jumpPending = false;
|
|
2675
|
+
let enabled = true;
|
|
2676
|
+
let firstUpdate = true;
|
|
2677
|
+
const setPinned = (pinned) => {
|
|
2678
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
2679
|
+
isPinned = pinned;
|
|
2680
|
+
};
|
|
2681
|
+
return [
|
|
2682
|
+
// Update listener for scrolling when content changes.
|
|
2683
|
+
EditorView14.updateListener.of((update2) => {
|
|
2684
|
+
const { view, heightChanged, state, startState } = update2;
|
|
2685
|
+
for (const tr of update2.transactions) {
|
|
2686
|
+
for (const effect of tr.effects) {
|
|
2687
|
+
if (effect.is(autoScrollEffect)) {
|
|
2688
|
+
enabled = effect.value;
|
|
2689
|
+
if (enabled) {
|
|
2690
|
+
setPinned(true);
|
|
2691
|
+
view.dispatch({
|
|
2692
|
+
effects: crawlerActiveEffect.of(true)
|
|
2693
|
+
});
|
|
2694
|
+
} else {
|
|
2695
|
+
view.dispatch({
|
|
2696
|
+
effects: crawlerActiveEffect.of(false)
|
|
2697
|
+
});
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
if (!enabled) {
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
2706
|
+
firstUpdate = false;
|
|
2707
|
+
jumpPending = true;
|
|
2708
|
+
requestAnimationFrame(() => {
|
|
2709
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
2710
|
+
jumpPending = false;
|
|
2711
|
+
});
|
|
2712
|
+
return;
|
|
2713
|
+
}
|
|
2714
|
+
firstUpdate = false;
|
|
2715
|
+
if (jumpPending) {
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
if (heightChanged) {
|
|
2719
|
+
if (isPinned) {
|
|
2720
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2721
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2722
|
+
if (delta > 0) {
|
|
2723
|
+
setPinned(true);
|
|
2724
|
+
view.dispatch({
|
|
2725
|
+
effects: crawlerActiveEffect.of(true)
|
|
2726
|
+
});
|
|
2727
|
+
} else if (delta < -1) {
|
|
2728
|
+
setPinned(false);
|
|
2729
|
+
}
|
|
2730
|
+
} else {
|
|
2731
|
+
if (state.doc.length === 0) {
|
|
2732
|
+
setPinned(true);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}),
|
|
2737
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
2738
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
2739
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
2740
|
+
scrollOnResize ? ViewPlugin10.fromClass(class {
|
|
2741
|
+
observer;
|
|
2742
|
+
firstObservation = true;
|
|
2743
|
+
destroyed = false;
|
|
2744
|
+
constructor(view) {
|
|
2745
|
+
const onResize = throttle2(() => {
|
|
2746
|
+
if (this.destroyed || !enabled) {
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
setPinned(true);
|
|
2750
|
+
requestAnimationFrame(() => {
|
|
2751
|
+
if (this.destroyed) {
|
|
2752
|
+
return;
|
|
2753
|
+
}
|
|
2754
|
+
view.scrollDOM.scrollTo({
|
|
2755
|
+
top: view.scrollDOM.scrollHeight,
|
|
2756
|
+
behavior: "instant"
|
|
2757
|
+
});
|
|
2758
|
+
view.dispatch({
|
|
2759
|
+
effects: crawlerActiveEffect.of(false)
|
|
2760
|
+
});
|
|
2761
|
+
});
|
|
2762
|
+
}, 50);
|
|
2763
|
+
this.observer = new ResizeObserver(() => {
|
|
2764
|
+
if (this.firstObservation) {
|
|
2765
|
+
this.firstObservation = false;
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
onResize();
|
|
2769
|
+
});
|
|
2770
|
+
this.observer.observe(view.scrollDOM);
|
|
2771
|
+
}
|
|
2772
|
+
destroy() {
|
|
2773
|
+
this.destroyed = true;
|
|
2774
|
+
this.observer.disconnect();
|
|
2775
|
+
}
|
|
2776
|
+
}) : [],
|
|
2777
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
2778
|
+
ViewPlugin10.fromClass(class {
|
|
2779
|
+
cleanup;
|
|
2780
|
+
constructor(view) {
|
|
2781
|
+
const onUserScroll = throttle2(() => {
|
|
2782
|
+
requestAnimationFrame(() => {
|
|
2783
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2784
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2785
|
+
const pinned = Math.abs(delta) <= 1;
|
|
2786
|
+
setPinned(pinned);
|
|
2787
|
+
if (!pinned) {
|
|
2788
|
+
view.dispatch({
|
|
2789
|
+
effects: crawlerActiveEffect.of(false)
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
});
|
|
2793
|
+
}, 500);
|
|
2794
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
2795
|
+
if (isPinned) {
|
|
2796
|
+
setPinned(false);
|
|
2797
|
+
view.dispatch({
|
|
2798
|
+
effects: crawlerActiveEffect.of(false)
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
onUserScroll();
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2804
|
+
destroy() {
|
|
2805
|
+
this.cleanup();
|
|
2806
|
+
}
|
|
2807
|
+
}),
|
|
2808
|
+
// Scroll button.
|
|
2809
|
+
ViewPlugin10.fromClass(class {
|
|
2810
|
+
constructor(view) {
|
|
2811
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
2812
|
+
icon: "ph--arrow-down--regular"
|
|
2813
|
+
});
|
|
2814
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
2815
|
+
"data-density": "fine"
|
|
2816
|
+
}).append(icon).on("click", () => {
|
|
2817
|
+
setPinned(true);
|
|
2818
|
+
view.dispatch({
|
|
2819
|
+
effects: crawlerLineEffect.of({
|
|
2820
|
+
line: -1,
|
|
2821
|
+
position: "end",
|
|
2822
|
+
behavior: "smooth"
|
|
2823
|
+
})
|
|
2824
|
+
});
|
|
2825
|
+
});
|
|
2826
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
2827
|
+
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
2828
|
+
}
|
|
2829
|
+
})
|
|
2830
|
+
];
|
|
2831
|
+
};
|
|
2832
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
2833
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
2834
|
+
passive: true
|
|
2835
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
2836
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
2837
|
+
onUserScroll();
|
|
2838
|
+
}
|
|
2839
|
+
}));
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
// src/extensions/scrolling/scroll-past-end.ts
|
|
2843
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2844
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2845
|
+
_height = 1e3;
|
|
2846
|
+
_attrs = {
|
|
2847
|
+
style: `padding-bottom: ${this._height}px`
|
|
2848
|
+
};
|
|
2849
|
+
update({ view }) {
|
|
2850
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2851
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2852
|
+
if (height >= 0 && height !== this._height) {
|
|
2853
|
+
this._height = height;
|
|
2854
|
+
this._attrs = {
|
|
2855
|
+
style: `padding-bottom: ${height}px`
|
|
2856
|
+
};
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
});
|
|
2860
|
+
var scrollPastEnd = () => [
|
|
2861
|
+
scrollPastEndPlugin,
|
|
2862
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
|
|
2863
|
+
];
|
|
2864
|
+
|
|
2865
|
+
// src/extensions/scrolling/scroller.ts
|
|
2866
|
+
import { isTruthy as isTruthy2 } from "@dxos/util";
|
|
2867
|
+
var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
|
|
2868
|
+
return [
|
|
2869
|
+
crawler({
|
|
2870
|
+
overScroll
|
|
2871
|
+
}),
|
|
2872
|
+
autoScroll2 && autoScroll({
|
|
2873
|
+
scrollOnResize
|
|
2874
|
+
})
|
|
2875
|
+
].filter(isTruthy2);
|
|
2876
|
+
};
|
|
2877
|
+
|
|
2878
|
+
// src/extensions/factories.ts
|
|
2879
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2880
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2881
|
+
tabindex: "0"
|
|
2882
|
+
});
|
|
2883
|
+
var filterChars = (chars) => {
|
|
2884
|
+
return EditorState.transactionFilter.of((transaction) => {
|
|
2885
|
+
if (!transaction.docChanged) {
|
|
2886
|
+
return transaction;
|
|
2887
|
+
}
|
|
2888
|
+
const changes = [];
|
|
2889
|
+
transaction.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
2890
|
+
const inserted = text.toString();
|
|
2891
|
+
const filtered = inserted.replace(chars, "");
|
|
2892
|
+
if (inserted !== filtered) {
|
|
2893
|
+
changes.push({
|
|
2894
|
+
from: fromB,
|
|
2895
|
+
to: toB,
|
|
2896
|
+
insert: filtered
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
});
|
|
2900
|
+
if (changes.length) {
|
|
2901
|
+
return [
|
|
2902
|
+
transaction,
|
|
2903
|
+
{
|
|
2904
|
+
changes,
|
|
2905
|
+
sequential: true
|
|
2906
|
+
}
|
|
2907
|
+
];
|
|
2908
|
+
}
|
|
2909
|
+
return transaction;
|
|
2910
|
+
});
|
|
2911
|
+
};
|
|
2912
|
+
var defaultBasicOptions = {
|
|
2913
|
+
allowMultipleSelections: true,
|
|
2914
|
+
bracketMatching: true,
|
|
2915
|
+
closeBrackets: true,
|
|
2916
|
+
drawSelection: true,
|
|
2917
|
+
focus: true,
|
|
2918
|
+
history: true,
|
|
2919
|
+
keymap: "standard",
|
|
2920
|
+
lineWrapping: true,
|
|
2921
|
+
search: false
|
|
2922
|
+
};
|
|
2923
|
+
var keymaps = {
|
|
2924
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2925
|
+
standard: standardKeymap,
|
|
2926
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
2927
|
+
default: defaultKeymap
|
|
2928
|
+
};
|
|
2929
|
+
var createBasicExtensions = (propsProp) => {
|
|
2930
|
+
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2931
|
+
return [
|
|
2932
|
+
// NOTE: Doesn't catch errors in keymap functions.
|
|
2933
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2934
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2935
|
+
}),
|
|
2936
|
+
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2812
2937
|
props.bracketMatching && bracketMatching(),
|
|
2813
2938
|
props.closeBrackets && closeBrackets(),
|
|
2814
2939
|
props.dropCursor && dropCursor2(),
|
|
2815
2940
|
props.drawSelection && drawSelection({
|
|
2816
2941
|
cursorBlinkRate: 1200
|
|
2817
2942
|
}),
|
|
2818
|
-
props.editable !== void 0 &&
|
|
2943
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2819
2944
|
props.focus && focus,
|
|
2820
2945
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2821
2946
|
props.history && history(),
|
|
@@ -2823,9 +2948,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2823
2948
|
lineNumbers(),
|
|
2824
2949
|
editorGutter
|
|
2825
2950
|
],
|
|
2826
|
-
props.lineWrapping &&
|
|
2951
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2827
2952
|
props.placeholder && placeholder2(props.placeholder),
|
|
2828
2953
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2954
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2955
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2956
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2957
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2958
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2959
|
+
// depend on being able to populate the doc themselves.
|
|
2960
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2829
2961
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2830
2962
|
props.tabbable && tabbable,
|
|
2831
2963
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2850,17 +2982,17 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2850
2982
|
preventDefault: true,
|
|
2851
2983
|
run: () => true
|
|
2852
2984
|
}
|
|
2853
|
-
].filter(
|
|
2854
|
-
].filter(
|
|
2985
|
+
].filter(isTruthy3))
|
|
2986
|
+
].filter(isTruthy3);
|
|
2855
2987
|
};
|
|
2856
2988
|
var grow = {
|
|
2857
2989
|
editor: {
|
|
2858
|
-
className: "
|
|
2990
|
+
className: "h-full w-full"
|
|
2859
2991
|
}
|
|
2860
2992
|
};
|
|
2861
2993
|
var fullWidth = {
|
|
2862
2994
|
editor: {
|
|
2863
|
-
className: "
|
|
2995
|
+
className: "w-full"
|
|
2864
2996
|
}
|
|
2865
2997
|
};
|
|
2866
2998
|
var defaultThemeSlots = grow;
|
|
@@ -2868,27 +3000,32 @@ var defaultStyles = {
|
|
|
2868
3000
|
dark: vscodeDarkStyle,
|
|
2869
3001
|
light: vscodeLightStyle
|
|
2870
3002
|
};
|
|
2871
|
-
var createThemeExtensions = ({ monospace,
|
|
3003
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2872
3004
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2873
3005
|
return [
|
|
2874
3006
|
baseTheme,
|
|
2875
|
-
|
|
3007
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2876
3008
|
createFontTheme({
|
|
2877
3009
|
monospace
|
|
2878
3010
|
}),
|
|
2879
3011
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2880
|
-
slots.editor?.className &&
|
|
3012
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2881
3013
|
class: slots.editor.className
|
|
2882
3014
|
}),
|
|
2883
|
-
slots.content?.className &&
|
|
3015
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2884
3016
|
class: slots.content.className
|
|
2885
3017
|
}),
|
|
2886
|
-
slots.
|
|
3018
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2887
3019
|
constructor(view) {
|
|
2888
|
-
|
|
3020
|
+
if (slots.scroller?.className) {
|
|
3021
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
3022
|
+
}
|
|
3023
|
+
if (scrollbarThin) {
|
|
3024
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3025
|
+
}
|
|
2889
3026
|
}
|
|
2890
3027
|
})
|
|
2891
|
-
].filter(
|
|
3028
|
+
].filter(isTruthy3);
|
|
2892
3029
|
};
|
|
2893
3030
|
var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
2894
3031
|
const extensions = [];
|
|
@@ -2903,8 +3040,8 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2903
3040
|
channel: `awareness.${id}`,
|
|
2904
3041
|
peerId: identity.identityKey.toHex(),
|
|
2905
3042
|
info: {
|
|
2906
|
-
darkColor: `var(--
|
|
2907
|
-
lightColor: `var(--
|
|
3043
|
+
darkColor: `var(--color-${hue}-border)`,
|
|
3044
|
+
lightColor: `var(--color-${hue}-border)`,
|
|
2908
3045
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex())
|
|
2909
3046
|
}
|
|
2910
3047
|
})));
|
|
@@ -2914,7 +3051,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2914
3051
|
|
|
2915
3052
|
// src/extensions/folding.ts
|
|
2916
3053
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2917
|
-
import { EditorView as
|
|
3054
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2918
3055
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2919
3056
|
var folding = () => {
|
|
2920
3057
|
return [
|
|
@@ -2922,13 +3059,14 @@ var folding = () => {
|
|
|
2922
3059
|
placeholderDOM: () => Domino2.of("span").root
|
|
2923
3060
|
}),
|
|
2924
3061
|
foldGutter({
|
|
3062
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2925
3063
|
markerDOM: (open) => {
|
|
2926
|
-
return Domino2.of("div").classNames("flex
|
|
3064
|
+
return Domino2.of("div").classNames("flex h-full justify-center items-center").append(Domino2.of("svg", Domino2.SVG).classNames(mx4("w-4 h-4 cursor-pointer", open && "rotate-90")).append(Domino2.of("use", Domino2.SVG).attributes({
|
|
2927
3065
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2928
3066
|
}))).root;
|
|
2929
3067
|
}
|
|
2930
3068
|
}),
|
|
2931
|
-
|
|
3069
|
+
EditorView17.theme({
|
|
2932
3070
|
".cm-foldGutter": {
|
|
2933
3071
|
opacity: 0.3,
|
|
2934
3072
|
transition: "opacity 0.3s",
|
|
@@ -2942,7 +3080,7 @@ var folding = () => {
|
|
|
2942
3080
|
};
|
|
2943
3081
|
|
|
2944
3082
|
// src/extensions/hashtag.ts
|
|
2945
|
-
import { Decoration as Decoration8, EditorView as
|
|
3083
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2946
3084
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
2947
3085
|
var TagWidget = class extends WidgetType4 {
|
|
2948
3086
|
_text;
|
|
@@ -2963,7 +3101,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
2963
3101
|
})
|
|
2964
3102
|
});
|
|
2965
3103
|
var hashtag = () => [
|
|
2966
|
-
|
|
3104
|
+
ViewPlugin13.fromClass(class {
|
|
2967
3105
|
tags;
|
|
2968
3106
|
constructor(view) {
|
|
2969
3107
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -2973,11 +3111,11 @@ var hashtag = () => [
|
|
|
2973
3111
|
}
|
|
2974
3112
|
}, {
|
|
2975
3113
|
decorations: (instance) => instance.tags,
|
|
2976
|
-
provide: (plugin) =>
|
|
3114
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
2977
3115
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
2978
3116
|
})
|
|
2979
3117
|
}),
|
|
2980
|
-
|
|
3118
|
+
EditorView18.theme({
|
|
2981
3119
|
".cm-tag": {
|
|
2982
3120
|
borderRadius: "4px",
|
|
2983
3121
|
marginRight: "6px",
|
|
@@ -3032,18 +3170,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3032
3170
|
};
|
|
3033
3171
|
|
|
3034
3172
|
// src/extensions/listener.ts
|
|
3035
|
-
import { EditorView as
|
|
3173
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3036
3174
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3037
3175
|
var listener = ({ onFocus, onChange }) => {
|
|
3038
3176
|
return [
|
|
3039
|
-
onFocus &&
|
|
3177
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3040
3178
|
onFocus({
|
|
3041
3179
|
id: state.facet(documentId),
|
|
3042
3180
|
focusing
|
|
3043
3181
|
});
|
|
3044
3182
|
return null;
|
|
3045
3183
|
}),
|
|
3046
|
-
onChange &&
|
|
3184
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3047
3185
|
if (docChanged) {
|
|
3048
3186
|
onChange({
|
|
3049
3187
|
id: state.facet(documentId),
|
|
@@ -3058,7 +3196,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3058
3196
|
import { snippet } from "@codemirror/autocomplete";
|
|
3059
3197
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3060
3198
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3061
|
-
import { EditorView as
|
|
3199
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3062
3200
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3063
3201
|
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;
|
|
3064
3202
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4147,7 +4285,7 @@ var getFormatting = (state) => {
|
|
|
4147
4285
|
};
|
|
4148
4286
|
};
|
|
4149
4287
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4150
|
-
return
|
|
4288
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4151
4289
|
if (update2.docChanged || update2.selectionSet) {
|
|
4152
4290
|
onStateChange(getFormatting(update2.state));
|
|
4153
4291
|
}
|
|
@@ -4208,11 +4346,10 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4208
4346
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4209
4347
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4210
4348
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4211
|
-
import {
|
|
4212
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4349
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4213
4350
|
import { languages } from "@codemirror/language-data";
|
|
4214
4351
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4215
|
-
import { isTruthy as
|
|
4352
|
+
import { isTruthy as isTruthy4 } from "@dxos/util";
|
|
4216
4353
|
|
|
4217
4354
|
// src/extensions/markdown/highlight.ts
|
|
4218
4355
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -4330,30 +4467,38 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4330
4467
|
],
|
|
4331
4468
|
class: "font-mono"
|
|
4332
4469
|
},
|
|
4333
|
-
// Headings
|
|
4470
|
+
// Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
|
|
4471
|
+
// StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
|
|
4472
|
+
// HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
|
|
4473
|
+
// Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
|
|
4474
|
+
{
|
|
4475
|
+
tag: tags.heading,
|
|
4476
|
+
color: "var(--color-cm-heading) !important",
|
|
4477
|
+
fontWeight: "300"
|
|
4478
|
+
},
|
|
4334
4479
|
{
|
|
4335
4480
|
tag: tags.heading1,
|
|
4336
|
-
|
|
4481
|
+
...markdownTheme.heading(1)
|
|
4337
4482
|
},
|
|
4338
4483
|
{
|
|
4339
4484
|
tag: tags.heading2,
|
|
4340
|
-
|
|
4485
|
+
...markdownTheme.heading(2)
|
|
4341
4486
|
},
|
|
4342
4487
|
{
|
|
4343
4488
|
tag: tags.heading3,
|
|
4344
|
-
|
|
4489
|
+
...markdownTheme.heading(3)
|
|
4345
4490
|
},
|
|
4346
4491
|
{
|
|
4347
4492
|
tag: tags.heading4,
|
|
4348
|
-
|
|
4493
|
+
...markdownTheme.heading(4)
|
|
4349
4494
|
},
|
|
4350
4495
|
{
|
|
4351
4496
|
tag: tags.heading5,
|
|
4352
|
-
|
|
4497
|
+
...markdownTheme.heading(5)
|
|
4353
4498
|
},
|
|
4354
4499
|
{
|
|
4355
4500
|
tag: tags.heading6,
|
|
4356
|
-
|
|
4501
|
+
...markdownTheme.heading(6)
|
|
4357
4502
|
},
|
|
4358
4503
|
// Emphasis.
|
|
4359
4504
|
{
|
|
@@ -4408,15 +4553,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4408
4553
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4409
4554
|
base: markdownLanguage2,
|
|
4410
4555
|
// Languages for syntax highlighting fenced code blocks.
|
|
4556
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4411
4557
|
defaultCodeLanguage: jsonLanguage,
|
|
4412
|
-
codeLanguages:
|
|
4558
|
+
codeLanguages: [
|
|
4559
|
+
...options.codeLanguages ?? [],
|
|
4560
|
+
...languages
|
|
4561
|
+
],
|
|
4413
4562
|
// Don't complete HTML tags.
|
|
4414
4563
|
completeHTMLTags: false,
|
|
4415
4564
|
// Parser extensions.
|
|
4416
4565
|
extensions: [
|
|
4417
4566
|
// GFM provided by default.
|
|
4418
4567
|
markdownTagsExtensions,
|
|
4419
|
-
...options.extensions ?? defaultExtensions()
|
|
4568
|
+
...options.extensions ?? defaultExtensions(),
|
|
4569
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4570
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4571
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4572
|
+
noFencedCodeFolding
|
|
4420
4573
|
]
|
|
4421
4574
|
}),
|
|
4422
4575
|
// Custom styles.
|
|
@@ -4428,21 +4581,16 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4428
4581
|
...defaultKeymap2,
|
|
4429
4582
|
// TODO(burdon): Remove?
|
|
4430
4583
|
...completionKeymap
|
|
4431
|
-
].filter(
|
|
4584
|
+
].filter(isTruthy4))
|
|
4432
4585
|
];
|
|
4433
4586
|
};
|
|
4434
|
-
var
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
]
|
|
4440
|
-
|
|
4441
|
-
"xml",
|
|
4442
|
-
"xhtml"
|
|
4443
|
-
],
|
|
4444
|
-
load: async () => xml()
|
|
4445
|
-
});
|
|
4587
|
+
var noFencedCodeFolding = {
|
|
4588
|
+
props: [
|
|
4589
|
+
foldNodeProp.add({
|
|
4590
|
+
FencedCode: () => null
|
|
4591
|
+
})
|
|
4592
|
+
]
|
|
4593
|
+
};
|
|
4446
4594
|
var defaultExtensions = () => [
|
|
4447
4595
|
noSetExtHeading,
|
|
4448
4596
|
noHtml
|
|
@@ -4462,19 +4610,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4462
4610
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4463
4611
|
});
|
|
4464
4612
|
var convertTreeToJson = (state) => {
|
|
4465
|
-
const treeToJson = (
|
|
4613
|
+
const treeToJson = (cursor) => {
|
|
4466
4614
|
const node = {
|
|
4467
|
-
type:
|
|
4468
|
-
from:
|
|
4469
|
-
to:
|
|
4470
|
-
text: state.doc.slice(
|
|
4615
|
+
type: cursor.type.name,
|
|
4616
|
+
from: cursor.from,
|
|
4617
|
+
to: cursor.to,
|
|
4618
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4471
4619
|
children: []
|
|
4472
4620
|
};
|
|
4473
|
-
if (
|
|
4621
|
+
if (cursor.firstChild()) {
|
|
4474
4622
|
do {
|
|
4475
|
-
node.children.push(treeToJson(
|
|
4476
|
-
} while (
|
|
4477
|
-
|
|
4623
|
+
node.children.push(treeToJson(cursor));
|
|
4624
|
+
} while (cursor.nextSibling());
|
|
4625
|
+
cursor.parent();
|
|
4478
4626
|
}
|
|
4479
4627
|
return node;
|
|
4480
4628
|
};
|
|
@@ -4484,16 +4632,15 @@ var convertTreeToJson = (state) => {
|
|
|
4484
4632
|
// src/extensions/markdown/decorate.ts
|
|
4485
4633
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4486
4634
|
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4487
|
-
import { Decoration as Decoration11, EditorView as
|
|
4635
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4488
4636
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4489
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4490
4637
|
|
|
4491
4638
|
// src/extensions/markdown/changes.ts
|
|
4492
4639
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4493
4640
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4494
|
-
import { ViewPlugin as
|
|
4641
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4495
4642
|
var adjustChanges = () => {
|
|
4496
|
-
return
|
|
4643
|
+
return ViewPlugin14.fromClass(class {
|
|
4497
4644
|
update(update2) {
|
|
4498
4645
|
const tree = syntaxTree4(update2.state);
|
|
4499
4646
|
const adjustments = [];
|
|
@@ -4635,7 +4782,7 @@ var getValidUrl = (str) => {
|
|
|
4635
4782
|
// src/extensions/markdown/image.ts
|
|
4636
4783
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4637
4784
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4638
|
-
import { Decoration as Decoration9, EditorView as
|
|
4785
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4639
4786
|
var image = (_options = {}) => {
|
|
4640
4787
|
return [
|
|
4641
4788
|
StateField7.define({
|
|
@@ -4646,10 +4793,10 @@ var image = (_options = {}) => {
|
|
|
4646
4793
|
if (!tr.docChanged && !tr.selection) {
|
|
4647
4794
|
return value;
|
|
4648
4795
|
}
|
|
4649
|
-
const
|
|
4796
|
+
const cursor = tr.state.selection.main.head;
|
|
4650
4797
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4651
|
-
let from = Math.min(
|
|
4652
|
-
let to = Math.max(
|
|
4798
|
+
let from = Math.min(cursor, oldCursor);
|
|
4799
|
+
let to = Math.max(cursor, oldCursor);
|
|
4653
4800
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4654
4801
|
from = Math.min(from, fromB);
|
|
4655
4802
|
to = Math.max(to, toB);
|
|
@@ -4663,19 +4810,19 @@ var image = (_options = {}) => {
|
|
|
4663
4810
|
add: buildDecorations(tr.state, from, to)
|
|
4664
4811
|
});
|
|
4665
4812
|
},
|
|
4666
|
-
provide: (field) =>
|
|
4813
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4667
4814
|
})
|
|
4668
4815
|
];
|
|
4669
4816
|
};
|
|
4670
4817
|
var buildDecorations = (state, from, to) => {
|
|
4671
4818
|
const decorations2 = [];
|
|
4672
|
-
const
|
|
4819
|
+
const cursor = state.selection.main.head;
|
|
4673
4820
|
syntaxTree5(state).iterate({
|
|
4674
4821
|
enter: (node) => {
|
|
4675
4822
|
if (node.name === "Image") {
|
|
4676
4823
|
const urlNode = node.node.getChild("URL");
|
|
4677
4824
|
if (urlNode) {
|
|
4678
|
-
const hide2 = state.readOnly ||
|
|
4825
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4679
4826
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4680
4827
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4681
4828
|
return;
|
|
@@ -4723,10 +4870,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4723
4870
|
};
|
|
4724
4871
|
|
|
4725
4872
|
// src/extensions/markdown/styles.ts
|
|
4726
|
-
import { EditorView as
|
|
4873
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4727
4874
|
var bulletListIndentationWidth = 24;
|
|
4728
4875
|
var orderedListIndentationWidth = 36;
|
|
4729
|
-
var formattingStyles =
|
|
4876
|
+
var formattingStyles = EditorView22.theme({
|
|
4730
4877
|
/**
|
|
4731
4878
|
* Horizontal rule.
|
|
4732
4879
|
*/
|
|
@@ -4735,7 +4882,7 @@ var formattingStyles = EditorView21.theme({
|
|
|
4735
4882
|
width: "100%",
|
|
4736
4883
|
height: "0",
|
|
4737
4884
|
verticalAlign: "middle",
|
|
4738
|
-
borderTop: "1px solid var(--
|
|
4885
|
+
borderTop: "1px solid var(--color-cm-separator)",
|
|
4739
4886
|
opacity: 0.5
|
|
4740
4887
|
},
|
|
4741
4888
|
/**
|
|
@@ -4758,19 +4905,44 @@ var formattingStyles = EditorView21.theme({
|
|
|
4758
4905
|
* Blockquote.
|
|
4759
4906
|
*/
|
|
4760
4907
|
"& .cm-blockquote": {
|
|
4761
|
-
background: "var(--
|
|
4762
|
-
borderLeft: "2px solid var(--
|
|
4908
|
+
background: "var(--color-cm-codeblock)",
|
|
4909
|
+
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4763
4910
|
paddingLeft: "1rem",
|
|
4764
|
-
margin:
|
|
4911
|
+
margin: 0
|
|
4765
4912
|
},
|
|
4766
4913
|
/**
|
|
4767
4914
|
* Code and codeblocks.
|
|
4768
4915
|
*/
|
|
4916
|
+
"& code": {
|
|
4917
|
+
fontFamily: fontMono,
|
|
4918
|
+
color: "var(--color-cm-code)",
|
|
4919
|
+
whiteSpace: "nowrap"
|
|
4920
|
+
},
|
|
4769
4921
|
"& .cm-code": {
|
|
4770
|
-
fontFamily: fontMono
|
|
4922
|
+
fontFamily: fontMono,
|
|
4923
|
+
color: "var(--color-cm-code)"
|
|
4924
|
+
},
|
|
4925
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4926
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4927
|
+
// so constrain them to the target 24px height.
|
|
4928
|
+
"& .cm-code-inline": {
|
|
4929
|
+
fontFamily: fontMono,
|
|
4930
|
+
height: "24px",
|
|
4931
|
+
// display: 'inline-flex',
|
|
4932
|
+
alignItems: "center",
|
|
4933
|
+
overflow: "hidden",
|
|
4934
|
+
whiteSpace: "nowrap",
|
|
4935
|
+
color: "var(--color-cm-code-inline)"
|
|
4936
|
+
},
|
|
4937
|
+
"& .cm-code-mark": {
|
|
4938
|
+
fontFamily: fontMono,
|
|
4939
|
+
height: "24px",
|
|
4940
|
+
display: "inline-flex",
|
|
4941
|
+
alignItems: "center",
|
|
4942
|
+
overflow: "hidden"
|
|
4771
4943
|
},
|
|
4772
4944
|
"& .cm-codeblock-line": {
|
|
4773
|
-
background: "var(--
|
|
4945
|
+
background: "var(--color-cm-codeblock)",
|
|
4774
4946
|
paddingInline: "1rem !important"
|
|
4775
4947
|
},
|
|
4776
4948
|
"& .cm-codeblock-start": {
|
|
@@ -4799,16 +4971,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4799
4971
|
*/
|
|
4800
4972
|
".cm-table *": {
|
|
4801
4973
|
fontFamily: fontMono,
|
|
4974
|
+
lineHeight: 1.5,
|
|
4802
4975
|
textDecoration: "none !important"
|
|
4803
4976
|
},
|
|
4804
4977
|
".cm-table-head": {
|
|
4805
4978
|
padding: "2px 16px 2px 0px",
|
|
4979
|
+
overflowWrap: "break-word",
|
|
4980
|
+
whiteSpace: "pre-wrap",
|
|
4981
|
+
wordBreak: "keep-all",
|
|
4806
4982
|
textAlign: "left",
|
|
4807
|
-
|
|
4808
|
-
|
|
4983
|
+
color: "var(--color-subdued)",
|
|
4984
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4809
4985
|
},
|
|
4810
4986
|
".cm-table-cell": {
|
|
4811
|
-
padding: "2px 16px 2px 0px"
|
|
4987
|
+
padding: "2px 16px 2px 0px",
|
|
4988
|
+
overflowWrap: "break-word",
|
|
4989
|
+
whiteSpace: "pre-wrap",
|
|
4990
|
+
wordBreak: "keep-all",
|
|
4991
|
+
verticalAlign: "top"
|
|
4812
4992
|
},
|
|
4813
4993
|
/**
|
|
4814
4994
|
* Image.
|
|
@@ -4824,12 +5004,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4824
5004
|
},
|
|
4825
5005
|
".cm-image-with-loader": {
|
|
4826
5006
|
display: "block",
|
|
4827
|
-
opacity:
|
|
5007
|
+
opacity: 0,
|
|
4828
5008
|
transitionDuration: "350ms",
|
|
4829
5009
|
transitionProperty: "opacity"
|
|
4830
5010
|
},
|
|
4831
5011
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4832
|
-
opacity:
|
|
5012
|
+
opacity: 1
|
|
4833
5013
|
},
|
|
4834
5014
|
".cm-image-wrapper": {
|
|
4835
5015
|
"grid-template-columns": "1fr",
|
|
@@ -4848,17 +5028,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4848
5028
|
// src/extensions/markdown/table.ts
|
|
4849
5029
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4850
5030
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4851
|
-
import { Decoration as Decoration10, EditorView as
|
|
5031
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4852
5032
|
var table = (options = {}) => {
|
|
4853
5033
|
return StateField8.define({
|
|
4854
5034
|
create: (state) => update(state, options),
|
|
4855
5035
|
update: (_, tr) => update(tr.state, options),
|
|
4856
|
-
provide: (field) =>
|
|
5036
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4857
5037
|
});
|
|
4858
5038
|
};
|
|
4859
5039
|
var update = (state, _options) => {
|
|
4860
5040
|
const builder = new RangeSetBuilder4();
|
|
4861
|
-
const
|
|
5041
|
+
const cursor = state.selection.main.head;
|
|
4862
5042
|
const tables = [];
|
|
4863
5043
|
const getTable = () => tables[tables.length - 1];
|
|
4864
5044
|
const getRow = () => {
|
|
@@ -4896,7 +5076,7 @@ var update = (state, _options) => {
|
|
|
4896
5076
|
}
|
|
4897
5077
|
});
|
|
4898
5078
|
tables.forEach((table2) => {
|
|
4899
|
-
const replace = state.readOnly ||
|
|
5079
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4900
5080
|
if (replace) {
|
|
4901
5081
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4902
5082
|
block: true,
|
|
@@ -4910,6 +5090,26 @@ var update = (state, _options) => {
|
|
|
4910
5090
|
});
|
|
4911
5091
|
return builder.finish();
|
|
4912
5092
|
};
|
|
5093
|
+
var renderCellContent = (el, text) => {
|
|
5094
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5095
|
+
for (const part of parts) {
|
|
5096
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5097
|
+
const code = document.createElement("code");
|
|
5098
|
+
code.textContent = part.slice(1, -1);
|
|
5099
|
+
el.appendChild(code);
|
|
5100
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5101
|
+
const strong = document.createElement("strong");
|
|
5102
|
+
strong.textContent = part.slice(2, -2);
|
|
5103
|
+
el.appendChild(strong);
|
|
5104
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5105
|
+
const em = document.createElement("em");
|
|
5106
|
+
em.textContent = part.slice(1, -1);
|
|
5107
|
+
el.appendChild(em);
|
|
5108
|
+
} else {
|
|
5109
|
+
el.appendChild(document.createTextNode(part));
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
};
|
|
4913
5113
|
var TableWidget = class extends WidgetType6 {
|
|
4914
5114
|
_table;
|
|
4915
5115
|
constructor(_table) {
|
|
@@ -4929,7 +5129,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4929
5129
|
this._table.header?.forEach((cell) => {
|
|
4930
5130
|
const th = document.createElement("th");
|
|
4931
5131
|
th.setAttribute("class", "cm-table-head");
|
|
4932
|
-
tr.appendChild(th)
|
|
5132
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
4933
5133
|
});
|
|
4934
5134
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
4935
5135
|
this._table.rows?.forEach((row) => {
|
|
@@ -4937,7 +5137,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4937
5137
|
row.forEach((cell) => {
|
|
4938
5138
|
const td = document.createElement("td");
|
|
4939
5139
|
td.setAttribute("class", "cm-table-cell");
|
|
4940
|
-
tr2.appendChild(td)
|
|
5140
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
4941
5141
|
});
|
|
4942
5142
|
});
|
|
4943
5143
|
return div;
|
|
@@ -4945,7 +5145,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4945
5145
|
};
|
|
4946
5146
|
|
|
4947
5147
|
// src/extensions/markdown/decorate.ts
|
|
4948
|
-
var
|
|
5148
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
|
|
4949
5149
|
var Unicode = {
|
|
4950
5150
|
emDash: "\u2014",
|
|
4951
5151
|
bullet: "\u2022",
|
|
@@ -4968,7 +5168,6 @@ var LinkButton = class extends WidgetType7 {
|
|
|
4968
5168
|
eq(other) {
|
|
4969
5169
|
return this.url === other.url;
|
|
4970
5170
|
}
|
|
4971
|
-
// TODO(burdon): Create icon and link directly without react?
|
|
4972
5171
|
toDOM(view) {
|
|
4973
5172
|
const el = document.createElement("span");
|
|
4974
5173
|
this.render(el, {
|
|
@@ -5045,10 +5244,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5045
5244
|
class: "cm-code cm-codeblock-line"
|
|
5046
5245
|
});
|
|
5047
5246
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5048
|
-
class:
|
|
5247
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5049
5248
|
});
|
|
5050
5249
|
var fencedCodeLineLast = Decoration11.line({
|
|
5051
|
-
class:
|
|
5250
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5052
5251
|
});
|
|
5053
5252
|
var commentBlockLine = fencedCodeLine;
|
|
5054
5253
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5080,15 +5279,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5080
5279
|
const { state } = view;
|
|
5081
5280
|
const headerLevels = [];
|
|
5082
5281
|
const getHeaderLevels = (node, level) => {
|
|
5083
|
-
invariant4(level > 0, void 0, {
|
|
5084
|
-
F: __dxlog_file11,
|
|
5085
|
-
L: 180,
|
|
5086
|
-
S: void 0,
|
|
5087
|
-
A: [
|
|
5088
|
-
"level > 0",
|
|
5089
|
-
""
|
|
5090
|
-
]
|
|
5091
|
-
});
|
|
5282
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5092
5283
|
if (level > headerLevels.length) {
|
|
5093
5284
|
const len = headerLevels.length;
|
|
5094
5285
|
headerLevels.length = level;
|
|
@@ -5119,15 +5310,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5119
5310
|
listLevels.pop();
|
|
5120
5311
|
};
|
|
5121
5312
|
const getCurrentListLevel = () => {
|
|
5122
|
-
invariant4(listLevels.length, void 0, {
|
|
5123
|
-
F: __dxlog_file11,
|
|
5124
|
-
L: 202,
|
|
5125
|
-
S: void 0,
|
|
5126
|
-
A: [
|
|
5127
|
-
"listLevels.length",
|
|
5128
|
-
""
|
|
5129
|
-
]
|
|
5130
|
-
});
|
|
5313
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5131
5314
|
return listLevels[listLevels.length - 1];
|
|
5132
5315
|
};
|
|
5133
5316
|
const enterNode = (node) => {
|
|
@@ -5165,13 +5348,13 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5165
5348
|
deco: hide
|
|
5166
5349
|
});
|
|
5167
5350
|
} else {
|
|
5168
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5351
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5169
5352
|
if (num.length) {
|
|
5170
5353
|
atomicDecoRanges.push({
|
|
5171
5354
|
from: mark.from,
|
|
5172
5355
|
to: mark.from + len,
|
|
5173
5356
|
deco: Decoration11.replace({
|
|
5174
|
-
widget: new TextWidget(num, markdownTheme.heading(level))
|
|
5357
|
+
widget: new TextWidget(num, markdownTheme.heading(level).className)
|
|
5175
5358
|
})
|
|
5176
5359
|
});
|
|
5177
5360
|
}
|
|
@@ -5348,11 +5531,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5348
5531
|
}
|
|
5349
5532
|
decoRanges.push({
|
|
5350
5533
|
from: marks[0].to,
|
|
5351
|
-
to: marks[1].from,
|
|
5534
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5352
5535
|
deco: Decoration11.mark({
|
|
5353
5536
|
tagName: "a",
|
|
5354
5537
|
attributes: {
|
|
5355
|
-
class: "cm-link",
|
|
5538
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5356
5539
|
href: url,
|
|
5357
5540
|
rel: "noreferrer",
|
|
5358
5541
|
target: "_blank"
|
|
@@ -5430,8 +5613,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5430
5613
|
deco.add(from, to, d);
|
|
5431
5614
|
}
|
|
5432
5615
|
const atomicDeco = new RangeSetBuilder5();
|
|
5433
|
-
for (const { from, to, deco:
|
|
5434
|
-
|
|
5616
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5617
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5618
|
+
continue;
|
|
5619
|
+
}
|
|
5620
|
+
atomicDeco.add(from, to, deco2);
|
|
5435
5621
|
}
|
|
5436
5622
|
return {
|
|
5437
5623
|
deco: deco.finish(),
|
|
@@ -5441,7 +5627,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5441
5627
|
var forceUpdate = StateEffect7.define();
|
|
5442
5628
|
var decorateMarkdown = (options = {}) => {
|
|
5443
5629
|
return [
|
|
5444
|
-
|
|
5630
|
+
ViewPlugin15.fromClass(class {
|
|
5445
5631
|
deco;
|
|
5446
5632
|
atomicDeco;
|
|
5447
5633
|
pendingUpdate;
|
|
@@ -5476,9 +5662,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5476
5662
|
}
|
|
5477
5663
|
}, {
|
|
5478
5664
|
provide: (plugin) => [
|
|
5479
|
-
Prec4.low(
|
|
5480
|
-
|
|
5481
|
-
|
|
5665
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5666
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5667
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5482
5668
|
]
|
|
5483
5669
|
}),
|
|
5484
5670
|
image(),
|
|
@@ -5510,8 +5696,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5510
5696
|
return {
|
|
5511
5697
|
pos: link.from,
|
|
5512
5698
|
end: link.to,
|
|
5513
|
-
|
|
5514
|
-
// above: true,
|
|
5699
|
+
above: true,
|
|
5515
5700
|
create: () => {
|
|
5516
5701
|
const el = document.createElement("div");
|
|
5517
5702
|
el.className = tooltipContent({});
|
|
@@ -5527,16 +5712,13 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5527
5712
|
};
|
|
5528
5713
|
}
|
|
5529
5714
|
};
|
|
5530
|
-
}, {
|
|
5531
|
-
// NOTE: 0 = default of 300ms.
|
|
5532
|
-
hoverTime: 1
|
|
5533
5715
|
});
|
|
5534
5716
|
};
|
|
5535
5717
|
|
|
5536
5718
|
// src/extensions/mention.ts
|
|
5537
5719
|
import { autocompletion } from "@codemirror/autocomplete";
|
|
5538
|
-
import { log as
|
|
5539
|
-
var
|
|
5720
|
+
import { log as log9 } from "@dxos/log";
|
|
5721
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
|
|
5540
5722
|
var mention = ({ debug, onSearch }) => {
|
|
5541
5723
|
return autocompletion({
|
|
5542
5724
|
// TODO(burdon): Not working.
|
|
@@ -5548,14 +5730,9 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5548
5730
|
icons: false,
|
|
5549
5731
|
override: [
|
|
5550
5732
|
(context) => {
|
|
5551
|
-
|
|
5733
|
+
log9.info("completion context", {
|
|
5552
5734
|
context
|
|
5553
|
-
}, {
|
|
5554
|
-
F: __dxlog_file12,
|
|
5555
|
-
L: 27,
|
|
5556
|
-
S: void 0,
|
|
5557
|
-
C: (f, a) => f(...a)
|
|
5558
|
-
});
|
|
5735
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5559
5736
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5560
5737
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5561
5738
|
return null;
|
|
@@ -5634,7 +5811,7 @@ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
|
|
5634
5811
|
import { StateField as StateField10 } from "@codemirror/state";
|
|
5635
5812
|
import { Facet as Facet2 } from "@codemirror/state";
|
|
5636
5813
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
5637
|
-
var
|
|
5814
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
|
|
5638
5815
|
var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
|
|
5639
5816
|
return {
|
|
5640
5817
|
type,
|
|
@@ -5788,15 +5965,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5788
5965
|
break;
|
|
5789
5966
|
}
|
|
5790
5967
|
case "BulletList": {
|
|
5791
|
-
invariant5(current, void 0, {
|
|
5792
|
-
F: __dxlog_file13,
|
|
5793
|
-
L: 219,
|
|
5794
|
-
S: void 0,
|
|
5795
|
-
A: [
|
|
5796
|
-
"current",
|
|
5797
|
-
""
|
|
5798
|
-
]
|
|
5799
|
-
});
|
|
5968
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5800
5969
|
parent = current;
|
|
5801
5970
|
if (current) {
|
|
5802
5971
|
current.lineRange.to = current.node.from;
|
|
@@ -5805,15 +5974,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5805
5974
|
break;
|
|
5806
5975
|
}
|
|
5807
5976
|
case "ListItem": {
|
|
5808
|
-
invariant5(parent, void 0, {
|
|
5809
|
-
F: __dxlog_file13,
|
|
5810
|
-
L: 228,
|
|
5811
|
-
S: void 0,
|
|
5812
|
-
A: [
|
|
5813
|
-
"parent",
|
|
5814
|
-
""
|
|
5815
|
-
]
|
|
5816
|
-
});
|
|
5977
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5817
5978
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5818
5979
|
const docRange = {
|
|
5819
5980
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5847,42 +6008,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5847
6008
|
break;
|
|
5848
6009
|
}
|
|
5849
6010
|
case "ListMark": {
|
|
5850
|
-
invariant5(current, void 0, {
|
|
5851
|
-
F: __dxlog_file13,
|
|
5852
|
-
L: 272,
|
|
5853
|
-
S: void 0,
|
|
5854
|
-
A: [
|
|
5855
|
-
"current",
|
|
5856
|
-
""
|
|
5857
|
-
]
|
|
5858
|
-
});
|
|
6011
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5859
6012
|
current.type = "bullet";
|
|
5860
6013
|
current.contentRange.from = node.from + "- ".length;
|
|
5861
6014
|
break;
|
|
5862
6015
|
}
|
|
5863
6016
|
case "Task": {
|
|
5864
|
-
invariant5(current, void 0, {
|
|
5865
|
-
F: __dxlog_file13,
|
|
5866
|
-
L: 278,
|
|
5867
|
-
S: void 0,
|
|
5868
|
-
A: [
|
|
5869
|
-
"current",
|
|
5870
|
-
""
|
|
5871
|
-
]
|
|
5872
|
-
});
|
|
6017
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5873
6018
|
current.type = "task";
|
|
5874
6019
|
break;
|
|
5875
6020
|
}
|
|
5876
6021
|
case "TaskMarker": {
|
|
5877
|
-
invariant5(current, void 0, {
|
|
5878
|
-
F: __dxlog_file13,
|
|
5879
|
-
L: 283,
|
|
5880
|
-
S: void 0,
|
|
5881
|
-
A: [
|
|
5882
|
-
"current",
|
|
5883
|
-
""
|
|
5884
|
-
]
|
|
5885
|
-
});
|
|
6022
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5886
6023
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5887
6024
|
break;
|
|
5888
6025
|
}
|
|
@@ -5890,29 +6027,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5890
6027
|
},
|
|
5891
6028
|
leave: (node) => {
|
|
5892
6029
|
if (node.name === "BulletList") {
|
|
5893
|
-
invariant5(parent, void 0, {
|
|
5894
|
-
F: __dxlog_file13,
|
|
5895
|
-
L: 291,
|
|
5896
|
-
S: void 0,
|
|
5897
|
-
A: [
|
|
5898
|
-
"parent",
|
|
5899
|
-
""
|
|
5900
|
-
]
|
|
5901
|
-
});
|
|
6030
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5902
6031
|
prevSiblings[level--] = void 0;
|
|
5903
6032
|
parent = parent.parent;
|
|
5904
6033
|
}
|
|
5905
6034
|
}
|
|
5906
6035
|
});
|
|
5907
|
-
invariant5(tree, void 0, {
|
|
5908
|
-
F: __dxlog_file13,
|
|
5909
|
-
L: 298,
|
|
5910
|
-
S: void 0,
|
|
5911
|
-
A: [
|
|
5912
|
-
"tree",
|
|
5913
|
-
""
|
|
5914
|
-
]
|
|
5915
|
-
});
|
|
6036
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5916
6037
|
return tree;
|
|
5917
6038
|
};
|
|
5918
6039
|
return [
|
|
@@ -6197,17 +6318,17 @@ var commands = () => keymap11.of([
|
|
|
6197
6318
|
|
|
6198
6319
|
// src/extensions/outliner/outliner.ts
|
|
6199
6320
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6200
|
-
import { Decoration as Decoration12, EditorView as
|
|
6201
|
-
import { mx as
|
|
6321
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6322
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6202
6323
|
|
|
6203
6324
|
// src/extensions/outliner/editor.ts
|
|
6204
6325
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6205
|
-
import { ViewPlugin as
|
|
6206
|
-
import { log as
|
|
6207
|
-
var
|
|
6326
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6327
|
+
import { log as log10 } from "@dxos/log";
|
|
6328
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6208
6329
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6209
6330
|
var initialize = () => {
|
|
6210
|
-
return
|
|
6331
|
+
return ViewPlugin16.fromClass(class {
|
|
6211
6332
|
constructor(view) {
|
|
6212
6333
|
const first = view.state.doc.lineAt(0);
|
|
6213
6334
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6336,7 +6457,7 @@ var editor = () => [
|
|
|
6336
6457
|
cancel = true;
|
|
6337
6458
|
return;
|
|
6338
6459
|
}
|
|
6339
|
-
|
|
6460
|
+
log10("change", {
|
|
6340
6461
|
item,
|
|
6341
6462
|
line: {
|
|
6342
6463
|
from: line.from,
|
|
@@ -6354,35 +6475,20 @@ var editor = () => [
|
|
|
6354
6475
|
text: insert.toString(),
|
|
6355
6476
|
length: insert.length
|
|
6356
6477
|
}
|
|
6357
|
-
}, {
|
|
6358
|
-
F: __dxlog_file14,
|
|
6359
|
-
L: 164,
|
|
6360
|
-
S: void 0,
|
|
6361
|
-
C: (f, a) => f(...a)
|
|
6362
|
-
});
|
|
6478
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6363
6479
|
}
|
|
6364
6480
|
});
|
|
6365
6481
|
if (changes.length > 0) {
|
|
6366
|
-
|
|
6482
|
+
log10("modified,", {
|
|
6367
6483
|
changes
|
|
6368
|
-
}, {
|
|
6369
|
-
F: __dxlog_file14,
|
|
6370
|
-
L: 175,
|
|
6371
|
-
S: void 0,
|
|
6372
|
-
C: (f, a) => f(...a)
|
|
6373
|
-
});
|
|
6484
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6374
6485
|
return [
|
|
6375
6486
|
{
|
|
6376
6487
|
changes
|
|
6377
6488
|
}
|
|
6378
6489
|
];
|
|
6379
6490
|
} else if (cancel) {
|
|
6380
|
-
|
|
6381
|
-
F: __dxlog_file14,
|
|
6382
|
-
L: 178,
|
|
6383
|
-
S: void 0,
|
|
6384
|
-
C: (f, a) => f(...a)
|
|
6385
|
-
});
|
|
6491
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6386
6492
|
return [];
|
|
6387
6493
|
}
|
|
6388
6494
|
return tr;
|
|
@@ -6390,10 +6496,10 @@ var editor = () => [
|
|
|
6390
6496
|
];
|
|
6391
6497
|
|
|
6392
6498
|
// src/extensions/outliner/menu.ts
|
|
6393
|
-
import { EditorView as
|
|
6394
|
-
import { addEventListener } from "@dxos/async";
|
|
6499
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6500
|
+
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6395
6501
|
var menu = (options = {}) => [
|
|
6396
|
-
|
|
6502
|
+
ViewPlugin17.fromClass(class {
|
|
6397
6503
|
view;
|
|
6398
6504
|
tag;
|
|
6399
6505
|
rafId;
|
|
@@ -6413,7 +6519,7 @@ var menu = (options = {}) => [
|
|
|
6413
6519
|
}
|
|
6414
6520
|
container.appendChild(this.tag);
|
|
6415
6521
|
const handler = () => this.scheduleUpdate();
|
|
6416
|
-
this.cleanup =
|
|
6522
|
+
this.cleanup = addEventListener2(container, "scroll", handler);
|
|
6417
6523
|
this.scheduleUpdate();
|
|
6418
6524
|
}
|
|
6419
6525
|
destroy() {
|
|
@@ -6455,7 +6561,7 @@ var menu = (options = {}) => [
|
|
|
6455
6561
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6456
6562
|
}
|
|
6457
6563
|
}),
|
|
6458
|
-
|
|
6564
|
+
EditorView25.theme({
|
|
6459
6565
|
".cm-popover-trigger": {
|
|
6460
6566
|
position: "fixed",
|
|
6461
6567
|
padding: "0",
|
|
@@ -6491,12 +6597,12 @@ var outliner = (_options = {}) => [
|
|
|
6491
6597
|
listPaddingLeft: 8
|
|
6492
6598
|
}),
|
|
6493
6599
|
// Researve space for menu.
|
|
6494
|
-
|
|
6495
|
-
class: "
|
|
6600
|
+
EditorView26.contentAttributes.of({
|
|
6601
|
+
class: "w-full !mr-[3rem]"
|
|
6496
6602
|
})
|
|
6497
6603
|
];
|
|
6498
6604
|
var decorations = () => [
|
|
6499
|
-
|
|
6605
|
+
ViewPlugin18.fromClass(class {
|
|
6500
6606
|
decorations = Decoration12.none;
|
|
6501
6607
|
constructor(view) {
|
|
6502
6608
|
this.updateDecorations(view.state, view);
|
|
@@ -6521,7 +6627,7 @@ var decorations = () => [
|
|
|
6521
6627
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6522
6628
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6523
6629
|
decorations2.push(Decoration12.line({
|
|
6524
|
-
class:
|
|
6630
|
+
class: mx6("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
|
|
6525
6631
|
}).range(line.from, line.from));
|
|
6526
6632
|
}
|
|
6527
6633
|
}
|
|
@@ -6531,7 +6637,7 @@ var decorations = () => [
|
|
|
6531
6637
|
decorations: (v) => v.decorations
|
|
6532
6638
|
}),
|
|
6533
6639
|
// Theme.
|
|
6534
|
-
|
|
6640
|
+
EditorView26.theme(Object.assign({
|
|
6535
6641
|
".cm-list-item": {
|
|
6536
6642
|
borderLeftWidth: "1px",
|
|
6537
6643
|
borderRightWidth: "1px",
|
|
@@ -6556,38 +6662,67 @@ var decorations = () => [
|
|
|
6556
6662
|
marginBottom: "2px"
|
|
6557
6663
|
},
|
|
6558
6664
|
".cm-list-item-focused": {
|
|
6559
|
-
borderColor: "var(--
|
|
6665
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6560
6666
|
},
|
|
6561
6667
|
"&:focus-within .cm-list-item-selected": {
|
|
6562
|
-
borderColor: "var(--
|
|
6668
|
+
borderColor: "var(--color-separator)"
|
|
6563
6669
|
}
|
|
6564
6670
|
}))
|
|
6565
6671
|
];
|
|
6566
6672
|
|
|
6567
6673
|
// src/extensions/preview/preview.ts
|
|
6568
6674
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6569
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6570
|
-
import { Decoration as Decoration13, EditorView as
|
|
6675
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6676
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6677
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6678
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6571
6679
|
var preview = (options = {}) => {
|
|
6680
|
+
const viewRef = {
|
|
6681
|
+
current: void 0
|
|
6682
|
+
};
|
|
6572
6683
|
return [
|
|
6573
6684
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6574
6685
|
// "Block decorations may not be specified via plugins".
|
|
6575
6686
|
StateField11.define({
|
|
6576
|
-
create: (state) => buildDecorations3(state, options),
|
|
6687
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6577
6688
|
update: (decorations2, tr) => {
|
|
6578
|
-
if (tr.docChanged) {
|
|
6579
|
-
return buildDecorations3(tr.state, options);
|
|
6689
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6690
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6580
6691
|
}
|
|
6581
6692
|
return decorations2.map(tr.changes);
|
|
6582
6693
|
},
|
|
6583
6694
|
provide: (field) => [
|
|
6584
|
-
|
|
6585
|
-
|
|
6695
|
+
EditorView27.decorations.from(field),
|
|
6696
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6586
6697
|
]
|
|
6698
|
+
}),
|
|
6699
|
+
ViewPlugin19.define((view) => {
|
|
6700
|
+
viewRef.current = view;
|
|
6701
|
+
return {
|
|
6702
|
+
destroy() {
|
|
6703
|
+
viewRef.current = void 0;
|
|
6704
|
+
}
|
|
6705
|
+
};
|
|
6587
6706
|
})
|
|
6588
6707
|
];
|
|
6589
6708
|
};
|
|
6590
|
-
var
|
|
6709
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6710
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6711
|
+
if (!dxn) {
|
|
6712
|
+
return;
|
|
6713
|
+
}
|
|
6714
|
+
const ref = db.makeRef(dxn);
|
|
6715
|
+
const target = ref.target;
|
|
6716
|
+
if (target) {
|
|
6717
|
+
return Entity.getLabel(target);
|
|
6718
|
+
}
|
|
6719
|
+
void ref.tryLoad().then(() => {
|
|
6720
|
+
viewRef.current?.dispatch({
|
|
6721
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6722
|
+
});
|
|
6723
|
+
});
|
|
6724
|
+
};
|
|
6725
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6591
6726
|
const builder = new RangeSetBuilder6();
|
|
6592
6727
|
syntaxTree10(state).iterate({
|
|
6593
6728
|
enter: (node) => {
|
|
@@ -6599,8 +6734,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6599
6734
|
case "Link": {
|
|
6600
6735
|
const link = getLinkRef(state, node.node);
|
|
6601
6736
|
if (link) {
|
|
6737
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6738
|
+
const displayLink = resolved ? {
|
|
6739
|
+
...link,
|
|
6740
|
+
label: resolved
|
|
6741
|
+
} : link;
|
|
6602
6742
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6603
|
-
widget: new PreviewInlineWidget(options,
|
|
6743
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6604
6744
|
side: 1
|
|
6605
6745
|
}));
|
|
6606
6746
|
}
|
|
@@ -6676,7 +6816,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6676
6816
|
}
|
|
6677
6817
|
toDOM(_view) {
|
|
6678
6818
|
const root = document.createElement("div");
|
|
6679
|
-
root.classList.add("cm-preview-block", "density-fine");
|
|
6819
|
+
root.classList.add("cm-preview-block", "dx-density-fine");
|
|
6680
6820
|
this._options.addBlockContainer?.({
|
|
6681
6821
|
link: this._link,
|
|
6682
6822
|
el: root
|
|
@@ -6692,7 +6832,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6692
6832
|
};
|
|
6693
6833
|
|
|
6694
6834
|
// src/extensions/replacer.ts
|
|
6695
|
-
import { EditorView as
|
|
6835
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6696
6836
|
var defaultReplacements = [
|
|
6697
6837
|
{
|
|
6698
6838
|
input: "--",
|
|
@@ -6755,7 +6895,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6755
6895
|
const sortedReplacements = [
|
|
6756
6896
|
...replacements
|
|
6757
6897
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6758
|
-
return
|
|
6898
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6759
6899
|
if (insert.length !== 1) {
|
|
6760
6900
|
return false;
|
|
6761
6901
|
}
|
|
@@ -6789,12 +6929,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6789
6929
|
});
|
|
6790
6930
|
};
|
|
6791
6931
|
|
|
6932
|
+
// src/extensions/snippets.ts
|
|
6933
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6934
|
+
var defaultItems = [
|
|
6935
|
+
"hello world!",
|
|
6936
|
+
"this is a test.",
|
|
6937
|
+
"this is [DXOS](https://dxos.org)"
|
|
6938
|
+
];
|
|
6939
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6940
|
+
let timer;
|
|
6941
|
+
let index = 0;
|
|
6942
|
+
return [
|
|
6943
|
+
keymap12.of([
|
|
6944
|
+
{
|
|
6945
|
+
// Reset.
|
|
6946
|
+
key: "alt-meta-'",
|
|
6947
|
+
run: () => {
|
|
6948
|
+
clearTimeout(timer);
|
|
6949
|
+
index = 0;
|
|
6950
|
+
return true;
|
|
6951
|
+
}
|
|
6952
|
+
},
|
|
6953
|
+
{
|
|
6954
|
+
// Next snippet.
|
|
6955
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6956
|
+
key: "Shift-Meta-'",
|
|
6957
|
+
run: (view) => {
|
|
6958
|
+
clearTimeout(timer);
|
|
6959
|
+
const text = items[index++];
|
|
6960
|
+
if (index === items?.length) {
|
|
6961
|
+
index = 0;
|
|
6962
|
+
}
|
|
6963
|
+
let offset = 0;
|
|
6964
|
+
const insert = (delayMs = 0) => {
|
|
6965
|
+
timer = setTimeout(() => {
|
|
6966
|
+
const pos = view.state.selection.main.head;
|
|
6967
|
+
view.dispatch({
|
|
6968
|
+
changes: {
|
|
6969
|
+
from: pos,
|
|
6970
|
+
insert: text[offset++]
|
|
6971
|
+
},
|
|
6972
|
+
selection: {
|
|
6973
|
+
anchor: pos + 1
|
|
6974
|
+
}
|
|
6975
|
+
});
|
|
6976
|
+
if (offset < text.length) {
|
|
6977
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6978
|
+
}
|
|
6979
|
+
}, delayMs);
|
|
6980
|
+
};
|
|
6981
|
+
insert();
|
|
6982
|
+
return true;
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
])
|
|
6986
|
+
];
|
|
6987
|
+
};
|
|
6988
|
+
|
|
6792
6989
|
// src/extensions/submit.ts
|
|
6793
6990
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6794
|
-
import { keymap as
|
|
6991
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6795
6992
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6796
6993
|
return [
|
|
6797
|
-
Prec6.highest(
|
|
6994
|
+
Prec6.highest(keymap13.of([
|
|
6798
6995
|
{
|
|
6799
6996
|
key: "Enter",
|
|
6800
6997
|
preventDefault: true,
|
|
@@ -6839,6 +7036,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6839
7036
|
// src/extensions/tags/extended-markdown.ts
|
|
6840
7037
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6841
7038
|
import { parseMixed } from "@lezer/common";
|
|
7039
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6842
7040
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6843
7041
|
return [
|
|
6844
7042
|
createMarkdownExtensions({
|
|
@@ -6850,13 +7048,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6850
7048
|
{
|
|
6851
7049
|
name: "SetextHeading",
|
|
6852
7050
|
parse: () => false
|
|
6853
|
-
}
|
|
7051
|
+
},
|
|
7052
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7053
|
+
// even when their content contains blank lines.
|
|
7054
|
+
...xmlBlockParsers(registry)
|
|
6854
7055
|
]
|
|
6855
7056
|
}
|
|
6856
7057
|
]
|
|
6857
7058
|
})
|
|
6858
7059
|
];
|
|
6859
7060
|
};
|
|
7061
|
+
var xmlBlockParsers = (registry) => {
|
|
7062
|
+
const customTags = Object.keys(registry ?? {});
|
|
7063
|
+
if (customTags.length === 0) {
|
|
7064
|
+
return [];
|
|
7065
|
+
}
|
|
7066
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7067
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7068
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7069
|
+
return [
|
|
7070
|
+
{
|
|
7071
|
+
name: "XMLBlock",
|
|
7072
|
+
before: "HTMLBlock",
|
|
7073
|
+
parse: (cx, line) => {
|
|
7074
|
+
const match = openPattern.exec(line.text);
|
|
7075
|
+
if (!match) {
|
|
7076
|
+
return false;
|
|
7077
|
+
}
|
|
7078
|
+
if (selfClosePattern.test(line.text)) {
|
|
7079
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7080
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7081
|
+
cx.nextLine();
|
|
7082
|
+
return true;
|
|
7083
|
+
}
|
|
7084
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7085
|
+
return false;
|
|
7086
|
+
}
|
|
7087
|
+
const tagName = match[1];
|
|
7088
|
+
const closeTag = `</${tagName}>`;
|
|
7089
|
+
const start = cx.lineStart;
|
|
7090
|
+
if (line.text.includes(closeTag)) {
|
|
7091
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7092
|
+
cx.nextLine();
|
|
7093
|
+
return true;
|
|
7094
|
+
}
|
|
7095
|
+
let end = cx.lineStart + line.text.length;
|
|
7096
|
+
while (cx.nextLine()) {
|
|
7097
|
+
end = cx.lineStart + line.text.length;
|
|
7098
|
+
if (line.text.includes(closeTag)) {
|
|
7099
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7100
|
+
cx.nextLine();
|
|
7101
|
+
return true;
|
|
7102
|
+
}
|
|
7103
|
+
}
|
|
7104
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7105
|
+
return true;
|
|
7106
|
+
}
|
|
7107
|
+
}
|
|
7108
|
+
];
|
|
7109
|
+
};
|
|
6860
7110
|
var mixedParser = (registry) => {
|
|
6861
7111
|
const customTags = Object.keys(registry ?? {});
|
|
6862
7112
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6890,219 +7140,793 @@ var mixedParser = (registry) => {
|
|
|
6890
7140
|
});
|
|
6891
7141
|
};
|
|
6892
7142
|
|
|
6893
|
-
// src/extensions/tags/
|
|
6894
|
-
import { StateEffect as
|
|
6895
|
-
import { Decoration as Decoration14, EditorView as
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
var
|
|
6899
|
-
var
|
|
7143
|
+
// src/extensions/tags/fader.ts
|
|
7144
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7145
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7146
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7147
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7148
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7149
|
+
var fader = (options = {}) => {
|
|
7150
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7151
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7152
|
+
let lastCount = -1;
|
|
7153
|
+
const log12 = (expiries) => {
|
|
7154
|
+
if (expiries.length !== lastCount) {
|
|
7155
|
+
lastCount = expiries.length;
|
|
7156
|
+
}
|
|
7157
|
+
};
|
|
7158
|
+
const dequeue = StateEffect10.define();
|
|
7159
|
+
const fadeField = StateField12.define({
|
|
7160
|
+
create: () => ({
|
|
7161
|
+
decorations: Decoration14.none,
|
|
7162
|
+
expiries: [],
|
|
7163
|
+
batchStart: 0
|
|
7164
|
+
}),
|
|
7165
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
7166
|
+
for (const effect of tr.effects) {
|
|
7167
|
+
if (effect.is(dequeue)) {
|
|
7168
|
+
const now2 = effect.value;
|
|
7169
|
+
let removeCount = 0;
|
|
7170
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7171
|
+
removeCount++;
|
|
7172
|
+
}
|
|
7173
|
+
if (removeCount > 0) {
|
|
7174
|
+
expiries = expiries.slice(removeCount);
|
|
7175
|
+
let skipped = 0;
|
|
7176
|
+
decorations2 = decorations2.update({
|
|
7177
|
+
filter: () => {
|
|
7178
|
+
if (skipped < removeCount) {
|
|
7179
|
+
skipped++;
|
|
7180
|
+
return false;
|
|
7181
|
+
}
|
|
7182
|
+
return true;
|
|
7183
|
+
}
|
|
7184
|
+
});
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7187
|
+
}
|
|
7188
|
+
if (!tr.docChanged) {
|
|
7189
|
+
log12(expiries);
|
|
7190
|
+
return {
|
|
7191
|
+
decorations: decorations2,
|
|
7192
|
+
expiries,
|
|
7193
|
+
batchStart
|
|
7194
|
+
};
|
|
7195
|
+
}
|
|
7196
|
+
let isReset = tr.state.doc.length === 0;
|
|
7197
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7198
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7199
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7200
|
+
isReset = true;
|
|
7201
|
+
}
|
|
7202
|
+
});
|
|
7203
|
+
}
|
|
7204
|
+
if (isReset) {
|
|
7205
|
+
log12([]);
|
|
7206
|
+
return {
|
|
7207
|
+
decorations: Decoration14.none,
|
|
7208
|
+
expiries: [],
|
|
7209
|
+
batchStart: 0
|
|
7210
|
+
};
|
|
7211
|
+
}
|
|
7212
|
+
const now = Date.now();
|
|
7213
|
+
const add = [];
|
|
7214
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7215
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7216
|
+
add.push({
|
|
7217
|
+
from: fromB,
|
|
7218
|
+
to: toB
|
|
7219
|
+
});
|
|
7220
|
+
}
|
|
7221
|
+
});
|
|
7222
|
+
if (add.length > 0) {
|
|
7223
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7224
|
+
if (canCoalesce) {
|
|
7225
|
+
let lastFrom = -1;
|
|
7226
|
+
let lastTo = -1;
|
|
7227
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7228
|
+
lastFrom = from;
|
|
7229
|
+
lastTo = to;
|
|
7230
|
+
});
|
|
7231
|
+
if (lastFrom >= 0) {
|
|
7232
|
+
decorations2 = decorations2.update({
|
|
7233
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7234
|
+
});
|
|
7235
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7236
|
+
const mergedTo = add[add.length - 1].to;
|
|
7237
|
+
decorations2 = decorations2.update({
|
|
7238
|
+
add: [
|
|
7239
|
+
Decoration14.mark({
|
|
7240
|
+
class: "cm-fader"
|
|
7241
|
+
}).range(mergedFrom, mergedTo)
|
|
7242
|
+
]
|
|
7243
|
+
});
|
|
7244
|
+
expiries = [
|
|
7245
|
+
...expiries.slice(0, -1),
|
|
7246
|
+
now + removalDelay
|
|
7247
|
+
];
|
|
7248
|
+
}
|
|
7249
|
+
} else {
|
|
7250
|
+
batchStart = now;
|
|
7251
|
+
expiries = [
|
|
7252
|
+
...expiries,
|
|
7253
|
+
now + removalDelay
|
|
7254
|
+
];
|
|
7255
|
+
decorations2 = decorations2.update({
|
|
7256
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7257
|
+
class: "cm-fader"
|
|
7258
|
+
}).range(from, to))
|
|
7259
|
+
});
|
|
7260
|
+
}
|
|
7261
|
+
}
|
|
7262
|
+
log12(expiries);
|
|
7263
|
+
return {
|
|
7264
|
+
decorations: decorations2,
|
|
7265
|
+
expiries,
|
|
7266
|
+
batchStart
|
|
7267
|
+
};
|
|
7268
|
+
},
|
|
7269
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7270
|
+
});
|
|
7271
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7272
|
+
view;
|
|
7273
|
+
#timer;
|
|
7274
|
+
constructor(view) {
|
|
7275
|
+
this.view = view;
|
|
7276
|
+
this.#schedule();
|
|
7277
|
+
}
|
|
7278
|
+
update() {
|
|
7279
|
+
this.#schedule();
|
|
7280
|
+
}
|
|
7281
|
+
#schedule() {
|
|
7282
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7283
|
+
if (expiries.length === 0) {
|
|
7284
|
+
clearTimeout(this.#timer);
|
|
7285
|
+
this.#timer = void 0;
|
|
7286
|
+
return;
|
|
7287
|
+
}
|
|
7288
|
+
if (this.#timer !== void 0) {
|
|
7289
|
+
return;
|
|
7290
|
+
}
|
|
7291
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7292
|
+
this.#timer = setTimeout(() => {
|
|
7293
|
+
this.#timer = void 0;
|
|
7294
|
+
this.view.dispatch({
|
|
7295
|
+
effects: dequeue.of(Date.now())
|
|
7296
|
+
});
|
|
7297
|
+
}, delay);
|
|
7298
|
+
}
|
|
7299
|
+
destroy() {
|
|
7300
|
+
clearTimeout(this.#timer);
|
|
7301
|
+
}
|
|
7302
|
+
});
|
|
6900
7303
|
return [
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
7304
|
+
fadeField,
|
|
7305
|
+
cleanup,
|
|
7306
|
+
EditorView29.theme({
|
|
7307
|
+
".cm-fader": {
|
|
7308
|
+
animation: "fader 1s ease-out forwards"
|
|
7309
|
+
},
|
|
7310
|
+
"@keyframes fader": {
|
|
7311
|
+
"0%": {
|
|
7312
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7313
|
+
},
|
|
7314
|
+
"100%": {}
|
|
7315
|
+
}
|
|
7316
|
+
})
|
|
7317
|
+
];
|
|
7318
|
+
};
|
|
7319
|
+
|
|
7320
|
+
// src/extensions/tags/typewriter.ts
|
|
7321
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7322
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7323
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7324
|
+
var typewriterBypass = Annotation3.define();
|
|
7325
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7326
|
+
var CURSOR_LINGER = 3e3;
|
|
7327
|
+
var FRAME_BUDGET_MS = 4;
|
|
7328
|
+
var CHARS_PER_FRAME = 5;
|
|
7329
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7330
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7331
|
+
var typewriter = (options = {}) => {
|
|
7332
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7333
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7334
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7335
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7336
|
+
const suppressAppend = StateEffect11.define();
|
|
7337
|
+
const insertChunk = StateEffect11.define();
|
|
7338
|
+
const bufferField = StateField13.define({
|
|
7339
|
+
create: () => ({
|
|
7340
|
+
text: "",
|
|
7341
|
+
head: 0,
|
|
7342
|
+
insertAt: 0
|
|
7343
|
+
}),
|
|
6909
7344
|
update: (value, tr) => {
|
|
7345
|
+
let { text, head, insertAt } = value;
|
|
6910
7346
|
for (const effect of tr.effects) {
|
|
6911
|
-
if (effect.is(
|
|
6912
|
-
|
|
7347
|
+
if (effect.is(suppressAppend)) {
|
|
7348
|
+
if (text.length === head) {
|
|
7349
|
+
insertAt = effect.value.from;
|
|
7350
|
+
}
|
|
7351
|
+
text += effect.value.text;
|
|
7352
|
+
}
|
|
7353
|
+
if (effect.is(insertChunk)) {
|
|
7354
|
+
head += effect.value.text.length;
|
|
7355
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7356
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7357
|
+
text = text.slice(head);
|
|
7358
|
+
head = 0;
|
|
7359
|
+
}
|
|
6913
7360
|
}
|
|
6914
7361
|
}
|
|
6915
7362
|
if (tr.docChanged) {
|
|
6916
|
-
|
|
7363
|
+
let isReset = tr.state.doc.length === 0;
|
|
7364
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7365
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7366
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7367
|
+
isReset = true;
|
|
7368
|
+
}
|
|
7369
|
+
});
|
|
7370
|
+
}
|
|
7371
|
+
if (isReset) {
|
|
7372
|
+
return {
|
|
7373
|
+
text: "",
|
|
7374
|
+
head: 0,
|
|
7375
|
+
insertAt: 0
|
|
7376
|
+
};
|
|
7377
|
+
}
|
|
7378
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7379
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7380
|
+
}
|
|
6917
7381
|
}
|
|
6918
|
-
return
|
|
7382
|
+
return {
|
|
7383
|
+
text,
|
|
7384
|
+
head,
|
|
7385
|
+
insertAt
|
|
7386
|
+
};
|
|
7387
|
+
}
|
|
7388
|
+
});
|
|
7389
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7390
|
+
if (!tr.docChanged) {
|
|
7391
|
+
return tr;
|
|
6919
7392
|
}
|
|
7393
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7394
|
+
return tr;
|
|
7395
|
+
}
|
|
7396
|
+
let appendedText = "";
|
|
7397
|
+
let appendFrom = -1;
|
|
7398
|
+
let isAppendOnly = true;
|
|
7399
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7400
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7401
|
+
appendedText += inserted.sliceString(0);
|
|
7402
|
+
if (appendFrom === -1) {
|
|
7403
|
+
appendFrom = fromA;
|
|
7404
|
+
}
|
|
7405
|
+
} else {
|
|
7406
|
+
isAppendOnly = false;
|
|
7407
|
+
}
|
|
7408
|
+
});
|
|
7409
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7410
|
+
return tr;
|
|
7411
|
+
}
|
|
7412
|
+
return {
|
|
7413
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7414
|
+
effects: suppressAppend.of({
|
|
7415
|
+
from: appendFrom,
|
|
7416
|
+
text: appendedText
|
|
7417
|
+
})
|
|
7418
|
+
};
|
|
6920
7419
|
});
|
|
6921
|
-
const
|
|
7420
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6922
7421
|
view;
|
|
6923
|
-
|
|
7422
|
+
_raf;
|
|
7423
|
+
_activeStreamTag = null;
|
|
6924
7424
|
constructor(view) {
|
|
6925
7425
|
this.view = view;
|
|
6926
7426
|
}
|
|
6927
7427
|
update(update2) {
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
7428
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7429
|
+
const pending = text.length - head;
|
|
7430
|
+
if (pending === 0) {
|
|
7431
|
+
this._activeStreamTag = null;
|
|
7432
|
+
}
|
|
7433
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7434
|
+
this._start();
|
|
6935
7435
|
}
|
|
6936
7436
|
}
|
|
7437
|
+
_start() {
|
|
7438
|
+
queueMicrotask(() => {
|
|
7439
|
+
this.view.dispatch({
|
|
7440
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7441
|
+
annotations: typewriterBypass.of(true)
|
|
7442
|
+
});
|
|
7443
|
+
});
|
|
7444
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7445
|
+
}
|
|
7446
|
+
_tick = () => {
|
|
7447
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7448
|
+
const pending = text.length - head;
|
|
7449
|
+
if (pending === 0) {
|
|
7450
|
+
this.view.dispatch({
|
|
7451
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7452
|
+
annotations: typewriterBypass.of(true)
|
|
7453
|
+
});
|
|
7454
|
+
this._raf = void 0;
|
|
7455
|
+
return;
|
|
7456
|
+
}
|
|
7457
|
+
if (pending > flushThreshold) {
|
|
7458
|
+
const chunk = text.slice(head);
|
|
7459
|
+
this._activeStreamTag = null;
|
|
7460
|
+
this.view.dispatch({
|
|
7461
|
+
changes: {
|
|
7462
|
+
from: insertAt,
|
|
7463
|
+
insert: chunk
|
|
7464
|
+
},
|
|
7465
|
+
effects: insertChunk.of({
|
|
7466
|
+
from: insertAt,
|
|
7467
|
+
text: chunk
|
|
7468
|
+
})
|
|
7469
|
+
});
|
|
7470
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7471
|
+
return;
|
|
7472
|
+
}
|
|
7473
|
+
const startTime = performance.now();
|
|
7474
|
+
let pos = head;
|
|
7475
|
+
let activeTag = this._activeStreamTag;
|
|
7476
|
+
let charsEmitted = 0;
|
|
7477
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7478
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7479
|
+
if (result.count === 0) {
|
|
7480
|
+
break;
|
|
7481
|
+
}
|
|
7482
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7483
|
+
break;
|
|
7484
|
+
}
|
|
7485
|
+
if (result.enterTag) {
|
|
7486
|
+
activeTag = result.enterTag;
|
|
7487
|
+
}
|
|
7488
|
+
if (result.exitTag) {
|
|
7489
|
+
activeTag = null;
|
|
7490
|
+
}
|
|
7491
|
+
pos += result.count;
|
|
7492
|
+
charsEmitted += result.count;
|
|
7493
|
+
}
|
|
7494
|
+
const totalCount = pos - head;
|
|
7495
|
+
if (totalCount > 0) {
|
|
7496
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7497
|
+
this._activeStreamTag = activeTag;
|
|
7498
|
+
this.view.dispatch({
|
|
7499
|
+
changes: {
|
|
7500
|
+
from: insertAt,
|
|
7501
|
+
insert: chunk
|
|
7502
|
+
},
|
|
7503
|
+
effects: insertChunk.of({
|
|
7504
|
+
from: insertAt,
|
|
7505
|
+
text: chunk
|
|
7506
|
+
})
|
|
7507
|
+
});
|
|
7508
|
+
}
|
|
7509
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7510
|
+
};
|
|
6937
7511
|
destroy() {
|
|
6938
|
-
|
|
7512
|
+
if (this._raf !== void 0) {
|
|
7513
|
+
cancelAnimationFrame(this._raf);
|
|
7514
|
+
}
|
|
6939
7515
|
}
|
|
6940
7516
|
});
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
7517
|
+
return [
|
|
7518
|
+
bufferField,
|
|
7519
|
+
filter,
|
|
7520
|
+
drainPlugin,
|
|
7521
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7522
|
+
].filter(Boolean);
|
|
7523
|
+
};
|
|
7524
|
+
var typewriterCursor = (bufferField) => {
|
|
7525
|
+
const hideCursor = StateEffect11.define();
|
|
7526
|
+
const visibilityField = StateField13.define({
|
|
7527
|
+
create: () => ({
|
|
7528
|
+
visible: false,
|
|
7529
|
+
insertAt: 0,
|
|
7530
|
+
lastNonWsAt: 0
|
|
7531
|
+
}),
|
|
7532
|
+
update: (value, tr) => {
|
|
7533
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7534
|
+
const pending = text.length - head;
|
|
7535
|
+
if (pending > 0) {
|
|
7536
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7537
|
+
if (tr.docChanged) {
|
|
7538
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7539
|
+
const chunk = inserted.sliceString(0);
|
|
7540
|
+
if (chunk.trim().length > 0) {
|
|
7541
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7542
|
+
}
|
|
7543
|
+
});
|
|
7544
|
+
}
|
|
7545
|
+
return {
|
|
7546
|
+
visible: true,
|
|
7547
|
+
insertAt,
|
|
7548
|
+
lastNonWsAt
|
|
7549
|
+
};
|
|
7550
|
+
}
|
|
7551
|
+
for (const effect of tr.effects) {
|
|
7552
|
+
if (effect.is(hideCursor)) {
|
|
7553
|
+
return {
|
|
7554
|
+
...value,
|
|
7555
|
+
visible: false
|
|
7556
|
+
};
|
|
7557
|
+
}
|
|
6947
7558
|
}
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
7559
|
+
return value;
|
|
7560
|
+
}
|
|
7561
|
+
});
|
|
7562
|
+
const decorationField = StateField13.define({
|
|
7563
|
+
create: () => Decoration15.none,
|
|
7564
|
+
update: (_decorations, tr) => {
|
|
7565
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7566
|
+
if (!visible) {
|
|
7567
|
+
return Decoration15.none;
|
|
7568
|
+
}
|
|
7569
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7570
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7571
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7572
|
+
return Decoration15.set([
|
|
7573
|
+
Decoration15.widget({
|
|
6951
7574
|
widget: new CursorWidget(),
|
|
6952
7575
|
side: 1
|
|
6953
|
-
}).range(
|
|
7576
|
+
}).range(pos)
|
|
6954
7577
|
]);
|
|
6955
7578
|
},
|
|
6956
|
-
provide: (
|
|
7579
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7580
|
+
});
|
|
7581
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7582
|
+
view;
|
|
7583
|
+
_timer;
|
|
7584
|
+
constructor(view) {
|
|
7585
|
+
this.view = view;
|
|
7586
|
+
}
|
|
7587
|
+
update(update2) {
|
|
7588
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7589
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7590
|
+
const pending = text.length - head;
|
|
7591
|
+
if (pending > 0) {
|
|
7592
|
+
clearTimeout(this._timer);
|
|
7593
|
+
this._timer = void 0;
|
|
7594
|
+
} else if (visible && this._timer === void 0) {
|
|
7595
|
+
this._timer = setTimeout(() => {
|
|
7596
|
+
this.view.dispatch({
|
|
7597
|
+
effects: hideCursor.of(null)
|
|
7598
|
+
});
|
|
7599
|
+
this._timer = void 0;
|
|
7600
|
+
}, CURSOR_LINGER);
|
|
7601
|
+
}
|
|
7602
|
+
}
|
|
7603
|
+
destroy() {
|
|
7604
|
+
clearTimeout(this._timer);
|
|
7605
|
+
}
|
|
6957
7606
|
});
|
|
6958
7607
|
return [
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
7608
|
+
visibilityField,
|
|
7609
|
+
decorationField,
|
|
7610
|
+
timerPlugin
|
|
6962
7611
|
];
|
|
6963
7612
|
};
|
|
6964
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7613
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7614
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7615
|
+
// the blink animation isn't restarted on every transaction.
|
|
7616
|
+
eq(other) {
|
|
7617
|
+
return other instanceof _CursorWidget;
|
|
7618
|
+
}
|
|
6965
7619
|
toDOM() {
|
|
6966
|
-
const inner = Domino3.of("span").text("\
|
|
6967
|
-
animation: "blink
|
|
7620
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7621
|
+
animation: "blink 1s infinite",
|
|
7622
|
+
animationDelay: "250ms"
|
|
6968
7623
|
});
|
|
6969
7624
|
return Domino3.of("span").style({
|
|
6970
7625
|
opacity: "0.8"
|
|
6971
|
-
}).
|
|
7626
|
+
}).append(inner).root;
|
|
6972
7627
|
}
|
|
6973
7628
|
};
|
|
6974
|
-
var
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
7629
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7630
|
+
var TAG_NAME_PROBE = 64;
|
|
7631
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7632
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7633
|
+
if (start >= buffer.length) {
|
|
7634
|
+
return {
|
|
7635
|
+
count: 0
|
|
7636
|
+
};
|
|
7637
|
+
}
|
|
7638
|
+
if (activeStreamTag) {
|
|
7639
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7640
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7641
|
+
return {
|
|
7642
|
+
count: closeTag.length,
|
|
7643
|
+
exitTag: true
|
|
7644
|
+
};
|
|
7645
|
+
}
|
|
7646
|
+
if (buffer[start] === "<") {
|
|
7647
|
+
return {
|
|
7648
|
+
count: xmlElementLength(buffer, start)
|
|
7649
|
+
};
|
|
7650
|
+
}
|
|
7651
|
+
return {
|
|
7652
|
+
count: 1
|
|
7653
|
+
};
|
|
7654
|
+
}
|
|
7655
|
+
const ch = buffer[start];
|
|
7656
|
+
if (ch === "<") {
|
|
7657
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7658
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7659
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7660
|
+
const close = buffer.indexOf(">", start);
|
|
7661
|
+
if (close === -1) {
|
|
7662
|
+
return {
|
|
7663
|
+
count: 0
|
|
7664
|
+
};
|
|
6993
7665
|
}
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
isReset = true;
|
|
6999
|
-
}
|
|
7000
|
-
});
|
|
7666
|
+
if (buffer[close - 1] === "/") {
|
|
7667
|
+
return {
|
|
7668
|
+
count: close + 1 - start
|
|
7669
|
+
};
|
|
7001
7670
|
}
|
|
7002
|
-
|
|
7003
|
-
|
|
7671
|
+
return {
|
|
7672
|
+
count: close + 1 - start,
|
|
7673
|
+
enterTag: nameMatch[1]
|
|
7674
|
+
};
|
|
7675
|
+
}
|
|
7676
|
+
return {
|
|
7677
|
+
count: xmlElementLength(buffer, start)
|
|
7678
|
+
};
|
|
7679
|
+
}
|
|
7680
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7681
|
+
return {
|
|
7682
|
+
count: linkLength(buffer, start, start + 1)
|
|
7683
|
+
};
|
|
7684
|
+
}
|
|
7685
|
+
if (ch === "[") {
|
|
7686
|
+
return {
|
|
7687
|
+
count: linkLength(buffer, start, start)
|
|
7688
|
+
};
|
|
7689
|
+
}
|
|
7690
|
+
return {
|
|
7691
|
+
count: 1
|
|
7692
|
+
};
|
|
7693
|
+
};
|
|
7694
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7695
|
+
const close = buffer.indexOf(">", start);
|
|
7696
|
+
if (close === -1) {
|
|
7697
|
+
return 0;
|
|
7698
|
+
}
|
|
7699
|
+
if (buffer[close - 1] === "/") {
|
|
7700
|
+
return close + 1 - start;
|
|
7701
|
+
}
|
|
7702
|
+
if (buffer[start + 1] === "/") {
|
|
7703
|
+
return close + 1 - start;
|
|
7704
|
+
}
|
|
7705
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7706
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7707
|
+
if (!nameMatch) {
|
|
7708
|
+
return 1;
|
|
7709
|
+
}
|
|
7710
|
+
const tagName = nameMatch[1];
|
|
7711
|
+
let depth = 0;
|
|
7712
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7713
|
+
tagPattern.lastIndex = start;
|
|
7714
|
+
let match;
|
|
7715
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7716
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7717
|
+
const isClosing = match[1] === "/";
|
|
7718
|
+
if (isSelfClosing) {
|
|
7719
|
+
if (depth === 0) {
|
|
7720
|
+
return match.index + match[0].length - start;
|
|
7721
|
+
}
|
|
7722
|
+
} else if (isClosing) {
|
|
7723
|
+
depth--;
|
|
7724
|
+
if (depth === 0) {
|
|
7725
|
+
return match.index + match[0].length - start;
|
|
7004
7726
|
}
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7727
|
+
} else {
|
|
7728
|
+
depth++;
|
|
7729
|
+
}
|
|
7730
|
+
}
|
|
7731
|
+
return 0;
|
|
7732
|
+
};
|
|
7733
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7734
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7735
|
+
if (bracketClose === -1) {
|
|
7736
|
+
return 0;
|
|
7737
|
+
}
|
|
7738
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7739
|
+
return 0;
|
|
7740
|
+
}
|
|
7741
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7742
|
+
return 1;
|
|
7743
|
+
}
|
|
7744
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7745
|
+
if (parenClose === -1) {
|
|
7746
|
+
return 0;
|
|
7747
|
+
}
|
|
7748
|
+
return parenClose + 1 - start;
|
|
7749
|
+
};
|
|
7750
|
+
|
|
7751
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7752
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7753
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7754
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7755
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7756
|
+
class: lineClass
|
|
7757
|
+
}) : void 0;
|
|
7758
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7759
|
+
class: contentClass
|
|
7760
|
+
}) : void 0;
|
|
7761
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7762
|
+
const buildDecorations5 = (view) => {
|
|
7763
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7764
|
+
if (!text.includes(`<${tag}`)) {
|
|
7765
|
+
return Decoration16.none;
|
|
7766
|
+
}
|
|
7767
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7768
|
+
const ranges = [];
|
|
7769
|
+
tree.iterate({
|
|
7770
|
+
enter: (node) => {
|
|
7771
|
+
if (node.type.name !== "Element") {
|
|
7008
7772
|
return;
|
|
7009
7773
|
}
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7774
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7775
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7776
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7777
|
+
if (!openTag || !tagNameNode) {
|
|
7778
|
+
return;
|
|
7014
7779
|
}
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7780
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7781
|
+
return;
|
|
7782
|
+
}
|
|
7783
|
+
const contentFrom = openTag.to;
|
|
7784
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7785
|
+
if (hideDecoration) {
|
|
7786
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7787
|
+
if (closeTag) {
|
|
7788
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7789
|
+
}
|
|
7790
|
+
}
|
|
7791
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7792
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7793
|
+
}
|
|
7794
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7795
|
+
let pos = contentFrom;
|
|
7796
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7797
|
+
const line = view.state.doc.lineAt(pos);
|
|
7798
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7799
|
+
if (line.to >= contentTo) {
|
|
7800
|
+
break;
|
|
7801
|
+
}
|
|
7802
|
+
pos = line.to + 1;
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
});
|
|
7807
|
+
return Decoration16.set(ranges, true);
|
|
7808
|
+
};
|
|
7809
|
+
return ViewPlugin22.fromClass(class {
|
|
7810
|
+
decorations;
|
|
7026
7811
|
constructor(view) {
|
|
7027
|
-
this.
|
|
7812
|
+
this.decorations = buildDecorations5(view);
|
|
7028
7813
|
}
|
|
7029
7814
|
update(update2) {
|
|
7030
|
-
if (
|
|
7031
|
-
|
|
7815
|
+
if (update2.docChanged) {
|
|
7816
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7032
7817
|
}
|
|
7033
|
-
|
|
7034
|
-
|
|
7818
|
+
}
|
|
7819
|
+
}, {
|
|
7820
|
+
decorations: (instance) => instance.decorations
|
|
7821
|
+
});
|
|
7822
|
+
};
|
|
7823
|
+
|
|
7824
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7825
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7826
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7827
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7828
|
+
"OpenTag",
|
|
7829
|
+
"CloseTag",
|
|
7830
|
+
"SelfClosingTag",
|
|
7831
|
+
"MismatchedCloseTag"
|
|
7832
|
+
]);
|
|
7833
|
+
var xmlElementMark = Decoration17.mark({
|
|
7834
|
+
class: "cm-xml-element"
|
|
7835
|
+
});
|
|
7836
|
+
var xmlTagMark = Decoration17.mark({
|
|
7837
|
+
class: "cm-xml-tag"
|
|
7838
|
+
});
|
|
7839
|
+
var xmlContentMark = Decoration17.mark({
|
|
7840
|
+
class: "cm-xml-content"
|
|
7841
|
+
});
|
|
7842
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7843
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7844
|
+
const buildDecorations5 = (view) => {
|
|
7845
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7846
|
+
if (!text.includes("<")) {
|
|
7847
|
+
return Decoration17.none;
|
|
7848
|
+
}
|
|
7849
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7850
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7851
|
+
const ranges = [];
|
|
7852
|
+
tree.iterate({
|
|
7853
|
+
enter: (node) => {
|
|
7854
|
+
const name = node.type.name;
|
|
7855
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7856
|
+
if (skipSet) {
|
|
7857
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7858
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7859
|
+
return false;
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7862
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7863
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7035
7864
|
return;
|
|
7036
7865
|
}
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7866
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7867
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7870
|
+
if (name === "Element" && node.from < node.to) {
|
|
7871
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7872
|
+
if (openTag && skipSet) {
|
|
7873
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7874
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7875
|
+
return false;
|
|
7876
|
+
}
|
|
7877
|
+
}
|
|
7878
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7879
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7880
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7881
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7882
|
+
}
|
|
7040
7883
|
}
|
|
7041
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7042
|
-
const id = setTimeout(() => {
|
|
7043
|
-
this.view.dispatch({
|
|
7044
|
-
effects: removeDecoration.of({
|
|
7045
|
-
from: fromB,
|
|
7046
|
-
to: toB
|
|
7047
|
-
})
|
|
7048
|
-
});
|
|
7049
|
-
this._timers.delete(key);
|
|
7050
|
-
}, totalDelay);
|
|
7051
|
-
this._timers.set(key, id);
|
|
7052
|
-
});
|
|
7053
|
-
}
|
|
7054
|
-
destroy() {
|
|
7055
|
-
for (const id of this._timers.values()) {
|
|
7056
|
-
clearTimeout(id);
|
|
7057
7884
|
}
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
}
|
|
7885
|
+
});
|
|
7886
|
+
return Decoration17.set(ranges, true);
|
|
7887
|
+
};
|
|
7061
7888
|
return [
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
},
|
|
7071
|
-
"@keyframes fade-in": {
|
|
7072
|
-
"0%": {
|
|
7073
|
-
opacity: "0"
|
|
7074
|
-
},
|
|
7075
|
-
"80%": {
|
|
7076
|
-
opacity: "1"
|
|
7077
|
-
},
|
|
7078
|
-
"100%": {
|
|
7079
|
-
opacity: "0.8"
|
|
7889
|
+
ViewPlugin23.fromClass(class {
|
|
7890
|
+
decorations;
|
|
7891
|
+
constructor(view) {
|
|
7892
|
+
this.decorations = buildDecorations5(view);
|
|
7893
|
+
}
|
|
7894
|
+
update(update2) {
|
|
7895
|
+
if (update2.docChanged) {
|
|
7896
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7080
7897
|
}
|
|
7081
7898
|
}
|
|
7899
|
+
}, {
|
|
7900
|
+
decorations: (instance) => instance.decorations
|
|
7901
|
+
}),
|
|
7902
|
+
EditorView31.baseTheme({
|
|
7903
|
+
".cm-xml-element": {
|
|
7904
|
+
backgroundColor: "var(--color-current-surface)",
|
|
7905
|
+
borderRadius: "0.25rem",
|
|
7906
|
+
padding: "0.25rem"
|
|
7907
|
+
},
|
|
7908
|
+
".cm-xml-tag": {
|
|
7909
|
+
color: "var(--color-blue-500)",
|
|
7910
|
+
fontFamily: "var(--font-mono)"
|
|
7911
|
+
},
|
|
7912
|
+
".cm-xml-content": {}
|
|
7082
7913
|
})
|
|
7083
7914
|
];
|
|
7084
7915
|
};
|
|
7085
7916
|
|
|
7086
7917
|
// src/extensions/tags/xml-tags.ts
|
|
7087
7918
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7088
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7089
|
-
import { Decoration as
|
|
7919
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7920
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7090
7921
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7091
|
-
import { log as
|
|
7922
|
+
import { log as log11 } from "@dxos/log";
|
|
7923
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7092
7924
|
|
|
7093
7925
|
// src/extensions/tags/xml-util.ts
|
|
7094
7926
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7095
|
-
var
|
|
7927
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7096
7928
|
var nodeToJson = (state, node) => {
|
|
7097
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7098
|
-
F: __dxlog_file15,
|
|
7099
|
-
L: 18,
|
|
7100
|
-
S: void 0,
|
|
7101
|
-
A: [
|
|
7102
|
-
"node.type.name === 'Element'",
|
|
7103
|
-
"'Node is not an Element'"
|
|
7104
|
-
]
|
|
7105
|
-
});
|
|
7929
|
+
invariant6(node.type.name === "Element", "Node is not an Element", { "~LogMeta": "~LogMeta", F: __dxlog_file16, L: 8, S: void 0, A: ["node.type.name === 'Element'", "'Node is not an Element'"] });
|
|
7106
7930
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7107
7931
|
if (openTag) {
|
|
7108
7932
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7134,13 +7958,23 @@ var nodeToJson = (state, node) => {
|
|
|
7134
7958
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7135
7959
|
const children = [];
|
|
7136
7960
|
let child = node.node.firstChild;
|
|
7961
|
+
const appendText = (raw) => {
|
|
7962
|
+
if (raw.length === 0) {
|
|
7963
|
+
return;
|
|
7964
|
+
}
|
|
7965
|
+
const last = children[children.length - 1];
|
|
7966
|
+
if (typeof last === "string") {
|
|
7967
|
+
children[children.length - 1] = last + raw;
|
|
7968
|
+
} else {
|
|
7969
|
+
children.push(raw);
|
|
7970
|
+
}
|
|
7971
|
+
};
|
|
7137
7972
|
while (child) {
|
|
7138
7973
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7139
7974
|
if (child.type.name === "Text") {
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
}
|
|
7975
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7976
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7977
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7144
7978
|
} else if (child.type.name === "Element") {
|
|
7145
7979
|
const data = nodeToJson(state, child);
|
|
7146
7980
|
if (data) {
|
|
@@ -7150,26 +7984,63 @@ var nodeToJson = (state, node) => {
|
|
|
7150
7984
|
}
|
|
7151
7985
|
child = child.nextSibling;
|
|
7152
7986
|
}
|
|
7987
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7988
|
+
children[0] = children[0].trimStart();
|
|
7989
|
+
}
|
|
7153
7990
|
if (children.length > 0) {
|
|
7154
|
-
|
|
7991
|
+
const lastIndex = children.length - 1;
|
|
7992
|
+
const last = children[lastIndex];
|
|
7993
|
+
if (typeof last === "string") {
|
|
7994
|
+
children[lastIndex] = last.trimEnd();
|
|
7995
|
+
}
|
|
7996
|
+
}
|
|
7997
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7998
|
+
if (trimmed.length > 0) {
|
|
7999
|
+
tag.children = trimmed;
|
|
7155
8000
|
}
|
|
7156
8001
|
}
|
|
7157
8002
|
return tag;
|
|
7158
8003
|
}
|
|
7159
8004
|
};
|
|
8005
|
+
var XML_NAMED_ENTITIES = {
|
|
8006
|
+
"<": "<",
|
|
8007
|
+
">": ">",
|
|
8008
|
+
"&": "&",
|
|
8009
|
+
""": '"',
|
|
8010
|
+
"'": "'"
|
|
8011
|
+
};
|
|
8012
|
+
var decodeXmlEntity = (raw) => {
|
|
8013
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
8014
|
+
if (named !== void 0) {
|
|
8015
|
+
return named;
|
|
8016
|
+
}
|
|
8017
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
8018
|
+
if (numeric) {
|
|
8019
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
8020
|
+
if (Number.isFinite(code)) {
|
|
8021
|
+
try {
|
|
8022
|
+
return String.fromCodePoint(code);
|
|
8023
|
+
} catch {
|
|
8024
|
+
}
|
|
8025
|
+
}
|
|
8026
|
+
}
|
|
8027
|
+
return raw;
|
|
8028
|
+
};
|
|
7160
8029
|
|
|
7161
8030
|
// src/extensions/tags/xml-tags.ts
|
|
7162
|
-
var
|
|
7163
|
-
var navigatePreviousEffect =
|
|
7164
|
-
var navigateNextEffect =
|
|
8031
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
8032
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8033
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7165
8034
|
var getXmlTextChild = (children) => {
|
|
7166
8035
|
const child = children?.[0];
|
|
7167
8036
|
return typeof child === "string" ? child : null;
|
|
7168
8037
|
};
|
|
7169
|
-
var
|
|
7170
|
-
var
|
|
7171
|
-
var
|
|
7172
|
-
var
|
|
8038
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8039
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8040
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8041
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8042
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8043
|
+
var widgetContextStateField = StateField14.define({
|
|
7173
8044
|
create: () => void 0,
|
|
7174
8045
|
update: (value, tr) => {
|
|
7175
8046
|
for (const effect of tr.effects) {
|
|
@@ -7180,7 +8051,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7180
8051
|
return value;
|
|
7181
8052
|
}
|
|
7182
8053
|
});
|
|
7183
|
-
var widgetStateMapStateField =
|
|
8054
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7184
8055
|
create: () => ({}),
|
|
7185
8056
|
update: (map, tr) => {
|
|
7186
8057
|
for (const effect of tr.effects) {
|
|
@@ -7189,15 +8060,10 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7189
8060
|
}
|
|
7190
8061
|
if (effect.is(xmlTagUpdateEffect)) {
|
|
7191
8062
|
const { id, value } = effect.value;
|
|
7192
|
-
|
|
8063
|
+
log11("widget updated", {
|
|
7193
8064
|
id,
|
|
7194
8065
|
value
|
|
7195
|
-
}, {
|
|
7196
|
-
F: __dxlog_file16,
|
|
7197
|
-
L: 153,
|
|
7198
|
-
S: void 0,
|
|
7199
|
-
C: (f, a) => f(...a)
|
|
7200
|
-
});
|
|
8066
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7201
8067
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7202
8068
|
return {
|
|
7203
8069
|
...map,
|
|
@@ -7224,15 +8090,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7224
8090
|
const widgets = /* @__PURE__ */ new Map();
|
|
7225
8091
|
const notifier = {
|
|
7226
8092
|
mounted: (state) => {
|
|
7227
|
-
|
|
8093
|
+
log11("widget mounted", {
|
|
7228
8094
|
id: state.id,
|
|
7229
8095
|
tag: state.props._tag
|
|
7230
|
-
}, {
|
|
7231
|
-
F: __dxlog_file16,
|
|
7232
|
-
L: 206,
|
|
7233
|
-
S: void 0,
|
|
7234
|
-
C: (f, a) => f(...a)
|
|
7235
|
-
});
|
|
8096
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7236
8097
|
widgets.set(state.id, state);
|
|
7237
8098
|
setWidgets?.([
|
|
7238
8099
|
...widgets.values()
|
|
@@ -7240,15 +8101,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7240
8101
|
},
|
|
7241
8102
|
unmounted: (id) => {
|
|
7242
8103
|
const state = widgets.get(id);
|
|
7243
|
-
|
|
8104
|
+
log11("widget unmounted", {
|
|
7244
8105
|
id,
|
|
7245
8106
|
tag: state?.props._tag
|
|
7246
|
-
}, {
|
|
7247
|
-
F: __dxlog_file16,
|
|
7248
|
-
L: 212,
|
|
7249
|
-
S: void 0,
|
|
7250
|
-
C: (f, a) => f(...a)
|
|
7251
|
-
});
|
|
8107
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7252
8108
|
widgets.delete(id);
|
|
7253
8109
|
setWidgets?.([
|
|
7254
8110
|
...widgets.values()
|
|
@@ -7257,7 +8113,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7257
8113
|
};
|
|
7258
8114
|
return notifier;
|
|
7259
8115
|
};
|
|
7260
|
-
var keyHandlers =
|
|
8116
|
+
var keyHandlers = keymap14.of([
|
|
7261
8117
|
{
|
|
7262
8118
|
key: "Mod-ArrowUp",
|
|
7263
8119
|
run: (view) => {
|
|
@@ -7278,7 +8134,7 @@ var keyHandlers = keymap13.of([
|
|
|
7278
8134
|
}
|
|
7279
8135
|
]);
|
|
7280
8136
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7281
|
-
return
|
|
8137
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7282
8138
|
update2.transactions.forEach((transaction) => {
|
|
7283
8139
|
for (const effect of transaction.effects) {
|
|
7284
8140
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7306,11 +8162,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7306
8162
|
anchor: line.from,
|
|
7307
8163
|
head: line.from
|
|
7308
8164
|
},
|
|
7309
|
-
effects:
|
|
7310
|
-
line: line.number,
|
|
7311
|
-
|
|
7312
|
-
offset: -16
|
|
7313
|
-
}
|
|
8165
|
+
effects: crawlerLineEffect.of({
|
|
8166
|
+
line: line.number - 1,
|
|
8167
|
+
offset: -16
|
|
7314
8168
|
})
|
|
7315
8169
|
});
|
|
7316
8170
|
continue;
|
|
@@ -7341,11 +8195,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7341
8195
|
anchor: line.to,
|
|
7342
8196
|
head: line.to
|
|
7343
8197
|
},
|
|
7344
|
-
effects:
|
|
7345
|
-
line: line.number,
|
|
7346
|
-
|
|
7347
|
-
offset: -16
|
|
7348
|
-
}
|
|
8198
|
+
effects: crawlerLineEffect.of({
|
|
8199
|
+
line: line.number - 1,
|
|
8200
|
+
offset: -16
|
|
7349
8201
|
})
|
|
7350
8202
|
});
|
|
7351
8203
|
} else {
|
|
@@ -7355,11 +8207,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7355
8207
|
anchor: line.to,
|
|
7356
8208
|
head: line.to
|
|
7357
8209
|
},
|
|
7358
|
-
effects:
|
|
7359
|
-
line: line.number,
|
|
7360
|
-
|
|
7361
|
-
position: "end"
|
|
7362
|
-
}
|
|
8210
|
+
effects: crawlerLineEffect.of({
|
|
8211
|
+
line: line.number - 1,
|
|
8212
|
+
position: "end"
|
|
7363
8213
|
})
|
|
7364
8214
|
});
|
|
7365
8215
|
}
|
|
@@ -7369,7 +8219,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7369
8219
|
});
|
|
7370
8220
|
});
|
|
7371
8221
|
};
|
|
7372
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8222
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7373
8223
|
update(update2) {
|
|
7374
8224
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7375
8225
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7396,19 +8246,25 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7396
8246
|
}
|
|
7397
8247
|
}
|
|
7398
8248
|
});
|
|
7399
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8249
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7400
8250
|
create: (state) => {
|
|
7401
8251
|
return buildDecorations4(state, {
|
|
7402
8252
|
from: 0,
|
|
7403
8253
|
to: state.doc.length
|
|
7404
8254
|
}, registry, notifier);
|
|
7405
8255
|
},
|
|
7406
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8256
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7407
8257
|
for (const effect of tr.effects) {
|
|
7408
8258
|
if (effect.is(xmlTagResetEffect)) {
|
|
8259
|
+
if (tr.docChanged) {
|
|
8260
|
+
return buildDecorations4(tr.state, {
|
|
8261
|
+
from: 0,
|
|
8262
|
+
to: tr.state.doc.length
|
|
8263
|
+
}, registry, notifier);
|
|
8264
|
+
}
|
|
7409
8265
|
return {
|
|
7410
8266
|
from: 0,
|
|
7411
|
-
decorations:
|
|
8267
|
+
decorations: Decoration18.none
|
|
7412
8268
|
};
|
|
7413
8269
|
}
|
|
7414
8270
|
}
|
|
@@ -7416,27 +8272,26 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7416
8272
|
const { state } = tr;
|
|
7417
8273
|
const reset = tr.changes.touchesRange(0, from);
|
|
7418
8274
|
if (reset) {
|
|
7419
|
-
|
|
8275
|
+
log11("document reset", {
|
|
7420
8276
|
from,
|
|
7421
8277
|
to: state.doc.length
|
|
7422
|
-
}, {
|
|
7423
|
-
F: __dxlog_file16,
|
|
7424
|
-
L: 371,
|
|
7425
|
-
S: void 0,
|
|
7426
|
-
C: (f, a) => f(...a)
|
|
7427
|
-
});
|
|
8278
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7428
8279
|
return buildDecorations4(state, {
|
|
7429
8280
|
from: 0,
|
|
7430
8281
|
to: state.doc.length
|
|
7431
8282
|
}, registry, notifier);
|
|
7432
8283
|
} else {
|
|
8284
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7433
8285
|
const result = buildDecorations4(state, {
|
|
7434
|
-
from,
|
|
8286
|
+
from: rebuildFrom,
|
|
7435
8287
|
to: state.doc.length
|
|
7436
8288
|
}, registry, notifier);
|
|
7437
8289
|
return {
|
|
7438
8290
|
from: result.from,
|
|
8291
|
+
streamingFrom: result.streamingFrom,
|
|
7439
8292
|
decorations: decorations2.update({
|
|
8293
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8294
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7440
8295
|
add: decorationSetToArray(result.decorations)
|
|
7441
8296
|
})
|
|
7442
8297
|
};
|
|
@@ -7444,12 +8299,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7444
8299
|
}
|
|
7445
8300
|
return {
|
|
7446
8301
|
from,
|
|
8302
|
+
streamingFrom,
|
|
7447
8303
|
decorations: decorations2
|
|
7448
8304
|
};
|
|
7449
8305
|
},
|
|
7450
8306
|
provide: (field) => [
|
|
7451
|
-
|
|
7452
|
-
|
|
8307
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8308
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7453
8309
|
]
|
|
7454
8310
|
});
|
|
7455
8311
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7460,10 +8316,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7460
8316
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7461
8317
|
return {
|
|
7462
8318
|
from: range.from,
|
|
7463
|
-
decorations:
|
|
8319
|
+
decorations: Decoration18.none
|
|
7464
8320
|
};
|
|
7465
8321
|
}
|
|
7466
8322
|
let last = range.from;
|
|
8323
|
+
let streamingFrom;
|
|
7467
8324
|
tree.iterate({
|
|
7468
8325
|
from: range.from,
|
|
7469
8326
|
to: range.to,
|
|
@@ -7476,21 +8333,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7476
8333
|
if (args) {
|
|
7477
8334
|
const def = registry[args._tag];
|
|
7478
8335
|
if (def) {
|
|
8336
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8337
|
+
return false;
|
|
8338
|
+
}
|
|
7479
8339
|
const { block, factory, Component } = def;
|
|
7480
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7481
8340
|
const nodeRange = {
|
|
7482
8341
|
from: node.node.from,
|
|
7483
8342
|
to: node.node.to
|
|
7484
8343
|
};
|
|
8344
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8345
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7485
8346
|
const props = {
|
|
7486
|
-
|
|
8347
|
+
id: widgetId,
|
|
7487
8348
|
range: nodeRange,
|
|
8349
|
+
context,
|
|
7488
8350
|
...args,
|
|
7489
8351
|
...widgetState
|
|
7490
8352
|
};
|
|
7491
|
-
const widget = factory ? factory(props) : Component ?
|
|
8353
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7492
8354
|
if (widget) {
|
|
7493
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8355
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7494
8356
|
widget,
|
|
7495
8357
|
block,
|
|
7496
8358
|
atomic: true,
|
|
@@ -7502,20 +8364,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7502
8364
|
}
|
|
7503
8365
|
}
|
|
7504
8366
|
} catch (err) {
|
|
7505
|
-
|
|
7506
|
-
F: __dxlog_file16,
|
|
7507
|
-
L: 456,
|
|
7508
|
-
S: void 0,
|
|
7509
|
-
C: (f, a) => f(...a)
|
|
7510
|
-
});
|
|
8367
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7511
8368
|
}
|
|
7512
8369
|
return false;
|
|
7513
8370
|
}
|
|
7514
8371
|
}
|
|
7515
8372
|
}
|
|
7516
8373
|
});
|
|
8374
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8375
|
+
if (streamingTagNames.length > 0) {
|
|
8376
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8377
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8378
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8379
|
+
let match;
|
|
8380
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8381
|
+
const tagName = match[1];
|
|
8382
|
+
const closeTag = `</${tagName}>`;
|
|
8383
|
+
const afterOpen = match.index + match[0].length;
|
|
8384
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8385
|
+
const absoluteFrom = range.from + match.index;
|
|
8386
|
+
const contentFrom = range.from + afterOpen;
|
|
8387
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8388
|
+
const def = registry[tagName];
|
|
8389
|
+
const props = {
|
|
8390
|
+
_tag: tagName,
|
|
8391
|
+
context,
|
|
8392
|
+
range: {
|
|
8393
|
+
from: absoluteFrom,
|
|
8394
|
+
to: range.to
|
|
8395
|
+
},
|
|
8396
|
+
children: innerText ? [
|
|
8397
|
+
innerText
|
|
8398
|
+
] : void 0
|
|
8399
|
+
};
|
|
8400
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8401
|
+
let attrMatch;
|
|
8402
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8403
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8404
|
+
}
|
|
8405
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8406
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8407
|
+
const mergedProps = {
|
|
8408
|
+
...props,
|
|
8409
|
+
id: widgetId,
|
|
8410
|
+
...widgetState
|
|
8411
|
+
};
|
|
8412
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8413
|
+
if (widget) {
|
|
8414
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8415
|
+
widget,
|
|
8416
|
+
block: def.block,
|
|
8417
|
+
atomic: true,
|
|
8418
|
+
inclusive: true,
|
|
8419
|
+
tag: tagName,
|
|
8420
|
+
streaming: true,
|
|
8421
|
+
contentFrom
|
|
8422
|
+
}));
|
|
8423
|
+
streamingFrom = absoluteFrom;
|
|
8424
|
+
last = absoluteFrom;
|
|
8425
|
+
}
|
|
8426
|
+
break;
|
|
8427
|
+
}
|
|
8428
|
+
}
|
|
8429
|
+
}
|
|
7517
8430
|
return {
|
|
7518
8431
|
from: last,
|
|
8432
|
+
streamingFrom,
|
|
7519
8433
|
decorations: builder.finish()
|
|
7520
8434
|
};
|
|
7521
8435
|
};
|
|
@@ -7524,108 +8438,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7524
8438
|
Component;
|
|
7525
8439
|
props;
|
|
7526
8440
|
notifier;
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
S: this,
|
|
7534
|
-
A: [
|
|
7535
|
-
"id",
|
|
7536
|
-
""
|
|
7537
|
-
]
|
|
7538
|
-
});
|
|
8441
|
+
streaming;
|
|
8442
|
+
#root = null;
|
|
8443
|
+
#view;
|
|
8444
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8445
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8446
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7539
8447
|
}
|
|
7540
8448
|
get root() {
|
|
7541
|
-
return this
|
|
8449
|
+
return this.#root;
|
|
7542
8450
|
}
|
|
7543
8451
|
eq(other) {
|
|
8452
|
+
if (this.streaming) {
|
|
8453
|
+
return false;
|
|
8454
|
+
}
|
|
7544
8455
|
return this.id === other.id;
|
|
7545
8456
|
}
|
|
7546
8457
|
ignoreEvent() {
|
|
7547
8458
|
return true;
|
|
7548
8459
|
}
|
|
7549
|
-
toDOM(
|
|
7550
|
-
this
|
|
8460
|
+
toDOM(view) {
|
|
8461
|
+
this.#view = view;
|
|
8462
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8463
|
+
const props = Object.assign({}, this.props, {
|
|
8464
|
+
view
|
|
8465
|
+
});
|
|
8466
|
+
this.notifier.mounted({
|
|
8467
|
+
id: this.id,
|
|
8468
|
+
root: this.#root,
|
|
8469
|
+
props,
|
|
8470
|
+
Component: this.Component
|
|
8471
|
+
});
|
|
8472
|
+
return this.#root;
|
|
8473
|
+
}
|
|
8474
|
+
updateDOM(dom) {
|
|
8475
|
+
this.#root = dom;
|
|
8476
|
+
const props = Object.assign({}, this.props, {
|
|
8477
|
+
view: this.#view
|
|
8478
|
+
});
|
|
7551
8479
|
this.notifier.mounted({
|
|
7552
8480
|
id: this.id,
|
|
7553
|
-
root: this
|
|
7554
|
-
props
|
|
8481
|
+
root: this.#root,
|
|
8482
|
+
props,
|
|
7555
8483
|
Component: this.Component
|
|
7556
8484
|
});
|
|
7557
|
-
return
|
|
8485
|
+
return true;
|
|
7558
8486
|
}
|
|
7559
8487
|
destroy(_dom) {
|
|
7560
8488
|
this.notifier.unmounted(this.id);
|
|
7561
|
-
this
|
|
8489
|
+
this.#root = null;
|
|
8490
|
+
this.#view = void 0;
|
|
7562
8491
|
}
|
|
7563
8492
|
};
|
|
7564
|
-
|
|
7565
|
-
// src/extensions/typewriter.ts
|
|
7566
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7567
|
-
var defaultItems = [
|
|
7568
|
-
"hello world!",
|
|
7569
|
-
"this is a test.",
|
|
7570
|
-
"this is [DXOS](https://dxos.org)"
|
|
7571
|
-
];
|
|
7572
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7573
|
-
let t;
|
|
7574
|
-
let idx = 0;
|
|
7575
|
-
return [
|
|
7576
|
-
keymap14.of([
|
|
7577
|
-
{
|
|
7578
|
-
// Reset.
|
|
7579
|
-
key: "alt-meta-'",
|
|
7580
|
-
run: () => {
|
|
7581
|
-
clearTimeout(t);
|
|
7582
|
-
idx = 0;
|
|
7583
|
-
return true;
|
|
7584
|
-
}
|
|
7585
|
-
},
|
|
7586
|
-
{
|
|
7587
|
-
// Next prompt.
|
|
7588
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7589
|
-
key: "Shift-Meta-'",
|
|
7590
|
-
run: (view) => {
|
|
7591
|
-
clearTimeout(t);
|
|
7592
|
-
const text = items[idx++];
|
|
7593
|
-
if (idx === items?.length) {
|
|
7594
|
-
idx = 0;
|
|
7595
|
-
}
|
|
7596
|
-
let i = 0;
|
|
7597
|
-
const insert = (d = 0) => {
|
|
7598
|
-
t = setTimeout(() => {
|
|
7599
|
-
const pos = view.state.selection.main.head;
|
|
7600
|
-
view.dispatch({
|
|
7601
|
-
changes: {
|
|
7602
|
-
from: pos,
|
|
7603
|
-
insert: text[i++]
|
|
7604
|
-
},
|
|
7605
|
-
selection: {
|
|
7606
|
-
anchor: pos + 1
|
|
7607
|
-
}
|
|
7608
|
-
});
|
|
7609
|
-
if (i < text.length) {
|
|
7610
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7611
|
-
}
|
|
7612
|
-
}, d);
|
|
7613
|
-
};
|
|
7614
|
-
insert();
|
|
7615
|
-
return true;
|
|
7616
|
-
}
|
|
7617
|
-
}
|
|
7618
|
-
])
|
|
7619
|
-
];
|
|
7620
|
-
};
|
|
7621
8493
|
export {
|
|
7622
8494
|
Cursor,
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
EditorState3 as EditorState,
|
|
7626
|
-
EditorView30 as EditorView,
|
|
7627
|
-
EditorViewMode,
|
|
7628
|
-
EditorViewModes,
|
|
8495
|
+
EditorState4 as EditorState,
|
|
8496
|
+
EditorView33 as EditorView,
|
|
7629
8497
|
Inline,
|
|
7630
8498
|
InputModeExtensions,
|
|
7631
8499
|
List,
|
|
@@ -7642,6 +8510,7 @@ export {
|
|
|
7642
8510
|
addStyle,
|
|
7643
8511
|
annotations,
|
|
7644
8512
|
autoScroll,
|
|
8513
|
+
autoScrollEffect,
|
|
7645
8514
|
autocomplete,
|
|
7646
8515
|
automerge,
|
|
7647
8516
|
awareness,
|
|
@@ -7655,9 +8524,14 @@ export {
|
|
|
7655
8524
|
commentClickedEffect,
|
|
7656
8525
|
comments,
|
|
7657
8526
|
commentsState,
|
|
8527
|
+
compactSlots,
|
|
7658
8528
|
convertTreeToJson,
|
|
8529
|
+
crawler,
|
|
8530
|
+
crawlerActiveEffect,
|
|
8531
|
+
crawlerLineEffect,
|
|
7659
8532
|
createBasicExtensions,
|
|
7660
8533
|
createComment,
|
|
8534
|
+
createCrawler,
|
|
7661
8535
|
createDataExtensions,
|
|
7662
8536
|
createEditorStateStore,
|
|
7663
8537
|
createEditorStateTransaction,
|
|
@@ -7677,12 +8551,12 @@ export {
|
|
|
7677
8551
|
defaultThemeSlots,
|
|
7678
8552
|
deleteItem,
|
|
7679
8553
|
documentId,
|
|
8554
|
+
documentSlots,
|
|
7680
8555
|
dropFile,
|
|
8556
|
+
editorClassNames,
|
|
7681
8557
|
editorInputMode,
|
|
7682
|
-
editorSlots,
|
|
7683
|
-
editorWidth,
|
|
7684
|
-
editorWithToolbarLayout,
|
|
7685
8558
|
extendedMarkdown,
|
|
8559
|
+
fader,
|
|
7686
8560
|
filterChars,
|
|
7687
8561
|
flattenRect,
|
|
7688
8562
|
focus,
|
|
@@ -7718,6 +8592,7 @@ export {
|
|
|
7718
8592
|
markdownTagsExtensions,
|
|
7719
8593
|
matchCompletion,
|
|
7720
8594
|
mention,
|
|
8595
|
+
mobileSlots,
|
|
7721
8596
|
modalStateEffect,
|
|
7722
8597
|
modalStateField,
|
|
7723
8598
|
moveItemDown,
|
|
@@ -7737,10 +8612,10 @@ export {
|
|
|
7737
8612
|
removeList,
|
|
7738
8613
|
removeStyle,
|
|
7739
8614
|
replacer,
|
|
8615
|
+
scrollPastEnd,
|
|
7740
8616
|
scrollThreadIntoView,
|
|
7741
|
-
scrollToBottomEffect,
|
|
7742
8617
|
scrollToLine,
|
|
7743
|
-
|
|
8618
|
+
scroller,
|
|
7744
8619
|
selectionState,
|
|
7745
8620
|
setBlockquote,
|
|
7746
8621
|
setComments,
|
|
@@ -7748,10 +8623,8 @@ export {
|
|
|
7748
8623
|
setSelection,
|
|
7749
8624
|
setStyle,
|
|
7750
8625
|
singleValueFacet,
|
|
7751
|
-
|
|
7752
|
-
stackItemContentEditorClassNames,
|
|
8626
|
+
snippets2 as snippets,
|
|
7753
8627
|
staticCompletion,
|
|
7754
|
-
streamer,
|
|
7755
8628
|
submit,
|
|
7756
8629
|
tabbable,
|
|
7757
8630
|
table,
|
|
@@ -7770,7 +8643,12 @@ export {
|
|
|
7770
8643
|
treeFacet,
|
|
7771
8644
|
typeahead,
|
|
7772
8645
|
typewriter,
|
|
8646
|
+
typewriterBypass,
|
|
8647
|
+
typewriterDrainingEffect,
|
|
7773
8648
|
wrapWithCatch,
|
|
8649
|
+
xmlBlockDecoration,
|
|
8650
|
+
xmlElementLength,
|
|
8651
|
+
xmlFormatting,
|
|
7774
8652
|
xmlTagContextEffect,
|
|
7775
8653
|
xmlTagResetEffect,
|
|
7776
8654
|
xmlTagUpdateEffect,
|