@dxos/ui-editor 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +1871 -1018
- 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 +1869 -1015
- 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/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -0
- 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 +4 -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/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scroller.d.ts +68 -0
- package/dist/types/src/extensions/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 +36 -39
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/auto-scroll.ts +234 -0
- 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 +4 -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/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +256 -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 +124 -34
- 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,228 +511,339 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
501
511
|
];
|
|
502
512
|
};
|
|
503
513
|
|
|
504
|
-
// src/extensions/
|
|
514
|
+
// src/extensions/auto-scroll.ts
|
|
505
515
|
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
506
516
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
507
|
-
import {
|
|
517
|
+
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
508
518
|
import { Domino } from "@dxos/ui";
|
|
519
|
+
import { getSize } from "@dxos/ui-theme";
|
|
509
520
|
|
|
510
|
-
// src/extensions/
|
|
521
|
+
// src/extensions/scroller.ts
|
|
511
522
|
import { StateEffect } from "@codemirror/state";
|
|
512
523
|
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
513
|
-
|
|
514
|
-
var
|
|
515
|
-
|
|
524
|
+
import { log as log2 } from "@dxos/log";
|
|
525
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
526
|
+
var scrollerLineEffect = StateEffect.define();
|
|
527
|
+
var scrollerCrawlEffect = StateEffect.define();
|
|
528
|
+
var scrollToLine = (view, options) => {
|
|
529
|
+
view.dispatch({
|
|
530
|
+
effects: scrollerLineEffect.of(options)
|
|
531
|
+
});
|
|
532
|
+
};
|
|
533
|
+
var scroller = ({ overScroll = 0 } = {}) => {
|
|
534
|
+
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
516
535
|
view;
|
|
536
|
+
crawler;
|
|
517
537
|
constructor(view) {
|
|
518
538
|
this.view = view;
|
|
539
|
+
this.crawler = createCrawler(this.view);
|
|
519
540
|
}
|
|
520
541
|
// No-op.
|
|
521
542
|
destroy() {
|
|
543
|
+
this.crawler.cancel();
|
|
522
544
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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;
|
|
545
|
+
cancel() {
|
|
546
|
+
this.crawler.cancel();
|
|
547
|
+
}
|
|
548
|
+
crawl(start = false) {
|
|
549
|
+
if (start) {
|
|
550
|
+
this.crawler.scroll();
|
|
558
551
|
} else {
|
|
559
|
-
|
|
552
|
+
this.crawler.cancel();
|
|
560
553
|
}
|
|
561
|
-
const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
562
|
-
this.animateScroll(scroller, clampedScrollTop);
|
|
563
554
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
555
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
556
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
557
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
558
|
+
const doc = this.view.state.doc;
|
|
559
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
560
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
561
|
+
const lineStart = doc.line(line + 1).from;
|
|
562
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
563
|
+
if (coords) {
|
|
564
|
+
const currentScrollTop = scrollTop;
|
|
565
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
566
|
+
if (position === "end") {
|
|
567
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
568
|
+
} else {
|
|
569
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
570
|
+
}
|
|
571
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
572
|
+
}
|
|
570
573
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
+
requestAnimationFrame(() => {
|
|
575
|
+
this.view.scrollDOM.scrollTo({
|
|
576
|
+
top: targetScrollTop
|
|
577
|
+
});
|
|
574
578
|
});
|
|
575
579
|
}
|
|
576
580
|
});
|
|
577
581
|
return [
|
|
578
582
|
scrollPlugin,
|
|
579
|
-
//
|
|
583
|
+
// Listen for effect.
|
|
580
584
|
EditorView4.updateListener.of((update2) => {
|
|
581
585
|
update2.transactions.forEach((transaction) => {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
});
|
|
586
|
+
try {
|
|
587
|
+
const plugin = update2.view.plugin(scrollPlugin);
|
|
588
|
+
if (plugin) {
|
|
589
|
+
for (const effect of transaction.effects) {
|
|
590
|
+
if (effect.is(scrollerCrawlEffect)) {
|
|
591
|
+
plugin.crawl(effect.value);
|
|
592
|
+
} else if (effect.is(scrollerLineEffect)) {
|
|
593
|
+
plugin.scroll(effect.value);
|
|
594
|
+
}
|
|
592
595
|
}
|
|
593
596
|
}
|
|
597
|
+
} catch (err) {
|
|
598
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
594
599
|
}
|
|
595
600
|
});
|
|
601
|
+
}),
|
|
602
|
+
// Styles.
|
|
603
|
+
EditorView4.theme({
|
|
604
|
+
".cm-scroller": {
|
|
605
|
+
overflowY: "scroll",
|
|
606
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
607
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
608
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
609
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
610
|
+
overflowAnchor: "auto"
|
|
611
|
+
},
|
|
612
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
613
|
+
display: "none"
|
|
614
|
+
},
|
|
615
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
616
|
+
background: "transparent",
|
|
617
|
+
transition: "background 0.15s"
|
|
618
|
+
},
|
|
619
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
620
|
+
background: "var(--color-scrollbar-thumb)"
|
|
621
|
+
},
|
|
622
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
623
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
624
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
625
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
626
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
627
|
+
".cm-content::after": {
|
|
628
|
+
content: '""',
|
|
629
|
+
display: "block",
|
|
630
|
+
height: `${overScroll}px`
|
|
631
|
+
},
|
|
632
|
+
".cm-scroll-button": {
|
|
633
|
+
position: "absolute",
|
|
634
|
+
bottom: "0.5rem",
|
|
635
|
+
right: "1rem"
|
|
636
|
+
}
|
|
596
637
|
})
|
|
597
638
|
];
|
|
598
639
|
};
|
|
599
|
-
|
|
600
|
-
view.
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
640
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
641
|
+
const el = view.scrollDOM;
|
|
642
|
+
let currentTop = 0;
|
|
643
|
+
let velocity = 0;
|
|
644
|
+
let rafId = null;
|
|
645
|
+
let lastTime = 0;
|
|
646
|
+
function frame(now) {
|
|
647
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
648
|
+
lastTime = now;
|
|
649
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
650
|
+
const delta = targetTop - currentTop;
|
|
651
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
652
|
+
el.scrollTop = targetTop;
|
|
653
|
+
currentTop = targetTop;
|
|
654
|
+
velocity = 0;
|
|
655
|
+
rafId = null;
|
|
656
|
+
lastTime = 0;
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
660
|
+
velocity += accel * dt;
|
|
661
|
+
currentTop += velocity * dt;
|
|
662
|
+
el.scrollTop = currentTop;
|
|
663
|
+
rafId = requestAnimationFrame(frame);
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
scroll: () => {
|
|
667
|
+
if (rafId === null) {
|
|
668
|
+
currentTop = el.scrollTop;
|
|
669
|
+
lastTime = 0;
|
|
670
|
+
rafId = requestAnimationFrame(frame);
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
cancel: () => {
|
|
674
|
+
if (rafId !== null) {
|
|
675
|
+
cancelAnimationFrame(rafId);
|
|
676
|
+
velocity = 0;
|
|
677
|
+
lastTime = 0;
|
|
678
|
+
rafId = null;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
607
683
|
|
|
608
|
-
// src/extensions/
|
|
609
|
-
var
|
|
610
|
-
var autoScroll = ({
|
|
684
|
+
// src/extensions/auto-scroll.ts
|
|
685
|
+
var autoScrollEffect = StateEffect2.define();
|
|
686
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
611
687
|
let buttonContainer;
|
|
612
|
-
let hideTimeout;
|
|
613
|
-
let lastScrollTop = 0;
|
|
614
688
|
let isPinned = true;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
689
|
+
let jumpPending = false;
|
|
690
|
+
let enabled = true;
|
|
691
|
+
let firstUpdate = true;
|
|
692
|
+
const setPinned = (pinned) => {
|
|
693
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
694
|
+
isPinned = pinned;
|
|
618
695
|
};
|
|
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
696
|
return [
|
|
653
|
-
// Update listener for
|
|
654
|
-
EditorView5.updateListener.of((
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
697
|
+
// Update listener for scrolling when content changes.
|
|
698
|
+
EditorView5.updateListener.of((update2) => {
|
|
699
|
+
const { view, heightChanged, state, startState } = update2;
|
|
700
|
+
for (const tr of update2.transactions) {
|
|
701
|
+
for (const effect of tr.effects) {
|
|
702
|
+
if (effect.is(autoScrollEffect)) {
|
|
703
|
+
enabled = effect.value;
|
|
704
|
+
if (enabled) {
|
|
705
|
+
setPinned(true);
|
|
706
|
+
view.dispatch({
|
|
707
|
+
effects: scrollerCrawlEffect.of(true)
|
|
708
|
+
});
|
|
709
|
+
} else {
|
|
710
|
+
view.dispatch({
|
|
711
|
+
effects: scrollerCrawlEffect.of(false)
|
|
712
|
+
});
|
|
713
|
+
}
|
|
659
714
|
}
|
|
660
715
|
}
|
|
661
|
-
}
|
|
662
|
-
if (
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
716
|
+
}
|
|
717
|
+
if (!enabled) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
721
|
+
firstUpdate = false;
|
|
722
|
+
jumpPending = true;
|
|
723
|
+
requestAnimationFrame(() => {
|
|
724
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
725
|
+
jumpPending = false;
|
|
726
|
+
});
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
firstUpdate = false;
|
|
730
|
+
if (jumpPending) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
if (heightChanged) {
|
|
734
|
+
if (isPinned) {
|
|
735
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
736
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
737
|
+
if (delta > 0) {
|
|
738
|
+
setPinned(true);
|
|
739
|
+
view.dispatch({
|
|
740
|
+
effects: scrollerCrawlEffect.of(true)
|
|
741
|
+
});
|
|
742
|
+
} else if (delta < -1) {
|
|
743
|
+
setPinned(false);
|
|
744
|
+
}
|
|
745
|
+
} else {
|
|
746
|
+
if (state.doc.length === 0) {
|
|
747
|
+
setPinned(true);
|
|
673
748
|
}
|
|
674
|
-
} else if (distanceFromBottom < 0) {
|
|
675
|
-
setPinned(false);
|
|
676
749
|
}
|
|
677
750
|
}
|
|
678
751
|
}),
|
|
679
|
-
//
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
752
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
753
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
754
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
755
|
+
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
756
|
+
observer;
|
|
757
|
+
firstObservation = true;
|
|
758
|
+
destroyed = false;
|
|
759
|
+
constructor(view) {
|
|
760
|
+
const onResize = throttle(() => {
|
|
761
|
+
if (this.destroyed || !enabled) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
setPinned(true);
|
|
765
|
+
requestAnimationFrame(() => {
|
|
766
|
+
if (this.destroyed) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
view.scrollDOM.scrollTo({
|
|
770
|
+
top: view.scrollDOM.scrollHeight,
|
|
771
|
+
behavior: "instant"
|
|
772
|
+
});
|
|
773
|
+
view.dispatch({
|
|
774
|
+
effects: scrollerCrawlEffect.of(false)
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
}, 50);
|
|
778
|
+
this.observer = new ResizeObserver(() => {
|
|
779
|
+
if (this.firstObservation) {
|
|
780
|
+
this.firstObservation = false;
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
onResize();
|
|
784
|
+
});
|
|
785
|
+
this.observer.observe(view.scrollDOM);
|
|
786
|
+
}
|
|
787
|
+
destroy() {
|
|
788
|
+
this.destroyed = true;
|
|
789
|
+
this.observer.disconnect();
|
|
790
|
+
}
|
|
791
|
+
}) : [],
|
|
792
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
793
|
+
ViewPlugin6.fromClass(class {
|
|
794
|
+
cleanup;
|
|
795
|
+
constructor(view) {
|
|
796
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
797
|
+
requestAnimationFrame(() => {
|
|
798
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
799
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
800
|
+
const pinned = delta === 0;
|
|
801
|
+
setPinned(pinned);
|
|
802
|
+
if (!pinned) {
|
|
803
|
+
view.dispatch({
|
|
804
|
+
effects: scrollerCrawlEffect.of(false)
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
}, 500));
|
|
809
|
+
}
|
|
810
|
+
destroy() {
|
|
811
|
+
this.cleanup();
|
|
690
812
|
}
|
|
691
813
|
}),
|
|
692
814
|
// Scroll button.
|
|
693
815
|
ViewPlugin6.fromClass(class {
|
|
694
816
|
constructor(view) {
|
|
695
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
817
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
696
818
|
icon: "ph--arrow-down--regular"
|
|
697
819
|
});
|
|
698
|
-
const button = Domino.of("button").classNames("dx-button bg-
|
|
820
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
699
821
|
"data-density": "fine"
|
|
700
|
-
}).
|
|
701
|
-
|
|
822
|
+
}).append(icon).on("click", () => {
|
|
823
|
+
setPinned(true);
|
|
824
|
+
view.dispatch({
|
|
825
|
+
effects: scrollerLineEffect.of({
|
|
826
|
+
line: -1,
|
|
827
|
+
position: "end",
|
|
828
|
+
behavior: "smooth"
|
|
829
|
+
})
|
|
830
|
+
});
|
|
702
831
|
});
|
|
703
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").
|
|
832
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
704
833
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
705
834
|
}
|
|
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
835
|
})
|
|
724
836
|
];
|
|
725
837
|
};
|
|
838
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
839
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
840
|
+
passive: true
|
|
841
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
842
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
843
|
+
onUserScroll();
|
|
844
|
+
}
|
|
845
|
+
}));
|
|
846
|
+
}
|
|
726
847
|
|
|
727
848
|
// src/extensions/automerge/automerge.ts
|
|
728
849
|
import { next as A3 } from "@automerge/automerge";
|
|
@@ -736,32 +857,22 @@ var initialSync = Transaction.userEvent.of("initial.sync");
|
|
|
736
857
|
|
|
737
858
|
// src/extensions/automerge/cursor.ts
|
|
738
859
|
import { fromCursor, toCursor } from "@dxos/echo-db";
|
|
739
|
-
import { log as
|
|
740
|
-
var
|
|
860
|
+
import { log as log3 } from "@dxos/log";
|
|
861
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
741
862
|
var cursorConverter = (accessor) => ({
|
|
742
863
|
toCursor: (pos, assoc) => {
|
|
743
864
|
try {
|
|
744
865
|
return toCursor(accessor, pos, assoc);
|
|
745
866
|
} catch (err) {
|
|
746
|
-
|
|
747
|
-
F: __dxlog_file2,
|
|
748
|
-
L: 15,
|
|
749
|
-
S: void 0,
|
|
750
|
-
C: (f, a) => f(...a)
|
|
751
|
-
});
|
|
867
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
752
868
|
return "";
|
|
753
869
|
}
|
|
754
870
|
},
|
|
755
|
-
fromCursor: (
|
|
871
|
+
fromCursor: (cursor) => {
|
|
756
872
|
try {
|
|
757
|
-
return fromCursor(accessor,
|
|
873
|
+
return fromCursor(accessor, cursor);
|
|
758
874
|
} catch (err) {
|
|
759
|
-
|
|
760
|
-
F: __dxlog_file2,
|
|
761
|
-
L: 24,
|
|
762
|
-
S: void 0,
|
|
763
|
-
C: (f, a) => f(...a)
|
|
764
|
-
});
|
|
875
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
765
876
|
return 0;
|
|
766
877
|
}
|
|
767
878
|
}
|
|
@@ -782,7 +893,7 @@ var isReconcile = (tr) => {
|
|
|
782
893
|
|
|
783
894
|
// src/extensions/automerge/sync.ts
|
|
784
895
|
import { next as A2 } from "@automerge/automerge";
|
|
785
|
-
import { log as
|
|
896
|
+
import { log as log4 } from "@dxos/log";
|
|
786
897
|
|
|
787
898
|
// src/extensions/automerge/update-automerge.ts
|
|
788
899
|
import { next as A } from "@automerge/automerge";
|
|
@@ -923,7 +1034,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
923
1034
|
};
|
|
924
1035
|
|
|
925
1036
|
// src/extensions/automerge/sync.ts
|
|
926
|
-
var
|
|
1037
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
927
1038
|
var Syncer = class {
|
|
928
1039
|
_handle;
|
|
929
1040
|
_state;
|
|
@@ -946,12 +1057,7 @@ var Syncer = class {
|
|
|
946
1057
|
this._pending = false;
|
|
947
1058
|
}
|
|
948
1059
|
onEditorChange(view) {
|
|
949
|
-
|
|
950
|
-
F: __dxlog_file3,
|
|
951
|
-
L: 45,
|
|
952
|
-
S: this,
|
|
953
|
-
C: (f, a) => f(...a)
|
|
954
|
-
});
|
|
1060
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
955
1061
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
956
1062
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
957
1063
|
if (newHeads) {
|
|
@@ -962,12 +1068,7 @@ var Syncer = class {
|
|
|
962
1068
|
}
|
|
963
1069
|
}
|
|
964
1070
|
onAutomergeChange(view) {
|
|
965
|
-
|
|
966
|
-
F: __dxlog_file3,
|
|
967
|
-
L: 60,
|
|
968
|
-
S: this,
|
|
969
|
-
C: (f, a) => f(...a)
|
|
970
|
-
});
|
|
1071
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
971
1072
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
972
1073
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
973
1074
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1029,6 +1130,17 @@ var automerge = (accessor) => {
|
|
|
1029
1130
|
const value = DocAccessor.getValue(accessor);
|
|
1030
1131
|
const current = this._view.state.doc.toString();
|
|
1031
1132
|
if (value !== current) {
|
|
1133
|
+
this._view.dispatch({
|
|
1134
|
+
changes: {
|
|
1135
|
+
from: 0,
|
|
1136
|
+
to: this._view.state.doc.length,
|
|
1137
|
+
insert: value
|
|
1138
|
+
},
|
|
1139
|
+
annotations: [
|
|
1140
|
+
initialSync,
|
|
1141
|
+
reconcileAnnotation.of(true)
|
|
1142
|
+
]
|
|
1143
|
+
});
|
|
1032
1144
|
}
|
|
1033
1145
|
});
|
|
1034
1146
|
}
|
|
@@ -1056,7 +1168,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
|
1056
1168
|
import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1057
1169
|
import { Event } from "@dxos/async";
|
|
1058
1170
|
import { Context } from "@dxos/context";
|
|
1059
|
-
var
|
|
1171
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1060
1172
|
var dummyProvider = {
|
|
1061
1173
|
remoteStateChange: new Event(),
|
|
1062
1174
|
open: () => {
|
|
@@ -1079,10 +1191,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1079
1191
|
];
|
|
1080
1192
|
};
|
|
1081
1193
|
var RemoteSelectionsDecorator = class {
|
|
1082
|
-
_ctx = new Context(void 0, {
|
|
1083
|
-
F: __dxlog_file4,
|
|
1084
|
-
L: 80
|
|
1085
|
-
});
|
|
1194
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1086
1195
|
_cursorConverter;
|
|
1087
1196
|
_provider;
|
|
1088
1197
|
_lastAnchor;
|
|
@@ -1293,8 +1402,8 @@ var styles = EditorView7.theme({
|
|
|
1293
1402
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1294
1403
|
import { Context as Context2 } from "@dxos/context";
|
|
1295
1404
|
import { invariant } from "@dxos/invariant";
|
|
1296
|
-
import { log as
|
|
1297
|
-
var
|
|
1405
|
+
import { log as log5 } from "@dxos/log";
|
|
1406
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1298
1407
|
var DEBOUNCE_INTERVAL = 100;
|
|
1299
1408
|
var SpaceAwarenessProvider = class {
|
|
1300
1409
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1313,10 +1422,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1313
1422
|
this._info = info;
|
|
1314
1423
|
}
|
|
1315
1424
|
open() {
|
|
1316
|
-
this._ctx = new Context2(void 0, {
|
|
1317
|
-
F: __dxlog_file5,
|
|
1318
|
-
L: 57
|
|
1319
|
-
});
|
|
1425
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1320
1426
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1321
1427
|
if (this._localState) {
|
|
1322
1428
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1341,14 +1447,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1341
1447
|
void this._messenger.postMessage(this._channel, {
|
|
1342
1448
|
kind: "query"
|
|
1343
1449
|
}).catch((err) => {
|
|
1344
|
-
|
|
1450
|
+
log5.debug("failed to query awareness", {
|
|
1345
1451
|
err
|
|
1346
|
-
}, {
|
|
1347
|
-
F: __dxlog_file5,
|
|
1348
|
-
L: 91,
|
|
1349
|
-
S: this,
|
|
1350
|
-
C: (f, a) => f(...a)
|
|
1351
|
-
});
|
|
1452
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1352
1453
|
});
|
|
1353
1454
|
}
|
|
1354
1455
|
close() {
|
|
@@ -1360,15 +1461,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1360
1461
|
return Array.from(this._remoteStates.values());
|
|
1361
1462
|
}
|
|
1362
1463
|
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
|
-
});
|
|
1464
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1372
1465
|
this._localState = {
|
|
1373
1466
|
peerId: this._peerId,
|
|
1374
1467
|
position,
|
|
@@ -1377,27 +1470,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1377
1470
|
this._postTask.schedule();
|
|
1378
1471
|
}
|
|
1379
1472
|
_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
|
-
});
|
|
1473
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1389
1474
|
this._postTask.schedule();
|
|
1390
1475
|
}
|
|
1391
1476
|
_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
|
-
});
|
|
1477
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1401
1478
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1402
1479
|
this.remoteStateChange.emit();
|
|
1403
1480
|
}
|
|
@@ -1406,9 +1483,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1406
1483
|
// src/extensions/blast.ts
|
|
1407
1484
|
import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
|
|
1408
1485
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1409
|
-
import { throttle } from "@dxos/async";
|
|
1486
|
+
import { throttle as throttle2 } from "@dxos/async";
|
|
1410
1487
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1411
|
-
var
|
|
1488
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1412
1489
|
var defaultOptions = {
|
|
1413
1490
|
effect: 2,
|
|
1414
1491
|
maxParticles: 200,
|
|
@@ -1526,15 +1603,7 @@ var Blaster = class {
|
|
|
1526
1603
|
return this._node;
|
|
1527
1604
|
}
|
|
1528
1605
|
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
|
-
});
|
|
1606
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1538
1607
|
this._canvas = document.createElement("canvas");
|
|
1539
1608
|
this._canvas.id = "code-blast-canvas";
|
|
1540
1609
|
this._canvas.style.position = "absolute";
|
|
@@ -1563,15 +1632,7 @@ var Blaster = class {
|
|
|
1563
1632
|
}
|
|
1564
1633
|
}
|
|
1565
1634
|
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
|
-
});
|
|
1635
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1575
1636
|
this._running = true;
|
|
1576
1637
|
this.loop();
|
|
1577
1638
|
}
|
|
@@ -1598,11 +1659,11 @@ var Blaster = class {
|
|
|
1598
1659
|
this.drawParticles();
|
|
1599
1660
|
requestAnimationFrame(this.loop.bind(this));
|
|
1600
1661
|
}
|
|
1601
|
-
shake =
|
|
1662
|
+
shake = throttle2(({ time }) => {
|
|
1602
1663
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1603
1664
|
this._shakeTimeMax = time;
|
|
1604
1665
|
}, 100);
|
|
1605
|
-
spawn =
|
|
1666
|
+
spawn = throttle2(({ element, point }) => {
|
|
1606
1667
|
const color = getRGBComponents(element, this._options.color);
|
|
1607
1668
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1608
1669
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1776,11 +1837,11 @@ var blocks = () => [
|
|
|
1776
1837
|
".cm-line.block-line": {
|
|
1777
1838
|
paddingLeft: "0.75rem",
|
|
1778
1839
|
paddingRight: "0.75rem",
|
|
1779
|
-
borderLeft: "1px solid var(--
|
|
1780
|
-
borderRight: "1px solid var(--
|
|
1840
|
+
borderLeft: "1px solid var(--color-subdued-separator)",
|
|
1841
|
+
borderRight: "1px solid var(--color-subdued-separator)"
|
|
1781
1842
|
},
|
|
1782
1843
|
".cm-line.block-single": {
|
|
1783
|
-
border: "1px solid var(--
|
|
1844
|
+
border: "1px solid var(--color-subdued-separator)",
|
|
1784
1845
|
borderRadius: "6px",
|
|
1785
1846
|
paddingTop: "0.5rem",
|
|
1786
1847
|
paddingBottom: "0.5rem",
|
|
@@ -1788,7 +1849,7 @@ var blocks = () => [
|
|
|
1788
1849
|
marginBottom: "0.5rem"
|
|
1789
1850
|
},
|
|
1790
1851
|
".cm-line.block-first": {
|
|
1791
|
-
borderTop: "1px solid var(--
|
|
1852
|
+
borderTop: "1px solid var(--color-subdued-separator)",
|
|
1792
1853
|
borderTopLeftRadius: "6px",
|
|
1793
1854
|
borderTopRightRadius: "6px",
|
|
1794
1855
|
paddingTop: "0.5rem",
|
|
@@ -1796,7 +1857,7 @@ var blocks = () => [
|
|
|
1796
1857
|
},
|
|
1797
1858
|
".cm-line.block-middle": {},
|
|
1798
1859
|
".cm-line.block-last": {
|
|
1799
|
-
borderBottom: "1px solid var(--
|
|
1860
|
+
borderBottom: "1px solid var(--color-subdued-separator)",
|
|
1800
1861
|
borderBottomLeftRadius: "6px",
|
|
1801
1862
|
borderBottomRightRadius: "6px",
|
|
1802
1863
|
paddingBottom: "0.5rem",
|
|
@@ -1808,8 +1869,8 @@ var blocks = () => [
|
|
|
1808
1869
|
// src/extensions/bookmarks.ts
|
|
1809
1870
|
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1810
1871
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1811
|
-
import { log as
|
|
1812
|
-
var
|
|
1872
|
+
import { log as log6 } from "@dxos/log";
|
|
1873
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1813
1874
|
var addBookmark = StateEffect4.define();
|
|
1814
1875
|
var removeBookmark = StateEffect4.define();
|
|
1815
1876
|
var clearBookmarks = StateEffect4.define();
|
|
@@ -1821,12 +1882,7 @@ var bookmarks = () => {
|
|
|
1821
1882
|
key: "Mod-ArrowUp",
|
|
1822
1883
|
run: (view) => {
|
|
1823
1884
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1824
|
-
|
|
1825
|
-
F: __dxlog_file7,
|
|
1826
|
-
L: 29,
|
|
1827
|
-
S: void 0,
|
|
1828
|
-
C: (f, a) => f(...a)
|
|
1829
|
-
});
|
|
1885
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1830
1886
|
return true;
|
|
1831
1887
|
}
|
|
1832
1888
|
},
|
|
@@ -1834,12 +1890,7 @@ var bookmarks = () => {
|
|
|
1834
1890
|
key: "Mod-ArrowDown",
|
|
1835
1891
|
run: (view) => {
|
|
1836
1892
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1837
|
-
|
|
1838
|
-
F: __dxlog_file7,
|
|
1839
|
-
L: 37,
|
|
1840
|
-
S: void 0,
|
|
1841
|
-
C: (f, a) => f(...a)
|
|
1842
|
-
});
|
|
1893
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1843
1894
|
return true;
|
|
1844
1895
|
}
|
|
1845
1896
|
}
|
|
@@ -1879,19 +1930,19 @@ import { invertedEffects } from "@codemirror/commands";
|
|
|
1879
1930
|
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1880
1931
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1881
1932
|
import sortBy from "lodash.sortby";
|
|
1882
|
-
import { debounce as
|
|
1883
|
-
import { log as
|
|
1933
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
1934
|
+
import { log as log7 } from "@dxos/log";
|
|
1884
1935
|
import { isNonNullable } from "@dxos/util";
|
|
1885
1936
|
|
|
1886
1937
|
// src/extensions/selection.ts
|
|
1887
1938
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1888
1939
|
import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view";
|
|
1889
|
-
import { debounce
|
|
1940
|
+
import { debounce } from "@dxos/async";
|
|
1890
1941
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1891
1942
|
import { isTruthy } from "@dxos/util";
|
|
1892
|
-
var
|
|
1943
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1893
1944
|
var documentId = singleValueFacet();
|
|
1894
|
-
var stateRestoreAnnotation = "dxos.
|
|
1945
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1895
1946
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1896
1947
|
return {
|
|
1897
1948
|
selection,
|
|
@@ -1904,33 +1955,17 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1904
1955
|
};
|
|
1905
1956
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1906
1957
|
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
|
-
});
|
|
1958
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1916
1959
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1917
1960
|
return state ? JSON.parse(state) : void 0;
|
|
1918
1961
|
},
|
|
1919
1962
|
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
|
-
});
|
|
1963
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1929
1964
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1930
1965
|
}
|
|
1931
1966
|
});
|
|
1932
1967
|
var selectionState = ({ getState, setState } = {}) => {
|
|
1933
|
-
const setStateDebounced =
|
|
1968
|
+
const setStateDebounced = debounce(setState, 1e3);
|
|
1934
1969
|
return [
|
|
1935
1970
|
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
1936
1971
|
// EditorView.domEventHandlers({
|
|
@@ -1977,7 +2012,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1977
2012
|
};
|
|
1978
2013
|
|
|
1979
2014
|
// src/extensions/comments.ts
|
|
1980
|
-
var
|
|
2015
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1981
2016
|
var setComments = StateEffect5.define();
|
|
1982
2017
|
var setSelection = StateEffect5.define();
|
|
1983
2018
|
var setCommentState = StateEffect5.define();
|
|
@@ -2022,14 +2057,14 @@ var commentsState = StateField3.define({
|
|
|
2022
2057
|
var styles2 = EditorView11.theme({
|
|
2023
2058
|
".cm-comment, .cm-comment-current": {
|
|
2024
2059
|
padding: "3px 0",
|
|
2025
|
-
color: "var(--
|
|
2026
|
-
backgroundColor: "var(--
|
|
2060
|
+
color: "var(--color-cm-comment-text)",
|
|
2061
|
+
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2027
2062
|
},
|
|
2028
2063
|
".cm-comment > span, .cm-comment-current > span": {
|
|
2029
2064
|
boxDecorationBreak: "clone",
|
|
2030
|
-
boxShadow: "0 0 1px 3px var(--
|
|
2031
|
-
backgroundColor: "var(--
|
|
2032
|
-
color: "var(--
|
|
2065
|
+
boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
|
|
2066
|
+
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2067
|
+
color: "var(--color-cm-comment-text)",
|
|
2033
2068
|
cursor: "pointer"
|
|
2034
2069
|
}
|
|
2035
2070
|
});
|
|
@@ -2047,12 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2047
2082
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2048
2083
|
const range = comment.range;
|
|
2049
2084
|
if (!range) {
|
|
2050
|
-
|
|
2051
|
-
F: __dxlog_file9,
|
|
2052
|
-
L: 140,
|
|
2053
|
-
S: void 0,
|
|
2054
|
-
C: (f, a) => f(...a)
|
|
2055
|
-
});
|
|
2085
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2056
2086
|
return void 0;
|
|
2057
2087
|
} else if (range.from === range.to) {
|
|
2058
2088
|
return void 0;
|
|
@@ -2165,10 +2195,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2165
2195
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2166
2196
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2167
2197
|
if (!exists) {
|
|
2168
|
-
const
|
|
2198
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2169
2199
|
onUpdate({
|
|
2170
2200
|
id: comment.id,
|
|
2171
|
-
cursor
|
|
2201
|
+
cursor
|
|
2172
2202
|
});
|
|
2173
2203
|
}
|
|
2174
2204
|
}
|
|
@@ -2197,13 +2227,13 @@ var createComment = (view) => {
|
|
|
2197
2227
|
}
|
|
2198
2228
|
});
|
|
2199
2229
|
}
|
|
2200
|
-
const
|
|
2230
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2201
2231
|
from,
|
|
2202
2232
|
to
|
|
2203
2233
|
});
|
|
2204
|
-
if (
|
|
2234
|
+
if (cursor) {
|
|
2205
2235
|
options.onCreate?.({
|
|
2206
|
-
cursor
|
|
2236
|
+
cursor,
|
|
2207
2237
|
from,
|
|
2208
2238
|
location: view.coordsAtPos(from)
|
|
2209
2239
|
});
|
|
@@ -2214,7 +2244,7 @@ var createComment = (view) => {
|
|
|
2214
2244
|
var optionsFacet = singleValueFacet();
|
|
2215
2245
|
var comments = (options = {}) => {
|
|
2216
2246
|
const { key: shortcut = "meta-'" } = options;
|
|
2217
|
-
const handleSelect =
|
|
2247
|
+
const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
|
|
2218
2248
|
return [
|
|
2219
2249
|
optionsFacet.of(options),
|
|
2220
2250
|
options.id ? documentId.of(options.id) : void 0,
|
|
@@ -2392,9 +2422,9 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fro
|
|
|
2392
2422
|
// src/extensions/debug.ts
|
|
2393
2423
|
import { syntaxTree } from "@codemirror/language";
|
|
2394
2424
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
2395
|
-
var debugNodeLogger = (
|
|
2425
|
+
var debugNodeLogger = (log12 = console.log) => {
|
|
2396
2426
|
const logTokens = (state) => syntaxTree(state).iterate({
|
|
2397
|
-
enter: (node) =>
|
|
2427
|
+
enter: (node) => log12(node.type)
|
|
2398
2428
|
});
|
|
2399
2429
|
return StateField4.define({
|
|
2400
2430
|
create: (state) => logTokens(state),
|
|
@@ -2429,8 +2459,8 @@ var dropFile = (options = {}) => {
|
|
|
2429
2459
|
};
|
|
2430
2460
|
var styles3 = EditorView12.theme({
|
|
2431
2461
|
".cm-dropCursor": {
|
|
2432
|
-
borderLeft: "2px solid var(--
|
|
2433
|
-
color: "var(--
|
|
2462
|
+
borderLeft: "2px solid var(--color-accent-text)",
|
|
2463
|
+
color: "var(--color-accent-text)",
|
|
2434
2464
|
padding: "0 4px"
|
|
2435
2465
|
},
|
|
2436
2466
|
".cm-dropCursor:after": {
|
|
@@ -2444,47 +2474,66 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2444
2474
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2445
2475
|
import { searchKeymap } from "@codemirror/search";
|
|
2446
2476
|
import { EditorState } from "@codemirror/state";
|
|
2447
|
-
import { EditorView as
|
|
2477
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2448
2478
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2449
2479
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2450
2480
|
import { generateName } from "@dxos/display-name";
|
|
2451
|
-
import { log as
|
|
2481
|
+
import { log as log8 } from "@dxos/log";
|
|
2452
2482
|
import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
|
|
2453
2483
|
|
|
2454
|
-
// src/styles/
|
|
2484
|
+
// src/styles/theme.ts
|
|
2485
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
2455
2486
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2456
2487
|
var headings = {
|
|
2457
|
-
1:
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2488
|
+
1: {
|
|
2489
|
+
className: "text-3xl",
|
|
2490
|
+
fontSize: "var(--text-3xl)",
|
|
2491
|
+
lineHeight: "var(--text-4xl--line-height)"
|
|
2492
|
+
},
|
|
2493
|
+
2: {
|
|
2494
|
+
className: "text-2xl",
|
|
2495
|
+
fontSize: "var(--text-2xl)",
|
|
2496
|
+
lineHeight: "var(--text-3xl--line-height)"
|
|
2497
|
+
},
|
|
2498
|
+
3: {
|
|
2499
|
+
className: "text-xl",
|
|
2500
|
+
fontSize: "var(--text-xl)",
|
|
2501
|
+
lineHeight: "var(--text-2xl--line-height)"
|
|
2502
|
+
},
|
|
2503
|
+
4: {
|
|
2504
|
+
className: "text-lg",
|
|
2505
|
+
fontSize: "var(--text-lg)",
|
|
2506
|
+
lineHeight: "var(--text-xl--line-height)"
|
|
2507
|
+
},
|
|
2508
|
+
5: {
|
|
2509
|
+
className: "text-base",
|
|
2510
|
+
fontSize: "var(--text-base)",
|
|
2511
|
+
lineHeight: "var(--text-lg--line-height)"
|
|
2512
|
+
},
|
|
2513
|
+
6: {
|
|
2514
|
+
className: "text-base",
|
|
2515
|
+
fontSize: "var(--text-base)",
|
|
2516
|
+
lineHeight: "var(--text-base--line-height)"
|
|
2517
|
+
}
|
|
2463
2518
|
};
|
|
2519
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2520
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2464
2521
|
var markdownTheme = {
|
|
2465
|
-
code: "font-mono
|
|
2466
|
-
codeMark: "font-mono
|
|
2467
|
-
mark: "
|
|
2468
|
-
heading: (level) => {
|
|
2469
|
-
|
|
2470
|
-
|
|
2522
|
+
code: "font-mono! cm-code-inline",
|
|
2523
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2524
|
+
mark: "font-mono!",
|
|
2525
|
+
heading: (level) => ({
|
|
2526
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2527
|
+
color: "var(--color-cm-heading) !important",
|
|
2528
|
+
lineHeight: headings[level].lineHeight,
|
|
2529
|
+
fontSize: headings[level].fontSize,
|
|
2530
|
+
fontWeight: "100 !important"
|
|
2531
|
+
})
|
|
2471
2532
|
};
|
|
2472
|
-
|
|
2473
|
-
// src/styles/theme.ts
|
|
2474
|
-
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
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
2533
|
var baseTheme = EditorView13.baseTheme({
|
|
2534
|
+
/**
|
|
2535
|
+
* Outer frame.
|
|
2536
|
+
*/
|
|
2488
2537
|
"&": {},
|
|
2489
2538
|
"&.cm-focused": {
|
|
2490
2539
|
outline: "none"
|
|
@@ -2493,7 +2542,27 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2493
2542
|
* Scroller
|
|
2494
2543
|
*/
|
|
2495
2544
|
".cm-scroller": {
|
|
2496
|
-
|
|
2545
|
+
// Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
|
|
2546
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2547
|
+
// open/close) don't jump the user's view.
|
|
2548
|
+
overflowAnchor: "auto"
|
|
2549
|
+
},
|
|
2550
|
+
".cm-scroller::-webkit-scrollbar": {
|
|
2551
|
+
width: "var(--scrollbar-size,8px)",
|
|
2552
|
+
height: "var(--scrollbar-size,8px)"
|
|
2553
|
+
},
|
|
2554
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2555
|
+
background: "transparent"
|
|
2556
|
+
},
|
|
2557
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2558
|
+
background: "transparent"
|
|
2559
|
+
},
|
|
2560
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2561
|
+
background: "transparent",
|
|
2562
|
+
transition: "background 0.15s"
|
|
2563
|
+
},
|
|
2564
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2565
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2497
2566
|
},
|
|
2498
2567
|
/**
|
|
2499
2568
|
* Content
|
|
@@ -2501,7 +2570,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2501
2570
|
*/
|
|
2502
2571
|
".cm-content": {
|
|
2503
2572
|
padding: "unset",
|
|
2504
|
-
lineHeight: "24px",
|
|
2505
2573
|
color: "unset"
|
|
2506
2574
|
},
|
|
2507
2575
|
/**
|
|
@@ -2515,8 +2583,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2515
2583
|
".cm-gutter": {},
|
|
2516
2584
|
".cm-gutter.cm-lineNumbers": {
|
|
2517
2585
|
paddingRight: "4px",
|
|
2518
|
-
borderRight: "1px solid var(--
|
|
2519
|
-
color: "var(--
|
|
2586
|
+
borderRight: "1px solid var(--color-subdued-separator)",
|
|
2587
|
+
color: "var(--color-subdued)"
|
|
2520
2588
|
},
|
|
2521
2589
|
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
|
2522
2590
|
minWidth: "40px"
|
|
@@ -2532,29 +2600,36 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2532
2600
|
* Line.
|
|
2533
2601
|
*/
|
|
2534
2602
|
".cm-line": {
|
|
2535
|
-
lineHeight:
|
|
2603
|
+
lineHeight: 1.5,
|
|
2536
2604
|
paddingInline: 0
|
|
2537
2605
|
},
|
|
2606
|
+
/**
|
|
2607
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2608
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2609
|
+
*/
|
|
2610
|
+
".cm-line *": {
|
|
2611
|
+
lineHeight: "inherit"
|
|
2612
|
+
},
|
|
2538
2613
|
".cm-activeLine": {
|
|
2539
|
-
background: "var(--
|
|
2614
|
+
background: "var(--color-cm-active-line)"
|
|
2540
2615
|
},
|
|
2541
2616
|
/**
|
|
2542
2617
|
* Cursor (layer).
|
|
2543
2618
|
*/
|
|
2544
2619
|
".cm-cursor, .cm-dropCursor": {
|
|
2545
|
-
borderLeft: "2px solid var(--
|
|
2620
|
+
borderLeft: "2px solid var(--color-cm-cursor)"
|
|
2546
2621
|
},
|
|
2547
2622
|
".cm-placeholder": {
|
|
2548
|
-
color: "var(--
|
|
2623
|
+
color: "var(--color-placeholder)"
|
|
2549
2624
|
},
|
|
2550
2625
|
/**
|
|
2551
2626
|
* Selection (layer).
|
|
2552
2627
|
*/
|
|
2553
2628
|
".cm-selectionBackground": {
|
|
2554
|
-
background: "var(--
|
|
2629
|
+
background: "var(--color-cm-selection)"
|
|
2555
2630
|
},
|
|
2556
2631
|
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2557
|
-
background: "var(--
|
|
2632
|
+
background: "var(--color-cm-focused-selection)"
|
|
2558
2633
|
},
|
|
2559
2634
|
/**
|
|
2560
2635
|
* Search.
|
|
@@ -2564,8 +2639,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2564
2639
|
margin: "0 -3px",
|
|
2565
2640
|
padding: "3px",
|
|
2566
2641
|
borderRadius: "3px",
|
|
2567
|
-
background: "var(--
|
|
2568
|
-
color: "var(--
|
|
2642
|
+
background: "var(--color-cm-highlight-surface)",
|
|
2643
|
+
color: "var(--color-cm-highlight)"
|
|
2569
2644
|
},
|
|
2570
2645
|
".cm-searchMatch-selected": {
|
|
2571
2646
|
textDecoration: "underline"
|
|
@@ -2576,20 +2651,29 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2576
2651
|
".cm-link": {
|
|
2577
2652
|
textDecorationLine: "underline",
|
|
2578
2653
|
textDecorationThickness: "1px",
|
|
2579
|
-
textDecorationColor: "var(--
|
|
2654
|
+
textDecorationColor: "var(--color-separator)",
|
|
2580
2655
|
textUnderlineOffset: "2px",
|
|
2581
2656
|
borderRadius: ".125rem"
|
|
2582
2657
|
},
|
|
2583
2658
|
".cm-link > span": {
|
|
2584
|
-
color: "var(--
|
|
2659
|
+
color: "var(--color-accent-text)"
|
|
2660
|
+
},
|
|
2661
|
+
".cm-link > span:hover": {
|
|
2662
|
+
color: "var(--color-accent-text-hover)"
|
|
2585
2663
|
},
|
|
2586
2664
|
/**
|
|
2587
2665
|
* Tooltip.
|
|
2588
2666
|
*/
|
|
2589
2667
|
".cm-tooltip": {
|
|
2590
|
-
background: "var(--
|
|
2668
|
+
background: "var(--color-modal-surface)"
|
|
2591
2669
|
},
|
|
2592
2670
|
".cm-tooltip-below": {},
|
|
2671
|
+
".cm-tooltip-hover": {
|
|
2672
|
+
background: "var(--color-modal-surface)",
|
|
2673
|
+
border: "1px solid var(--color-separator)",
|
|
2674
|
+
borderRadius: "4px",
|
|
2675
|
+
overflow: "hidden"
|
|
2676
|
+
},
|
|
2593
2677
|
/**
|
|
2594
2678
|
* Autocomplete.
|
|
2595
2679
|
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
@@ -2597,7 +2681,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2597
2681
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
2598
2682
|
marginTop: "6px",
|
|
2599
2683
|
marginLeft: "-10px",
|
|
2600
|
-
border: "2px solid var(--
|
|
2684
|
+
border: "2px solid var(--color-separator)",
|
|
2601
2685
|
borderRadius: "4px"
|
|
2602
2686
|
},
|
|
2603
2687
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
@@ -2607,12 +2691,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2607
2691
|
padding: "4px"
|
|
2608
2692
|
},
|
|
2609
2693
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2610
|
-
background: "var(--
|
|
2611
|
-
color: "var(--
|
|
2694
|
+
background: "var(--color-active-surface)",
|
|
2695
|
+
color: "var(--color-base-surface-text)"
|
|
2612
2696
|
},
|
|
2613
2697
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2614
2698
|
paddingLeft: "4px !important",
|
|
2615
|
-
color: "var(--
|
|
2699
|
+
color: "var(--color-base-surface-text)"
|
|
2616
2700
|
},
|
|
2617
2701
|
/**
|
|
2618
2702
|
* Completion info.
|
|
@@ -2621,17 +2705,17 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2621
2705
|
width: "360px !important",
|
|
2622
2706
|
margin: "-10px 1px 0 1px",
|
|
2623
2707
|
padding: "8px !important",
|
|
2624
|
-
borderColor: "var(--
|
|
2708
|
+
borderColor: "var(--color-separator)"
|
|
2625
2709
|
},
|
|
2626
2710
|
".cm-completionIcon": {
|
|
2627
2711
|
display: "none"
|
|
2628
2712
|
},
|
|
2629
2713
|
".cm-completionLabel": {
|
|
2630
|
-
color: "var(--
|
|
2714
|
+
color: "var(--color-description)",
|
|
2631
2715
|
padding: "0 4px"
|
|
2632
2716
|
},
|
|
2633
2717
|
".cm-completionMatchedText": {
|
|
2634
|
-
color: "var(--
|
|
2718
|
+
color: "var(--color-base-surface-text)",
|
|
2635
2719
|
textDecoration: "none !important"
|
|
2636
2720
|
},
|
|
2637
2721
|
/**
|
|
@@ -2655,7 +2739,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2655
2739
|
backgroundColor: "var(--surface-bg)"
|
|
2656
2740
|
},
|
|
2657
2741
|
".cm-panel input, .cm-panel button, .cm-panel label": {
|
|
2658
|
-
color: "var(--
|
|
2742
|
+
color: "var(--color-subdued)",
|
|
2659
2743
|
fontSize: "14px",
|
|
2660
2744
|
all: "unset",
|
|
2661
2745
|
margin: "3px !important",
|
|
@@ -2663,10 +2747,10 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2663
2747
|
outline: "1px solid transparent"
|
|
2664
2748
|
},
|
|
2665
2749
|
".cm-panel input, .cm-panel button": {
|
|
2666
|
-
backgroundColor: "var(--
|
|
2750
|
+
backgroundColor: "var(--color-input-surface)"
|
|
2667
2751
|
},
|
|
2668
2752
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2669
|
-
outline: "1px solid var(--
|
|
2753
|
+
outline: "1px solid var(--color-neutral-focus-indicator)"
|
|
2670
2754
|
},
|
|
2671
2755
|
".cm-panel label": {
|
|
2672
2756
|
display: "inline-flex",
|
|
@@ -2679,34 +2763,33 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2679
2763
|
height: "8px",
|
|
2680
2764
|
marginRight: "6px !important",
|
|
2681
2765
|
padding: "2px !important",
|
|
2682
|
-
color: "var(--
|
|
2766
|
+
color: "var(--color-neutral-focus-indicator)"
|
|
2683
2767
|
},
|
|
2684
2768
|
".cm-panel button": {
|
|
2685
2769
|
"&:hover": {
|
|
2686
|
-
// TODO(burdon): Replace with layer and @apply bg-
|
|
2687
|
-
backgroundColor: "var(--
|
|
2770
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
|
|
2771
|
+
backgroundColor: "var(--color-accent-surface-hover) !important"
|
|
2688
2772
|
},
|
|
2689
2773
|
"&:active": {
|
|
2690
|
-
backgroundColor: "var(--
|
|
2774
|
+
backgroundColor: "var(--color-accent-surface-hover)"
|
|
2691
2775
|
}
|
|
2692
2776
|
},
|
|
2693
2777
|
".cm-panel.cm-search": {
|
|
2694
2778
|
padding: "4px",
|
|
2695
|
-
borderTop: "1px solid var(--
|
|
2779
|
+
borderTop: "1px solid var(--color-separator)"
|
|
2696
2780
|
}
|
|
2697
2781
|
});
|
|
2698
2782
|
var editorGutter = EditorView13.theme({
|
|
2699
2783
|
".cm-gutters": {
|
|
2700
2784
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2701
|
-
background: "var(--
|
|
2785
|
+
background: "var(--color-base-surface) !important",
|
|
2702
2786
|
paddingRight: "1rem"
|
|
2703
2787
|
}
|
|
2704
2788
|
});
|
|
2705
2789
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2706
|
-
//
|
|
2790
|
+
// Main content.
|
|
2707
2791
|
".cm-scroller": {
|
|
2708
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2709
|
-
fontSize: "16px"
|
|
2792
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2710
2793
|
},
|
|
2711
2794
|
// Maintain defaults for UI components.
|
|
2712
2795
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2746,9 +2829,32 @@ var focus = [
|
|
|
2746
2829
|
})
|
|
2747
2830
|
];
|
|
2748
2831
|
|
|
2832
|
+
// src/extensions/scroll-past-end.ts
|
|
2833
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2834
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2835
|
+
height = 1e3;
|
|
2836
|
+
attrs = {
|
|
2837
|
+
style: "padding-bottom: 1000px"
|
|
2838
|
+
};
|
|
2839
|
+
update({ view }) {
|
|
2840
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2841
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2842
|
+
if (height >= 0 && height !== this.height) {
|
|
2843
|
+
this.height = height;
|
|
2844
|
+
this.attrs = {
|
|
2845
|
+
style: `padding-bottom: ${height}px`
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
});
|
|
2850
|
+
var scrollPastEnd = () => [
|
|
2851
|
+
scrollPastEndPlugin,
|
|
2852
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
|
|
2853
|
+
];
|
|
2854
|
+
|
|
2749
2855
|
// src/extensions/factories.ts
|
|
2750
|
-
var
|
|
2751
|
-
var tabbable =
|
|
2856
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2857
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2752
2858
|
tabindex: "0"
|
|
2753
2859
|
});
|
|
2754
2860
|
var filterChars = (chars) => {
|
|
@@ -2801,13 +2907,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2801
2907
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2802
2908
|
return [
|
|
2803
2909
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
F: __dxlog_file10,
|
|
2807
|
-
L: 132,
|
|
2808
|
-
S: void 0,
|
|
2809
|
-
C: (f, a) => f(...a)
|
|
2810
|
-
});
|
|
2910
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2911
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2811
2912
|
}),
|
|
2812
2913
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2813
2914
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2816,7 +2917,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2816
2917
|
props.drawSelection && drawSelection({
|
|
2817
2918
|
cursorBlinkRate: 1200
|
|
2818
2919
|
}),
|
|
2819
|
-
props.editable !== void 0 &&
|
|
2920
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2820
2921
|
props.focus && focus,
|
|
2821
2922
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2822
2923
|
props.history && history(),
|
|
@@ -2824,9 +2925,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2824
2925
|
lineNumbers(),
|
|
2825
2926
|
editorGutter
|
|
2826
2927
|
],
|
|
2827
|
-
props.lineWrapping &&
|
|
2928
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2828
2929
|
props.placeholder && placeholder2(props.placeholder),
|
|
2829
2930
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2931
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2932
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2933
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2934
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2935
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2936
|
+
// depend on being able to populate the doc themselves.
|
|
2937
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2830
2938
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2831
2939
|
props.tabbable && tabbable,
|
|
2832
2940
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2856,12 +2964,12 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2856
2964
|
};
|
|
2857
2965
|
var grow = {
|
|
2858
2966
|
editor: {
|
|
2859
|
-
className: "
|
|
2967
|
+
className: "h-full w-full"
|
|
2860
2968
|
}
|
|
2861
2969
|
};
|
|
2862
2970
|
var fullWidth = {
|
|
2863
2971
|
editor: {
|
|
2864
|
-
className: "
|
|
2972
|
+
className: "w-full"
|
|
2865
2973
|
}
|
|
2866
2974
|
};
|
|
2867
2975
|
var defaultThemeSlots = grow;
|
|
@@ -2869,24 +2977,29 @@ var defaultStyles = {
|
|
|
2869
2977
|
dark: vscodeDarkStyle,
|
|
2870
2978
|
light: vscodeLightStyle
|
|
2871
2979
|
};
|
|
2872
|
-
var createThemeExtensions = ({ monospace,
|
|
2980
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2873
2981
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2874
2982
|
return [
|
|
2875
2983
|
baseTheme,
|
|
2876
|
-
|
|
2984
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2877
2985
|
createFontTheme({
|
|
2878
2986
|
monospace
|
|
2879
2987
|
}),
|
|
2880
2988
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2881
|
-
slots.editor?.className &&
|
|
2989
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2882
2990
|
class: slots.editor.className
|
|
2883
2991
|
}),
|
|
2884
|
-
slots.content?.className &&
|
|
2992
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2885
2993
|
class: slots.content.className
|
|
2886
2994
|
}),
|
|
2887
|
-
slots.
|
|
2995
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2888
2996
|
constructor(view) {
|
|
2889
|
-
|
|
2997
|
+
if (slots.scroller?.className) {
|
|
2998
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
2999
|
+
}
|
|
3000
|
+
if (scrollbarThin) {
|
|
3001
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3002
|
+
}
|
|
2890
3003
|
}
|
|
2891
3004
|
})
|
|
2892
3005
|
].filter(isTruthy2);
|
|
@@ -2904,8 +3017,8 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2904
3017
|
channel: `awareness.${id}`,
|
|
2905
3018
|
peerId: identity.identityKey.toHex(),
|
|
2906
3019
|
info: {
|
|
2907
|
-
darkColor: `var(--
|
|
2908
|
-
lightColor: `var(--
|
|
3020
|
+
darkColor: `var(--color-${hue}-border)`,
|
|
3021
|
+
lightColor: `var(--color-${hue}-border)`,
|
|
2909
3022
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex())
|
|
2910
3023
|
}
|
|
2911
3024
|
})));
|
|
@@ -2915,7 +3028,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2915
3028
|
|
|
2916
3029
|
// src/extensions/folding.ts
|
|
2917
3030
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2918
|
-
import { EditorView as
|
|
3031
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2919
3032
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2920
3033
|
var folding = () => {
|
|
2921
3034
|
return [
|
|
@@ -2923,13 +3036,14 @@ var folding = () => {
|
|
|
2923
3036
|
placeholderDOM: () => Domino2.of("span").root
|
|
2924
3037
|
}),
|
|
2925
3038
|
foldGutter({
|
|
3039
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2926
3040
|
markerDOM: (open) => {
|
|
2927
|
-
return Domino2.of("div").classNames("flex
|
|
3041
|
+
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({
|
|
2928
3042
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2929
3043
|
}))).root;
|
|
2930
3044
|
}
|
|
2931
3045
|
}),
|
|
2932
|
-
|
|
3046
|
+
EditorView17.theme({
|
|
2933
3047
|
".cm-foldGutter": {
|
|
2934
3048
|
opacity: 0.3,
|
|
2935
3049
|
transition: "opacity 0.3s",
|
|
@@ -2943,7 +3057,7 @@ var folding = () => {
|
|
|
2943
3057
|
};
|
|
2944
3058
|
|
|
2945
3059
|
// src/extensions/hashtag.ts
|
|
2946
|
-
import { Decoration as Decoration8, EditorView as
|
|
3060
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2947
3061
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
2948
3062
|
var TagWidget = class extends WidgetType4 {
|
|
2949
3063
|
_text;
|
|
@@ -2964,7 +3078,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
2964
3078
|
})
|
|
2965
3079
|
});
|
|
2966
3080
|
var hashtag = () => [
|
|
2967
|
-
|
|
3081
|
+
ViewPlugin13.fromClass(class {
|
|
2968
3082
|
tags;
|
|
2969
3083
|
constructor(view) {
|
|
2970
3084
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -2974,11 +3088,11 @@ var hashtag = () => [
|
|
|
2974
3088
|
}
|
|
2975
3089
|
}, {
|
|
2976
3090
|
decorations: (instance) => instance.tags,
|
|
2977
|
-
provide: (plugin) =>
|
|
3091
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
2978
3092
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
2979
3093
|
})
|
|
2980
3094
|
}),
|
|
2981
|
-
|
|
3095
|
+
EditorView18.theme({
|
|
2982
3096
|
".cm-tag": {
|
|
2983
3097
|
borderRadius: "4px",
|
|
2984
3098
|
marginRight: "6px",
|
|
@@ -3033,18 +3147,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3033
3147
|
};
|
|
3034
3148
|
|
|
3035
3149
|
// src/extensions/listener.ts
|
|
3036
|
-
import { EditorView as
|
|
3150
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3037
3151
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3038
3152
|
var listener = ({ onFocus, onChange }) => {
|
|
3039
3153
|
return [
|
|
3040
|
-
onFocus &&
|
|
3154
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3041
3155
|
onFocus({
|
|
3042
3156
|
id: state.facet(documentId),
|
|
3043
3157
|
focusing
|
|
3044
3158
|
});
|
|
3045
3159
|
return null;
|
|
3046
3160
|
}),
|
|
3047
|
-
onChange &&
|
|
3161
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3048
3162
|
if (docChanged) {
|
|
3049
3163
|
onChange({
|
|
3050
3164
|
id: state.facet(documentId),
|
|
@@ -3059,7 +3173,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3059
3173
|
import { snippet } from "@codemirror/autocomplete";
|
|
3060
3174
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3061
3175
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3062
|
-
import { EditorView as
|
|
3176
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3063
3177
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3064
3178
|
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;
|
|
3065
3179
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4148,7 +4262,7 @@ var getFormatting = (state) => {
|
|
|
4148
4262
|
};
|
|
4149
4263
|
};
|
|
4150
4264
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4151
|
-
return
|
|
4265
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4152
4266
|
if (update2.docChanged || update2.selectionSet) {
|
|
4153
4267
|
onStateChange(getFormatting(update2.state));
|
|
4154
4268
|
}
|
|
@@ -4209,8 +4323,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4209
4323
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4210
4324
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4211
4325
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4212
|
-
import {
|
|
4213
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4326
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4214
4327
|
import { languages } from "@codemirror/language-data";
|
|
4215
4328
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4216
4329
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4331,30 +4444,38 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4331
4444
|
],
|
|
4332
4445
|
class: "font-mono"
|
|
4333
4446
|
},
|
|
4334
|
-
// Headings
|
|
4447
|
+
// Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
|
|
4448
|
+
// StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
|
|
4449
|
+
// HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
|
|
4450
|
+
// Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
|
|
4451
|
+
{
|
|
4452
|
+
tag: tags.heading,
|
|
4453
|
+
color: "var(--color-cm-heading) !important",
|
|
4454
|
+
fontWeight: "300"
|
|
4455
|
+
},
|
|
4335
4456
|
{
|
|
4336
4457
|
tag: tags.heading1,
|
|
4337
|
-
|
|
4458
|
+
...markdownTheme.heading(1)
|
|
4338
4459
|
},
|
|
4339
4460
|
{
|
|
4340
4461
|
tag: tags.heading2,
|
|
4341
|
-
|
|
4462
|
+
...markdownTheme.heading(2)
|
|
4342
4463
|
},
|
|
4343
4464
|
{
|
|
4344
4465
|
tag: tags.heading3,
|
|
4345
|
-
|
|
4466
|
+
...markdownTheme.heading(3)
|
|
4346
4467
|
},
|
|
4347
4468
|
{
|
|
4348
4469
|
tag: tags.heading4,
|
|
4349
|
-
|
|
4470
|
+
...markdownTheme.heading(4)
|
|
4350
4471
|
},
|
|
4351
4472
|
{
|
|
4352
4473
|
tag: tags.heading5,
|
|
4353
|
-
|
|
4474
|
+
...markdownTheme.heading(5)
|
|
4354
4475
|
},
|
|
4355
4476
|
{
|
|
4356
4477
|
tag: tags.heading6,
|
|
4357
|
-
|
|
4478
|
+
...markdownTheme.heading(6)
|
|
4358
4479
|
},
|
|
4359
4480
|
// Emphasis.
|
|
4360
4481
|
{
|
|
@@ -4409,15 +4530,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4409
4530
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4410
4531
|
base: markdownLanguage2,
|
|
4411
4532
|
// Languages for syntax highlighting fenced code blocks.
|
|
4533
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4412
4534
|
defaultCodeLanguage: jsonLanguage,
|
|
4413
|
-
codeLanguages:
|
|
4535
|
+
codeLanguages: [
|
|
4536
|
+
...options.codeLanguages ?? [],
|
|
4537
|
+
...languages
|
|
4538
|
+
],
|
|
4414
4539
|
// Don't complete HTML tags.
|
|
4415
4540
|
completeHTMLTags: false,
|
|
4416
4541
|
// Parser extensions.
|
|
4417
4542
|
extensions: [
|
|
4418
4543
|
// GFM provided by default.
|
|
4419
4544
|
markdownTagsExtensions,
|
|
4420
|
-
...options.extensions ?? defaultExtensions()
|
|
4545
|
+
...options.extensions ?? defaultExtensions(),
|
|
4546
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4547
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4548
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4549
|
+
noFencedCodeFolding
|
|
4421
4550
|
]
|
|
4422
4551
|
}),
|
|
4423
4552
|
// Custom styles.
|
|
@@ -4432,18 +4561,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4432
4561
|
].filter(isTruthy3))
|
|
4433
4562
|
];
|
|
4434
4563
|
};
|
|
4435
|
-
var
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
]
|
|
4441
|
-
|
|
4442
|
-
"xml",
|
|
4443
|
-
"xhtml"
|
|
4444
|
-
],
|
|
4445
|
-
load: async () => xml()
|
|
4446
|
-
});
|
|
4564
|
+
var noFencedCodeFolding = {
|
|
4565
|
+
props: [
|
|
4566
|
+
foldNodeProp.add({
|
|
4567
|
+
FencedCode: () => null
|
|
4568
|
+
})
|
|
4569
|
+
]
|
|
4570
|
+
};
|
|
4447
4571
|
var defaultExtensions = () => [
|
|
4448
4572
|
noSetExtHeading,
|
|
4449
4573
|
noHtml
|
|
@@ -4463,19 +4587,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4463
4587
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4464
4588
|
});
|
|
4465
4589
|
var convertTreeToJson = (state) => {
|
|
4466
|
-
const treeToJson = (
|
|
4590
|
+
const treeToJson = (cursor) => {
|
|
4467
4591
|
const node = {
|
|
4468
|
-
type:
|
|
4469
|
-
from:
|
|
4470
|
-
to:
|
|
4471
|
-
text: state.doc.slice(
|
|
4592
|
+
type: cursor.type.name,
|
|
4593
|
+
from: cursor.from,
|
|
4594
|
+
to: cursor.to,
|
|
4595
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4472
4596
|
children: []
|
|
4473
4597
|
};
|
|
4474
|
-
if (
|
|
4598
|
+
if (cursor.firstChild()) {
|
|
4475
4599
|
do {
|
|
4476
|
-
node.children.push(treeToJson(
|
|
4477
|
-
} while (
|
|
4478
|
-
|
|
4600
|
+
node.children.push(treeToJson(cursor));
|
|
4601
|
+
} while (cursor.nextSibling());
|
|
4602
|
+
cursor.parent();
|
|
4479
4603
|
}
|
|
4480
4604
|
return node;
|
|
4481
4605
|
};
|
|
@@ -4485,16 +4609,15 @@ var convertTreeToJson = (state) => {
|
|
|
4485
4609
|
// src/extensions/markdown/decorate.ts
|
|
4486
4610
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4487
4611
|
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4488
|
-
import { Decoration as Decoration11, EditorView as
|
|
4612
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4489
4613
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4490
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4491
4614
|
|
|
4492
4615
|
// src/extensions/markdown/changes.ts
|
|
4493
4616
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4494
4617
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4495
|
-
import { ViewPlugin as
|
|
4618
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4496
4619
|
var adjustChanges = () => {
|
|
4497
|
-
return
|
|
4620
|
+
return ViewPlugin14.fromClass(class {
|
|
4498
4621
|
update(update2) {
|
|
4499
4622
|
const tree = syntaxTree4(update2.state);
|
|
4500
4623
|
const adjustments = [];
|
|
@@ -4636,7 +4759,7 @@ var getValidUrl = (str) => {
|
|
|
4636
4759
|
// src/extensions/markdown/image.ts
|
|
4637
4760
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4638
4761
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4639
|
-
import { Decoration as Decoration9, EditorView as
|
|
4762
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4640
4763
|
var image = (_options = {}) => {
|
|
4641
4764
|
return [
|
|
4642
4765
|
StateField7.define({
|
|
@@ -4647,10 +4770,10 @@ var image = (_options = {}) => {
|
|
|
4647
4770
|
if (!tr.docChanged && !tr.selection) {
|
|
4648
4771
|
return value;
|
|
4649
4772
|
}
|
|
4650
|
-
const
|
|
4773
|
+
const cursor = tr.state.selection.main.head;
|
|
4651
4774
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4652
|
-
let from = Math.min(
|
|
4653
|
-
let to = Math.max(
|
|
4775
|
+
let from = Math.min(cursor, oldCursor);
|
|
4776
|
+
let to = Math.max(cursor, oldCursor);
|
|
4654
4777
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4655
4778
|
from = Math.min(from, fromB);
|
|
4656
4779
|
to = Math.max(to, toB);
|
|
@@ -4664,19 +4787,19 @@ var image = (_options = {}) => {
|
|
|
4664
4787
|
add: buildDecorations(tr.state, from, to)
|
|
4665
4788
|
});
|
|
4666
4789
|
},
|
|
4667
|
-
provide: (field) =>
|
|
4790
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4668
4791
|
})
|
|
4669
4792
|
];
|
|
4670
4793
|
};
|
|
4671
4794
|
var buildDecorations = (state, from, to) => {
|
|
4672
4795
|
const decorations2 = [];
|
|
4673
|
-
const
|
|
4796
|
+
const cursor = state.selection.main.head;
|
|
4674
4797
|
syntaxTree5(state).iterate({
|
|
4675
4798
|
enter: (node) => {
|
|
4676
4799
|
if (node.name === "Image") {
|
|
4677
4800
|
const urlNode = node.node.getChild("URL");
|
|
4678
4801
|
if (urlNode) {
|
|
4679
|
-
const hide2 = state.readOnly ||
|
|
4802
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4680
4803
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4681
4804
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4682
4805
|
return;
|
|
@@ -4724,10 +4847,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4724
4847
|
};
|
|
4725
4848
|
|
|
4726
4849
|
// src/extensions/markdown/styles.ts
|
|
4727
|
-
import { EditorView as
|
|
4850
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4728
4851
|
var bulletListIndentationWidth = 24;
|
|
4729
4852
|
var orderedListIndentationWidth = 36;
|
|
4730
|
-
var formattingStyles =
|
|
4853
|
+
var formattingStyles = EditorView22.theme({
|
|
4731
4854
|
/**
|
|
4732
4855
|
* Horizontal rule.
|
|
4733
4856
|
*/
|
|
@@ -4736,7 +4859,7 @@ var formattingStyles = EditorView21.theme({
|
|
|
4736
4859
|
width: "100%",
|
|
4737
4860
|
height: "0",
|
|
4738
4861
|
verticalAlign: "middle",
|
|
4739
|
-
borderTop: "1px solid var(--
|
|
4862
|
+
borderTop: "1px solid var(--color-cm-separator)",
|
|
4740
4863
|
opacity: 0.5
|
|
4741
4864
|
},
|
|
4742
4865
|
/**
|
|
@@ -4759,22 +4882,47 @@ var formattingStyles = EditorView21.theme({
|
|
|
4759
4882
|
* Blockquote.
|
|
4760
4883
|
*/
|
|
4761
4884
|
"& .cm-blockquote": {
|
|
4762
|
-
background: "var(--
|
|
4763
|
-
borderLeft: "2px solid var(--
|
|
4885
|
+
background: "var(--color-cm-codeblock)",
|
|
4886
|
+
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4764
4887
|
paddingLeft: "1rem",
|
|
4765
|
-
margin:
|
|
4888
|
+
margin: 0
|
|
4766
4889
|
},
|
|
4767
4890
|
/**
|
|
4768
4891
|
* Code and codeblocks.
|
|
4769
4892
|
*/
|
|
4770
|
-
"&
|
|
4771
|
-
fontFamily: fontMono
|
|
4893
|
+
"& code": {
|
|
4894
|
+
fontFamily: fontMono,
|
|
4895
|
+
color: "var(--color-cm-code)",
|
|
4896
|
+
whiteSpace: "nowrap"
|
|
4772
4897
|
},
|
|
4773
|
-
"& .cm-
|
|
4774
|
-
|
|
4775
|
-
|
|
4898
|
+
"& .cm-code": {
|
|
4899
|
+
fontFamily: fontMono,
|
|
4900
|
+
color: "var(--color-cm-code)"
|
|
4776
4901
|
},
|
|
4777
|
-
|
|
4902
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4903
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4904
|
+
// so constrain them to the target 24px height.
|
|
4905
|
+
"& .cm-code-inline": {
|
|
4906
|
+
fontFamily: fontMono,
|
|
4907
|
+
height: "24px",
|
|
4908
|
+
// display: 'inline-flex',
|
|
4909
|
+
alignItems: "center",
|
|
4910
|
+
overflow: "hidden",
|
|
4911
|
+
whiteSpace: "nowrap",
|
|
4912
|
+
color: "var(--color-cm-code-inline)"
|
|
4913
|
+
},
|
|
4914
|
+
"& .cm-code-mark": {
|
|
4915
|
+
fontFamily: fontMono,
|
|
4916
|
+
height: "24px",
|
|
4917
|
+
display: "inline-flex",
|
|
4918
|
+
alignItems: "center",
|
|
4919
|
+
overflow: "hidden"
|
|
4920
|
+
},
|
|
4921
|
+
"& .cm-codeblock-line": {
|
|
4922
|
+
background: "var(--color-cm-codeblock)",
|
|
4923
|
+
paddingInline: "1rem !important"
|
|
4924
|
+
},
|
|
4925
|
+
"& .cm-codeblock-start": {
|
|
4778
4926
|
borderTopLeftRadius: ".25rem",
|
|
4779
4927
|
borderTopRightRadius: ".25rem"
|
|
4780
4928
|
},
|
|
@@ -4800,16 +4948,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4800
4948
|
*/
|
|
4801
4949
|
".cm-table *": {
|
|
4802
4950
|
fontFamily: fontMono,
|
|
4951
|
+
lineHeight: 1.5,
|
|
4803
4952
|
textDecoration: "none !important"
|
|
4804
4953
|
},
|
|
4805
4954
|
".cm-table-head": {
|
|
4806
4955
|
padding: "2px 16px 2px 0px",
|
|
4956
|
+
overflowWrap: "break-word",
|
|
4957
|
+
whiteSpace: "pre-wrap",
|
|
4958
|
+
wordBreak: "keep-all",
|
|
4807
4959
|
textAlign: "left",
|
|
4808
|
-
|
|
4809
|
-
|
|
4960
|
+
color: "var(--color-subdued)",
|
|
4961
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4810
4962
|
},
|
|
4811
4963
|
".cm-table-cell": {
|
|
4812
|
-
padding: "2px 16px 2px 0px"
|
|
4964
|
+
padding: "2px 16px 2px 0px",
|
|
4965
|
+
overflowWrap: "break-word",
|
|
4966
|
+
whiteSpace: "pre-wrap",
|
|
4967
|
+
wordBreak: "keep-all",
|
|
4968
|
+
verticalAlign: "top"
|
|
4813
4969
|
},
|
|
4814
4970
|
/**
|
|
4815
4971
|
* Image.
|
|
@@ -4825,12 +4981,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4825
4981
|
},
|
|
4826
4982
|
".cm-image-with-loader": {
|
|
4827
4983
|
display: "block",
|
|
4828
|
-
opacity:
|
|
4984
|
+
opacity: 0,
|
|
4829
4985
|
transitionDuration: "350ms",
|
|
4830
4986
|
transitionProperty: "opacity"
|
|
4831
4987
|
},
|
|
4832
4988
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4833
|
-
opacity:
|
|
4989
|
+
opacity: 1
|
|
4834
4990
|
},
|
|
4835
4991
|
".cm-image-wrapper": {
|
|
4836
4992
|
"grid-template-columns": "1fr",
|
|
@@ -4849,17 +5005,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4849
5005
|
// src/extensions/markdown/table.ts
|
|
4850
5006
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4851
5007
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4852
|
-
import { Decoration as Decoration10, EditorView as
|
|
5008
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4853
5009
|
var table = (options = {}) => {
|
|
4854
5010
|
return StateField8.define({
|
|
4855
5011
|
create: (state) => update(state, options),
|
|
4856
5012
|
update: (_, tr) => update(tr.state, options),
|
|
4857
|
-
provide: (field) =>
|
|
5013
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4858
5014
|
});
|
|
4859
5015
|
};
|
|
4860
5016
|
var update = (state, _options) => {
|
|
4861
5017
|
const builder = new RangeSetBuilder4();
|
|
4862
|
-
const
|
|
5018
|
+
const cursor = state.selection.main.head;
|
|
4863
5019
|
const tables = [];
|
|
4864
5020
|
const getTable = () => tables[tables.length - 1];
|
|
4865
5021
|
const getRow = () => {
|
|
@@ -4897,7 +5053,7 @@ var update = (state, _options) => {
|
|
|
4897
5053
|
}
|
|
4898
5054
|
});
|
|
4899
5055
|
tables.forEach((table2) => {
|
|
4900
|
-
const replace = state.readOnly ||
|
|
5056
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4901
5057
|
if (replace) {
|
|
4902
5058
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4903
5059
|
block: true,
|
|
@@ -4911,6 +5067,26 @@ var update = (state, _options) => {
|
|
|
4911
5067
|
});
|
|
4912
5068
|
return builder.finish();
|
|
4913
5069
|
};
|
|
5070
|
+
var renderCellContent = (el, text) => {
|
|
5071
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5072
|
+
for (const part of parts) {
|
|
5073
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5074
|
+
const code = document.createElement("code");
|
|
5075
|
+
code.textContent = part.slice(1, -1);
|
|
5076
|
+
el.appendChild(code);
|
|
5077
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5078
|
+
const strong = document.createElement("strong");
|
|
5079
|
+
strong.textContent = part.slice(2, -2);
|
|
5080
|
+
el.appendChild(strong);
|
|
5081
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5082
|
+
const em = document.createElement("em");
|
|
5083
|
+
em.textContent = part.slice(1, -1);
|
|
5084
|
+
el.appendChild(em);
|
|
5085
|
+
} else {
|
|
5086
|
+
el.appendChild(document.createTextNode(part));
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
};
|
|
4914
5090
|
var TableWidget = class extends WidgetType6 {
|
|
4915
5091
|
_table;
|
|
4916
5092
|
constructor(_table) {
|
|
@@ -4930,7 +5106,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4930
5106
|
this._table.header?.forEach((cell) => {
|
|
4931
5107
|
const th = document.createElement("th");
|
|
4932
5108
|
th.setAttribute("class", "cm-table-head");
|
|
4933
|
-
tr.appendChild(th)
|
|
5109
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
4934
5110
|
});
|
|
4935
5111
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
4936
5112
|
this._table.rows?.forEach((row) => {
|
|
@@ -4938,7 +5114,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4938
5114
|
row.forEach((cell) => {
|
|
4939
5115
|
const td = document.createElement("td");
|
|
4940
5116
|
td.setAttribute("class", "cm-table-cell");
|
|
4941
|
-
tr2.appendChild(td)
|
|
5117
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
4942
5118
|
});
|
|
4943
5119
|
});
|
|
4944
5120
|
return div;
|
|
@@ -4946,7 +5122,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4946
5122
|
};
|
|
4947
5123
|
|
|
4948
5124
|
// src/extensions/markdown/decorate.ts
|
|
4949
|
-
var
|
|
5125
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
|
|
4950
5126
|
var Unicode = {
|
|
4951
5127
|
emDash: "\u2014",
|
|
4952
5128
|
bullet: "\u2022",
|
|
@@ -4969,7 +5145,6 @@ var LinkButton = class extends WidgetType7 {
|
|
|
4969
5145
|
eq(other) {
|
|
4970
5146
|
return this.url === other.url;
|
|
4971
5147
|
}
|
|
4972
|
-
// TODO(burdon): Create icon and link directly without react?
|
|
4973
5148
|
toDOM(view) {
|
|
4974
5149
|
const el = document.createElement("span");
|
|
4975
5150
|
this.render(el, {
|
|
@@ -5046,10 +5221,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5046
5221
|
class: "cm-code cm-codeblock-line"
|
|
5047
5222
|
});
|
|
5048
5223
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5049
|
-
class:
|
|
5224
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5050
5225
|
});
|
|
5051
5226
|
var fencedCodeLineLast = Decoration11.line({
|
|
5052
|
-
class:
|
|
5227
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5053
5228
|
});
|
|
5054
5229
|
var commentBlockLine = fencedCodeLine;
|
|
5055
5230
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5081,15 +5256,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5081
5256
|
const { state } = view;
|
|
5082
5257
|
const headerLevels = [];
|
|
5083
5258
|
const getHeaderLevels = (node, level) => {
|
|
5084
|
-
invariant4(level > 0, void 0, {
|
|
5085
|
-
F: __dxlog_file11,
|
|
5086
|
-
L: 180,
|
|
5087
|
-
S: void 0,
|
|
5088
|
-
A: [
|
|
5089
|
-
"level > 0",
|
|
5090
|
-
""
|
|
5091
|
-
]
|
|
5092
|
-
});
|
|
5259
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5093
5260
|
if (level > headerLevels.length) {
|
|
5094
5261
|
const len = headerLevels.length;
|
|
5095
5262
|
headerLevels.length = level;
|
|
@@ -5120,15 +5287,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5120
5287
|
listLevels.pop();
|
|
5121
5288
|
};
|
|
5122
5289
|
const getCurrentListLevel = () => {
|
|
5123
|
-
invariant4(listLevels.length, void 0, {
|
|
5124
|
-
F: __dxlog_file11,
|
|
5125
|
-
L: 202,
|
|
5126
|
-
S: void 0,
|
|
5127
|
-
A: [
|
|
5128
|
-
"listLevels.length",
|
|
5129
|
-
""
|
|
5130
|
-
]
|
|
5131
|
-
});
|
|
5290
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5132
5291
|
return listLevels[listLevels.length - 1];
|
|
5133
5292
|
};
|
|
5134
5293
|
const enterNode = (node) => {
|
|
@@ -5166,13 +5325,13 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5166
5325
|
deco: hide
|
|
5167
5326
|
});
|
|
5168
5327
|
} else {
|
|
5169
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5328
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5170
5329
|
if (num.length) {
|
|
5171
5330
|
atomicDecoRanges.push({
|
|
5172
5331
|
from: mark.from,
|
|
5173
5332
|
to: mark.from + len,
|
|
5174
5333
|
deco: Decoration11.replace({
|
|
5175
|
-
widget: new TextWidget(num, markdownTheme.heading(level))
|
|
5334
|
+
widget: new TextWidget(num, markdownTheme.heading(level).className)
|
|
5176
5335
|
})
|
|
5177
5336
|
});
|
|
5178
5337
|
}
|
|
@@ -5349,11 +5508,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5349
5508
|
}
|
|
5350
5509
|
decoRanges.push({
|
|
5351
5510
|
from: marks[0].to,
|
|
5352
|
-
to: marks[1].from,
|
|
5511
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5353
5512
|
deco: Decoration11.mark({
|
|
5354
5513
|
tagName: "a",
|
|
5355
5514
|
attributes: {
|
|
5356
|
-
class: "cm-link",
|
|
5515
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5357
5516
|
href: url,
|
|
5358
5517
|
rel: "noreferrer",
|
|
5359
5518
|
target: "_blank"
|
|
@@ -5431,8 +5590,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5431
5590
|
deco.add(from, to, d);
|
|
5432
5591
|
}
|
|
5433
5592
|
const atomicDeco = new RangeSetBuilder5();
|
|
5434
|
-
for (const { from, to, deco:
|
|
5435
|
-
|
|
5593
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5594
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5595
|
+
continue;
|
|
5596
|
+
}
|
|
5597
|
+
atomicDeco.add(from, to, deco2);
|
|
5436
5598
|
}
|
|
5437
5599
|
return {
|
|
5438
5600
|
deco: deco.finish(),
|
|
@@ -5442,7 +5604,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5442
5604
|
var forceUpdate = StateEffect7.define();
|
|
5443
5605
|
var decorateMarkdown = (options = {}) => {
|
|
5444
5606
|
return [
|
|
5445
|
-
|
|
5607
|
+
ViewPlugin15.fromClass(class {
|
|
5446
5608
|
deco;
|
|
5447
5609
|
atomicDeco;
|
|
5448
5610
|
pendingUpdate;
|
|
@@ -5477,9 +5639,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5477
5639
|
}
|
|
5478
5640
|
}, {
|
|
5479
5641
|
provide: (plugin) => [
|
|
5480
|
-
Prec4.low(
|
|
5481
|
-
|
|
5482
|
-
|
|
5642
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5643
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5644
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5483
5645
|
]
|
|
5484
5646
|
}),
|
|
5485
5647
|
image(),
|
|
@@ -5511,8 +5673,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5511
5673
|
return {
|
|
5512
5674
|
pos: link.from,
|
|
5513
5675
|
end: link.to,
|
|
5514
|
-
|
|
5515
|
-
// above: true,
|
|
5676
|
+
above: true,
|
|
5516
5677
|
create: () => {
|
|
5517
5678
|
const el = document.createElement("div");
|
|
5518
5679
|
el.className = tooltipContent({});
|
|
@@ -5528,16 +5689,13 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5528
5689
|
};
|
|
5529
5690
|
}
|
|
5530
5691
|
};
|
|
5531
|
-
}, {
|
|
5532
|
-
// NOTE: 0 = default of 300ms.
|
|
5533
|
-
hoverTime: 1
|
|
5534
5692
|
});
|
|
5535
5693
|
};
|
|
5536
5694
|
|
|
5537
5695
|
// src/extensions/mention.ts
|
|
5538
5696
|
import { autocompletion } from "@codemirror/autocomplete";
|
|
5539
|
-
import { log as
|
|
5540
|
-
var
|
|
5697
|
+
import { log as log9 } from "@dxos/log";
|
|
5698
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
|
|
5541
5699
|
var mention = ({ debug, onSearch }) => {
|
|
5542
5700
|
return autocompletion({
|
|
5543
5701
|
// TODO(burdon): Not working.
|
|
@@ -5549,14 +5707,9 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5549
5707
|
icons: false,
|
|
5550
5708
|
override: [
|
|
5551
5709
|
(context) => {
|
|
5552
|
-
|
|
5710
|
+
log9.info("completion context", {
|
|
5553
5711
|
context
|
|
5554
|
-
}, {
|
|
5555
|
-
F: __dxlog_file12,
|
|
5556
|
-
L: 27,
|
|
5557
|
-
S: void 0,
|
|
5558
|
-
C: (f, a) => f(...a)
|
|
5559
|
-
});
|
|
5712
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5560
5713
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5561
5714
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5562
5715
|
return null;
|
|
@@ -5635,7 +5788,7 @@ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
|
|
5635
5788
|
import { StateField as StateField10 } from "@codemirror/state";
|
|
5636
5789
|
import { Facet as Facet2 } from "@codemirror/state";
|
|
5637
5790
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
5638
|
-
var
|
|
5791
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
|
|
5639
5792
|
var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
|
|
5640
5793
|
return {
|
|
5641
5794
|
type,
|
|
@@ -5789,15 +5942,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5789
5942
|
break;
|
|
5790
5943
|
}
|
|
5791
5944
|
case "BulletList": {
|
|
5792
|
-
invariant5(current, void 0, {
|
|
5793
|
-
F: __dxlog_file13,
|
|
5794
|
-
L: 219,
|
|
5795
|
-
S: void 0,
|
|
5796
|
-
A: [
|
|
5797
|
-
"current",
|
|
5798
|
-
""
|
|
5799
|
-
]
|
|
5800
|
-
});
|
|
5945
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5801
5946
|
parent = current;
|
|
5802
5947
|
if (current) {
|
|
5803
5948
|
current.lineRange.to = current.node.from;
|
|
@@ -5806,15 +5951,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5806
5951
|
break;
|
|
5807
5952
|
}
|
|
5808
5953
|
case "ListItem": {
|
|
5809
|
-
invariant5(parent, void 0, {
|
|
5810
|
-
F: __dxlog_file13,
|
|
5811
|
-
L: 228,
|
|
5812
|
-
S: void 0,
|
|
5813
|
-
A: [
|
|
5814
|
-
"parent",
|
|
5815
|
-
""
|
|
5816
|
-
]
|
|
5817
|
-
});
|
|
5954
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5818
5955
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5819
5956
|
const docRange = {
|
|
5820
5957
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5848,42 +5985,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5848
5985
|
break;
|
|
5849
5986
|
}
|
|
5850
5987
|
case "ListMark": {
|
|
5851
|
-
invariant5(current, void 0, {
|
|
5852
|
-
F: __dxlog_file13,
|
|
5853
|
-
L: 272,
|
|
5854
|
-
S: void 0,
|
|
5855
|
-
A: [
|
|
5856
|
-
"current",
|
|
5857
|
-
""
|
|
5858
|
-
]
|
|
5859
|
-
});
|
|
5988
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5860
5989
|
current.type = "bullet";
|
|
5861
5990
|
current.contentRange.from = node.from + "- ".length;
|
|
5862
5991
|
break;
|
|
5863
5992
|
}
|
|
5864
5993
|
case "Task": {
|
|
5865
|
-
invariant5(current, void 0, {
|
|
5866
|
-
F: __dxlog_file13,
|
|
5867
|
-
L: 278,
|
|
5868
|
-
S: void 0,
|
|
5869
|
-
A: [
|
|
5870
|
-
"current",
|
|
5871
|
-
""
|
|
5872
|
-
]
|
|
5873
|
-
});
|
|
5994
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5874
5995
|
current.type = "task";
|
|
5875
5996
|
break;
|
|
5876
5997
|
}
|
|
5877
5998
|
case "TaskMarker": {
|
|
5878
|
-
invariant5(current, void 0, {
|
|
5879
|
-
F: __dxlog_file13,
|
|
5880
|
-
L: 283,
|
|
5881
|
-
S: void 0,
|
|
5882
|
-
A: [
|
|
5883
|
-
"current",
|
|
5884
|
-
""
|
|
5885
|
-
]
|
|
5886
|
-
});
|
|
5999
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5887
6000
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5888
6001
|
break;
|
|
5889
6002
|
}
|
|
@@ -5891,29 +6004,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5891
6004
|
},
|
|
5892
6005
|
leave: (node) => {
|
|
5893
6006
|
if (node.name === "BulletList") {
|
|
5894
|
-
invariant5(parent, void 0, {
|
|
5895
|
-
F: __dxlog_file13,
|
|
5896
|
-
L: 291,
|
|
5897
|
-
S: void 0,
|
|
5898
|
-
A: [
|
|
5899
|
-
"parent",
|
|
5900
|
-
""
|
|
5901
|
-
]
|
|
5902
|
-
});
|
|
6007
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5903
6008
|
prevSiblings[level--] = void 0;
|
|
5904
6009
|
parent = parent.parent;
|
|
5905
6010
|
}
|
|
5906
6011
|
}
|
|
5907
6012
|
});
|
|
5908
|
-
invariant5(tree, void 0, {
|
|
5909
|
-
F: __dxlog_file13,
|
|
5910
|
-
L: 298,
|
|
5911
|
-
S: void 0,
|
|
5912
|
-
A: [
|
|
5913
|
-
"tree",
|
|
5914
|
-
""
|
|
5915
|
-
]
|
|
5916
|
-
});
|
|
6013
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5917
6014
|
return tree;
|
|
5918
6015
|
};
|
|
5919
6016
|
return [
|
|
@@ -6198,17 +6295,17 @@ var commands = () => keymap11.of([
|
|
|
6198
6295
|
|
|
6199
6296
|
// src/extensions/outliner/outliner.ts
|
|
6200
6297
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6201
|
-
import { Decoration as Decoration12, EditorView as
|
|
6202
|
-
import { mx as
|
|
6298
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6299
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6203
6300
|
|
|
6204
6301
|
// src/extensions/outliner/editor.ts
|
|
6205
6302
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6206
|
-
import { ViewPlugin as
|
|
6207
|
-
import { log as
|
|
6208
|
-
var
|
|
6303
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6304
|
+
import { log as log10 } from "@dxos/log";
|
|
6305
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6209
6306
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6210
6307
|
var initialize = () => {
|
|
6211
|
-
return
|
|
6308
|
+
return ViewPlugin16.fromClass(class {
|
|
6212
6309
|
constructor(view) {
|
|
6213
6310
|
const first = view.state.doc.lineAt(0);
|
|
6214
6311
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6337,7 +6434,7 @@ var editor = () => [
|
|
|
6337
6434
|
cancel = true;
|
|
6338
6435
|
return;
|
|
6339
6436
|
}
|
|
6340
|
-
|
|
6437
|
+
log10("change", {
|
|
6341
6438
|
item,
|
|
6342
6439
|
line: {
|
|
6343
6440
|
from: line.from,
|
|
@@ -6355,35 +6452,20 @@ var editor = () => [
|
|
|
6355
6452
|
text: insert.toString(),
|
|
6356
6453
|
length: insert.length
|
|
6357
6454
|
}
|
|
6358
|
-
}, {
|
|
6359
|
-
F: __dxlog_file14,
|
|
6360
|
-
L: 164,
|
|
6361
|
-
S: void 0,
|
|
6362
|
-
C: (f, a) => f(...a)
|
|
6363
|
-
});
|
|
6455
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6364
6456
|
}
|
|
6365
6457
|
});
|
|
6366
6458
|
if (changes.length > 0) {
|
|
6367
|
-
|
|
6459
|
+
log10("modified,", {
|
|
6368
6460
|
changes
|
|
6369
|
-
}, {
|
|
6370
|
-
F: __dxlog_file14,
|
|
6371
|
-
L: 175,
|
|
6372
|
-
S: void 0,
|
|
6373
|
-
C: (f, a) => f(...a)
|
|
6374
|
-
});
|
|
6461
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6375
6462
|
return [
|
|
6376
6463
|
{
|
|
6377
6464
|
changes
|
|
6378
6465
|
}
|
|
6379
6466
|
];
|
|
6380
6467
|
} else if (cancel) {
|
|
6381
|
-
|
|
6382
|
-
F: __dxlog_file14,
|
|
6383
|
-
L: 178,
|
|
6384
|
-
S: void 0,
|
|
6385
|
-
C: (f, a) => f(...a)
|
|
6386
|
-
});
|
|
6468
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6387
6469
|
return [];
|
|
6388
6470
|
}
|
|
6389
6471
|
return tr;
|
|
@@ -6391,10 +6473,10 @@ var editor = () => [
|
|
|
6391
6473
|
];
|
|
6392
6474
|
|
|
6393
6475
|
// src/extensions/outliner/menu.ts
|
|
6394
|
-
import { EditorView as
|
|
6395
|
-
import { addEventListener } from "@dxos/async";
|
|
6476
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6477
|
+
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6396
6478
|
var menu = (options = {}) => [
|
|
6397
|
-
|
|
6479
|
+
ViewPlugin17.fromClass(class {
|
|
6398
6480
|
view;
|
|
6399
6481
|
tag;
|
|
6400
6482
|
rafId;
|
|
@@ -6414,7 +6496,7 @@ var menu = (options = {}) => [
|
|
|
6414
6496
|
}
|
|
6415
6497
|
container.appendChild(this.tag);
|
|
6416
6498
|
const handler = () => this.scheduleUpdate();
|
|
6417
|
-
this.cleanup =
|
|
6499
|
+
this.cleanup = addEventListener2(container, "scroll", handler);
|
|
6418
6500
|
this.scheduleUpdate();
|
|
6419
6501
|
}
|
|
6420
6502
|
destroy() {
|
|
@@ -6456,7 +6538,7 @@ var menu = (options = {}) => [
|
|
|
6456
6538
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6457
6539
|
}
|
|
6458
6540
|
}),
|
|
6459
|
-
|
|
6541
|
+
EditorView25.theme({
|
|
6460
6542
|
".cm-popover-trigger": {
|
|
6461
6543
|
position: "fixed",
|
|
6462
6544
|
padding: "0",
|
|
@@ -6492,12 +6574,12 @@ var outliner = (_options = {}) => [
|
|
|
6492
6574
|
listPaddingLeft: 8
|
|
6493
6575
|
}),
|
|
6494
6576
|
// Researve space for menu.
|
|
6495
|
-
|
|
6496
|
-
class: "
|
|
6577
|
+
EditorView26.contentAttributes.of({
|
|
6578
|
+
class: "w-full !mr-[3rem]"
|
|
6497
6579
|
})
|
|
6498
6580
|
];
|
|
6499
6581
|
var decorations = () => [
|
|
6500
|
-
|
|
6582
|
+
ViewPlugin18.fromClass(class {
|
|
6501
6583
|
decorations = Decoration12.none;
|
|
6502
6584
|
constructor(view) {
|
|
6503
6585
|
this.updateDecorations(view.state, view);
|
|
@@ -6522,7 +6604,7 @@ var decorations = () => [
|
|
|
6522
6604
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6523
6605
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6524
6606
|
decorations2.push(Decoration12.line({
|
|
6525
|
-
class:
|
|
6607
|
+
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"))
|
|
6526
6608
|
}).range(line.from, line.from));
|
|
6527
6609
|
}
|
|
6528
6610
|
}
|
|
@@ -6532,7 +6614,7 @@ var decorations = () => [
|
|
|
6532
6614
|
decorations: (v) => v.decorations
|
|
6533
6615
|
}),
|
|
6534
6616
|
// Theme.
|
|
6535
|
-
|
|
6617
|
+
EditorView26.theme(Object.assign({
|
|
6536
6618
|
".cm-list-item": {
|
|
6537
6619
|
borderLeftWidth: "1px",
|
|
6538
6620
|
borderRightWidth: "1px",
|
|
@@ -6557,38 +6639,67 @@ var decorations = () => [
|
|
|
6557
6639
|
marginBottom: "2px"
|
|
6558
6640
|
},
|
|
6559
6641
|
".cm-list-item-focused": {
|
|
6560
|
-
borderColor: "var(--
|
|
6642
|
+
borderColor: "var(--color-neutral-focus-indicator)"
|
|
6561
6643
|
},
|
|
6562
6644
|
"&:focus-within .cm-list-item-selected": {
|
|
6563
|
-
borderColor: "var(--
|
|
6645
|
+
borderColor: "var(--color-separator)"
|
|
6564
6646
|
}
|
|
6565
6647
|
}))
|
|
6566
6648
|
];
|
|
6567
6649
|
|
|
6568
6650
|
// src/extensions/preview/preview.ts
|
|
6569
6651
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6570
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6571
|
-
import { Decoration as Decoration13, EditorView as
|
|
6652
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6653
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6654
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6655
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6572
6656
|
var preview = (options = {}) => {
|
|
6657
|
+
const viewRef = {
|
|
6658
|
+
current: void 0
|
|
6659
|
+
};
|
|
6573
6660
|
return [
|
|
6574
6661
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6575
6662
|
// "Block decorations may not be specified via plugins".
|
|
6576
6663
|
StateField11.define({
|
|
6577
|
-
create: (state) => buildDecorations3(state, options),
|
|
6664
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6578
6665
|
update: (decorations2, tr) => {
|
|
6579
|
-
if (tr.docChanged) {
|
|
6580
|
-
return buildDecorations3(tr.state, options);
|
|
6666
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6667
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6581
6668
|
}
|
|
6582
6669
|
return decorations2.map(tr.changes);
|
|
6583
6670
|
},
|
|
6584
6671
|
provide: (field) => [
|
|
6585
|
-
|
|
6586
|
-
|
|
6672
|
+
EditorView27.decorations.from(field),
|
|
6673
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6587
6674
|
]
|
|
6675
|
+
}),
|
|
6676
|
+
ViewPlugin19.define((view) => {
|
|
6677
|
+
viewRef.current = view;
|
|
6678
|
+
return {
|
|
6679
|
+
destroy() {
|
|
6680
|
+
viewRef.current = void 0;
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
6588
6683
|
})
|
|
6589
6684
|
];
|
|
6590
6685
|
};
|
|
6591
|
-
var
|
|
6686
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6687
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6688
|
+
if (!dxn) {
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
const ref = db.makeRef(dxn);
|
|
6692
|
+
const target = ref.target;
|
|
6693
|
+
if (target) {
|
|
6694
|
+
return Entity.getLabel(target);
|
|
6695
|
+
}
|
|
6696
|
+
void ref.tryLoad().then(() => {
|
|
6697
|
+
viewRef.current?.dispatch({
|
|
6698
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6699
|
+
});
|
|
6700
|
+
});
|
|
6701
|
+
};
|
|
6702
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6592
6703
|
const builder = new RangeSetBuilder6();
|
|
6593
6704
|
syntaxTree10(state).iterate({
|
|
6594
6705
|
enter: (node) => {
|
|
@@ -6600,8 +6711,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6600
6711
|
case "Link": {
|
|
6601
6712
|
const link = getLinkRef(state, node.node);
|
|
6602
6713
|
if (link) {
|
|
6714
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6715
|
+
const displayLink = resolved ? {
|
|
6716
|
+
...link,
|
|
6717
|
+
label: resolved
|
|
6718
|
+
} : link;
|
|
6603
6719
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6604
|
-
widget: new PreviewInlineWidget(options,
|
|
6720
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6605
6721
|
side: 1
|
|
6606
6722
|
}));
|
|
6607
6723
|
}
|
|
@@ -6677,7 +6793,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6677
6793
|
}
|
|
6678
6794
|
toDOM(_view) {
|
|
6679
6795
|
const root = document.createElement("div");
|
|
6680
|
-
root.classList.add("cm-preview-block", "density-fine");
|
|
6796
|
+
root.classList.add("cm-preview-block", "dx-density-fine");
|
|
6681
6797
|
this._options.addBlockContainer?.({
|
|
6682
6798
|
link: this._link,
|
|
6683
6799
|
el: root
|
|
@@ -6693,7 +6809,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6693
6809
|
};
|
|
6694
6810
|
|
|
6695
6811
|
// src/extensions/replacer.ts
|
|
6696
|
-
import { EditorView as
|
|
6812
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6697
6813
|
var defaultReplacements = [
|
|
6698
6814
|
{
|
|
6699
6815
|
input: "--",
|
|
@@ -6756,7 +6872,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6756
6872
|
const sortedReplacements = [
|
|
6757
6873
|
...replacements
|
|
6758
6874
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6759
|
-
return
|
|
6875
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6760
6876
|
if (insert.length !== 1) {
|
|
6761
6877
|
return false;
|
|
6762
6878
|
}
|
|
@@ -6790,12 +6906,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6790
6906
|
});
|
|
6791
6907
|
};
|
|
6792
6908
|
|
|
6909
|
+
// src/extensions/snippets.ts
|
|
6910
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6911
|
+
var defaultItems = [
|
|
6912
|
+
"hello world!",
|
|
6913
|
+
"this is a test.",
|
|
6914
|
+
"this is [DXOS](https://dxos.org)"
|
|
6915
|
+
];
|
|
6916
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6917
|
+
let timer;
|
|
6918
|
+
let index = 0;
|
|
6919
|
+
return [
|
|
6920
|
+
keymap12.of([
|
|
6921
|
+
{
|
|
6922
|
+
// Reset.
|
|
6923
|
+
key: "alt-meta-'",
|
|
6924
|
+
run: () => {
|
|
6925
|
+
clearTimeout(timer);
|
|
6926
|
+
index = 0;
|
|
6927
|
+
return true;
|
|
6928
|
+
}
|
|
6929
|
+
},
|
|
6930
|
+
{
|
|
6931
|
+
// Next snippet.
|
|
6932
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6933
|
+
key: "Shift-Meta-'",
|
|
6934
|
+
run: (view) => {
|
|
6935
|
+
clearTimeout(timer);
|
|
6936
|
+
const text = items[index++];
|
|
6937
|
+
if (index === items?.length) {
|
|
6938
|
+
index = 0;
|
|
6939
|
+
}
|
|
6940
|
+
let offset = 0;
|
|
6941
|
+
const insert = (delayMs = 0) => {
|
|
6942
|
+
timer = setTimeout(() => {
|
|
6943
|
+
const pos = view.state.selection.main.head;
|
|
6944
|
+
view.dispatch({
|
|
6945
|
+
changes: {
|
|
6946
|
+
from: pos,
|
|
6947
|
+
insert: text[offset++]
|
|
6948
|
+
},
|
|
6949
|
+
selection: {
|
|
6950
|
+
anchor: pos + 1
|
|
6951
|
+
}
|
|
6952
|
+
});
|
|
6953
|
+
if (offset < text.length) {
|
|
6954
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6955
|
+
}
|
|
6956
|
+
}, delayMs);
|
|
6957
|
+
};
|
|
6958
|
+
insert();
|
|
6959
|
+
return true;
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
])
|
|
6963
|
+
];
|
|
6964
|
+
};
|
|
6965
|
+
|
|
6793
6966
|
// src/extensions/submit.ts
|
|
6794
6967
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6795
|
-
import { keymap as
|
|
6968
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6796
6969
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6797
6970
|
return [
|
|
6798
|
-
Prec6.highest(
|
|
6971
|
+
Prec6.highest(keymap13.of([
|
|
6799
6972
|
{
|
|
6800
6973
|
key: "Enter",
|
|
6801
6974
|
preventDefault: true,
|
|
@@ -6840,6 +7013,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6840
7013
|
// src/extensions/tags/extended-markdown.ts
|
|
6841
7014
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6842
7015
|
import { parseMixed } from "@lezer/common";
|
|
7016
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6843
7017
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6844
7018
|
return [
|
|
6845
7019
|
createMarkdownExtensions({
|
|
@@ -6851,13 +7025,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6851
7025
|
{
|
|
6852
7026
|
name: "SetextHeading",
|
|
6853
7027
|
parse: () => false
|
|
6854
|
-
}
|
|
7028
|
+
},
|
|
7029
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7030
|
+
// even when their content contains blank lines.
|
|
7031
|
+
...xmlBlockParsers(registry)
|
|
6855
7032
|
]
|
|
6856
7033
|
}
|
|
6857
7034
|
]
|
|
6858
7035
|
})
|
|
6859
7036
|
];
|
|
6860
7037
|
};
|
|
7038
|
+
var xmlBlockParsers = (registry) => {
|
|
7039
|
+
const customTags = Object.keys(registry ?? {});
|
|
7040
|
+
if (customTags.length === 0) {
|
|
7041
|
+
return [];
|
|
7042
|
+
}
|
|
7043
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7044
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7045
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7046
|
+
return [
|
|
7047
|
+
{
|
|
7048
|
+
name: "XMLBlock",
|
|
7049
|
+
before: "HTMLBlock",
|
|
7050
|
+
parse: (cx, line) => {
|
|
7051
|
+
const match = openPattern.exec(line.text);
|
|
7052
|
+
if (!match) {
|
|
7053
|
+
return false;
|
|
7054
|
+
}
|
|
7055
|
+
if (selfClosePattern.test(line.text)) {
|
|
7056
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7057
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7058
|
+
cx.nextLine();
|
|
7059
|
+
return true;
|
|
7060
|
+
}
|
|
7061
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7062
|
+
return false;
|
|
7063
|
+
}
|
|
7064
|
+
const tagName = match[1];
|
|
7065
|
+
const closeTag = `</${tagName}>`;
|
|
7066
|
+
const start = cx.lineStart;
|
|
7067
|
+
if (line.text.includes(closeTag)) {
|
|
7068
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7069
|
+
cx.nextLine();
|
|
7070
|
+
return true;
|
|
7071
|
+
}
|
|
7072
|
+
let end = cx.lineStart + line.text.length;
|
|
7073
|
+
while (cx.nextLine()) {
|
|
7074
|
+
end = cx.lineStart + line.text.length;
|
|
7075
|
+
if (line.text.includes(closeTag)) {
|
|
7076
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7077
|
+
cx.nextLine();
|
|
7078
|
+
return true;
|
|
7079
|
+
}
|
|
7080
|
+
}
|
|
7081
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7082
|
+
return true;
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
];
|
|
7086
|
+
};
|
|
6861
7087
|
var mixedParser = (registry) => {
|
|
6862
7088
|
const customTags = Object.keys(registry ?? {});
|
|
6863
7089
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6891,219 +7117,793 @@ var mixedParser = (registry) => {
|
|
|
6891
7117
|
});
|
|
6892
7118
|
};
|
|
6893
7119
|
|
|
6894
|
-
// src/extensions/tags/
|
|
6895
|
-
import { StateEffect as
|
|
6896
|
-
import { Decoration as Decoration14, EditorView as
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
var
|
|
6900
|
-
var
|
|
7120
|
+
// src/extensions/tags/fader.ts
|
|
7121
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7122
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7123
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7124
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7125
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7126
|
+
var fader = (options = {}) => {
|
|
7127
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7128
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7129
|
+
let lastCount = -1;
|
|
7130
|
+
const log12 = (expiries) => {
|
|
7131
|
+
if (expiries.length !== lastCount) {
|
|
7132
|
+
lastCount = expiries.length;
|
|
7133
|
+
}
|
|
7134
|
+
};
|
|
7135
|
+
const dequeue = StateEffect10.define();
|
|
7136
|
+
const fadeField = StateField12.define({
|
|
7137
|
+
create: () => ({
|
|
7138
|
+
decorations: Decoration14.none,
|
|
7139
|
+
expiries: [],
|
|
7140
|
+
batchStart: 0
|
|
7141
|
+
}),
|
|
7142
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
7143
|
+
for (const effect of tr.effects) {
|
|
7144
|
+
if (effect.is(dequeue)) {
|
|
7145
|
+
const now2 = effect.value;
|
|
7146
|
+
let removeCount = 0;
|
|
7147
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7148
|
+
removeCount++;
|
|
7149
|
+
}
|
|
7150
|
+
if (removeCount > 0) {
|
|
7151
|
+
expiries = expiries.slice(removeCount);
|
|
7152
|
+
let skipped = 0;
|
|
7153
|
+
decorations2 = decorations2.update({
|
|
7154
|
+
filter: () => {
|
|
7155
|
+
if (skipped < removeCount) {
|
|
7156
|
+
skipped++;
|
|
7157
|
+
return false;
|
|
7158
|
+
}
|
|
7159
|
+
return true;
|
|
7160
|
+
}
|
|
7161
|
+
});
|
|
7162
|
+
}
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
if (!tr.docChanged) {
|
|
7166
|
+
log12(expiries);
|
|
7167
|
+
return {
|
|
7168
|
+
decorations: decorations2,
|
|
7169
|
+
expiries,
|
|
7170
|
+
batchStart
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
7173
|
+
let isReset = tr.state.doc.length === 0;
|
|
7174
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7175
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7176
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7177
|
+
isReset = true;
|
|
7178
|
+
}
|
|
7179
|
+
});
|
|
7180
|
+
}
|
|
7181
|
+
if (isReset) {
|
|
7182
|
+
log12([]);
|
|
7183
|
+
return {
|
|
7184
|
+
decorations: Decoration14.none,
|
|
7185
|
+
expiries: [],
|
|
7186
|
+
batchStart: 0
|
|
7187
|
+
};
|
|
7188
|
+
}
|
|
7189
|
+
const now = Date.now();
|
|
7190
|
+
const add = [];
|
|
7191
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7192
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7193
|
+
add.push({
|
|
7194
|
+
from: fromB,
|
|
7195
|
+
to: toB
|
|
7196
|
+
});
|
|
7197
|
+
}
|
|
7198
|
+
});
|
|
7199
|
+
if (add.length > 0) {
|
|
7200
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7201
|
+
if (canCoalesce) {
|
|
7202
|
+
let lastFrom = -1;
|
|
7203
|
+
let lastTo = -1;
|
|
7204
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7205
|
+
lastFrom = from;
|
|
7206
|
+
lastTo = to;
|
|
7207
|
+
});
|
|
7208
|
+
if (lastFrom >= 0) {
|
|
7209
|
+
decorations2 = decorations2.update({
|
|
7210
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7211
|
+
});
|
|
7212
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7213
|
+
const mergedTo = add[add.length - 1].to;
|
|
7214
|
+
decorations2 = decorations2.update({
|
|
7215
|
+
add: [
|
|
7216
|
+
Decoration14.mark({
|
|
7217
|
+
class: "cm-fader"
|
|
7218
|
+
}).range(mergedFrom, mergedTo)
|
|
7219
|
+
]
|
|
7220
|
+
});
|
|
7221
|
+
expiries = [
|
|
7222
|
+
...expiries.slice(0, -1),
|
|
7223
|
+
now + removalDelay
|
|
7224
|
+
];
|
|
7225
|
+
}
|
|
7226
|
+
} else {
|
|
7227
|
+
batchStart = now;
|
|
7228
|
+
expiries = [
|
|
7229
|
+
...expiries,
|
|
7230
|
+
now + removalDelay
|
|
7231
|
+
];
|
|
7232
|
+
decorations2 = decorations2.update({
|
|
7233
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7234
|
+
class: "cm-fader"
|
|
7235
|
+
}).range(from, to))
|
|
7236
|
+
});
|
|
7237
|
+
}
|
|
7238
|
+
}
|
|
7239
|
+
log12(expiries);
|
|
7240
|
+
return {
|
|
7241
|
+
decorations: decorations2,
|
|
7242
|
+
expiries,
|
|
7243
|
+
batchStart
|
|
7244
|
+
};
|
|
7245
|
+
},
|
|
7246
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7247
|
+
});
|
|
7248
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7249
|
+
view;
|
|
7250
|
+
#timer;
|
|
7251
|
+
constructor(view) {
|
|
7252
|
+
this.view = view;
|
|
7253
|
+
this.#schedule();
|
|
7254
|
+
}
|
|
7255
|
+
update() {
|
|
7256
|
+
this.#schedule();
|
|
7257
|
+
}
|
|
7258
|
+
#schedule() {
|
|
7259
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7260
|
+
if (expiries.length === 0) {
|
|
7261
|
+
clearTimeout(this.#timer);
|
|
7262
|
+
this.#timer = void 0;
|
|
7263
|
+
return;
|
|
7264
|
+
}
|
|
7265
|
+
if (this.#timer !== void 0) {
|
|
7266
|
+
return;
|
|
7267
|
+
}
|
|
7268
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7269
|
+
this.#timer = setTimeout(() => {
|
|
7270
|
+
this.#timer = void 0;
|
|
7271
|
+
this.view.dispatch({
|
|
7272
|
+
effects: dequeue.of(Date.now())
|
|
7273
|
+
});
|
|
7274
|
+
}, delay);
|
|
7275
|
+
}
|
|
7276
|
+
destroy() {
|
|
7277
|
+
clearTimeout(this.#timer);
|
|
7278
|
+
}
|
|
7279
|
+
});
|
|
6901
7280
|
return [
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
7281
|
+
fadeField,
|
|
7282
|
+
cleanup,
|
|
7283
|
+
EditorView29.theme({
|
|
7284
|
+
".cm-fader": {
|
|
7285
|
+
animation: "fader 1s ease-out forwards"
|
|
7286
|
+
},
|
|
7287
|
+
"@keyframes fader": {
|
|
7288
|
+
"0%": {
|
|
7289
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7290
|
+
},
|
|
7291
|
+
"100%": {}
|
|
7292
|
+
}
|
|
7293
|
+
})
|
|
7294
|
+
];
|
|
7295
|
+
};
|
|
7296
|
+
|
|
7297
|
+
// src/extensions/tags/typewriter.ts
|
|
7298
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7299
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7300
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7301
|
+
var typewriterBypass = Annotation3.define();
|
|
7302
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7303
|
+
var CURSOR_LINGER = 3e3;
|
|
7304
|
+
var FRAME_BUDGET_MS = 4;
|
|
7305
|
+
var CHARS_PER_FRAME = 5;
|
|
7306
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7307
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7308
|
+
var typewriter = (options = {}) => {
|
|
7309
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7310
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7311
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7312
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7313
|
+
const suppressAppend = StateEffect11.define();
|
|
7314
|
+
const insertChunk = StateEffect11.define();
|
|
7315
|
+
const bufferField = StateField13.define({
|
|
7316
|
+
create: () => ({
|
|
7317
|
+
text: "",
|
|
7318
|
+
head: 0,
|
|
7319
|
+
insertAt: 0
|
|
7320
|
+
}),
|
|
6910
7321
|
update: (value, tr) => {
|
|
7322
|
+
let { text, head, insertAt } = value;
|
|
6911
7323
|
for (const effect of tr.effects) {
|
|
6912
|
-
if (effect.is(
|
|
6913
|
-
|
|
7324
|
+
if (effect.is(suppressAppend)) {
|
|
7325
|
+
if (text.length === head) {
|
|
7326
|
+
insertAt = effect.value.from;
|
|
7327
|
+
}
|
|
7328
|
+
text += effect.value.text;
|
|
7329
|
+
}
|
|
7330
|
+
if (effect.is(insertChunk)) {
|
|
7331
|
+
head += effect.value.text.length;
|
|
7332
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7333
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7334
|
+
text = text.slice(head);
|
|
7335
|
+
head = 0;
|
|
7336
|
+
}
|
|
6914
7337
|
}
|
|
6915
7338
|
}
|
|
6916
7339
|
if (tr.docChanged) {
|
|
6917
|
-
|
|
7340
|
+
let isReset = tr.state.doc.length === 0;
|
|
7341
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7342
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7343
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7344
|
+
isReset = true;
|
|
7345
|
+
}
|
|
7346
|
+
});
|
|
7347
|
+
}
|
|
7348
|
+
if (isReset) {
|
|
7349
|
+
return {
|
|
7350
|
+
text: "",
|
|
7351
|
+
head: 0,
|
|
7352
|
+
insertAt: 0
|
|
7353
|
+
};
|
|
7354
|
+
}
|
|
7355
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7356
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7357
|
+
}
|
|
6918
7358
|
}
|
|
6919
|
-
return
|
|
7359
|
+
return {
|
|
7360
|
+
text,
|
|
7361
|
+
head,
|
|
7362
|
+
insertAt
|
|
7363
|
+
};
|
|
6920
7364
|
}
|
|
6921
7365
|
});
|
|
6922
|
-
const
|
|
7366
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7367
|
+
if (!tr.docChanged) {
|
|
7368
|
+
return tr;
|
|
7369
|
+
}
|
|
7370
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7371
|
+
return tr;
|
|
7372
|
+
}
|
|
7373
|
+
let appendedText = "";
|
|
7374
|
+
let appendFrom = -1;
|
|
7375
|
+
let isAppendOnly = true;
|
|
7376
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7377
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7378
|
+
appendedText += inserted.sliceString(0);
|
|
7379
|
+
if (appendFrom === -1) {
|
|
7380
|
+
appendFrom = fromA;
|
|
7381
|
+
}
|
|
7382
|
+
} else {
|
|
7383
|
+
isAppendOnly = false;
|
|
7384
|
+
}
|
|
7385
|
+
});
|
|
7386
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7387
|
+
return tr;
|
|
7388
|
+
}
|
|
7389
|
+
return {
|
|
7390
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7391
|
+
effects: suppressAppend.of({
|
|
7392
|
+
from: appendFrom,
|
|
7393
|
+
text: appendedText
|
|
7394
|
+
})
|
|
7395
|
+
};
|
|
7396
|
+
});
|
|
7397
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6923
7398
|
view;
|
|
6924
|
-
|
|
7399
|
+
_raf;
|
|
7400
|
+
_activeStreamTag = null;
|
|
6925
7401
|
constructor(view) {
|
|
6926
7402
|
this.view = view;
|
|
6927
7403
|
}
|
|
6928
7404
|
update(update2) {
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
7405
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7406
|
+
const pending = text.length - head;
|
|
7407
|
+
if (pending === 0) {
|
|
7408
|
+
this._activeStreamTag = null;
|
|
7409
|
+
}
|
|
7410
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7411
|
+
this._start();
|
|
6936
7412
|
}
|
|
6937
7413
|
}
|
|
7414
|
+
_start() {
|
|
7415
|
+
queueMicrotask(() => {
|
|
7416
|
+
this.view.dispatch({
|
|
7417
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7418
|
+
annotations: typewriterBypass.of(true)
|
|
7419
|
+
});
|
|
7420
|
+
});
|
|
7421
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7422
|
+
}
|
|
7423
|
+
_tick = () => {
|
|
7424
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7425
|
+
const pending = text.length - head;
|
|
7426
|
+
if (pending === 0) {
|
|
7427
|
+
this.view.dispatch({
|
|
7428
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7429
|
+
annotations: typewriterBypass.of(true)
|
|
7430
|
+
});
|
|
7431
|
+
this._raf = void 0;
|
|
7432
|
+
return;
|
|
7433
|
+
}
|
|
7434
|
+
if (pending > flushThreshold) {
|
|
7435
|
+
const chunk = text.slice(head);
|
|
7436
|
+
this._activeStreamTag = null;
|
|
7437
|
+
this.view.dispatch({
|
|
7438
|
+
changes: {
|
|
7439
|
+
from: insertAt,
|
|
7440
|
+
insert: chunk
|
|
7441
|
+
},
|
|
7442
|
+
effects: insertChunk.of({
|
|
7443
|
+
from: insertAt,
|
|
7444
|
+
text: chunk
|
|
7445
|
+
})
|
|
7446
|
+
});
|
|
7447
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7448
|
+
return;
|
|
7449
|
+
}
|
|
7450
|
+
const startTime = performance.now();
|
|
7451
|
+
let pos = head;
|
|
7452
|
+
let activeTag = this._activeStreamTag;
|
|
7453
|
+
let charsEmitted = 0;
|
|
7454
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7455
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7456
|
+
if (result.count === 0) {
|
|
7457
|
+
break;
|
|
7458
|
+
}
|
|
7459
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7460
|
+
break;
|
|
7461
|
+
}
|
|
7462
|
+
if (result.enterTag) {
|
|
7463
|
+
activeTag = result.enterTag;
|
|
7464
|
+
}
|
|
7465
|
+
if (result.exitTag) {
|
|
7466
|
+
activeTag = null;
|
|
7467
|
+
}
|
|
7468
|
+
pos += result.count;
|
|
7469
|
+
charsEmitted += result.count;
|
|
7470
|
+
}
|
|
7471
|
+
const totalCount = pos - head;
|
|
7472
|
+
if (totalCount > 0) {
|
|
7473
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7474
|
+
this._activeStreamTag = activeTag;
|
|
7475
|
+
this.view.dispatch({
|
|
7476
|
+
changes: {
|
|
7477
|
+
from: insertAt,
|
|
7478
|
+
insert: chunk
|
|
7479
|
+
},
|
|
7480
|
+
effects: insertChunk.of({
|
|
7481
|
+
from: insertAt,
|
|
7482
|
+
text: chunk
|
|
7483
|
+
})
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7487
|
+
};
|
|
6938
7488
|
destroy() {
|
|
6939
|
-
|
|
7489
|
+
if (this._raf !== void 0) {
|
|
7490
|
+
cancelAnimationFrame(this._raf);
|
|
7491
|
+
}
|
|
6940
7492
|
}
|
|
6941
7493
|
});
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
7494
|
+
return [
|
|
7495
|
+
bufferField,
|
|
7496
|
+
filter,
|
|
7497
|
+
drainPlugin,
|
|
7498
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7499
|
+
].filter(Boolean);
|
|
7500
|
+
};
|
|
7501
|
+
var typewriterCursor = (bufferField) => {
|
|
7502
|
+
const hideCursor = StateEffect11.define();
|
|
7503
|
+
const visibilityField = StateField13.define({
|
|
7504
|
+
create: () => ({
|
|
7505
|
+
visible: false,
|
|
7506
|
+
insertAt: 0,
|
|
7507
|
+
lastNonWsAt: 0
|
|
7508
|
+
}),
|
|
7509
|
+
update: (value, tr) => {
|
|
7510
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7511
|
+
const pending = text.length - head;
|
|
7512
|
+
if (pending > 0) {
|
|
7513
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7514
|
+
if (tr.docChanged) {
|
|
7515
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7516
|
+
const chunk = inserted.sliceString(0);
|
|
7517
|
+
if (chunk.trim().length > 0) {
|
|
7518
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7519
|
+
}
|
|
7520
|
+
});
|
|
7521
|
+
}
|
|
7522
|
+
return {
|
|
7523
|
+
visible: true,
|
|
7524
|
+
insertAt,
|
|
7525
|
+
lastNonWsAt
|
|
7526
|
+
};
|
|
7527
|
+
}
|
|
7528
|
+
for (const effect of tr.effects) {
|
|
7529
|
+
if (effect.is(hideCursor)) {
|
|
7530
|
+
return {
|
|
7531
|
+
...value,
|
|
7532
|
+
visible: false
|
|
7533
|
+
};
|
|
7534
|
+
}
|
|
6948
7535
|
}
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
7536
|
+
return value;
|
|
7537
|
+
}
|
|
7538
|
+
});
|
|
7539
|
+
const decorationField = StateField13.define({
|
|
7540
|
+
create: () => Decoration15.none,
|
|
7541
|
+
update: (_decorations, tr) => {
|
|
7542
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7543
|
+
if (!visible) {
|
|
7544
|
+
return Decoration15.none;
|
|
7545
|
+
}
|
|
7546
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7547
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7548
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7549
|
+
return Decoration15.set([
|
|
7550
|
+
Decoration15.widget({
|
|
6952
7551
|
widget: new CursorWidget(),
|
|
6953
7552
|
side: 1
|
|
6954
|
-
}).range(
|
|
7553
|
+
}).range(pos)
|
|
6955
7554
|
]);
|
|
6956
7555
|
},
|
|
6957
|
-
provide: (
|
|
7556
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7557
|
+
});
|
|
7558
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7559
|
+
view;
|
|
7560
|
+
_timer;
|
|
7561
|
+
constructor(view) {
|
|
7562
|
+
this.view = view;
|
|
7563
|
+
}
|
|
7564
|
+
update(update2) {
|
|
7565
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7566
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7567
|
+
const pending = text.length - head;
|
|
7568
|
+
if (pending > 0) {
|
|
7569
|
+
clearTimeout(this._timer);
|
|
7570
|
+
this._timer = void 0;
|
|
7571
|
+
} else if (visible && this._timer === void 0) {
|
|
7572
|
+
this._timer = setTimeout(() => {
|
|
7573
|
+
this.view.dispatch({
|
|
7574
|
+
effects: hideCursor.of(null)
|
|
7575
|
+
});
|
|
7576
|
+
this._timer = void 0;
|
|
7577
|
+
}, CURSOR_LINGER);
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
destroy() {
|
|
7581
|
+
clearTimeout(this._timer);
|
|
7582
|
+
}
|
|
6958
7583
|
});
|
|
6959
7584
|
return [
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
7585
|
+
visibilityField,
|
|
7586
|
+
decorationField,
|
|
7587
|
+
timerPlugin
|
|
6963
7588
|
];
|
|
6964
7589
|
};
|
|
6965
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7590
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7591
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7592
|
+
// the blink animation isn't restarted on every transaction.
|
|
7593
|
+
eq(other) {
|
|
7594
|
+
return other instanceof _CursorWidget;
|
|
7595
|
+
}
|
|
6966
7596
|
toDOM() {
|
|
6967
|
-
const inner = Domino3.of("span").text("\
|
|
6968
|
-
animation: "blink
|
|
7597
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7598
|
+
animation: "blink 1s infinite",
|
|
7599
|
+
animationDelay: "250ms"
|
|
6969
7600
|
});
|
|
6970
7601
|
return Domino3.of("span").style({
|
|
6971
7602
|
opacity: "0.8"
|
|
6972
|
-
}).
|
|
7603
|
+
}).append(inner).root;
|
|
6973
7604
|
}
|
|
6974
7605
|
};
|
|
6975
|
-
var
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
7606
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7607
|
+
var TAG_NAME_PROBE = 64;
|
|
7608
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7609
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7610
|
+
if (start >= buffer.length) {
|
|
7611
|
+
return {
|
|
7612
|
+
count: 0
|
|
7613
|
+
};
|
|
7614
|
+
}
|
|
7615
|
+
if (activeStreamTag) {
|
|
7616
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7617
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7618
|
+
return {
|
|
7619
|
+
count: closeTag.length,
|
|
7620
|
+
exitTag: true
|
|
7621
|
+
};
|
|
7622
|
+
}
|
|
7623
|
+
if (buffer[start] === "<") {
|
|
7624
|
+
return {
|
|
7625
|
+
count: xmlElementLength(buffer, start)
|
|
7626
|
+
};
|
|
7627
|
+
}
|
|
7628
|
+
return {
|
|
7629
|
+
count: 1
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
const ch = buffer[start];
|
|
7633
|
+
if (ch === "<") {
|
|
7634
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7635
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7636
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7637
|
+
const close = buffer.indexOf(">", start);
|
|
7638
|
+
if (close === -1) {
|
|
7639
|
+
return {
|
|
7640
|
+
count: 0
|
|
7641
|
+
};
|
|
6994
7642
|
}
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
isReset = true;
|
|
7000
|
-
}
|
|
7001
|
-
});
|
|
7643
|
+
if (buffer[close - 1] === "/") {
|
|
7644
|
+
return {
|
|
7645
|
+
count: close + 1 - start
|
|
7646
|
+
};
|
|
7002
7647
|
}
|
|
7003
|
-
|
|
7004
|
-
|
|
7648
|
+
return {
|
|
7649
|
+
count: close + 1 - start,
|
|
7650
|
+
enterTag: nameMatch[1]
|
|
7651
|
+
};
|
|
7652
|
+
}
|
|
7653
|
+
return {
|
|
7654
|
+
count: xmlElementLength(buffer, start)
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7657
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7658
|
+
return {
|
|
7659
|
+
count: linkLength(buffer, start, start + 1)
|
|
7660
|
+
};
|
|
7661
|
+
}
|
|
7662
|
+
if (ch === "[") {
|
|
7663
|
+
return {
|
|
7664
|
+
count: linkLength(buffer, start, start)
|
|
7665
|
+
};
|
|
7666
|
+
}
|
|
7667
|
+
return {
|
|
7668
|
+
count: 1
|
|
7669
|
+
};
|
|
7670
|
+
};
|
|
7671
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7672
|
+
const close = buffer.indexOf(">", start);
|
|
7673
|
+
if (close === -1) {
|
|
7674
|
+
return 0;
|
|
7675
|
+
}
|
|
7676
|
+
if (buffer[close - 1] === "/") {
|
|
7677
|
+
return close + 1 - start;
|
|
7678
|
+
}
|
|
7679
|
+
if (buffer[start + 1] === "/") {
|
|
7680
|
+
return close + 1 - start;
|
|
7681
|
+
}
|
|
7682
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7683
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7684
|
+
if (!nameMatch) {
|
|
7685
|
+
return 1;
|
|
7686
|
+
}
|
|
7687
|
+
const tagName = nameMatch[1];
|
|
7688
|
+
let depth = 0;
|
|
7689
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7690
|
+
tagPattern.lastIndex = start;
|
|
7691
|
+
let match;
|
|
7692
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7693
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7694
|
+
const isClosing = match[1] === "/";
|
|
7695
|
+
if (isSelfClosing) {
|
|
7696
|
+
if (depth === 0) {
|
|
7697
|
+
return match.index + match[0].length - start;
|
|
7698
|
+
}
|
|
7699
|
+
} else if (isClosing) {
|
|
7700
|
+
depth--;
|
|
7701
|
+
if (depth === 0) {
|
|
7702
|
+
return match.index + match[0].length - start;
|
|
7005
7703
|
}
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7704
|
+
} else {
|
|
7705
|
+
depth++;
|
|
7706
|
+
}
|
|
7707
|
+
}
|
|
7708
|
+
return 0;
|
|
7709
|
+
};
|
|
7710
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7711
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7712
|
+
if (bracketClose === -1) {
|
|
7713
|
+
return 0;
|
|
7714
|
+
}
|
|
7715
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7716
|
+
return 0;
|
|
7717
|
+
}
|
|
7718
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7719
|
+
return 1;
|
|
7720
|
+
}
|
|
7721
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7722
|
+
if (parenClose === -1) {
|
|
7723
|
+
return 0;
|
|
7724
|
+
}
|
|
7725
|
+
return parenClose + 1 - start;
|
|
7726
|
+
};
|
|
7727
|
+
|
|
7728
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7729
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7730
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7731
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7732
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7733
|
+
class: lineClass
|
|
7734
|
+
}) : void 0;
|
|
7735
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7736
|
+
class: contentClass
|
|
7737
|
+
}) : void 0;
|
|
7738
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7739
|
+
const buildDecorations5 = (view) => {
|
|
7740
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7741
|
+
if (!text.includes(`<${tag}`)) {
|
|
7742
|
+
return Decoration16.none;
|
|
7743
|
+
}
|
|
7744
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7745
|
+
const ranges = [];
|
|
7746
|
+
tree.iterate({
|
|
7747
|
+
enter: (node) => {
|
|
7748
|
+
if (node.type.name !== "Element") {
|
|
7009
7749
|
return;
|
|
7010
7750
|
}
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7751
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7752
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7753
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7754
|
+
if (!openTag || !tagNameNode) {
|
|
7755
|
+
return;
|
|
7015
7756
|
}
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7757
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7758
|
+
return;
|
|
7759
|
+
}
|
|
7760
|
+
const contentFrom = openTag.to;
|
|
7761
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7762
|
+
if (hideDecoration) {
|
|
7763
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7764
|
+
if (closeTag) {
|
|
7765
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7766
|
+
}
|
|
7767
|
+
}
|
|
7768
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7769
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7770
|
+
}
|
|
7771
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7772
|
+
let pos = contentFrom;
|
|
7773
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7774
|
+
const line = view.state.doc.lineAt(pos);
|
|
7775
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7776
|
+
if (line.to >= contentTo) {
|
|
7777
|
+
break;
|
|
7778
|
+
}
|
|
7779
|
+
pos = line.to + 1;
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
}
|
|
7783
|
+
});
|
|
7784
|
+
return Decoration16.set(ranges, true);
|
|
7785
|
+
};
|
|
7786
|
+
return ViewPlugin22.fromClass(class {
|
|
7787
|
+
decorations;
|
|
7027
7788
|
constructor(view) {
|
|
7028
|
-
this.
|
|
7789
|
+
this.decorations = buildDecorations5(view);
|
|
7029
7790
|
}
|
|
7030
7791
|
update(update2) {
|
|
7031
|
-
if (
|
|
7032
|
-
|
|
7792
|
+
if (update2.docChanged) {
|
|
7793
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7033
7794
|
}
|
|
7034
|
-
|
|
7035
|
-
|
|
7795
|
+
}
|
|
7796
|
+
}, {
|
|
7797
|
+
decorations: (instance) => instance.decorations
|
|
7798
|
+
});
|
|
7799
|
+
};
|
|
7800
|
+
|
|
7801
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7802
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7803
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7804
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7805
|
+
"OpenTag",
|
|
7806
|
+
"CloseTag",
|
|
7807
|
+
"SelfClosingTag",
|
|
7808
|
+
"MismatchedCloseTag"
|
|
7809
|
+
]);
|
|
7810
|
+
var xmlElementMark = Decoration17.mark({
|
|
7811
|
+
class: "cm-xml-element"
|
|
7812
|
+
});
|
|
7813
|
+
var xmlTagMark = Decoration17.mark({
|
|
7814
|
+
class: "cm-xml-tag"
|
|
7815
|
+
});
|
|
7816
|
+
var xmlContentMark = Decoration17.mark({
|
|
7817
|
+
class: "cm-xml-content"
|
|
7818
|
+
});
|
|
7819
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7820
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7821
|
+
const buildDecorations5 = (view) => {
|
|
7822
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7823
|
+
if (!text.includes("<")) {
|
|
7824
|
+
return Decoration17.none;
|
|
7825
|
+
}
|
|
7826
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7827
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7828
|
+
const ranges = [];
|
|
7829
|
+
tree.iterate({
|
|
7830
|
+
enter: (node) => {
|
|
7831
|
+
const name = node.type.name;
|
|
7832
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7833
|
+
if (skipSet) {
|
|
7834
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7835
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7836
|
+
return false;
|
|
7837
|
+
}
|
|
7838
|
+
}
|
|
7839
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7840
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7036
7841
|
return;
|
|
7037
7842
|
}
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7843
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7844
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7845
|
+
return;
|
|
7846
|
+
}
|
|
7847
|
+
if (name === "Element" && node.from < node.to) {
|
|
7848
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7849
|
+
if (openTag && skipSet) {
|
|
7850
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7851
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7852
|
+
return false;
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7856
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7857
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7858
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7859
|
+
}
|
|
7041
7860
|
}
|
|
7042
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7043
|
-
const id = setTimeout(() => {
|
|
7044
|
-
this.view.dispatch({
|
|
7045
|
-
effects: removeDecoration.of({
|
|
7046
|
-
from: fromB,
|
|
7047
|
-
to: toB
|
|
7048
|
-
})
|
|
7049
|
-
});
|
|
7050
|
-
this._timers.delete(key);
|
|
7051
|
-
}, totalDelay);
|
|
7052
|
-
this._timers.set(key, id);
|
|
7053
|
-
});
|
|
7054
|
-
}
|
|
7055
|
-
destroy() {
|
|
7056
|
-
for (const id of this._timers.values()) {
|
|
7057
|
-
clearTimeout(id);
|
|
7058
7861
|
}
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
}
|
|
7862
|
+
});
|
|
7863
|
+
return Decoration17.set(ranges, true);
|
|
7864
|
+
};
|
|
7062
7865
|
return [
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
},
|
|
7072
|
-
"@keyframes fade-in": {
|
|
7073
|
-
"0%": {
|
|
7074
|
-
opacity: "0"
|
|
7075
|
-
},
|
|
7076
|
-
"80%": {
|
|
7077
|
-
opacity: "1"
|
|
7078
|
-
},
|
|
7079
|
-
"100%": {
|
|
7080
|
-
opacity: "0.8"
|
|
7866
|
+
ViewPlugin23.fromClass(class {
|
|
7867
|
+
decorations;
|
|
7868
|
+
constructor(view) {
|
|
7869
|
+
this.decorations = buildDecorations5(view);
|
|
7870
|
+
}
|
|
7871
|
+
update(update2) {
|
|
7872
|
+
if (update2.docChanged) {
|
|
7873
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7081
7874
|
}
|
|
7082
7875
|
}
|
|
7876
|
+
}, {
|
|
7877
|
+
decorations: (instance) => instance.decorations
|
|
7878
|
+
}),
|
|
7879
|
+
EditorView31.baseTheme({
|
|
7880
|
+
".cm-xml-element": {
|
|
7881
|
+
backgroundColor: "var(--color-active-surface)",
|
|
7882
|
+
borderRadius: "0.25rem",
|
|
7883
|
+
padding: "0.25rem"
|
|
7884
|
+
},
|
|
7885
|
+
".cm-xml-tag": {
|
|
7886
|
+
color: "var(--color-blue-500)",
|
|
7887
|
+
fontFamily: "var(--font-mono)"
|
|
7888
|
+
},
|
|
7889
|
+
".cm-xml-content": {}
|
|
7083
7890
|
})
|
|
7084
7891
|
];
|
|
7085
7892
|
};
|
|
7086
7893
|
|
|
7087
7894
|
// src/extensions/tags/xml-tags.ts
|
|
7088
7895
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7089
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7090
|
-
import { Decoration as
|
|
7896
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7897
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7091
7898
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7092
|
-
import { log as
|
|
7899
|
+
import { log as log11 } from "@dxos/log";
|
|
7900
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7093
7901
|
|
|
7094
7902
|
// src/extensions/tags/xml-util.ts
|
|
7095
7903
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7096
|
-
var
|
|
7904
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7097
7905
|
var nodeToJson = (state, node) => {
|
|
7098
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7099
|
-
F: __dxlog_file15,
|
|
7100
|
-
L: 18,
|
|
7101
|
-
S: void 0,
|
|
7102
|
-
A: [
|
|
7103
|
-
"node.type.name === 'Element'",
|
|
7104
|
-
"'Node is not an Element'"
|
|
7105
|
-
]
|
|
7106
|
-
});
|
|
7906
|
+
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'"] });
|
|
7107
7907
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7108
7908
|
if (openTag) {
|
|
7109
7909
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7135,13 +7935,23 @@ var nodeToJson = (state, node) => {
|
|
|
7135
7935
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7136
7936
|
const children = [];
|
|
7137
7937
|
let child = node.node.firstChild;
|
|
7938
|
+
const appendText = (raw) => {
|
|
7939
|
+
if (raw.length === 0) {
|
|
7940
|
+
return;
|
|
7941
|
+
}
|
|
7942
|
+
const last = children[children.length - 1];
|
|
7943
|
+
if (typeof last === "string") {
|
|
7944
|
+
children[children.length - 1] = last + raw;
|
|
7945
|
+
} else {
|
|
7946
|
+
children.push(raw);
|
|
7947
|
+
}
|
|
7948
|
+
};
|
|
7138
7949
|
while (child) {
|
|
7139
7950
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7140
7951
|
if (child.type.name === "Text") {
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
}
|
|
7952
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7953
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7954
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7145
7955
|
} else if (child.type.name === "Element") {
|
|
7146
7956
|
const data = nodeToJson(state, child);
|
|
7147
7957
|
if (data) {
|
|
@@ -7151,26 +7961,63 @@ var nodeToJson = (state, node) => {
|
|
|
7151
7961
|
}
|
|
7152
7962
|
child = child.nextSibling;
|
|
7153
7963
|
}
|
|
7964
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7965
|
+
children[0] = children[0].trimStart();
|
|
7966
|
+
}
|
|
7154
7967
|
if (children.length > 0) {
|
|
7155
|
-
|
|
7968
|
+
const lastIndex = children.length - 1;
|
|
7969
|
+
const last = children[lastIndex];
|
|
7970
|
+
if (typeof last === "string") {
|
|
7971
|
+
children[lastIndex] = last.trimEnd();
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7975
|
+
if (trimmed.length > 0) {
|
|
7976
|
+
tag.children = trimmed;
|
|
7156
7977
|
}
|
|
7157
7978
|
}
|
|
7158
7979
|
return tag;
|
|
7159
7980
|
}
|
|
7160
7981
|
};
|
|
7982
|
+
var XML_NAMED_ENTITIES = {
|
|
7983
|
+
"<": "<",
|
|
7984
|
+
">": ">",
|
|
7985
|
+
"&": "&",
|
|
7986
|
+
""": '"',
|
|
7987
|
+
"'": "'"
|
|
7988
|
+
};
|
|
7989
|
+
var decodeXmlEntity = (raw) => {
|
|
7990
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
7991
|
+
if (named !== void 0) {
|
|
7992
|
+
return named;
|
|
7993
|
+
}
|
|
7994
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
7995
|
+
if (numeric) {
|
|
7996
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
7997
|
+
if (Number.isFinite(code)) {
|
|
7998
|
+
try {
|
|
7999
|
+
return String.fromCodePoint(code);
|
|
8000
|
+
} catch {
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
return raw;
|
|
8005
|
+
};
|
|
7161
8006
|
|
|
7162
8007
|
// src/extensions/tags/xml-tags.ts
|
|
7163
|
-
var
|
|
7164
|
-
var navigatePreviousEffect =
|
|
7165
|
-
var navigateNextEffect =
|
|
8008
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
8009
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8010
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7166
8011
|
var getXmlTextChild = (children) => {
|
|
7167
8012
|
const child = children?.[0];
|
|
7168
8013
|
return typeof child === "string" ? child : null;
|
|
7169
8014
|
};
|
|
7170
|
-
var
|
|
7171
|
-
var
|
|
7172
|
-
var
|
|
7173
|
-
var
|
|
8015
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8016
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8017
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8018
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8019
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8020
|
+
var widgetContextStateField = StateField14.define({
|
|
7174
8021
|
create: () => void 0,
|
|
7175
8022
|
update: (value, tr) => {
|
|
7176
8023
|
for (const effect of tr.effects) {
|
|
@@ -7181,7 +8028,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7181
8028
|
return value;
|
|
7182
8029
|
}
|
|
7183
8030
|
});
|
|
7184
|
-
var widgetStateMapStateField =
|
|
8031
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7185
8032
|
create: () => ({}),
|
|
7186
8033
|
update: (map, tr) => {
|
|
7187
8034
|
for (const effect of tr.effects) {
|
|
@@ -7190,15 +8037,10 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7190
8037
|
}
|
|
7191
8038
|
if (effect.is(xmlTagUpdateEffect)) {
|
|
7192
8039
|
const { id, value } = effect.value;
|
|
7193
|
-
|
|
8040
|
+
log11("widget updated", {
|
|
7194
8041
|
id,
|
|
7195
8042
|
value
|
|
7196
|
-
}, {
|
|
7197
|
-
F: __dxlog_file16,
|
|
7198
|
-
L: 153,
|
|
7199
|
-
S: void 0,
|
|
7200
|
-
C: (f, a) => f(...a)
|
|
7201
|
-
});
|
|
8043
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7202
8044
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7203
8045
|
return {
|
|
7204
8046
|
...map,
|
|
@@ -7225,15 +8067,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7225
8067
|
const widgets = /* @__PURE__ */ new Map();
|
|
7226
8068
|
const notifier = {
|
|
7227
8069
|
mounted: (state) => {
|
|
7228
|
-
|
|
8070
|
+
log11("widget mounted", {
|
|
7229
8071
|
id: state.id,
|
|
7230
8072
|
tag: state.props._tag
|
|
7231
|
-
}, {
|
|
7232
|
-
F: __dxlog_file16,
|
|
7233
|
-
L: 206,
|
|
7234
|
-
S: void 0,
|
|
7235
|
-
C: (f, a) => f(...a)
|
|
7236
|
-
});
|
|
8073
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7237
8074
|
widgets.set(state.id, state);
|
|
7238
8075
|
setWidgets?.([
|
|
7239
8076
|
...widgets.values()
|
|
@@ -7241,15 +8078,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7241
8078
|
},
|
|
7242
8079
|
unmounted: (id) => {
|
|
7243
8080
|
const state = widgets.get(id);
|
|
7244
|
-
|
|
8081
|
+
log11("widget unmounted", {
|
|
7245
8082
|
id,
|
|
7246
8083
|
tag: state?.props._tag
|
|
7247
|
-
}, {
|
|
7248
|
-
F: __dxlog_file16,
|
|
7249
|
-
L: 212,
|
|
7250
|
-
S: void 0,
|
|
7251
|
-
C: (f, a) => f(...a)
|
|
7252
|
-
});
|
|
8084
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7253
8085
|
widgets.delete(id);
|
|
7254
8086
|
setWidgets?.([
|
|
7255
8087
|
...widgets.values()
|
|
@@ -7258,7 +8090,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7258
8090
|
};
|
|
7259
8091
|
return notifier;
|
|
7260
8092
|
};
|
|
7261
|
-
var keyHandlers =
|
|
8093
|
+
var keyHandlers = keymap14.of([
|
|
7262
8094
|
{
|
|
7263
8095
|
key: "Mod-ArrowUp",
|
|
7264
8096
|
run: (view) => {
|
|
@@ -7279,7 +8111,7 @@ var keyHandlers = keymap13.of([
|
|
|
7279
8111
|
}
|
|
7280
8112
|
]);
|
|
7281
8113
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7282
|
-
return
|
|
8114
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7283
8115
|
update2.transactions.forEach((transaction) => {
|
|
7284
8116
|
for (const effect of transaction.effects) {
|
|
7285
8117
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7307,11 +8139,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7307
8139
|
anchor: line.from,
|
|
7308
8140
|
head: line.from
|
|
7309
8141
|
},
|
|
7310
|
-
effects:
|
|
7311
|
-
line: line.number,
|
|
7312
|
-
|
|
7313
|
-
offset: -16
|
|
7314
|
-
}
|
|
8142
|
+
effects: scrollerLineEffect.of({
|
|
8143
|
+
line: line.number - 1,
|
|
8144
|
+
offset: -16
|
|
7315
8145
|
})
|
|
7316
8146
|
});
|
|
7317
8147
|
continue;
|
|
@@ -7342,11 +8172,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7342
8172
|
anchor: line.to,
|
|
7343
8173
|
head: line.to
|
|
7344
8174
|
},
|
|
7345
|
-
effects:
|
|
7346
|
-
line: line.number,
|
|
7347
|
-
|
|
7348
|
-
offset: -16
|
|
7349
|
-
}
|
|
8175
|
+
effects: scrollerLineEffect.of({
|
|
8176
|
+
line: line.number - 1,
|
|
8177
|
+
offset: -16
|
|
7350
8178
|
})
|
|
7351
8179
|
});
|
|
7352
8180
|
} else {
|
|
@@ -7356,11 +8184,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7356
8184
|
anchor: line.to,
|
|
7357
8185
|
head: line.to
|
|
7358
8186
|
},
|
|
7359
|
-
effects:
|
|
7360
|
-
line: line.number,
|
|
7361
|
-
|
|
7362
|
-
position: "end"
|
|
7363
|
-
}
|
|
8187
|
+
effects: scrollerLineEffect.of({
|
|
8188
|
+
line: line.number - 1,
|
|
8189
|
+
position: "end"
|
|
7364
8190
|
})
|
|
7365
8191
|
});
|
|
7366
8192
|
}
|
|
@@ -7370,7 +8196,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7370
8196
|
});
|
|
7371
8197
|
});
|
|
7372
8198
|
};
|
|
7373
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8199
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7374
8200
|
update(update2) {
|
|
7375
8201
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7376
8202
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7397,19 +8223,25 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7397
8223
|
}
|
|
7398
8224
|
}
|
|
7399
8225
|
});
|
|
7400
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8226
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7401
8227
|
create: (state) => {
|
|
7402
8228
|
return buildDecorations4(state, {
|
|
7403
8229
|
from: 0,
|
|
7404
8230
|
to: state.doc.length
|
|
7405
8231
|
}, registry, notifier);
|
|
7406
8232
|
},
|
|
7407
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8233
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7408
8234
|
for (const effect of tr.effects) {
|
|
7409
8235
|
if (effect.is(xmlTagResetEffect)) {
|
|
8236
|
+
if (tr.docChanged) {
|
|
8237
|
+
return buildDecorations4(tr.state, {
|
|
8238
|
+
from: 0,
|
|
8239
|
+
to: tr.state.doc.length
|
|
8240
|
+
}, registry, notifier);
|
|
8241
|
+
}
|
|
7410
8242
|
return {
|
|
7411
8243
|
from: 0,
|
|
7412
|
-
decorations:
|
|
8244
|
+
decorations: Decoration18.none
|
|
7413
8245
|
};
|
|
7414
8246
|
}
|
|
7415
8247
|
}
|
|
@@ -7417,27 +8249,26 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7417
8249
|
const { state } = tr;
|
|
7418
8250
|
const reset = tr.changes.touchesRange(0, from);
|
|
7419
8251
|
if (reset) {
|
|
7420
|
-
|
|
8252
|
+
log11("document reset", {
|
|
7421
8253
|
from,
|
|
7422
8254
|
to: state.doc.length
|
|
7423
|
-
}, {
|
|
7424
|
-
F: __dxlog_file16,
|
|
7425
|
-
L: 371,
|
|
7426
|
-
S: void 0,
|
|
7427
|
-
C: (f, a) => f(...a)
|
|
7428
|
-
});
|
|
8255
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7429
8256
|
return buildDecorations4(state, {
|
|
7430
8257
|
from: 0,
|
|
7431
8258
|
to: state.doc.length
|
|
7432
8259
|
}, registry, notifier);
|
|
7433
8260
|
} else {
|
|
8261
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7434
8262
|
const result = buildDecorations4(state, {
|
|
7435
|
-
from,
|
|
8263
|
+
from: rebuildFrom,
|
|
7436
8264
|
to: state.doc.length
|
|
7437
8265
|
}, registry, notifier);
|
|
7438
8266
|
return {
|
|
7439
8267
|
from: result.from,
|
|
8268
|
+
streamingFrom: result.streamingFrom,
|
|
7440
8269
|
decorations: decorations2.update({
|
|
8270
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8271
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7441
8272
|
add: decorationSetToArray(result.decorations)
|
|
7442
8273
|
})
|
|
7443
8274
|
};
|
|
@@ -7445,12 +8276,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7445
8276
|
}
|
|
7446
8277
|
return {
|
|
7447
8278
|
from,
|
|
8279
|
+
streamingFrom,
|
|
7448
8280
|
decorations: decorations2
|
|
7449
8281
|
};
|
|
7450
8282
|
},
|
|
7451
8283
|
provide: (field) => [
|
|
7452
|
-
|
|
7453
|
-
|
|
8284
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8285
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7454
8286
|
]
|
|
7455
8287
|
});
|
|
7456
8288
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7461,10 +8293,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7461
8293
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7462
8294
|
return {
|
|
7463
8295
|
from: range.from,
|
|
7464
|
-
decorations:
|
|
8296
|
+
decorations: Decoration18.none
|
|
7465
8297
|
};
|
|
7466
8298
|
}
|
|
7467
8299
|
let last = range.from;
|
|
8300
|
+
let streamingFrom;
|
|
7468
8301
|
tree.iterate({
|
|
7469
8302
|
from: range.from,
|
|
7470
8303
|
to: range.to,
|
|
@@ -7477,21 +8310,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7477
8310
|
if (args) {
|
|
7478
8311
|
const def = registry[args._tag];
|
|
7479
8312
|
if (def) {
|
|
8313
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8314
|
+
return false;
|
|
8315
|
+
}
|
|
7480
8316
|
const { block, factory, Component } = def;
|
|
7481
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7482
8317
|
const nodeRange = {
|
|
7483
8318
|
from: node.node.from,
|
|
7484
8319
|
to: node.node.to
|
|
7485
8320
|
};
|
|
8321
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8322
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7486
8323
|
const props = {
|
|
7487
|
-
|
|
8324
|
+
id: widgetId,
|
|
7488
8325
|
range: nodeRange,
|
|
8326
|
+
context,
|
|
7489
8327
|
...args,
|
|
7490
8328
|
...widgetState
|
|
7491
8329
|
};
|
|
7492
|
-
const widget = factory ? factory(props) : Component ?
|
|
8330
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7493
8331
|
if (widget) {
|
|
7494
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8332
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7495
8333
|
widget,
|
|
7496
8334
|
block,
|
|
7497
8335
|
atomic: true,
|
|
@@ -7503,20 +8341,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7503
8341
|
}
|
|
7504
8342
|
}
|
|
7505
8343
|
} catch (err) {
|
|
7506
|
-
|
|
7507
|
-
F: __dxlog_file16,
|
|
7508
|
-
L: 456,
|
|
7509
|
-
S: void 0,
|
|
7510
|
-
C: (f, a) => f(...a)
|
|
7511
|
-
});
|
|
8344
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7512
8345
|
}
|
|
7513
8346
|
return false;
|
|
7514
8347
|
}
|
|
7515
8348
|
}
|
|
7516
8349
|
}
|
|
7517
8350
|
});
|
|
8351
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8352
|
+
if (streamingTagNames.length > 0) {
|
|
8353
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8354
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8355
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8356
|
+
let match;
|
|
8357
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8358
|
+
const tagName = match[1];
|
|
8359
|
+
const closeTag = `</${tagName}>`;
|
|
8360
|
+
const afterOpen = match.index + match[0].length;
|
|
8361
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8362
|
+
const absoluteFrom = range.from + match.index;
|
|
8363
|
+
const contentFrom = range.from + afterOpen;
|
|
8364
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8365
|
+
const def = registry[tagName];
|
|
8366
|
+
const props = {
|
|
8367
|
+
_tag: tagName,
|
|
8368
|
+
context,
|
|
8369
|
+
range: {
|
|
8370
|
+
from: absoluteFrom,
|
|
8371
|
+
to: range.to
|
|
8372
|
+
},
|
|
8373
|
+
children: innerText ? [
|
|
8374
|
+
innerText
|
|
8375
|
+
] : void 0
|
|
8376
|
+
};
|
|
8377
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8378
|
+
let attrMatch;
|
|
8379
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8380
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8381
|
+
}
|
|
8382
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8383
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8384
|
+
const mergedProps = {
|
|
8385
|
+
...props,
|
|
8386
|
+
id: widgetId,
|
|
8387
|
+
...widgetState
|
|
8388
|
+
};
|
|
8389
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8390
|
+
if (widget) {
|
|
8391
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8392
|
+
widget,
|
|
8393
|
+
block: def.block,
|
|
8394
|
+
atomic: true,
|
|
8395
|
+
inclusive: true,
|
|
8396
|
+
tag: tagName,
|
|
8397
|
+
streaming: true,
|
|
8398
|
+
contentFrom
|
|
8399
|
+
}));
|
|
8400
|
+
streamingFrom = absoluteFrom;
|
|
8401
|
+
last = absoluteFrom;
|
|
8402
|
+
}
|
|
8403
|
+
break;
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
7518
8407
|
return {
|
|
7519
8408
|
from: last,
|
|
8409
|
+
streamingFrom,
|
|
7520
8410
|
decorations: builder.finish()
|
|
7521
8411
|
};
|
|
7522
8412
|
};
|
|
@@ -7525,108 +8415,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7525
8415
|
Component;
|
|
7526
8416
|
props;
|
|
7527
8417
|
notifier;
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
S: this,
|
|
7535
|
-
A: [
|
|
7536
|
-
"id",
|
|
7537
|
-
""
|
|
7538
|
-
]
|
|
7539
|
-
});
|
|
8418
|
+
streaming;
|
|
8419
|
+
#root = null;
|
|
8420
|
+
#view;
|
|
8421
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8422
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8423
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7540
8424
|
}
|
|
7541
8425
|
get root() {
|
|
7542
|
-
return this
|
|
8426
|
+
return this.#root;
|
|
7543
8427
|
}
|
|
7544
8428
|
eq(other) {
|
|
8429
|
+
if (this.streaming) {
|
|
8430
|
+
return false;
|
|
8431
|
+
}
|
|
7545
8432
|
return this.id === other.id;
|
|
7546
8433
|
}
|
|
7547
8434
|
ignoreEvent() {
|
|
7548
8435
|
return true;
|
|
7549
8436
|
}
|
|
7550
|
-
toDOM(
|
|
7551
|
-
this
|
|
8437
|
+
toDOM(view) {
|
|
8438
|
+
this.#view = view;
|
|
8439
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8440
|
+
const props = Object.assign({}, this.props, {
|
|
8441
|
+
view
|
|
8442
|
+
});
|
|
8443
|
+
this.notifier.mounted({
|
|
8444
|
+
id: this.id,
|
|
8445
|
+
root: this.#root,
|
|
8446
|
+
props,
|
|
8447
|
+
Component: this.Component
|
|
8448
|
+
});
|
|
8449
|
+
return this.#root;
|
|
8450
|
+
}
|
|
8451
|
+
updateDOM(dom) {
|
|
8452
|
+
this.#root = dom;
|
|
8453
|
+
const props = Object.assign({}, this.props, {
|
|
8454
|
+
view: this.#view
|
|
8455
|
+
});
|
|
7552
8456
|
this.notifier.mounted({
|
|
7553
8457
|
id: this.id,
|
|
7554
|
-
root: this
|
|
7555
|
-
props
|
|
8458
|
+
root: this.#root,
|
|
8459
|
+
props,
|
|
7556
8460
|
Component: this.Component
|
|
7557
8461
|
});
|
|
7558
|
-
return
|
|
8462
|
+
return true;
|
|
7559
8463
|
}
|
|
7560
8464
|
destroy(_dom) {
|
|
7561
8465
|
this.notifier.unmounted(this.id);
|
|
7562
|
-
this
|
|
8466
|
+
this.#root = null;
|
|
8467
|
+
this.#view = void 0;
|
|
7563
8468
|
}
|
|
7564
8469
|
};
|
|
7565
|
-
|
|
7566
|
-
// src/extensions/typewriter.ts
|
|
7567
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7568
|
-
var defaultItems = [
|
|
7569
|
-
"hello world!",
|
|
7570
|
-
"this is a test.",
|
|
7571
|
-
"this is [DXOS](https://dxos.org)"
|
|
7572
|
-
];
|
|
7573
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7574
|
-
let t;
|
|
7575
|
-
let idx = 0;
|
|
7576
|
-
return [
|
|
7577
|
-
keymap14.of([
|
|
7578
|
-
{
|
|
7579
|
-
// Reset.
|
|
7580
|
-
key: "alt-meta-'",
|
|
7581
|
-
run: () => {
|
|
7582
|
-
clearTimeout(t);
|
|
7583
|
-
idx = 0;
|
|
7584
|
-
return true;
|
|
7585
|
-
}
|
|
7586
|
-
},
|
|
7587
|
-
{
|
|
7588
|
-
// Next prompt.
|
|
7589
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7590
|
-
key: "Shift-Meta-'",
|
|
7591
|
-
run: (view) => {
|
|
7592
|
-
clearTimeout(t);
|
|
7593
|
-
const text = items[idx++];
|
|
7594
|
-
if (idx === items?.length) {
|
|
7595
|
-
idx = 0;
|
|
7596
|
-
}
|
|
7597
|
-
let i = 0;
|
|
7598
|
-
const insert = (d = 0) => {
|
|
7599
|
-
t = setTimeout(() => {
|
|
7600
|
-
const pos = view.state.selection.main.head;
|
|
7601
|
-
view.dispatch({
|
|
7602
|
-
changes: {
|
|
7603
|
-
from: pos,
|
|
7604
|
-
insert: text[i++]
|
|
7605
|
-
},
|
|
7606
|
-
selection: {
|
|
7607
|
-
anchor: pos + 1
|
|
7608
|
-
}
|
|
7609
|
-
});
|
|
7610
|
-
if (i < text.length) {
|
|
7611
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7612
|
-
}
|
|
7613
|
-
}, d);
|
|
7614
|
-
};
|
|
7615
|
-
insert();
|
|
7616
|
-
return true;
|
|
7617
|
-
}
|
|
7618
|
-
}
|
|
7619
|
-
])
|
|
7620
|
-
];
|
|
7621
|
-
};
|
|
7622
8470
|
export {
|
|
7623
8471
|
Cursor,
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
EditorState3 as EditorState,
|
|
7627
|
-
EditorView30 as EditorView,
|
|
7628
|
-
EditorViewMode,
|
|
7629
|
-
EditorViewModes,
|
|
8472
|
+
EditorState4 as EditorState,
|
|
8473
|
+
EditorView33 as EditorView,
|
|
7630
8474
|
Inline,
|
|
7631
8475
|
InputModeExtensions,
|
|
7632
8476
|
List,
|
|
@@ -7643,6 +8487,7 @@ export {
|
|
|
7643
8487
|
addStyle,
|
|
7644
8488
|
annotations,
|
|
7645
8489
|
autoScroll,
|
|
8490
|
+
autoScrollEffect,
|
|
7646
8491
|
autocomplete,
|
|
7647
8492
|
automerge,
|
|
7648
8493
|
awareness,
|
|
@@ -7656,9 +8501,11 @@ export {
|
|
|
7656
8501
|
commentClickedEffect,
|
|
7657
8502
|
comments,
|
|
7658
8503
|
commentsState,
|
|
8504
|
+
compactSlots,
|
|
7659
8505
|
convertTreeToJson,
|
|
7660
8506
|
createBasicExtensions,
|
|
7661
8507
|
createComment,
|
|
8508
|
+
createCrawler,
|
|
7662
8509
|
createDataExtensions,
|
|
7663
8510
|
createEditorStateStore,
|
|
7664
8511
|
createEditorStateTransaction,
|
|
@@ -7678,12 +8525,12 @@ export {
|
|
|
7678
8525
|
defaultThemeSlots,
|
|
7679
8526
|
deleteItem,
|
|
7680
8527
|
documentId,
|
|
8528
|
+
documentSlots,
|
|
7681
8529
|
dropFile,
|
|
8530
|
+
editorClassNames,
|
|
7682
8531
|
editorInputMode,
|
|
7683
|
-
editorSlots,
|
|
7684
|
-
editorWidth,
|
|
7685
|
-
editorWithToolbarLayout,
|
|
7686
8532
|
extendedMarkdown,
|
|
8533
|
+
fader,
|
|
7687
8534
|
filterChars,
|
|
7688
8535
|
flattenRect,
|
|
7689
8536
|
focus,
|
|
@@ -7719,6 +8566,7 @@ export {
|
|
|
7719
8566
|
markdownTagsExtensions,
|
|
7720
8567
|
matchCompletion,
|
|
7721
8568
|
mention,
|
|
8569
|
+
mobileSlots,
|
|
7722
8570
|
modalStateEffect,
|
|
7723
8571
|
modalStateField,
|
|
7724
8572
|
moveItemDown,
|
|
@@ -7738,10 +8586,12 @@ export {
|
|
|
7738
8586
|
removeList,
|
|
7739
8587
|
removeStyle,
|
|
7740
8588
|
replacer,
|
|
8589
|
+
scrollPastEnd,
|
|
7741
8590
|
scrollThreadIntoView,
|
|
7742
|
-
scrollToBottomEffect,
|
|
7743
8591
|
scrollToLine,
|
|
7744
|
-
|
|
8592
|
+
scroller,
|
|
8593
|
+
scrollerCrawlEffect,
|
|
8594
|
+
scrollerLineEffect,
|
|
7745
8595
|
selectionState,
|
|
7746
8596
|
setBlockquote,
|
|
7747
8597
|
setComments,
|
|
@@ -7749,10 +8599,8 @@ export {
|
|
|
7749
8599
|
setSelection,
|
|
7750
8600
|
setStyle,
|
|
7751
8601
|
singleValueFacet,
|
|
7752
|
-
|
|
7753
|
-
stackItemContentEditorClassNames,
|
|
8602
|
+
snippets2 as snippets,
|
|
7754
8603
|
staticCompletion,
|
|
7755
|
-
streamer,
|
|
7756
8604
|
submit,
|
|
7757
8605
|
tabbable,
|
|
7758
8606
|
table,
|
|
@@ -7771,7 +8619,12 @@ export {
|
|
|
7771
8619
|
treeFacet,
|
|
7772
8620
|
typeahead,
|
|
7773
8621
|
typewriter,
|
|
8622
|
+
typewriterBypass,
|
|
8623
|
+
typewriterDrainingEffect,
|
|
7774
8624
|
wrapWithCatch,
|
|
8625
|
+
xmlBlockDecoration,
|
|
8626
|
+
xmlElementLength,
|
|
8627
|
+
xmlFormatting,
|
|
7775
8628
|
xmlTagContextEffect,
|
|
7776
8629
|
xmlTagResetEffect,
|
|
7777
8630
|
xmlTagUpdateEffect,
|