@dxos/ui-editor 0.8.4-main.9735255 → 0.8.4-main.abd8ff62ef
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 +1852 -1008
- 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 +1849 -1004
- 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.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 +3 -1
- 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 +33 -36
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/auto-scroll.ts +232 -0
- package/src/extensions/automerge/automerge.test.tsx +30 -10
- 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 +62 -15
- 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 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/dist/lib/browser/chunk-HL3YF6WC.mjs +0 -22
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs +0 -24
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +0 -7
- package/dist/types/src/extensions/autoscroll.d.ts +0 -20
- package/dist/types/src/extensions/autoscroll.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling.d.ts +0 -78
- package/dist/types/src/extensions/scrolling.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/streamer.d.ts +0 -12
- package/dist/types/src/extensions/tags/streamer.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts +0 -10
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/dist/types/src/styles/markdown.d.ts +0 -8
- package/dist/types/src/styles/markdown.d.ts.map +0 -1
- package/dist/types/src/styles/tokens.d.ts +0 -3
- package/dist/types/src/styles/tokens.d.ts.map +0 -1
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -1,30 +1,44 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
EditorInputMode,
|
|
4
|
-
EditorInputModes,
|
|
5
|
-
EditorViewMode,
|
|
6
|
-
EditorViewModes
|
|
7
|
-
} from "./chunk-YJZGD3LY.mjs";
|
|
8
2
|
|
|
9
3
|
// src/index.ts
|
|
10
|
-
import { EditorState as
|
|
11
|
-
import { EditorView as
|
|
4
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
5
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
12
6
|
import { tags as tags2 } from "@lezer/highlight";
|
|
13
7
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
14
8
|
|
|
15
9
|
// src/defaults.ts
|
|
16
10
|
import { mx } from "@dxos/ui-theme";
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
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");
|
|
12
|
+
var documentSlots = {
|
|
13
|
+
content: {
|
|
14
|
+
/**
|
|
15
|
+
* CodeMirror content width.
|
|
16
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
17
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
18
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
19
|
+
*/
|
|
20
|
+
className: mx(
|
|
21
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
22
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
23
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
24
|
+
// scroll until a click forces a re-measure.
|
|
25
|
+
"dx-inline-size-container",
|
|
26
|
+
// Wider margin for web (vs. mobile).
|
|
27
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
28
|
+
"mx-auto! w-full"
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var compactSlots = {
|
|
22
33
|
content: {
|
|
23
|
-
className:
|
|
34
|
+
className: "mx-2!"
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var mobileSlots = {
|
|
38
|
+
content: {
|
|
39
|
+
className: "mx-2!"
|
|
24
40
|
}
|
|
25
41
|
};
|
|
26
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
27
|
-
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");
|
|
28
42
|
|
|
29
43
|
// src/extensions/annotations.ts
|
|
30
44
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -59,7 +73,7 @@ var annotations = ({ match } = {}) => {
|
|
|
59
73
|
".cm-annotation": {
|
|
60
74
|
textDecoration: "underline",
|
|
61
75
|
textDecorationStyle: "wavy",
|
|
62
|
-
textDecorationColor: "var(--
|
|
76
|
+
textDecorationColor: "var(--color-error-text)"
|
|
63
77
|
}
|
|
64
78
|
})
|
|
65
79
|
];
|
|
@@ -208,7 +222,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
208
222
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
209
223
|
var defaultCursorConverter = {
|
|
210
224
|
toCursor: (position) => position.toString(),
|
|
211
|
-
fromCursor: (
|
|
225
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
212
226
|
};
|
|
213
227
|
var Cursor = class _Cursor {
|
|
214
228
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -221,9 +235,9 @@ var Cursor = class _Cursor {
|
|
|
221
235
|
to
|
|
222
236
|
].join(":");
|
|
223
237
|
};
|
|
224
|
-
static getRangeFromCursor = (state,
|
|
238
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
225
239
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
226
|
-
const parts =
|
|
240
|
+
const parts = cursor.split(":");
|
|
227
241
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
228
242
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
229
243
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -259,12 +273,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
259
273
|
} catch (err) {
|
|
260
274
|
log.catch(err, {
|
|
261
275
|
label
|
|
262
|
-
}, {
|
|
263
|
-
F: __dxlog_file,
|
|
264
|
-
L: 20,
|
|
265
|
-
S: void 0,
|
|
266
|
-
C: (f, a) => f(...a)
|
|
267
|
-
});
|
|
276
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
268
277
|
}
|
|
269
278
|
};
|
|
270
279
|
};
|
|
@@ -290,12 +299,7 @@ var logChanges = (trs) => {
|
|
|
290
299
|
if (changes.length) {
|
|
291
300
|
log("changes", {
|
|
292
301
|
changes
|
|
293
|
-
}, {
|
|
294
|
-
F: __dxlog_file,
|
|
295
|
-
L: 54,
|
|
296
|
-
S: void 0,
|
|
297
|
-
C: (f, a) => f(...a)
|
|
298
|
-
});
|
|
302
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
299
303
|
}
|
|
300
304
|
};
|
|
301
305
|
|
|
@@ -502,228 +506,336 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
502
506
|
];
|
|
503
507
|
};
|
|
504
508
|
|
|
505
|
-
// src/extensions/
|
|
509
|
+
// src/extensions/auto-scroll.ts
|
|
506
510
|
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
507
511
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
508
|
-
import {
|
|
512
|
+
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
509
513
|
import { Domino } from "@dxos/ui";
|
|
514
|
+
import { getSize } from "@dxos/ui-theme";
|
|
510
515
|
|
|
511
|
-
// src/extensions/
|
|
516
|
+
// src/extensions/scroller.ts
|
|
512
517
|
import { StateEffect } from "@codemirror/state";
|
|
513
518
|
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
514
|
-
|
|
515
|
-
var
|
|
516
|
-
|
|
519
|
+
import { log as log2 } from "@dxos/log";
|
|
520
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
521
|
+
var scrollerLineEffect = StateEffect.define();
|
|
522
|
+
var scrollerCrawlEffect = StateEffect.define();
|
|
523
|
+
var scrollToLine = (view, options) => {
|
|
524
|
+
view.dispatch({
|
|
525
|
+
effects: scrollerLineEffect.of(options)
|
|
526
|
+
});
|
|
527
|
+
};
|
|
528
|
+
var scroller = ({ overScroll = 0 } = {}) => {
|
|
529
|
+
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
517
530
|
view;
|
|
531
|
+
crawler;
|
|
518
532
|
constructor(view) {
|
|
519
533
|
this.view = view;
|
|
534
|
+
this.crawler = createCrawler(this.view);
|
|
520
535
|
}
|
|
521
536
|
// No-op.
|
|
522
537
|
destroy() {
|
|
538
|
+
this.crawler.cancel();
|
|
523
539
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const scroller = this.view.scrollDOM;
|
|
531
|
-
const targetLine = Math.max(0, lineNumber - 1);
|
|
532
|
-
if (behavior === "instant") {
|
|
533
|
-
requestAnimationFrame(() => {
|
|
534
|
-
this.view.dispatch({
|
|
535
|
-
selection: {
|
|
536
|
-
anchor: doc.line(targetLine + 1).from
|
|
537
|
-
},
|
|
538
|
-
scrollIntoView: true
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
if (targetLine >= doc.lines) {
|
|
544
|
-
const targetScrollTop2 = scroller.scrollHeight - scroller.clientHeight + (animOffset || 0);
|
|
545
|
-
this.animateScroll(scroller, targetScrollTop2);
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
const lineStart = doc.line(targetLine + 1).from;
|
|
549
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
550
|
-
if (!coords) {
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
const currentScrollTop = scroller.scrollTop;
|
|
554
|
-
const scrollerRect = scroller.getBoundingClientRect();
|
|
555
|
-
const maxScrollTop = scroller.scrollHeight - scroller.clientHeight;
|
|
556
|
-
let targetScrollTop;
|
|
557
|
-
if (animPosition === "end") {
|
|
558
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + animOffset;
|
|
540
|
+
cancel() {
|
|
541
|
+
this.crawler.cancel();
|
|
542
|
+
}
|
|
543
|
+
crawl(start = false) {
|
|
544
|
+
if (start) {
|
|
545
|
+
this.crawler.scroll();
|
|
559
546
|
} else {
|
|
560
|
-
|
|
547
|
+
this.crawler.cancel();
|
|
561
548
|
}
|
|
562
|
-
const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
563
|
-
this.animateScroll(scroller, clampedScrollTop);
|
|
564
549
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
550
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
551
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
552
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
553
|
+
const doc = this.view.state.doc;
|
|
554
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
555
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
556
|
+
const lineStart = doc.line(line + 1).from;
|
|
557
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
558
|
+
if (coords) {
|
|
559
|
+
const currentScrollTop = scrollTop;
|
|
560
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
561
|
+
if (position === "end") {
|
|
562
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
563
|
+
} else {
|
|
564
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
565
|
+
}
|
|
566
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
567
|
+
}
|
|
571
568
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
569
|
+
requestAnimationFrame(() => {
|
|
570
|
+
this.view.scrollDOM.scrollTo({
|
|
571
|
+
top: targetScrollTop
|
|
572
|
+
});
|
|
575
573
|
});
|
|
576
574
|
}
|
|
577
575
|
});
|
|
578
576
|
return [
|
|
579
577
|
scrollPlugin,
|
|
580
|
-
//
|
|
578
|
+
// Listen for effect.s
|
|
581
579
|
EditorView4.updateListener.of((update2) => {
|
|
582
580
|
update2.transactions.forEach((transaction) => {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
});
|
|
581
|
+
try {
|
|
582
|
+
const plugin = update2.view.plugin(scrollPlugin);
|
|
583
|
+
if (plugin) {
|
|
584
|
+
for (const effect of transaction.effects) {
|
|
585
|
+
if (effect.is(scrollerCrawlEffect)) {
|
|
586
|
+
plugin.crawl(effect.value);
|
|
587
|
+
} else if (effect.is(scrollerLineEffect)) {
|
|
588
|
+
plugin.scroll(effect.value);
|
|
589
|
+
}
|
|
593
590
|
}
|
|
594
591
|
}
|
|
592
|
+
} catch (err) {
|
|
593
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
595
594
|
}
|
|
596
595
|
});
|
|
596
|
+
}),
|
|
597
|
+
// Styles.
|
|
598
|
+
EditorView4.theme({
|
|
599
|
+
".cm-scroller": {
|
|
600
|
+
overflowY: "scroll",
|
|
601
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
602
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
603
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
604
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
605
|
+
overflowAnchor: "auto"
|
|
606
|
+
},
|
|
607
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
608
|
+
display: "none"
|
|
609
|
+
},
|
|
610
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
611
|
+
background: "transparent",
|
|
612
|
+
transition: "background 0.15s"
|
|
613
|
+
},
|
|
614
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
615
|
+
background: "var(--color-scrollbar-thumb)"
|
|
616
|
+
},
|
|
617
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
618
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
619
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
620
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
621
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
622
|
+
".cm-content::after": {
|
|
623
|
+
content: '""',
|
|
624
|
+
display: "block",
|
|
625
|
+
height: `${overScroll}px`
|
|
626
|
+
},
|
|
627
|
+
".cm-scroll-button": {
|
|
628
|
+
position: "absolute",
|
|
629
|
+
bottom: "0.5rem",
|
|
630
|
+
right: "1rem"
|
|
631
|
+
}
|
|
597
632
|
})
|
|
598
633
|
];
|
|
599
634
|
};
|
|
600
|
-
|
|
601
|
-
view.
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
635
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
636
|
+
const el = view.scrollDOM;
|
|
637
|
+
let currentTop = 0;
|
|
638
|
+
let velocity = 0;
|
|
639
|
+
let rafId = null;
|
|
640
|
+
let lastTime = 0;
|
|
641
|
+
function frame(now) {
|
|
642
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
643
|
+
lastTime = now;
|
|
644
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
645
|
+
const delta = targetTop - currentTop;
|
|
646
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
647
|
+
el.scrollTop = targetTop;
|
|
648
|
+
currentTop = targetTop;
|
|
649
|
+
velocity = 0;
|
|
650
|
+
rafId = null;
|
|
651
|
+
lastTime = 0;
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
655
|
+
velocity += accel * dt;
|
|
656
|
+
currentTop += velocity * dt;
|
|
657
|
+
el.scrollTop = currentTop;
|
|
658
|
+
rafId = requestAnimationFrame(frame);
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
scroll: () => {
|
|
662
|
+
if (rafId === null) {
|
|
663
|
+
currentTop = el.scrollTop;
|
|
664
|
+
lastTime = 0;
|
|
665
|
+
rafId = requestAnimationFrame(frame);
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
cancel: () => {
|
|
669
|
+
if (rafId !== null) {
|
|
670
|
+
cancelAnimationFrame(rafId);
|
|
671
|
+
velocity = 0;
|
|
672
|
+
lastTime = 0;
|
|
673
|
+
rafId = null;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
}
|
|
608
678
|
|
|
609
|
-
// src/extensions/
|
|
610
|
-
var
|
|
611
|
-
var autoScroll = ({
|
|
679
|
+
// src/extensions/auto-scroll.ts
|
|
680
|
+
var autoScrollEffect = StateEffect2.define();
|
|
681
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
612
682
|
let buttonContainer;
|
|
613
|
-
let hideTimeout;
|
|
614
|
-
let lastScrollTop = 0;
|
|
615
683
|
let isPinned = true;
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
clearTimeout(hideTimeout);
|
|
623
|
-
hideTimeout = setTimeout(() => {
|
|
624
|
-
view.scrollDOM.classList.remove("cm-hide-scrollbar");
|
|
625
|
-
}, 1e3);
|
|
684
|
+
let jumpPending = false;
|
|
685
|
+
let enabled = true;
|
|
686
|
+
let firstUpdate = true;
|
|
687
|
+
const setPinned = (pinned) => {
|
|
688
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
689
|
+
isPinned = pinned;
|
|
626
690
|
};
|
|
627
|
-
const scrollToBottom = (view, behavior) => {
|
|
628
|
-
setPinned(true);
|
|
629
|
-
hideScrollbar(view);
|
|
630
|
-
const line = view.state.doc.lineAt(view.state.doc.length);
|
|
631
|
-
view.dispatch({
|
|
632
|
-
selection: {
|
|
633
|
-
anchor: line.to,
|
|
634
|
-
head: line.to
|
|
635
|
-
},
|
|
636
|
-
effects: scrollToLineEffect.of({
|
|
637
|
-
line: line.number,
|
|
638
|
-
options: {
|
|
639
|
-
position: "end",
|
|
640
|
-
offset: threshold,
|
|
641
|
-
behavior
|
|
642
|
-
}
|
|
643
|
-
})
|
|
644
|
-
});
|
|
645
|
-
};
|
|
646
|
-
const checkDistance = debounce((view) => {
|
|
647
|
-
const scrollerRect = view.scrollDOM.getBoundingClientRect();
|
|
648
|
-
const coords = view.coordsAtPos(view.state.doc.length);
|
|
649
|
-
const distanceFromBottom = coords ? coords.bottom - scrollerRect.bottom : 0;
|
|
650
|
-
setPinned(distanceFromBottom < 0);
|
|
651
|
-
}, 1e3);
|
|
652
|
-
const triggerUpdate = debounce((view) => scrollToBottom(view), throttleDelay);
|
|
653
691
|
return [
|
|
654
|
-
// Update listener for
|
|
655
|
-
EditorView5.updateListener.of((
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
692
|
+
// Update listener for scrolling when content changes.
|
|
693
|
+
EditorView5.updateListener.of((update2) => {
|
|
694
|
+
const { view, heightChanged, state, startState } = update2;
|
|
695
|
+
for (const tr of update2.transactions) {
|
|
696
|
+
for (const effect of tr.effects) {
|
|
697
|
+
if (effect.is(autoScrollEffect)) {
|
|
698
|
+
enabled = effect.value;
|
|
699
|
+
if (enabled) {
|
|
700
|
+
setPinned(true);
|
|
701
|
+
view.dispatch({
|
|
702
|
+
effects: scrollerCrawlEffect.of(true)
|
|
703
|
+
});
|
|
704
|
+
} else {
|
|
705
|
+
view.dispatch({
|
|
706
|
+
effects: scrollerCrawlEffect.of(false)
|
|
707
|
+
});
|
|
708
|
+
}
|
|
660
709
|
}
|
|
661
710
|
}
|
|
662
|
-
}
|
|
663
|
-
if (
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
711
|
+
}
|
|
712
|
+
if (!enabled) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
716
|
+
firstUpdate = false;
|
|
717
|
+
jumpPending = true;
|
|
718
|
+
requestAnimationFrame(() => {
|
|
719
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
720
|
+
jumpPending = false;
|
|
721
|
+
});
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
firstUpdate = false;
|
|
725
|
+
if (jumpPending) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
if (heightChanged) {
|
|
729
|
+
if (isPinned) {
|
|
730
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
731
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
732
|
+
if (delta > 0) {
|
|
733
|
+
setPinned(true);
|
|
734
|
+
view.dispatch({
|
|
735
|
+
effects: scrollerCrawlEffect.of(true)
|
|
736
|
+
});
|
|
737
|
+
} else if (delta < -1) {
|
|
738
|
+
setPinned(false);
|
|
739
|
+
}
|
|
740
|
+
} else {
|
|
741
|
+
if (state.doc.length === 0) {
|
|
742
|
+
setPinned(true);
|
|
674
743
|
}
|
|
675
|
-
} else if (distanceFromBottom < 0) {
|
|
676
|
-
setPinned(false);
|
|
677
744
|
}
|
|
678
745
|
}
|
|
679
746
|
}),
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
747
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
748
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
749
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
750
|
+
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
751
|
+
observer;
|
|
752
|
+
firstObservation = true;
|
|
753
|
+
destroyed = false;
|
|
754
|
+
constructor(view) {
|
|
755
|
+
const onResize = throttle(() => {
|
|
756
|
+
if (this.destroyed || !enabled) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
setPinned(true);
|
|
760
|
+
requestAnimationFrame(() => {
|
|
761
|
+
if (this.destroyed) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
765
|
+
view.dispatch({
|
|
766
|
+
effects: scrollerCrawlEffect.of(true)
|
|
767
|
+
});
|
|
768
|
+
});
|
|
769
|
+
}, 100);
|
|
770
|
+
this.observer = new ResizeObserver(() => {
|
|
771
|
+
if (this.firstObservation) {
|
|
772
|
+
this.firstObservation = false;
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
onResize();
|
|
776
|
+
});
|
|
777
|
+
this.observer.observe(view.scrollDOM);
|
|
778
|
+
}
|
|
779
|
+
destroy() {
|
|
780
|
+
this.destroyed = true;
|
|
781
|
+
this.observer.disconnect();
|
|
782
|
+
}
|
|
783
|
+
}) : [],
|
|
784
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
785
|
+
ViewPlugin6.fromClass(class {
|
|
786
|
+
cleanup;
|
|
787
|
+
constructor(view) {
|
|
788
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
789
|
+
requestAnimationFrame(() => {
|
|
790
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
791
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
792
|
+
const pinned = delta === 0;
|
|
793
|
+
setPinned(pinned);
|
|
794
|
+
if (!pinned) {
|
|
795
|
+
view.dispatch({
|
|
796
|
+
effects: scrollerCrawlEffect.of(false)
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
}, 500));
|
|
801
|
+
}
|
|
802
|
+
destroy() {
|
|
803
|
+
this.cleanup();
|
|
691
804
|
}
|
|
692
805
|
}),
|
|
693
806
|
// Scroll button.
|
|
694
807
|
ViewPlugin6.fromClass(class {
|
|
695
808
|
constructor(view) {
|
|
696
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
809
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
697
810
|
icon: "ph--arrow-down--regular"
|
|
698
811
|
});
|
|
699
|
-
const button = Domino.of("button").classNames("dx-button bg-
|
|
812
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
700
813
|
"data-density": "fine"
|
|
701
|
-
}).
|
|
702
|
-
|
|
814
|
+
}).append(icon).on("click", () => {
|
|
815
|
+
setPinned(true);
|
|
816
|
+
view.dispatch({
|
|
817
|
+
effects: scrollerLineEffect.of({
|
|
818
|
+
line: -1,
|
|
819
|
+
position: "end",
|
|
820
|
+
behavior: "smooth"
|
|
821
|
+
})
|
|
822
|
+
});
|
|
703
823
|
});
|
|
704
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").
|
|
824
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
705
825
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
706
826
|
}
|
|
707
|
-
}),
|
|
708
|
-
// Styles.
|
|
709
|
-
EditorView5.theme({
|
|
710
|
-
".cm-scroller": {
|
|
711
|
-
scrollbarWidth: "thin"
|
|
712
|
-
},
|
|
713
|
-
".cm-scroller.cm-hide-scrollbar": {
|
|
714
|
-
scrollbarWidth: "none"
|
|
715
|
-
},
|
|
716
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
717
|
-
display: "none"
|
|
718
|
-
},
|
|
719
|
-
".cm-scroll-button": {
|
|
720
|
-
position: "absolute",
|
|
721
|
-
bottom: "0.5rem",
|
|
722
|
-
right: "1rem"
|
|
723
|
-
}
|
|
724
827
|
})
|
|
725
828
|
];
|
|
726
829
|
};
|
|
830
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
831
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
832
|
+
passive: true
|
|
833
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
834
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
835
|
+
onUserScroll();
|
|
836
|
+
}
|
|
837
|
+
}));
|
|
838
|
+
}
|
|
727
839
|
|
|
728
840
|
// src/extensions/automerge/automerge.ts
|
|
729
841
|
import { next as A3 } from "@automerge/automerge";
|
|
@@ -737,32 +849,22 @@ var initialSync = Transaction.userEvent.of("initial.sync");
|
|
|
737
849
|
|
|
738
850
|
// src/extensions/automerge/cursor.ts
|
|
739
851
|
import { fromCursor, toCursor } from "@dxos/echo-db";
|
|
740
|
-
import { log as
|
|
741
|
-
var
|
|
852
|
+
import { log as log3 } from "@dxos/log";
|
|
853
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
742
854
|
var cursorConverter = (accessor) => ({
|
|
743
855
|
toCursor: (pos, assoc) => {
|
|
744
856
|
try {
|
|
745
857
|
return toCursor(accessor, pos, assoc);
|
|
746
858
|
} catch (err) {
|
|
747
|
-
|
|
748
|
-
F: __dxlog_file2,
|
|
749
|
-
L: 15,
|
|
750
|
-
S: void 0,
|
|
751
|
-
C: (f, a) => f(...a)
|
|
752
|
-
});
|
|
859
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
753
860
|
return "";
|
|
754
861
|
}
|
|
755
862
|
},
|
|
756
|
-
fromCursor: (
|
|
863
|
+
fromCursor: (cursor) => {
|
|
757
864
|
try {
|
|
758
|
-
return fromCursor(accessor,
|
|
865
|
+
return fromCursor(accessor, cursor);
|
|
759
866
|
} catch (err) {
|
|
760
|
-
|
|
761
|
-
F: __dxlog_file2,
|
|
762
|
-
L: 24,
|
|
763
|
-
S: void 0,
|
|
764
|
-
C: (f, a) => f(...a)
|
|
765
|
-
});
|
|
867
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
766
868
|
return 0;
|
|
767
869
|
}
|
|
768
870
|
}
|
|
@@ -783,7 +885,7 @@ var isReconcile = (tr) => {
|
|
|
783
885
|
|
|
784
886
|
// src/extensions/automerge/sync.ts
|
|
785
887
|
import { next as A2 } from "@automerge/automerge";
|
|
786
|
-
import { log as
|
|
888
|
+
import { log as log4 } from "@dxos/log";
|
|
787
889
|
|
|
788
890
|
// src/extensions/automerge/update-automerge.ts
|
|
789
891
|
import { next as A } from "@automerge/automerge";
|
|
@@ -924,7 +1026,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
924
1026
|
};
|
|
925
1027
|
|
|
926
1028
|
// src/extensions/automerge/sync.ts
|
|
927
|
-
var
|
|
1029
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
928
1030
|
var Syncer = class {
|
|
929
1031
|
_handle;
|
|
930
1032
|
_state;
|
|
@@ -947,12 +1049,7 @@ var Syncer = class {
|
|
|
947
1049
|
this._pending = false;
|
|
948
1050
|
}
|
|
949
1051
|
onEditorChange(view) {
|
|
950
|
-
|
|
951
|
-
F: __dxlog_file3,
|
|
952
|
-
L: 45,
|
|
953
|
-
S: this,
|
|
954
|
-
C: (f, a) => f(...a)
|
|
955
|
-
});
|
|
1052
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
956
1053
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
957
1054
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
958
1055
|
if (newHeads) {
|
|
@@ -963,12 +1060,7 @@ var Syncer = class {
|
|
|
963
1060
|
}
|
|
964
1061
|
}
|
|
965
1062
|
onAutomergeChange(view) {
|
|
966
|
-
|
|
967
|
-
F: __dxlog_file3,
|
|
968
|
-
L: 60,
|
|
969
|
-
S: this,
|
|
970
|
-
C: (f, a) => f(...a)
|
|
971
|
-
});
|
|
1063
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
972
1064
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
973
1065
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
974
1066
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1030,6 +1122,17 @@ var automerge = (accessor) => {
|
|
|
1030
1122
|
const value = DocAccessor.getValue(accessor);
|
|
1031
1123
|
const current = this._view.state.doc.toString();
|
|
1032
1124
|
if (value !== current) {
|
|
1125
|
+
this._view.dispatch({
|
|
1126
|
+
changes: {
|
|
1127
|
+
from: 0,
|
|
1128
|
+
to: this._view.state.doc.length,
|
|
1129
|
+
insert: value
|
|
1130
|
+
},
|
|
1131
|
+
annotations: [
|
|
1132
|
+
initialSync,
|
|
1133
|
+
reconcileAnnotation.of(true)
|
|
1134
|
+
]
|
|
1135
|
+
});
|
|
1033
1136
|
}
|
|
1034
1137
|
});
|
|
1035
1138
|
}
|
|
@@ -1057,7 +1160,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
|
1057
1160
|
import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1058
1161
|
import { Event } from "@dxos/async";
|
|
1059
1162
|
import { Context } from "@dxos/context";
|
|
1060
|
-
var
|
|
1163
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1061
1164
|
var dummyProvider = {
|
|
1062
1165
|
remoteStateChange: new Event(),
|
|
1063
1166
|
open: () => {
|
|
@@ -1080,10 +1183,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1080
1183
|
];
|
|
1081
1184
|
};
|
|
1082
1185
|
var RemoteSelectionsDecorator = class {
|
|
1083
|
-
_ctx = new Context(void 0, {
|
|
1084
|
-
F: __dxlog_file4,
|
|
1085
|
-
L: 80
|
|
1086
|
-
});
|
|
1186
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1087
1187
|
_cursorConverter;
|
|
1088
1188
|
_provider;
|
|
1089
1189
|
_lastAnchor;
|
|
@@ -1294,8 +1394,8 @@ var styles = EditorView7.theme({
|
|
|
1294
1394
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1295
1395
|
import { Context as Context2 } from "@dxos/context";
|
|
1296
1396
|
import { invariant } from "@dxos/invariant";
|
|
1297
|
-
import { log as
|
|
1298
|
-
var
|
|
1397
|
+
import { log as log5 } from "@dxos/log";
|
|
1398
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1299
1399
|
var DEBOUNCE_INTERVAL = 100;
|
|
1300
1400
|
var SpaceAwarenessProvider = class {
|
|
1301
1401
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1314,10 +1414,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1314
1414
|
this._info = info;
|
|
1315
1415
|
}
|
|
1316
1416
|
open() {
|
|
1317
|
-
this._ctx = new Context2(void 0, {
|
|
1318
|
-
F: __dxlog_file5,
|
|
1319
|
-
L: 57
|
|
1320
|
-
});
|
|
1417
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1321
1418
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1322
1419
|
if (this._localState) {
|
|
1323
1420
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1342,14 +1439,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1342
1439
|
void this._messenger.postMessage(this._channel, {
|
|
1343
1440
|
kind: "query"
|
|
1344
1441
|
}).catch((err) => {
|
|
1345
|
-
|
|
1442
|
+
log5.debug("failed to query awareness", {
|
|
1346
1443
|
err
|
|
1347
|
-
}, {
|
|
1348
|
-
F: __dxlog_file5,
|
|
1349
|
-
L: 91,
|
|
1350
|
-
S: this,
|
|
1351
|
-
C: (f, a) => f(...a)
|
|
1352
|
-
});
|
|
1444
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1353
1445
|
});
|
|
1354
1446
|
}
|
|
1355
1447
|
close() {
|
|
@@ -1361,15 +1453,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1361
1453
|
return Array.from(this._remoteStates.values());
|
|
1362
1454
|
}
|
|
1363
1455
|
update(position) {
|
|
1364
|
-
invariant(this._postTask, void 0, {
|
|
1365
|
-
F: __dxlog_file5,
|
|
1366
|
-
L: 106,
|
|
1367
|
-
S: this,
|
|
1368
|
-
A: [
|
|
1369
|
-
"this._postTask",
|
|
1370
|
-
""
|
|
1371
|
-
]
|
|
1372
|
-
});
|
|
1456
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1373
1457
|
this._localState = {
|
|
1374
1458
|
peerId: this._peerId,
|
|
1375
1459
|
position,
|
|
@@ -1378,27 +1462,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1378
1462
|
this._postTask.schedule();
|
|
1379
1463
|
}
|
|
1380
1464
|
_handleQueryMessage() {
|
|
1381
|
-
invariant(this._postTask, void 0, {
|
|
1382
|
-
F: __dxlog_file5,
|
|
1383
|
-
L: 117,
|
|
1384
|
-
S: this,
|
|
1385
|
-
A: [
|
|
1386
|
-
"this._postTask",
|
|
1387
|
-
""
|
|
1388
|
-
]
|
|
1389
|
-
});
|
|
1465
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1390
1466
|
this._postTask.schedule();
|
|
1391
1467
|
}
|
|
1392
1468
|
_handlePostMessage(message) {
|
|
1393
|
-
invariant(message.kind === "post", void 0, {
|
|
1394
|
-
F: __dxlog_file5,
|
|
1395
|
-
L: 122,
|
|
1396
|
-
S: this,
|
|
1397
|
-
A: [
|
|
1398
|
-
"message.kind === 'post'",
|
|
1399
|
-
""
|
|
1400
|
-
]
|
|
1401
|
-
});
|
|
1469
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1402
1470
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1403
1471
|
this.remoteStateChange.emit();
|
|
1404
1472
|
}
|
|
@@ -1407,9 +1475,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1407
1475
|
// src/extensions/blast.ts
|
|
1408
1476
|
import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
|
|
1409
1477
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1410
|
-
import { throttle } from "@dxos/async";
|
|
1478
|
+
import { throttle as throttle2 } from "@dxos/async";
|
|
1411
1479
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1412
|
-
var
|
|
1480
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1413
1481
|
var defaultOptions = {
|
|
1414
1482
|
effect: 2,
|
|
1415
1483
|
maxParticles: 200,
|
|
@@ -1527,15 +1595,7 @@ var Blaster = class {
|
|
|
1527
1595
|
return this._node;
|
|
1528
1596
|
}
|
|
1529
1597
|
initialize() {
|
|
1530
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1531
|
-
F: __dxlog_file6,
|
|
1532
|
-
L: 142,
|
|
1533
|
-
S: this,
|
|
1534
|
-
A: [
|
|
1535
|
-
"!this._canvas && !this._ctx",
|
|
1536
|
-
""
|
|
1537
|
-
]
|
|
1538
|
-
});
|
|
1598
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1539
1599
|
this._canvas = document.createElement("canvas");
|
|
1540
1600
|
this._canvas.id = "code-blast-canvas";
|
|
1541
1601
|
this._canvas.style.position = "absolute";
|
|
@@ -1564,15 +1624,7 @@ var Blaster = class {
|
|
|
1564
1624
|
}
|
|
1565
1625
|
}
|
|
1566
1626
|
start() {
|
|
1567
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1568
|
-
F: __dxlog_file6,
|
|
1569
|
-
L: 181,
|
|
1570
|
-
S: this,
|
|
1571
|
-
A: [
|
|
1572
|
-
"this._canvas && this._ctx",
|
|
1573
|
-
""
|
|
1574
|
-
]
|
|
1575
|
-
});
|
|
1627
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1576
1628
|
this._running = true;
|
|
1577
1629
|
this.loop();
|
|
1578
1630
|
}
|
|
@@ -1599,11 +1651,11 @@ var Blaster = class {
|
|
|
1599
1651
|
this.drawParticles();
|
|
1600
1652
|
requestAnimationFrame(this.loop.bind(this));
|
|
1601
1653
|
}
|
|
1602
|
-
shake =
|
|
1654
|
+
shake = throttle2(({ time }) => {
|
|
1603
1655
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1604
1656
|
this._shakeTimeMax = time;
|
|
1605
1657
|
}, 100);
|
|
1606
|
-
spawn =
|
|
1658
|
+
spawn = throttle2(({ element, point }) => {
|
|
1607
1659
|
const color = getRGBComponents(element, this._options.color);
|
|
1608
1660
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1609
1661
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1777,11 +1829,11 @@ var blocks = () => [
|
|
|
1777
1829
|
".cm-line.block-line": {
|
|
1778
1830
|
paddingLeft: "0.75rem",
|
|
1779
1831
|
paddingRight: "0.75rem",
|
|
1780
|
-
borderLeft: "1px solid var(--
|
|
1781
|
-
borderRight: "1px solid var(--
|
|
1832
|
+
borderLeft: "1px solid var(--color-subdued-separator)",
|
|
1833
|
+
borderRight: "1px solid var(--color-subdued-separator)"
|
|
1782
1834
|
},
|
|
1783
1835
|
".cm-line.block-single": {
|
|
1784
|
-
border: "1px solid var(--
|
|
1836
|
+
border: "1px solid var(--color-subdued-separator)",
|
|
1785
1837
|
borderRadius: "6px",
|
|
1786
1838
|
paddingTop: "0.5rem",
|
|
1787
1839
|
paddingBottom: "0.5rem",
|
|
@@ -1789,7 +1841,7 @@ var blocks = () => [
|
|
|
1789
1841
|
marginBottom: "0.5rem"
|
|
1790
1842
|
},
|
|
1791
1843
|
".cm-line.block-first": {
|
|
1792
|
-
borderTop: "1px solid var(--
|
|
1844
|
+
borderTop: "1px solid var(--color-subdued-separator)",
|
|
1793
1845
|
borderTopLeftRadius: "6px",
|
|
1794
1846
|
borderTopRightRadius: "6px",
|
|
1795
1847
|
paddingTop: "0.5rem",
|
|
@@ -1797,7 +1849,7 @@ var blocks = () => [
|
|
|
1797
1849
|
},
|
|
1798
1850
|
".cm-line.block-middle": {},
|
|
1799
1851
|
".cm-line.block-last": {
|
|
1800
|
-
borderBottom: "1px solid var(--
|
|
1852
|
+
borderBottom: "1px solid var(--color-subdued-separator)",
|
|
1801
1853
|
borderBottomLeftRadius: "6px",
|
|
1802
1854
|
borderBottomRightRadius: "6px",
|
|
1803
1855
|
paddingBottom: "0.5rem",
|
|
@@ -1809,8 +1861,8 @@ var blocks = () => [
|
|
|
1809
1861
|
// src/extensions/bookmarks.ts
|
|
1810
1862
|
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1811
1863
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1812
|
-
import { log as
|
|
1813
|
-
var
|
|
1864
|
+
import { log as log6 } from "@dxos/log";
|
|
1865
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1814
1866
|
var addBookmark = StateEffect4.define();
|
|
1815
1867
|
var removeBookmark = StateEffect4.define();
|
|
1816
1868
|
var clearBookmarks = StateEffect4.define();
|
|
@@ -1822,12 +1874,7 @@ var bookmarks = () => {
|
|
|
1822
1874
|
key: "Mod-ArrowUp",
|
|
1823
1875
|
run: (view) => {
|
|
1824
1876
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1825
|
-
|
|
1826
|
-
F: __dxlog_file7,
|
|
1827
|
-
L: 29,
|
|
1828
|
-
S: void 0,
|
|
1829
|
-
C: (f, a) => f(...a)
|
|
1830
|
-
});
|
|
1877
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1831
1878
|
return true;
|
|
1832
1879
|
}
|
|
1833
1880
|
},
|
|
@@ -1835,12 +1882,7 @@ var bookmarks = () => {
|
|
|
1835
1882
|
key: "Mod-ArrowDown",
|
|
1836
1883
|
run: (view) => {
|
|
1837
1884
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1838
|
-
|
|
1839
|
-
F: __dxlog_file7,
|
|
1840
|
-
L: 37,
|
|
1841
|
-
S: void 0,
|
|
1842
|
-
C: (f, a) => f(...a)
|
|
1843
|
-
});
|
|
1885
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1844
1886
|
return true;
|
|
1845
1887
|
}
|
|
1846
1888
|
}
|
|
@@ -1880,19 +1922,19 @@ import { invertedEffects } from "@codemirror/commands";
|
|
|
1880
1922
|
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1881
1923
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1882
1924
|
import sortBy from "lodash.sortby";
|
|
1883
|
-
import { debounce as
|
|
1884
|
-
import { log as
|
|
1925
|
+
import { debounce as debounce2 } from "@dxos/async";
|
|
1926
|
+
import { log as log7 } from "@dxos/log";
|
|
1885
1927
|
import { isNonNullable } from "@dxos/util";
|
|
1886
1928
|
|
|
1887
1929
|
// src/extensions/selection.ts
|
|
1888
1930
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1889
1931
|
import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view";
|
|
1890
|
-
import { debounce
|
|
1932
|
+
import { debounce } from "@dxos/async";
|
|
1891
1933
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1892
1934
|
import { isTruthy } from "@dxos/util";
|
|
1893
|
-
var
|
|
1935
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1894
1936
|
var documentId = singleValueFacet();
|
|
1895
|
-
var stateRestoreAnnotation = "dxos.
|
|
1937
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1896
1938
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1897
1939
|
return {
|
|
1898
1940
|
selection,
|
|
@@ -1905,33 +1947,17 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1905
1947
|
};
|
|
1906
1948
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1907
1949
|
getState: (id) => {
|
|
1908
|
-
invariant3(id, void 0, {
|
|
1909
|
-
F: __dxlog_file8,
|
|
1910
|
-
L: 47,
|
|
1911
|
-
S: void 0,
|
|
1912
|
-
A: [
|
|
1913
|
-
"id",
|
|
1914
|
-
""
|
|
1915
|
-
]
|
|
1916
|
-
});
|
|
1950
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1917
1951
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1918
1952
|
return state ? JSON.parse(state) : void 0;
|
|
1919
1953
|
},
|
|
1920
1954
|
setState: (id, state) => {
|
|
1921
|
-
invariant3(id, void 0, {
|
|
1922
|
-
F: __dxlog_file8,
|
|
1923
|
-
L: 53,
|
|
1924
|
-
S: void 0,
|
|
1925
|
-
A: [
|
|
1926
|
-
"id",
|
|
1927
|
-
""
|
|
1928
|
-
]
|
|
1929
|
-
});
|
|
1955
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1930
1956
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1931
1957
|
}
|
|
1932
1958
|
});
|
|
1933
1959
|
var selectionState = ({ getState, setState } = {}) => {
|
|
1934
|
-
const setStateDebounced =
|
|
1960
|
+
const setStateDebounced = debounce(setState, 1e3);
|
|
1935
1961
|
return [
|
|
1936
1962
|
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
1937
1963
|
// EditorView.domEventHandlers({
|
|
@@ -1978,7 +2004,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1978
2004
|
};
|
|
1979
2005
|
|
|
1980
2006
|
// src/extensions/comments.ts
|
|
1981
|
-
var
|
|
2007
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1982
2008
|
var setComments = StateEffect5.define();
|
|
1983
2009
|
var setSelection = StateEffect5.define();
|
|
1984
2010
|
var setCommentState = StateEffect5.define();
|
|
@@ -2023,14 +2049,14 @@ var commentsState = StateField3.define({
|
|
|
2023
2049
|
var styles2 = EditorView11.theme({
|
|
2024
2050
|
".cm-comment, .cm-comment-current": {
|
|
2025
2051
|
padding: "3px 0",
|
|
2026
|
-
color: "var(--
|
|
2027
|
-
backgroundColor: "var(--
|
|
2052
|
+
color: "var(--color-cm-comment-text)",
|
|
2053
|
+
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2028
2054
|
},
|
|
2029
2055
|
".cm-comment > span, .cm-comment-current > span": {
|
|
2030
2056
|
boxDecorationBreak: "clone",
|
|
2031
|
-
boxShadow: "0 0 1px 3px var(--
|
|
2032
|
-
backgroundColor: "var(--
|
|
2033
|
-
color: "var(--
|
|
2057
|
+
boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
|
|
2058
|
+
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2059
|
+
color: "var(--color-cm-comment-text)",
|
|
2034
2060
|
cursor: "pointer"
|
|
2035
2061
|
}
|
|
2036
2062
|
});
|
|
@@ -2048,12 +2074,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2048
2074
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2049
2075
|
const range = comment.range;
|
|
2050
2076
|
if (!range) {
|
|
2051
|
-
|
|
2052
|
-
F: __dxlog_file9,
|
|
2053
|
-
L: 140,
|
|
2054
|
-
S: void 0,
|
|
2055
|
-
C: (f, a) => f(...a)
|
|
2056
|
-
});
|
|
2077
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2057
2078
|
return void 0;
|
|
2058
2079
|
} else if (range.from === range.to) {
|
|
2059
2080
|
return void 0;
|
|
@@ -2166,10 +2187,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2166
2187
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2167
2188
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2168
2189
|
if (!exists) {
|
|
2169
|
-
const
|
|
2190
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2170
2191
|
onUpdate({
|
|
2171
2192
|
id: comment.id,
|
|
2172
|
-
cursor
|
|
2193
|
+
cursor
|
|
2173
2194
|
});
|
|
2174
2195
|
}
|
|
2175
2196
|
}
|
|
@@ -2198,13 +2219,13 @@ var createComment = (view) => {
|
|
|
2198
2219
|
}
|
|
2199
2220
|
});
|
|
2200
2221
|
}
|
|
2201
|
-
const
|
|
2222
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2202
2223
|
from,
|
|
2203
2224
|
to
|
|
2204
2225
|
});
|
|
2205
|
-
if (
|
|
2226
|
+
if (cursor) {
|
|
2206
2227
|
options.onCreate?.({
|
|
2207
|
-
cursor
|
|
2228
|
+
cursor,
|
|
2208
2229
|
from,
|
|
2209
2230
|
location: view.coordsAtPos(from)
|
|
2210
2231
|
});
|
|
@@ -2215,7 +2236,7 @@ var createComment = (view) => {
|
|
|
2215
2236
|
var optionsFacet = singleValueFacet();
|
|
2216
2237
|
var comments = (options = {}) => {
|
|
2217
2238
|
const { key: shortcut = "meta-'" } = options;
|
|
2218
|
-
const handleSelect =
|
|
2239
|
+
const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
|
|
2219
2240
|
return [
|
|
2220
2241
|
optionsFacet.of(options),
|
|
2221
2242
|
options.id ? documentId.of(options.id) : void 0,
|
|
@@ -2393,9 +2414,9 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fro
|
|
|
2393
2414
|
// src/extensions/debug.ts
|
|
2394
2415
|
import { syntaxTree } from "@codemirror/language";
|
|
2395
2416
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
2396
|
-
var debugNodeLogger = (
|
|
2417
|
+
var debugNodeLogger = (log12 = console.log) => {
|
|
2397
2418
|
const logTokens = (state) => syntaxTree(state).iterate({
|
|
2398
|
-
enter: (node) =>
|
|
2419
|
+
enter: (node) => log12(node.type)
|
|
2399
2420
|
});
|
|
2400
2421
|
return StateField4.define({
|
|
2401
2422
|
create: (state) => logTokens(state),
|
|
@@ -2430,8 +2451,8 @@ var dropFile = (options = {}) => {
|
|
|
2430
2451
|
};
|
|
2431
2452
|
var styles3 = EditorView12.theme({
|
|
2432
2453
|
".cm-dropCursor": {
|
|
2433
|
-
borderLeft: "2px solid var(--
|
|
2434
|
-
color: "var(--
|
|
2454
|
+
borderLeft: "2px solid var(--color-accent-text)",
|
|
2455
|
+
color: "var(--color-accent-text)",
|
|
2435
2456
|
padding: "0 4px"
|
|
2436
2457
|
},
|
|
2437
2458
|
".cm-dropCursor:after": {
|
|
@@ -2445,47 +2466,66 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2445
2466
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2446
2467
|
import { searchKeymap } from "@codemirror/search";
|
|
2447
2468
|
import { EditorState } from "@codemirror/state";
|
|
2448
|
-
import { EditorView as
|
|
2469
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2449
2470
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2450
2471
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2451
2472
|
import { generateName } from "@dxos/display-name";
|
|
2452
|
-
import { log as
|
|
2473
|
+
import { log as log8 } from "@dxos/log";
|
|
2453
2474
|
import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
|
|
2454
2475
|
|
|
2455
|
-
// src/styles/
|
|
2476
|
+
// src/styles/theme.ts
|
|
2477
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
2456
2478
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2457
2479
|
var headings = {
|
|
2458
|
-
1:
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2480
|
+
1: {
|
|
2481
|
+
className: "text-3xl",
|
|
2482
|
+
fontSize: "var(--text-3xl)",
|
|
2483
|
+
lineHeight: "var(--text-4xl--line-height)"
|
|
2484
|
+
},
|
|
2485
|
+
2: {
|
|
2486
|
+
className: "text-2xl",
|
|
2487
|
+
fontSize: "var(--text-2xl)",
|
|
2488
|
+
lineHeight: "var(--text-3xl--line-height)"
|
|
2489
|
+
},
|
|
2490
|
+
3: {
|
|
2491
|
+
className: "text-xl",
|
|
2492
|
+
fontSize: "var(--text-xl)",
|
|
2493
|
+
lineHeight: "var(--text-2xl--line-height)"
|
|
2494
|
+
},
|
|
2495
|
+
4: {
|
|
2496
|
+
className: "text-lg",
|
|
2497
|
+
fontSize: "var(--text-lg)",
|
|
2498
|
+
lineHeight: "var(--text-xl--line-height)"
|
|
2499
|
+
},
|
|
2500
|
+
5: {
|
|
2501
|
+
className: "text-base",
|
|
2502
|
+
fontSize: "var(--text-base)",
|
|
2503
|
+
lineHeight: "var(--text-lg--line-height)"
|
|
2504
|
+
},
|
|
2505
|
+
6: {
|
|
2506
|
+
className: "text-base",
|
|
2507
|
+
fontSize: "var(--text-base)",
|
|
2508
|
+
lineHeight: "var(--text-base--line-height)"
|
|
2509
|
+
}
|
|
2464
2510
|
};
|
|
2511
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2512
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2465
2513
|
var markdownTheme = {
|
|
2466
|
-
code: "font-mono
|
|
2467
|
-
codeMark: "font-mono
|
|
2468
|
-
mark: "
|
|
2469
|
-
heading: (level) => {
|
|
2470
|
-
|
|
2471
|
-
|
|
2514
|
+
code: "font-mono! cm-code-inline",
|
|
2515
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2516
|
+
mark: "font-mono!",
|
|
2517
|
+
heading: (level) => ({
|
|
2518
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2519
|
+
color: "var(--color-cm-heading) !important",
|
|
2520
|
+
lineHeight: headings[level].lineHeight,
|
|
2521
|
+
fontSize: headings[level].fontSize,
|
|
2522
|
+
fontWeight: "100 !important"
|
|
2523
|
+
})
|
|
2472
2524
|
};
|
|
2473
|
-
|
|
2474
|
-
// src/styles/theme.ts
|
|
2475
|
-
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
2476
|
-
|
|
2477
|
-
// src/styles/tokens.ts
|
|
2478
|
-
import { tokens } from "@dxos/ui-theme";
|
|
2479
|
-
import { get } from "@dxos/util";
|
|
2480
|
-
var getToken = (path, defaultValue) => {
|
|
2481
|
-
const value = get(tokens, path, defaultValue);
|
|
2482
|
-
return value?.toString() ?? "";
|
|
2483
|
-
};
|
|
2484
|
-
var fontBody = getToken("fontFamily.body");
|
|
2485
|
-
var fontMono = getToken("fontFamily.mono");
|
|
2486
|
-
|
|
2487
|
-
// src/styles/theme.ts
|
|
2488
2525
|
var baseTheme = EditorView13.baseTheme({
|
|
2526
|
+
/**
|
|
2527
|
+
* Outer frame.
|
|
2528
|
+
*/
|
|
2489
2529
|
"&": {},
|
|
2490
2530
|
"&.cm-focused": {
|
|
2491
2531
|
outline: "none"
|
|
@@ -2494,7 +2534,27 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2494
2534
|
* Scroller
|
|
2495
2535
|
*/
|
|
2496
2536
|
".cm-scroller": {
|
|
2497
|
-
|
|
2537
|
+
// Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
|
|
2538
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2539
|
+
// open/close) don't jump the user's view.
|
|
2540
|
+
overflowAnchor: "auto"
|
|
2541
|
+
},
|
|
2542
|
+
".cm-scroller::-webkit-scrollbar": {
|
|
2543
|
+
width: "var(--scrollbar-size,8px)",
|
|
2544
|
+
height: "var(--scrollbar-size,8px)"
|
|
2545
|
+
},
|
|
2546
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2547
|
+
background: "transparent"
|
|
2548
|
+
},
|
|
2549
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2550
|
+
background: "transparent"
|
|
2551
|
+
},
|
|
2552
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2553
|
+
background: "transparent",
|
|
2554
|
+
transition: "background 0.15s"
|
|
2555
|
+
},
|
|
2556
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2557
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2498
2558
|
},
|
|
2499
2559
|
/**
|
|
2500
2560
|
* Content
|
|
@@ -2502,7 +2562,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2502
2562
|
*/
|
|
2503
2563
|
".cm-content": {
|
|
2504
2564
|
padding: "unset",
|
|
2505
|
-
lineHeight: "24px",
|
|
2506
2565
|
color: "unset"
|
|
2507
2566
|
},
|
|
2508
2567
|
/**
|
|
@@ -2516,8 +2575,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2516
2575
|
".cm-gutter": {},
|
|
2517
2576
|
".cm-gutter.cm-lineNumbers": {
|
|
2518
2577
|
paddingRight: "4px",
|
|
2519
|
-
borderRight: "1px solid var(--
|
|
2520
|
-
color: "var(--
|
|
2578
|
+
borderRight: "1px solid var(--color-subdued-separator)",
|
|
2579
|
+
color: "var(--color-subdued)"
|
|
2521
2580
|
},
|
|
2522
2581
|
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
|
2523
2582
|
minWidth: "40px"
|
|
@@ -2533,29 +2592,36 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2533
2592
|
* Line.
|
|
2534
2593
|
*/
|
|
2535
2594
|
".cm-line": {
|
|
2536
|
-
lineHeight:
|
|
2595
|
+
lineHeight: 1.5,
|
|
2537
2596
|
paddingInline: 0
|
|
2538
2597
|
},
|
|
2598
|
+
/**
|
|
2599
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2600
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2601
|
+
*/
|
|
2602
|
+
".cm-line *": {
|
|
2603
|
+
lineHeight: "inherit"
|
|
2604
|
+
},
|
|
2539
2605
|
".cm-activeLine": {
|
|
2540
|
-
background: "var(--
|
|
2606
|
+
background: "var(--color-cm-active-line)"
|
|
2541
2607
|
},
|
|
2542
2608
|
/**
|
|
2543
2609
|
* Cursor (layer).
|
|
2544
2610
|
*/
|
|
2545
2611
|
".cm-cursor, .cm-dropCursor": {
|
|
2546
|
-
borderLeft: "2px solid var(--
|
|
2612
|
+
borderLeft: "2px solid var(--color-cm-cursor)"
|
|
2547
2613
|
},
|
|
2548
2614
|
".cm-placeholder": {
|
|
2549
|
-
color: "var(--
|
|
2615
|
+
color: "var(--color-placeholder)"
|
|
2550
2616
|
},
|
|
2551
2617
|
/**
|
|
2552
2618
|
* Selection (layer).
|
|
2553
2619
|
*/
|
|
2554
2620
|
".cm-selectionBackground": {
|
|
2555
|
-
background: "var(--
|
|
2621
|
+
background: "var(--color-cm-selection)"
|
|
2556
2622
|
},
|
|
2557
2623
|
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2558
|
-
background: "var(--
|
|
2624
|
+
background: "var(--color-cm-focused-selection)"
|
|
2559
2625
|
},
|
|
2560
2626
|
/**
|
|
2561
2627
|
* Search.
|
|
@@ -2565,8 +2631,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2565
2631
|
margin: "0 -3px",
|
|
2566
2632
|
padding: "3px",
|
|
2567
2633
|
borderRadius: "3px",
|
|
2568
|
-
background: "var(--
|
|
2569
|
-
color: "var(--
|
|
2634
|
+
background: "var(--color-cm-highlight-surface)",
|
|
2635
|
+
color: "var(--color-cm-highlight)"
|
|
2570
2636
|
},
|
|
2571
2637
|
".cm-searchMatch-selected": {
|
|
2572
2638
|
textDecoration: "underline"
|
|
@@ -2577,20 +2643,29 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2577
2643
|
".cm-link": {
|
|
2578
2644
|
textDecorationLine: "underline",
|
|
2579
2645
|
textDecorationThickness: "1px",
|
|
2580
|
-
textDecorationColor: "var(--
|
|
2646
|
+
textDecorationColor: "var(--color-separator)",
|
|
2581
2647
|
textUnderlineOffset: "2px",
|
|
2582
2648
|
borderRadius: ".125rem"
|
|
2583
2649
|
},
|
|
2584
2650
|
".cm-link > span": {
|
|
2585
|
-
color: "var(--
|
|
2651
|
+
color: "var(--color-accent-text)"
|
|
2652
|
+
},
|
|
2653
|
+
".cm-link > span:hover": {
|
|
2654
|
+
color: "var(--color-accent-text-hover)"
|
|
2586
2655
|
},
|
|
2587
2656
|
/**
|
|
2588
2657
|
* Tooltip.
|
|
2589
2658
|
*/
|
|
2590
2659
|
".cm-tooltip": {
|
|
2591
|
-
background: "var(--
|
|
2660
|
+
background: "var(--color-modal-surface)"
|
|
2592
2661
|
},
|
|
2593
2662
|
".cm-tooltip-below": {},
|
|
2663
|
+
".cm-tooltip-hover": {
|
|
2664
|
+
background: "var(--color-modal-surface)",
|
|
2665
|
+
border: "1px solid var(--color-separator)",
|
|
2666
|
+
borderRadius: "4px",
|
|
2667
|
+
overflow: "hidden"
|
|
2668
|
+
},
|
|
2594
2669
|
/**
|
|
2595
2670
|
* Autocomplete.
|
|
2596
2671
|
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
@@ -2598,7 +2673,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2598
2673
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
2599
2674
|
marginTop: "6px",
|
|
2600
2675
|
marginLeft: "-10px",
|
|
2601
|
-
border: "2px solid var(--
|
|
2676
|
+
border: "2px solid var(--color-separator)",
|
|
2602
2677
|
borderRadius: "4px"
|
|
2603
2678
|
},
|
|
2604
2679
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
@@ -2608,12 +2683,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2608
2683
|
padding: "4px"
|
|
2609
2684
|
},
|
|
2610
2685
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2611
|
-
background: "var(--
|
|
2612
|
-
color: "var(--
|
|
2686
|
+
background: "var(--color-active-surface)",
|
|
2687
|
+
color: "var(--color-base-surface-text)"
|
|
2613
2688
|
},
|
|
2614
2689
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2615
2690
|
paddingLeft: "4px !important",
|
|
2616
|
-
color: "var(--
|
|
2691
|
+
color: "var(--color-base-surface-text)"
|
|
2617
2692
|
},
|
|
2618
2693
|
/**
|
|
2619
2694
|
* Completion info.
|
|
@@ -2622,17 +2697,17 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2622
2697
|
width: "360px !important",
|
|
2623
2698
|
margin: "-10px 1px 0 1px",
|
|
2624
2699
|
padding: "8px !important",
|
|
2625
|
-
borderColor: "var(--
|
|
2700
|
+
borderColor: "var(--color-separator)"
|
|
2626
2701
|
},
|
|
2627
2702
|
".cm-completionIcon": {
|
|
2628
2703
|
display: "none"
|
|
2629
2704
|
},
|
|
2630
2705
|
".cm-completionLabel": {
|
|
2631
|
-
color: "var(--
|
|
2706
|
+
color: "var(--color-description)",
|
|
2632
2707
|
padding: "0 4px"
|
|
2633
2708
|
},
|
|
2634
2709
|
".cm-completionMatchedText": {
|
|
2635
|
-
color: "var(--
|
|
2710
|
+
color: "var(--color-base-surface-text)",
|
|
2636
2711
|
textDecoration: "none !important"
|
|
2637
2712
|
},
|
|
2638
2713
|
/**
|
|
@@ -2656,7 +2731,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2656
2731
|
backgroundColor: "var(--surface-bg)"
|
|
2657
2732
|
},
|
|
2658
2733
|
".cm-panel input, .cm-panel button, .cm-panel label": {
|
|
2659
|
-
color: "var(--
|
|
2734
|
+
color: "var(--color-subdued)",
|
|
2660
2735
|
fontSize: "14px",
|
|
2661
2736
|
all: "unset",
|
|
2662
2737
|
margin: "3px !important",
|
|
@@ -2664,10 +2739,10 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2664
2739
|
outline: "1px solid transparent"
|
|
2665
2740
|
},
|
|
2666
2741
|
".cm-panel input, .cm-panel button": {
|
|
2667
|
-
backgroundColor: "var(--
|
|
2742
|
+
backgroundColor: "var(--color-input-surface)"
|
|
2668
2743
|
},
|
|
2669
2744
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2670
|
-
outline: "1px solid var(--
|
|
2745
|
+
outline: "1px solid var(--color-neutral-focus-indicator)"
|
|
2671
2746
|
},
|
|
2672
2747
|
".cm-panel label": {
|
|
2673
2748
|
display: "inline-flex",
|
|
@@ -2680,33 +2755,33 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2680
2755
|
height: "8px",
|
|
2681
2756
|
marginRight: "6px !important",
|
|
2682
2757
|
padding: "2px !important",
|
|
2683
|
-
color: "var(--
|
|
2758
|
+
color: "var(--color-neutral-focus-indicator)"
|
|
2684
2759
|
},
|
|
2685
2760
|
".cm-panel button": {
|
|
2686
2761
|
"&:hover": {
|
|
2687
|
-
|
|
2762
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
|
|
2763
|
+
backgroundColor: "var(--color-accent-surface-hover) !important"
|
|
2688
2764
|
},
|
|
2689
2765
|
"&:active": {
|
|
2690
|
-
backgroundColor: "var(--
|
|
2766
|
+
backgroundColor: "var(--color-accent-surface-hover)"
|
|
2691
2767
|
}
|
|
2692
2768
|
},
|
|
2693
2769
|
".cm-panel.cm-search": {
|
|
2694
2770
|
padding: "4px",
|
|
2695
|
-
borderTop: "1px solid var(--
|
|
2771
|
+
borderTop: "1px solid var(--color-separator)"
|
|
2696
2772
|
}
|
|
2697
2773
|
});
|
|
2698
2774
|
var editorGutter = EditorView13.theme({
|
|
2699
2775
|
".cm-gutters": {
|
|
2700
2776
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2701
|
-
background: "var(--
|
|
2777
|
+
background: "var(--color-base-surface) !important",
|
|
2702
2778
|
paddingRight: "1rem"
|
|
2703
2779
|
}
|
|
2704
2780
|
});
|
|
2705
2781
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2706
|
-
//
|
|
2782
|
+
// Main content.
|
|
2707
2783
|
".cm-scroller": {
|
|
2708
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2709
|
-
fontSize: "16px"
|
|
2784
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2710
2785
|
},
|
|
2711
2786
|
// Maintain defaults for UI components.
|
|
2712
2787
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2746,9 +2821,32 @@ var focus = [
|
|
|
2746
2821
|
})
|
|
2747
2822
|
];
|
|
2748
2823
|
|
|
2824
|
+
// src/extensions/scroll-past-end.ts
|
|
2825
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2826
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2827
|
+
height = 1e3;
|
|
2828
|
+
attrs = {
|
|
2829
|
+
style: "padding-bottom: 1000px"
|
|
2830
|
+
};
|
|
2831
|
+
update({ view }) {
|
|
2832
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2833
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2834
|
+
if (height >= 0 && height !== this.height) {
|
|
2835
|
+
this.height = height;
|
|
2836
|
+
this.attrs = {
|
|
2837
|
+
style: `padding-bottom: ${height}px`
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
});
|
|
2842
|
+
var scrollPastEnd = () => [
|
|
2843
|
+
scrollPastEndPlugin,
|
|
2844
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
|
|
2845
|
+
];
|
|
2846
|
+
|
|
2749
2847
|
// src/extensions/factories.ts
|
|
2750
|
-
var
|
|
2751
|
-
var tabbable =
|
|
2848
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2849
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2752
2850
|
tabindex: "0"
|
|
2753
2851
|
});
|
|
2754
2852
|
var filterChars = (chars) => {
|
|
@@ -2801,13 +2899,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2801
2899
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2802
2900
|
return [
|
|
2803
2901
|
// 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
|
-
});
|
|
2902
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2903
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2811
2904
|
}),
|
|
2812
2905
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2813
2906
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2816,7 +2909,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2816
2909
|
props.drawSelection && drawSelection({
|
|
2817
2910
|
cursorBlinkRate: 1200
|
|
2818
2911
|
}),
|
|
2819
|
-
props.editable !== void 0 &&
|
|
2912
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2820
2913
|
props.focus && focus,
|
|
2821
2914
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2822
2915
|
props.history && history(),
|
|
@@ -2824,9 +2917,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2824
2917
|
lineNumbers(),
|
|
2825
2918
|
editorGutter
|
|
2826
2919
|
],
|
|
2827
|
-
props.lineWrapping &&
|
|
2920
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2828
2921
|
props.placeholder && placeholder2(props.placeholder),
|
|
2829
2922
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2923
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2924
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2925
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2926
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2927
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2928
|
+
// depend on being able to populate the doc themselves.
|
|
2929
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2830
2930
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2831
2931
|
props.tabbable && tabbable,
|
|
2832
2932
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2856,12 +2956,12 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2856
2956
|
};
|
|
2857
2957
|
var grow = {
|
|
2858
2958
|
editor: {
|
|
2859
|
-
className: "
|
|
2959
|
+
className: "h-full w-full"
|
|
2860
2960
|
}
|
|
2861
2961
|
};
|
|
2862
2962
|
var fullWidth = {
|
|
2863
2963
|
editor: {
|
|
2864
|
-
className: "
|
|
2964
|
+
className: "w-full"
|
|
2865
2965
|
}
|
|
2866
2966
|
};
|
|
2867
2967
|
var defaultThemeSlots = grow;
|
|
@@ -2869,24 +2969,29 @@ var defaultStyles = {
|
|
|
2869
2969
|
dark: vscodeDarkStyle,
|
|
2870
2970
|
light: vscodeLightStyle
|
|
2871
2971
|
};
|
|
2872
|
-
var createThemeExtensions = ({ monospace,
|
|
2972
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2873
2973
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2874
2974
|
return [
|
|
2875
2975
|
baseTheme,
|
|
2876
|
-
|
|
2976
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2877
2977
|
createFontTheme({
|
|
2878
2978
|
monospace
|
|
2879
2979
|
}),
|
|
2880
2980
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2881
|
-
slots.editor?.className &&
|
|
2981
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2882
2982
|
class: slots.editor.className
|
|
2883
2983
|
}),
|
|
2884
|
-
slots.content?.className &&
|
|
2984
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2885
2985
|
class: slots.content.className
|
|
2886
2986
|
}),
|
|
2887
|
-
slots.
|
|
2987
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2888
2988
|
constructor(view) {
|
|
2889
|
-
|
|
2989
|
+
if (slots.scroller?.className) {
|
|
2990
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
2991
|
+
}
|
|
2992
|
+
if (scrollbarThin) {
|
|
2993
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
2994
|
+
}
|
|
2890
2995
|
}
|
|
2891
2996
|
})
|
|
2892
2997
|
].filter(isTruthy2);
|
|
@@ -2904,8 +3009,8 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2904
3009
|
channel: `awareness.${id}`,
|
|
2905
3010
|
peerId: identity.identityKey.toHex(),
|
|
2906
3011
|
info: {
|
|
2907
|
-
darkColor: `var(--
|
|
2908
|
-
lightColor: `var(--
|
|
3012
|
+
darkColor: `var(--color-${hue}-border)`,
|
|
3013
|
+
lightColor: `var(--color-${hue}-border)`,
|
|
2909
3014
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex())
|
|
2910
3015
|
}
|
|
2911
3016
|
})));
|
|
@@ -2915,7 +3020,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2915
3020
|
|
|
2916
3021
|
// src/extensions/folding.ts
|
|
2917
3022
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2918
|
-
import { EditorView as
|
|
3023
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2919
3024
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2920
3025
|
var folding = () => {
|
|
2921
3026
|
return [
|
|
@@ -2923,13 +3028,14 @@ var folding = () => {
|
|
|
2923
3028
|
placeholderDOM: () => Domino2.of("span").root
|
|
2924
3029
|
}),
|
|
2925
3030
|
foldGutter({
|
|
3031
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2926
3032
|
markerDOM: (open) => {
|
|
2927
|
-
return Domino2.of("div").classNames("flex
|
|
3033
|
+
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
3034
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2929
3035
|
}))).root;
|
|
2930
3036
|
}
|
|
2931
3037
|
}),
|
|
2932
|
-
|
|
3038
|
+
EditorView17.theme({
|
|
2933
3039
|
".cm-foldGutter": {
|
|
2934
3040
|
opacity: 0.3,
|
|
2935
3041
|
transition: "opacity 0.3s",
|
|
@@ -2943,7 +3049,7 @@ var folding = () => {
|
|
|
2943
3049
|
};
|
|
2944
3050
|
|
|
2945
3051
|
// src/extensions/hashtag.ts
|
|
2946
|
-
import { Decoration as Decoration8, EditorView as
|
|
3052
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2947
3053
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
2948
3054
|
var TagWidget = class extends WidgetType4 {
|
|
2949
3055
|
_text;
|
|
@@ -2964,7 +3070,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
2964
3070
|
})
|
|
2965
3071
|
});
|
|
2966
3072
|
var hashtag = () => [
|
|
2967
|
-
|
|
3073
|
+
ViewPlugin13.fromClass(class {
|
|
2968
3074
|
tags;
|
|
2969
3075
|
constructor(view) {
|
|
2970
3076
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -2974,11 +3080,11 @@ var hashtag = () => [
|
|
|
2974
3080
|
}
|
|
2975
3081
|
}, {
|
|
2976
3082
|
decorations: (instance) => instance.tags,
|
|
2977
|
-
provide: (plugin) =>
|
|
3083
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
2978
3084
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
2979
3085
|
})
|
|
2980
3086
|
}),
|
|
2981
|
-
|
|
3087
|
+
EditorView18.theme({
|
|
2982
3088
|
".cm-tag": {
|
|
2983
3089
|
borderRadius: "4px",
|
|
2984
3090
|
marginRight: "6px",
|
|
@@ -3033,18 +3139,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3033
3139
|
};
|
|
3034
3140
|
|
|
3035
3141
|
// src/extensions/listener.ts
|
|
3036
|
-
import { EditorView as
|
|
3142
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3037
3143
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3038
3144
|
var listener = ({ onFocus, onChange }) => {
|
|
3039
3145
|
return [
|
|
3040
|
-
onFocus &&
|
|
3146
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3041
3147
|
onFocus({
|
|
3042
3148
|
id: state.facet(documentId),
|
|
3043
3149
|
focusing
|
|
3044
3150
|
});
|
|
3045
3151
|
return null;
|
|
3046
3152
|
}),
|
|
3047
|
-
onChange &&
|
|
3153
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3048
3154
|
if (docChanged) {
|
|
3049
3155
|
onChange({
|
|
3050
3156
|
id: state.facet(documentId),
|
|
@@ -3059,7 +3165,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3059
3165
|
import { snippet } from "@codemirror/autocomplete";
|
|
3060
3166
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3061
3167
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3062
|
-
import { EditorView as
|
|
3168
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3063
3169
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3064
3170
|
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
3171
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4148,7 +4254,7 @@ var getFormatting = (state) => {
|
|
|
4148
4254
|
};
|
|
4149
4255
|
};
|
|
4150
4256
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4151
|
-
return
|
|
4257
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4152
4258
|
if (update2.docChanged || update2.selectionSet) {
|
|
4153
4259
|
onStateChange(getFormatting(update2.state));
|
|
4154
4260
|
}
|
|
@@ -4209,8 +4315,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4209
4315
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4210
4316
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4211
4317
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4212
|
-
import {
|
|
4213
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4318
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4214
4319
|
import { languages } from "@codemirror/language-data";
|
|
4215
4320
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4216
4321
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4331,30 +4436,38 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4331
4436
|
],
|
|
4332
4437
|
class: "font-mono"
|
|
4333
4438
|
},
|
|
4334
|
-
// Headings
|
|
4439
|
+
// Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
|
|
4440
|
+
// StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
|
|
4441
|
+
// HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
|
|
4442
|
+
// Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
|
|
4443
|
+
{
|
|
4444
|
+
tag: tags.heading,
|
|
4445
|
+
color: "var(--color-cm-heading) !important",
|
|
4446
|
+
fontWeight: "300"
|
|
4447
|
+
},
|
|
4335
4448
|
{
|
|
4336
4449
|
tag: tags.heading1,
|
|
4337
|
-
|
|
4450
|
+
...markdownTheme.heading(1)
|
|
4338
4451
|
},
|
|
4339
4452
|
{
|
|
4340
4453
|
tag: tags.heading2,
|
|
4341
|
-
|
|
4454
|
+
...markdownTheme.heading(2)
|
|
4342
4455
|
},
|
|
4343
4456
|
{
|
|
4344
4457
|
tag: tags.heading3,
|
|
4345
|
-
|
|
4458
|
+
...markdownTheme.heading(3)
|
|
4346
4459
|
},
|
|
4347
4460
|
{
|
|
4348
4461
|
tag: tags.heading4,
|
|
4349
|
-
|
|
4462
|
+
...markdownTheme.heading(4)
|
|
4350
4463
|
},
|
|
4351
4464
|
{
|
|
4352
4465
|
tag: tags.heading5,
|
|
4353
|
-
|
|
4466
|
+
...markdownTheme.heading(5)
|
|
4354
4467
|
},
|
|
4355
4468
|
{
|
|
4356
4469
|
tag: tags.heading6,
|
|
4357
|
-
|
|
4470
|
+
...markdownTheme.heading(6)
|
|
4358
4471
|
},
|
|
4359
4472
|
// Emphasis.
|
|
4360
4473
|
{
|
|
@@ -4409,15 +4522,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4409
4522
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4410
4523
|
base: markdownLanguage2,
|
|
4411
4524
|
// Languages for syntax highlighting fenced code blocks.
|
|
4525
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4412
4526
|
defaultCodeLanguage: jsonLanguage,
|
|
4413
|
-
codeLanguages:
|
|
4527
|
+
codeLanguages: [
|
|
4528
|
+
...options.codeLanguages ?? [],
|
|
4529
|
+
...languages
|
|
4530
|
+
],
|
|
4414
4531
|
// Don't complete HTML tags.
|
|
4415
4532
|
completeHTMLTags: false,
|
|
4416
4533
|
// Parser extensions.
|
|
4417
4534
|
extensions: [
|
|
4418
4535
|
// GFM provided by default.
|
|
4419
4536
|
markdownTagsExtensions,
|
|
4420
|
-
...options.extensions ?? defaultExtensions()
|
|
4537
|
+
...options.extensions ?? defaultExtensions(),
|
|
4538
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4539
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4540
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4541
|
+
noFencedCodeFolding
|
|
4421
4542
|
]
|
|
4422
4543
|
}),
|
|
4423
4544
|
// Custom styles.
|
|
@@ -4432,18 +4553,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4432
4553
|
].filter(isTruthy3))
|
|
4433
4554
|
];
|
|
4434
4555
|
};
|
|
4435
|
-
var
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
]
|
|
4441
|
-
|
|
4442
|
-
"xml",
|
|
4443
|
-
"xhtml"
|
|
4444
|
-
],
|
|
4445
|
-
load: async () => xml()
|
|
4446
|
-
});
|
|
4556
|
+
var noFencedCodeFolding = {
|
|
4557
|
+
props: [
|
|
4558
|
+
foldNodeProp.add({
|
|
4559
|
+
FencedCode: () => null
|
|
4560
|
+
})
|
|
4561
|
+
]
|
|
4562
|
+
};
|
|
4447
4563
|
var defaultExtensions = () => [
|
|
4448
4564
|
noSetExtHeading,
|
|
4449
4565
|
noHtml
|
|
@@ -4463,19 +4579,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4463
4579
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4464
4580
|
});
|
|
4465
4581
|
var convertTreeToJson = (state) => {
|
|
4466
|
-
const treeToJson = (
|
|
4582
|
+
const treeToJson = (cursor) => {
|
|
4467
4583
|
const node = {
|
|
4468
|
-
type:
|
|
4469
|
-
from:
|
|
4470
|
-
to:
|
|
4471
|
-
text: state.doc.slice(
|
|
4584
|
+
type: cursor.type.name,
|
|
4585
|
+
from: cursor.from,
|
|
4586
|
+
to: cursor.to,
|
|
4587
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4472
4588
|
children: []
|
|
4473
4589
|
};
|
|
4474
|
-
if (
|
|
4590
|
+
if (cursor.firstChild()) {
|
|
4475
4591
|
do {
|
|
4476
|
-
node.children.push(treeToJson(
|
|
4477
|
-
} while (
|
|
4478
|
-
|
|
4592
|
+
node.children.push(treeToJson(cursor));
|
|
4593
|
+
} while (cursor.nextSibling());
|
|
4594
|
+
cursor.parent();
|
|
4479
4595
|
}
|
|
4480
4596
|
return node;
|
|
4481
4597
|
};
|
|
@@ -4485,16 +4601,15 @@ var convertTreeToJson = (state) => {
|
|
|
4485
4601
|
// src/extensions/markdown/decorate.ts
|
|
4486
4602
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4487
4603
|
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4488
|
-
import { Decoration as Decoration11, EditorView as
|
|
4604
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4489
4605
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4490
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4491
4606
|
|
|
4492
4607
|
// src/extensions/markdown/changes.ts
|
|
4493
4608
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4494
4609
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4495
|
-
import { ViewPlugin as
|
|
4610
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4496
4611
|
var adjustChanges = () => {
|
|
4497
|
-
return
|
|
4612
|
+
return ViewPlugin14.fromClass(class {
|
|
4498
4613
|
update(update2) {
|
|
4499
4614
|
const tree = syntaxTree4(update2.state);
|
|
4500
4615
|
const adjustments = [];
|
|
@@ -4636,7 +4751,7 @@ var getValidUrl = (str) => {
|
|
|
4636
4751
|
// src/extensions/markdown/image.ts
|
|
4637
4752
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4638
4753
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4639
|
-
import { Decoration as Decoration9, EditorView as
|
|
4754
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4640
4755
|
var image = (_options = {}) => {
|
|
4641
4756
|
return [
|
|
4642
4757
|
StateField7.define({
|
|
@@ -4647,10 +4762,10 @@ var image = (_options = {}) => {
|
|
|
4647
4762
|
if (!tr.docChanged && !tr.selection) {
|
|
4648
4763
|
return value;
|
|
4649
4764
|
}
|
|
4650
|
-
const
|
|
4765
|
+
const cursor = tr.state.selection.main.head;
|
|
4651
4766
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4652
|
-
let from = Math.min(
|
|
4653
|
-
let to = Math.max(
|
|
4767
|
+
let from = Math.min(cursor, oldCursor);
|
|
4768
|
+
let to = Math.max(cursor, oldCursor);
|
|
4654
4769
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4655
4770
|
from = Math.min(from, fromB);
|
|
4656
4771
|
to = Math.max(to, toB);
|
|
@@ -4664,19 +4779,19 @@ var image = (_options = {}) => {
|
|
|
4664
4779
|
add: buildDecorations(tr.state, from, to)
|
|
4665
4780
|
});
|
|
4666
4781
|
},
|
|
4667
|
-
provide: (field) =>
|
|
4782
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4668
4783
|
})
|
|
4669
4784
|
];
|
|
4670
4785
|
};
|
|
4671
4786
|
var buildDecorations = (state, from, to) => {
|
|
4672
4787
|
const decorations2 = [];
|
|
4673
|
-
const
|
|
4788
|
+
const cursor = state.selection.main.head;
|
|
4674
4789
|
syntaxTree5(state).iterate({
|
|
4675
4790
|
enter: (node) => {
|
|
4676
4791
|
if (node.name === "Image") {
|
|
4677
4792
|
const urlNode = node.node.getChild("URL");
|
|
4678
4793
|
if (urlNode) {
|
|
4679
|
-
const hide2 = state.readOnly ||
|
|
4794
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4680
4795
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4681
4796
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4682
4797
|
return;
|
|
@@ -4724,10 +4839,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4724
4839
|
};
|
|
4725
4840
|
|
|
4726
4841
|
// src/extensions/markdown/styles.ts
|
|
4727
|
-
import { EditorView as
|
|
4842
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4728
4843
|
var bulletListIndentationWidth = 24;
|
|
4729
4844
|
var orderedListIndentationWidth = 36;
|
|
4730
|
-
var formattingStyles =
|
|
4845
|
+
var formattingStyles = EditorView22.theme({
|
|
4731
4846
|
/**
|
|
4732
4847
|
* Horizontal rule.
|
|
4733
4848
|
*/
|
|
@@ -4736,7 +4851,7 @@ var formattingStyles = EditorView21.theme({
|
|
|
4736
4851
|
width: "100%",
|
|
4737
4852
|
height: "0",
|
|
4738
4853
|
verticalAlign: "middle",
|
|
4739
|
-
borderTop: "1px solid var(--
|
|
4854
|
+
borderTop: "1px solid var(--color-cm-separator)",
|
|
4740
4855
|
opacity: 0.5
|
|
4741
4856
|
},
|
|
4742
4857
|
/**
|
|
@@ -4759,19 +4874,44 @@ var formattingStyles = EditorView21.theme({
|
|
|
4759
4874
|
* Blockquote.
|
|
4760
4875
|
*/
|
|
4761
4876
|
"& .cm-blockquote": {
|
|
4762
|
-
background: "var(--
|
|
4763
|
-
borderLeft: "2px solid var(--
|
|
4877
|
+
background: "var(--color-cm-codeblock)",
|
|
4878
|
+
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4764
4879
|
paddingLeft: "1rem",
|
|
4765
|
-
margin:
|
|
4880
|
+
margin: 0
|
|
4766
4881
|
},
|
|
4767
4882
|
/**
|
|
4768
4883
|
* Code and codeblocks.
|
|
4769
4884
|
*/
|
|
4885
|
+
"& code": {
|
|
4886
|
+
fontFamily: fontMono,
|
|
4887
|
+
color: "var(--color-cm-code)",
|
|
4888
|
+
whiteSpace: "nowrap"
|
|
4889
|
+
},
|
|
4770
4890
|
"& .cm-code": {
|
|
4771
|
-
fontFamily: fontMono
|
|
4891
|
+
fontFamily: fontMono,
|
|
4892
|
+
color: "var(--color-cm-code)"
|
|
4893
|
+
},
|
|
4894
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4895
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4896
|
+
// so constrain them to the target 24px height.
|
|
4897
|
+
"& .cm-code-inline": {
|
|
4898
|
+
fontFamily: fontMono,
|
|
4899
|
+
height: "24px",
|
|
4900
|
+
// display: 'inline-flex',
|
|
4901
|
+
alignItems: "center",
|
|
4902
|
+
overflow: "hidden",
|
|
4903
|
+
whiteSpace: "nowrap",
|
|
4904
|
+
color: "var(--color-cm-code-inline)"
|
|
4905
|
+
},
|
|
4906
|
+
"& .cm-code-mark": {
|
|
4907
|
+
fontFamily: fontMono,
|
|
4908
|
+
height: "24px",
|
|
4909
|
+
display: "inline-flex",
|
|
4910
|
+
alignItems: "center",
|
|
4911
|
+
overflow: "hidden"
|
|
4772
4912
|
},
|
|
4773
4913
|
"& .cm-codeblock-line": {
|
|
4774
|
-
background: "var(--
|
|
4914
|
+
background: "var(--color-cm-codeblock)",
|
|
4775
4915
|
paddingInline: "1rem !important"
|
|
4776
4916
|
},
|
|
4777
4917
|
"& .cm-codeblock-start": {
|
|
@@ -4800,16 +4940,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4800
4940
|
*/
|
|
4801
4941
|
".cm-table *": {
|
|
4802
4942
|
fontFamily: fontMono,
|
|
4943
|
+
lineHeight: 1.5,
|
|
4803
4944
|
textDecoration: "none !important"
|
|
4804
4945
|
},
|
|
4805
4946
|
".cm-table-head": {
|
|
4806
4947
|
padding: "2px 16px 2px 0px",
|
|
4948
|
+
overflowWrap: "break-word",
|
|
4949
|
+
whiteSpace: "pre-wrap",
|
|
4950
|
+
wordBreak: "keep-all",
|
|
4807
4951
|
textAlign: "left",
|
|
4808
|
-
|
|
4809
|
-
|
|
4952
|
+
color: "var(--color-subdued)",
|
|
4953
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4810
4954
|
},
|
|
4811
4955
|
".cm-table-cell": {
|
|
4812
|
-
padding: "2px 16px 2px 0px"
|
|
4956
|
+
padding: "2px 16px 2px 0px",
|
|
4957
|
+
overflowWrap: "break-word",
|
|
4958
|
+
whiteSpace: "pre-wrap",
|
|
4959
|
+
wordBreak: "keep-all",
|
|
4960
|
+
verticalAlign: "top"
|
|
4813
4961
|
},
|
|
4814
4962
|
/**
|
|
4815
4963
|
* Image.
|
|
@@ -4825,12 +4973,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4825
4973
|
},
|
|
4826
4974
|
".cm-image-with-loader": {
|
|
4827
4975
|
display: "block",
|
|
4828
|
-
opacity:
|
|
4976
|
+
opacity: 0,
|
|
4829
4977
|
transitionDuration: "350ms",
|
|
4830
4978
|
transitionProperty: "opacity"
|
|
4831
4979
|
},
|
|
4832
4980
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4833
|
-
opacity:
|
|
4981
|
+
opacity: 1
|
|
4834
4982
|
},
|
|
4835
4983
|
".cm-image-wrapper": {
|
|
4836
4984
|
"grid-template-columns": "1fr",
|
|
@@ -4849,17 +4997,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4849
4997
|
// src/extensions/markdown/table.ts
|
|
4850
4998
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4851
4999
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4852
|
-
import { Decoration as Decoration10, EditorView as
|
|
5000
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4853
5001
|
var table = (options = {}) => {
|
|
4854
5002
|
return StateField8.define({
|
|
4855
5003
|
create: (state) => update(state, options),
|
|
4856
5004
|
update: (_, tr) => update(tr.state, options),
|
|
4857
|
-
provide: (field) =>
|
|
5005
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4858
5006
|
});
|
|
4859
5007
|
};
|
|
4860
5008
|
var update = (state, _options) => {
|
|
4861
5009
|
const builder = new RangeSetBuilder4();
|
|
4862
|
-
const
|
|
5010
|
+
const cursor = state.selection.main.head;
|
|
4863
5011
|
const tables = [];
|
|
4864
5012
|
const getTable = () => tables[tables.length - 1];
|
|
4865
5013
|
const getRow = () => {
|
|
@@ -4897,7 +5045,7 @@ var update = (state, _options) => {
|
|
|
4897
5045
|
}
|
|
4898
5046
|
});
|
|
4899
5047
|
tables.forEach((table2) => {
|
|
4900
|
-
const replace = state.readOnly ||
|
|
5048
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4901
5049
|
if (replace) {
|
|
4902
5050
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4903
5051
|
block: true,
|
|
@@ -4911,6 +5059,26 @@ var update = (state, _options) => {
|
|
|
4911
5059
|
});
|
|
4912
5060
|
return builder.finish();
|
|
4913
5061
|
};
|
|
5062
|
+
var renderCellContent = (el, text) => {
|
|
5063
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5064
|
+
for (const part of parts) {
|
|
5065
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5066
|
+
const code = document.createElement("code");
|
|
5067
|
+
code.textContent = part.slice(1, -1);
|
|
5068
|
+
el.appendChild(code);
|
|
5069
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5070
|
+
const strong = document.createElement("strong");
|
|
5071
|
+
strong.textContent = part.slice(2, -2);
|
|
5072
|
+
el.appendChild(strong);
|
|
5073
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5074
|
+
const em = document.createElement("em");
|
|
5075
|
+
em.textContent = part.slice(1, -1);
|
|
5076
|
+
el.appendChild(em);
|
|
5077
|
+
} else {
|
|
5078
|
+
el.appendChild(document.createTextNode(part));
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
};
|
|
4914
5082
|
var TableWidget = class extends WidgetType6 {
|
|
4915
5083
|
_table;
|
|
4916
5084
|
constructor(_table) {
|
|
@@ -4930,7 +5098,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4930
5098
|
this._table.header?.forEach((cell) => {
|
|
4931
5099
|
const th = document.createElement("th");
|
|
4932
5100
|
th.setAttribute("class", "cm-table-head");
|
|
4933
|
-
tr.appendChild(th)
|
|
5101
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
4934
5102
|
});
|
|
4935
5103
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
4936
5104
|
this._table.rows?.forEach((row) => {
|
|
@@ -4938,7 +5106,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4938
5106
|
row.forEach((cell) => {
|
|
4939
5107
|
const td = document.createElement("td");
|
|
4940
5108
|
td.setAttribute("class", "cm-table-cell");
|
|
4941
|
-
tr2.appendChild(td)
|
|
5109
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
4942
5110
|
});
|
|
4943
5111
|
});
|
|
4944
5112
|
return div;
|
|
@@ -4946,7 +5114,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4946
5114
|
};
|
|
4947
5115
|
|
|
4948
5116
|
// src/extensions/markdown/decorate.ts
|
|
4949
|
-
var
|
|
5117
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
|
|
4950
5118
|
var Unicode = {
|
|
4951
5119
|
emDash: "\u2014",
|
|
4952
5120
|
bullet: "\u2022",
|
|
@@ -4969,7 +5137,6 @@ var LinkButton = class extends WidgetType7 {
|
|
|
4969
5137
|
eq(other) {
|
|
4970
5138
|
return this.url === other.url;
|
|
4971
5139
|
}
|
|
4972
|
-
// TODO(burdon): Create icon and link directly without react?
|
|
4973
5140
|
toDOM(view) {
|
|
4974
5141
|
const el = document.createElement("span");
|
|
4975
5142
|
this.render(el, {
|
|
@@ -5046,10 +5213,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5046
5213
|
class: "cm-code cm-codeblock-line"
|
|
5047
5214
|
});
|
|
5048
5215
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5049
|
-
class:
|
|
5216
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5050
5217
|
});
|
|
5051
5218
|
var fencedCodeLineLast = Decoration11.line({
|
|
5052
|
-
class:
|
|
5219
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5053
5220
|
});
|
|
5054
5221
|
var commentBlockLine = fencedCodeLine;
|
|
5055
5222
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5081,15 +5248,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5081
5248
|
const { state } = view;
|
|
5082
5249
|
const headerLevels = [];
|
|
5083
5250
|
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
|
-
});
|
|
5251
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5093
5252
|
if (level > headerLevels.length) {
|
|
5094
5253
|
const len = headerLevels.length;
|
|
5095
5254
|
headerLevels.length = level;
|
|
@@ -5120,15 +5279,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5120
5279
|
listLevels.pop();
|
|
5121
5280
|
};
|
|
5122
5281
|
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
|
-
});
|
|
5282
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5132
5283
|
return listLevels[listLevels.length - 1];
|
|
5133
5284
|
};
|
|
5134
5285
|
const enterNode = (node) => {
|
|
@@ -5166,13 +5317,13 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5166
5317
|
deco: hide
|
|
5167
5318
|
});
|
|
5168
5319
|
} else {
|
|
5169
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5320
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5170
5321
|
if (num.length) {
|
|
5171
5322
|
atomicDecoRanges.push({
|
|
5172
5323
|
from: mark.from,
|
|
5173
5324
|
to: mark.from + len,
|
|
5174
5325
|
deco: Decoration11.replace({
|
|
5175
|
-
widget: new TextWidget(num, markdownTheme.heading(level))
|
|
5326
|
+
widget: new TextWidget(num, markdownTheme.heading(level).className)
|
|
5176
5327
|
})
|
|
5177
5328
|
});
|
|
5178
5329
|
}
|
|
@@ -5349,11 +5500,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5349
5500
|
}
|
|
5350
5501
|
decoRanges.push({
|
|
5351
5502
|
from: marks[0].to,
|
|
5352
|
-
to: marks[1].from,
|
|
5503
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5353
5504
|
deco: Decoration11.mark({
|
|
5354
5505
|
tagName: "a",
|
|
5355
5506
|
attributes: {
|
|
5356
|
-
class: "cm-link",
|
|
5507
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5357
5508
|
href: url,
|
|
5358
5509
|
rel: "noreferrer",
|
|
5359
5510
|
target: "_blank"
|
|
@@ -5431,8 +5582,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5431
5582
|
deco.add(from, to, d);
|
|
5432
5583
|
}
|
|
5433
5584
|
const atomicDeco = new RangeSetBuilder5();
|
|
5434
|
-
for (const { from, to, deco:
|
|
5435
|
-
|
|
5585
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5586
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5587
|
+
continue;
|
|
5588
|
+
}
|
|
5589
|
+
atomicDeco.add(from, to, deco2);
|
|
5436
5590
|
}
|
|
5437
5591
|
return {
|
|
5438
5592
|
deco: deco.finish(),
|
|
@@ -5442,7 +5596,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5442
5596
|
var forceUpdate = StateEffect7.define();
|
|
5443
5597
|
var decorateMarkdown = (options = {}) => {
|
|
5444
5598
|
return [
|
|
5445
|
-
|
|
5599
|
+
ViewPlugin15.fromClass(class {
|
|
5446
5600
|
deco;
|
|
5447
5601
|
atomicDeco;
|
|
5448
5602
|
pendingUpdate;
|
|
@@ -5477,9 +5631,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5477
5631
|
}
|
|
5478
5632
|
}, {
|
|
5479
5633
|
provide: (plugin) => [
|
|
5480
|
-
Prec4.low(
|
|
5481
|
-
|
|
5482
|
-
|
|
5634
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5635
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5636
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5483
5637
|
]
|
|
5484
5638
|
}),
|
|
5485
5639
|
image(),
|
|
@@ -5511,8 +5665,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5511
5665
|
return {
|
|
5512
5666
|
pos: link.from,
|
|
5513
5667
|
end: link.to,
|
|
5514
|
-
|
|
5515
|
-
// above: true,
|
|
5668
|
+
above: true,
|
|
5516
5669
|
create: () => {
|
|
5517
5670
|
const el = document.createElement("div");
|
|
5518
5671
|
el.className = tooltipContent({});
|
|
@@ -5528,16 +5681,13 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5528
5681
|
};
|
|
5529
5682
|
}
|
|
5530
5683
|
};
|
|
5531
|
-
}, {
|
|
5532
|
-
// NOTE: 0 = default of 300ms.
|
|
5533
|
-
hoverTime: 1
|
|
5534
5684
|
});
|
|
5535
5685
|
};
|
|
5536
5686
|
|
|
5537
5687
|
// src/extensions/mention.ts
|
|
5538
5688
|
import { autocompletion } from "@codemirror/autocomplete";
|
|
5539
|
-
import { log as
|
|
5540
|
-
var
|
|
5689
|
+
import { log as log9 } from "@dxos/log";
|
|
5690
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
|
|
5541
5691
|
var mention = ({ debug, onSearch }) => {
|
|
5542
5692
|
return autocompletion({
|
|
5543
5693
|
// TODO(burdon): Not working.
|
|
@@ -5549,14 +5699,9 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5549
5699
|
icons: false,
|
|
5550
5700
|
override: [
|
|
5551
5701
|
(context) => {
|
|
5552
|
-
|
|
5702
|
+
log9.info("completion context", {
|
|
5553
5703
|
context
|
|
5554
|
-
}, {
|
|
5555
|
-
F: __dxlog_file12,
|
|
5556
|
-
L: 27,
|
|
5557
|
-
S: void 0,
|
|
5558
|
-
C: (f, a) => f(...a)
|
|
5559
|
-
});
|
|
5704
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5560
5705
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5561
5706
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5562
5707
|
return null;
|
|
@@ -5635,7 +5780,7 @@ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
|
|
5635
5780
|
import { StateField as StateField10 } from "@codemirror/state";
|
|
5636
5781
|
import { Facet as Facet2 } from "@codemirror/state";
|
|
5637
5782
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
5638
|
-
var
|
|
5783
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
|
|
5639
5784
|
var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
|
|
5640
5785
|
return {
|
|
5641
5786
|
type,
|
|
@@ -5789,15 +5934,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5789
5934
|
break;
|
|
5790
5935
|
}
|
|
5791
5936
|
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
|
-
});
|
|
5937
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5801
5938
|
parent = current;
|
|
5802
5939
|
if (current) {
|
|
5803
5940
|
current.lineRange.to = current.node.from;
|
|
@@ -5806,15 +5943,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5806
5943
|
break;
|
|
5807
5944
|
}
|
|
5808
5945
|
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
|
-
});
|
|
5946
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5818
5947
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5819
5948
|
const docRange = {
|
|
5820
5949
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5848,42 +5977,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5848
5977
|
break;
|
|
5849
5978
|
}
|
|
5850
5979
|
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
|
-
});
|
|
5980
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5860
5981
|
current.type = "bullet";
|
|
5861
5982
|
current.contentRange.from = node.from + "- ".length;
|
|
5862
5983
|
break;
|
|
5863
5984
|
}
|
|
5864
5985
|
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
|
-
});
|
|
5986
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5874
5987
|
current.type = "task";
|
|
5875
5988
|
break;
|
|
5876
5989
|
}
|
|
5877
5990
|
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
|
-
});
|
|
5991
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5887
5992
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5888
5993
|
break;
|
|
5889
5994
|
}
|
|
@@ -5891,29 +5996,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5891
5996
|
},
|
|
5892
5997
|
leave: (node) => {
|
|
5893
5998
|
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
|
-
});
|
|
5999
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5903
6000
|
prevSiblings[level--] = void 0;
|
|
5904
6001
|
parent = parent.parent;
|
|
5905
6002
|
}
|
|
5906
6003
|
}
|
|
5907
6004
|
});
|
|
5908
|
-
invariant5(tree, void 0, {
|
|
5909
|
-
F: __dxlog_file13,
|
|
5910
|
-
L: 298,
|
|
5911
|
-
S: void 0,
|
|
5912
|
-
A: [
|
|
5913
|
-
"tree",
|
|
5914
|
-
""
|
|
5915
|
-
]
|
|
5916
|
-
});
|
|
6005
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5917
6006
|
return tree;
|
|
5918
6007
|
};
|
|
5919
6008
|
return [
|
|
@@ -6198,17 +6287,17 @@ var commands = () => keymap11.of([
|
|
|
6198
6287
|
|
|
6199
6288
|
// src/extensions/outliner/outliner.ts
|
|
6200
6289
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6201
|
-
import { Decoration as Decoration12, EditorView as
|
|
6202
|
-
import { mx as
|
|
6290
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6291
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6203
6292
|
|
|
6204
6293
|
// src/extensions/outliner/editor.ts
|
|
6205
6294
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6206
|
-
import { ViewPlugin as
|
|
6207
|
-
import { log as
|
|
6208
|
-
var
|
|
6295
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6296
|
+
import { log as log10 } from "@dxos/log";
|
|
6297
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6209
6298
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6210
6299
|
var initialize = () => {
|
|
6211
|
-
return
|
|
6300
|
+
return ViewPlugin16.fromClass(class {
|
|
6212
6301
|
constructor(view) {
|
|
6213
6302
|
const first = view.state.doc.lineAt(0);
|
|
6214
6303
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6337,7 +6426,7 @@ var editor = () => [
|
|
|
6337
6426
|
cancel = true;
|
|
6338
6427
|
return;
|
|
6339
6428
|
}
|
|
6340
|
-
|
|
6429
|
+
log10("change", {
|
|
6341
6430
|
item,
|
|
6342
6431
|
line: {
|
|
6343
6432
|
from: line.from,
|
|
@@ -6355,35 +6444,20 @@ var editor = () => [
|
|
|
6355
6444
|
text: insert.toString(),
|
|
6356
6445
|
length: insert.length
|
|
6357
6446
|
}
|
|
6358
|
-
}, {
|
|
6359
|
-
F: __dxlog_file14,
|
|
6360
|
-
L: 164,
|
|
6361
|
-
S: void 0,
|
|
6362
|
-
C: (f, a) => f(...a)
|
|
6363
|
-
});
|
|
6447
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6364
6448
|
}
|
|
6365
6449
|
});
|
|
6366
6450
|
if (changes.length > 0) {
|
|
6367
|
-
|
|
6451
|
+
log10("modified,", {
|
|
6368
6452
|
changes
|
|
6369
|
-
}, {
|
|
6370
|
-
F: __dxlog_file14,
|
|
6371
|
-
L: 175,
|
|
6372
|
-
S: void 0,
|
|
6373
|
-
C: (f, a) => f(...a)
|
|
6374
|
-
});
|
|
6453
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6375
6454
|
return [
|
|
6376
6455
|
{
|
|
6377
6456
|
changes
|
|
6378
6457
|
}
|
|
6379
6458
|
];
|
|
6380
6459
|
} else if (cancel) {
|
|
6381
|
-
|
|
6382
|
-
F: __dxlog_file14,
|
|
6383
|
-
L: 178,
|
|
6384
|
-
S: void 0,
|
|
6385
|
-
C: (f, a) => f(...a)
|
|
6386
|
-
});
|
|
6460
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6387
6461
|
return [];
|
|
6388
6462
|
}
|
|
6389
6463
|
return tr;
|
|
@@ -6391,10 +6465,10 @@ var editor = () => [
|
|
|
6391
6465
|
];
|
|
6392
6466
|
|
|
6393
6467
|
// src/extensions/outliner/menu.ts
|
|
6394
|
-
import { EditorView as
|
|
6395
|
-
import { addEventListener } from "@dxos/async";
|
|
6468
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6469
|
+
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6396
6470
|
var menu = (options = {}) => [
|
|
6397
|
-
|
|
6471
|
+
ViewPlugin17.fromClass(class {
|
|
6398
6472
|
view;
|
|
6399
6473
|
tag;
|
|
6400
6474
|
rafId;
|
|
@@ -6414,7 +6488,7 @@ var menu = (options = {}) => [
|
|
|
6414
6488
|
}
|
|
6415
6489
|
container.appendChild(this.tag);
|
|
6416
6490
|
const handler = () => this.scheduleUpdate();
|
|
6417
|
-
this.cleanup =
|
|
6491
|
+
this.cleanup = addEventListener2(container, "scroll", handler);
|
|
6418
6492
|
this.scheduleUpdate();
|
|
6419
6493
|
}
|
|
6420
6494
|
destroy() {
|
|
@@ -6456,7 +6530,7 @@ var menu = (options = {}) => [
|
|
|
6456
6530
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6457
6531
|
}
|
|
6458
6532
|
}),
|
|
6459
|
-
|
|
6533
|
+
EditorView25.theme({
|
|
6460
6534
|
".cm-popover-trigger": {
|
|
6461
6535
|
position: "fixed",
|
|
6462
6536
|
padding: "0",
|
|
@@ -6492,12 +6566,12 @@ var outliner = (_options = {}) => [
|
|
|
6492
6566
|
listPaddingLeft: 8
|
|
6493
6567
|
}),
|
|
6494
6568
|
// Researve space for menu.
|
|
6495
|
-
|
|
6496
|
-
class: "
|
|
6569
|
+
EditorView26.contentAttributes.of({
|
|
6570
|
+
class: "w-full !mr-[3rem]"
|
|
6497
6571
|
})
|
|
6498
6572
|
];
|
|
6499
6573
|
var decorations = () => [
|
|
6500
|
-
|
|
6574
|
+
ViewPlugin18.fromClass(class {
|
|
6501
6575
|
decorations = Decoration12.none;
|
|
6502
6576
|
constructor(view) {
|
|
6503
6577
|
this.updateDecorations(view.state, view);
|
|
@@ -6522,7 +6596,7 @@ var decorations = () => [
|
|
|
6522
6596
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6523
6597
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6524
6598
|
decorations2.push(Decoration12.line({
|
|
6525
|
-
class:
|
|
6599
|
+
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
6600
|
}).range(line.from, line.from));
|
|
6527
6601
|
}
|
|
6528
6602
|
}
|
|
@@ -6532,7 +6606,7 @@ var decorations = () => [
|
|
|
6532
6606
|
decorations: (v) => v.decorations
|
|
6533
6607
|
}),
|
|
6534
6608
|
// Theme.
|
|
6535
|
-
|
|
6609
|
+
EditorView26.theme(Object.assign({
|
|
6536
6610
|
".cm-list-item": {
|
|
6537
6611
|
borderLeftWidth: "1px",
|
|
6538
6612
|
borderRightWidth: "1px",
|
|
@@ -6557,38 +6631,67 @@ var decorations = () => [
|
|
|
6557
6631
|
marginBottom: "2px"
|
|
6558
6632
|
},
|
|
6559
6633
|
".cm-list-item-focused": {
|
|
6560
|
-
borderColor: "var(--
|
|
6634
|
+
borderColor: "var(--color-neutral-focus-indicator)"
|
|
6561
6635
|
},
|
|
6562
6636
|
"&:focus-within .cm-list-item-selected": {
|
|
6563
|
-
borderColor: "var(--
|
|
6637
|
+
borderColor: "var(--color-separator)"
|
|
6564
6638
|
}
|
|
6565
6639
|
}))
|
|
6566
6640
|
];
|
|
6567
6641
|
|
|
6568
6642
|
// src/extensions/preview/preview.ts
|
|
6569
6643
|
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
|
|
6644
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6645
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6646
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6647
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6572
6648
|
var preview = (options = {}) => {
|
|
6649
|
+
const viewRef = {
|
|
6650
|
+
current: void 0
|
|
6651
|
+
};
|
|
6573
6652
|
return [
|
|
6574
6653
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6575
6654
|
// "Block decorations may not be specified via plugins".
|
|
6576
6655
|
StateField11.define({
|
|
6577
|
-
create: (state) => buildDecorations3(state, options),
|
|
6656
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6578
6657
|
update: (decorations2, tr) => {
|
|
6579
|
-
if (tr.docChanged) {
|
|
6580
|
-
return buildDecorations3(tr.state, options);
|
|
6658
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6659
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6581
6660
|
}
|
|
6582
6661
|
return decorations2.map(tr.changes);
|
|
6583
6662
|
},
|
|
6584
6663
|
provide: (field) => [
|
|
6585
|
-
|
|
6586
|
-
|
|
6664
|
+
EditorView27.decorations.from(field),
|
|
6665
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6587
6666
|
]
|
|
6667
|
+
}),
|
|
6668
|
+
ViewPlugin19.define((view) => {
|
|
6669
|
+
viewRef.current = view;
|
|
6670
|
+
return {
|
|
6671
|
+
destroy() {
|
|
6672
|
+
viewRef.current = void 0;
|
|
6673
|
+
}
|
|
6674
|
+
};
|
|
6588
6675
|
})
|
|
6589
6676
|
];
|
|
6590
6677
|
};
|
|
6591
|
-
var
|
|
6678
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6679
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6680
|
+
if (!dxn) {
|
|
6681
|
+
return;
|
|
6682
|
+
}
|
|
6683
|
+
const ref = db.makeRef(dxn);
|
|
6684
|
+
const target = ref.target;
|
|
6685
|
+
if (target) {
|
|
6686
|
+
return Entity.getLabel(target);
|
|
6687
|
+
}
|
|
6688
|
+
void ref.tryLoad().then(() => {
|
|
6689
|
+
viewRef.current?.dispatch({
|
|
6690
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6691
|
+
});
|
|
6692
|
+
});
|
|
6693
|
+
};
|
|
6694
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6592
6695
|
const builder = new RangeSetBuilder6();
|
|
6593
6696
|
syntaxTree10(state).iterate({
|
|
6594
6697
|
enter: (node) => {
|
|
@@ -6600,8 +6703,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6600
6703
|
case "Link": {
|
|
6601
6704
|
const link = getLinkRef(state, node.node);
|
|
6602
6705
|
if (link) {
|
|
6706
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6707
|
+
const displayLink = resolved ? {
|
|
6708
|
+
...link,
|
|
6709
|
+
label: resolved
|
|
6710
|
+
} : link;
|
|
6603
6711
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6604
|
-
widget: new PreviewInlineWidget(options,
|
|
6712
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6605
6713
|
side: 1
|
|
6606
6714
|
}));
|
|
6607
6715
|
}
|
|
@@ -6632,13 +6740,13 @@ var getLinkRef = (state, node) => {
|
|
|
6632
6740
|
const mark = node.getChildren("LinkMark");
|
|
6633
6741
|
const urlNode = node.getChild("URL");
|
|
6634
6742
|
if (mark && urlNode) {
|
|
6635
|
-
const
|
|
6636
|
-
if (
|
|
6743
|
+
const dxn = state.sliceDoc(urlNode.from, urlNode.to);
|
|
6744
|
+
if (dxn.startsWith("dxn:")) {
|
|
6637
6745
|
const label = state.sliceDoc(mark[0].to, mark[1].from);
|
|
6638
6746
|
return {
|
|
6639
6747
|
block: state.sliceDoc(mark[0].from, mark[0].from + 1) === "!",
|
|
6640
6748
|
label,
|
|
6641
|
-
|
|
6749
|
+
dxn
|
|
6642
6750
|
};
|
|
6643
6751
|
}
|
|
6644
6752
|
}
|
|
@@ -6653,13 +6761,13 @@ var PreviewInlineWidget = class extends WidgetType8 {
|
|
|
6653
6761
|
// return false;
|
|
6654
6762
|
// }
|
|
6655
6763
|
eq(other) {
|
|
6656
|
-
return this._link.
|
|
6764
|
+
return this._link.dxn === other._link.dxn && this._link.label === other._link.label;
|
|
6657
6765
|
}
|
|
6658
6766
|
toDOM(_view) {
|
|
6659
6767
|
const root = document.createElement("dx-anchor");
|
|
6660
6768
|
root.classList.add("dx-tag--anchor");
|
|
6661
6769
|
root.textContent = this._link.label;
|
|
6662
|
-
root.setAttribute("
|
|
6770
|
+
root.setAttribute("dxn", this._link.dxn);
|
|
6663
6771
|
return root;
|
|
6664
6772
|
}
|
|
6665
6773
|
};
|
|
@@ -6673,11 +6781,11 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6673
6781
|
// return true;
|
|
6674
6782
|
// }
|
|
6675
6783
|
eq(other) {
|
|
6676
|
-
return this._link.
|
|
6784
|
+
return this._link.dxn === other._link.dxn;
|
|
6677
6785
|
}
|
|
6678
6786
|
toDOM(_view) {
|
|
6679
6787
|
const root = document.createElement("div");
|
|
6680
|
-
root.classList.add("cm-preview-block", "density-fine");
|
|
6788
|
+
root.classList.add("cm-preview-block", "dx-density-fine");
|
|
6681
6789
|
this._options.addBlockContainer?.({
|
|
6682
6790
|
link: this._link,
|
|
6683
6791
|
el: root
|
|
@@ -6693,7 +6801,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6693
6801
|
};
|
|
6694
6802
|
|
|
6695
6803
|
// src/extensions/replacer.ts
|
|
6696
|
-
import { EditorView as
|
|
6804
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6697
6805
|
var defaultReplacements = [
|
|
6698
6806
|
{
|
|
6699
6807
|
input: "--",
|
|
@@ -6756,7 +6864,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6756
6864
|
const sortedReplacements = [
|
|
6757
6865
|
...replacements
|
|
6758
6866
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6759
|
-
return
|
|
6867
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6760
6868
|
if (insert.length !== 1) {
|
|
6761
6869
|
return false;
|
|
6762
6870
|
}
|
|
@@ -6790,12 +6898,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6790
6898
|
});
|
|
6791
6899
|
};
|
|
6792
6900
|
|
|
6901
|
+
// src/extensions/snippets.ts
|
|
6902
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6903
|
+
var defaultItems = [
|
|
6904
|
+
"hello world!",
|
|
6905
|
+
"this is a test.",
|
|
6906
|
+
"this is [DXOS](https://dxos.org)"
|
|
6907
|
+
];
|
|
6908
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6909
|
+
let timer;
|
|
6910
|
+
let index = 0;
|
|
6911
|
+
return [
|
|
6912
|
+
keymap12.of([
|
|
6913
|
+
{
|
|
6914
|
+
// Reset.
|
|
6915
|
+
key: "alt-meta-'",
|
|
6916
|
+
run: () => {
|
|
6917
|
+
clearTimeout(timer);
|
|
6918
|
+
index = 0;
|
|
6919
|
+
return true;
|
|
6920
|
+
}
|
|
6921
|
+
},
|
|
6922
|
+
{
|
|
6923
|
+
// Next snippet.
|
|
6924
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6925
|
+
key: "Shift-Meta-'",
|
|
6926
|
+
run: (view) => {
|
|
6927
|
+
clearTimeout(timer);
|
|
6928
|
+
const text = items[index++];
|
|
6929
|
+
if (index === items?.length) {
|
|
6930
|
+
index = 0;
|
|
6931
|
+
}
|
|
6932
|
+
let offset = 0;
|
|
6933
|
+
const insert = (delayMs = 0) => {
|
|
6934
|
+
timer = setTimeout(() => {
|
|
6935
|
+
const pos = view.state.selection.main.head;
|
|
6936
|
+
view.dispatch({
|
|
6937
|
+
changes: {
|
|
6938
|
+
from: pos,
|
|
6939
|
+
insert: text[offset++]
|
|
6940
|
+
},
|
|
6941
|
+
selection: {
|
|
6942
|
+
anchor: pos + 1
|
|
6943
|
+
}
|
|
6944
|
+
});
|
|
6945
|
+
if (offset < text.length) {
|
|
6946
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6947
|
+
}
|
|
6948
|
+
}, delayMs);
|
|
6949
|
+
};
|
|
6950
|
+
insert();
|
|
6951
|
+
return true;
|
|
6952
|
+
}
|
|
6953
|
+
}
|
|
6954
|
+
])
|
|
6955
|
+
];
|
|
6956
|
+
};
|
|
6957
|
+
|
|
6793
6958
|
// src/extensions/submit.ts
|
|
6794
6959
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6795
|
-
import { keymap as
|
|
6960
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6796
6961
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6797
6962
|
return [
|
|
6798
|
-
Prec6.highest(
|
|
6963
|
+
Prec6.highest(keymap13.of([
|
|
6799
6964
|
{
|
|
6800
6965
|
key: "Enter",
|
|
6801
6966
|
preventDefault: true,
|
|
@@ -6840,6 +7005,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6840
7005
|
// src/extensions/tags/extended-markdown.ts
|
|
6841
7006
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6842
7007
|
import { parseMixed } from "@lezer/common";
|
|
7008
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6843
7009
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6844
7010
|
return [
|
|
6845
7011
|
createMarkdownExtensions({
|
|
@@ -6851,13 +7017,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6851
7017
|
{
|
|
6852
7018
|
name: "SetextHeading",
|
|
6853
7019
|
parse: () => false
|
|
6854
|
-
}
|
|
7020
|
+
},
|
|
7021
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7022
|
+
// even when their content contains blank lines.
|
|
7023
|
+
...xmlBlockParsers(registry)
|
|
6855
7024
|
]
|
|
6856
7025
|
}
|
|
6857
7026
|
]
|
|
6858
7027
|
})
|
|
6859
7028
|
];
|
|
6860
7029
|
};
|
|
7030
|
+
var xmlBlockParsers = (registry) => {
|
|
7031
|
+
const customTags = Object.keys(registry ?? {});
|
|
7032
|
+
if (customTags.length === 0) {
|
|
7033
|
+
return [];
|
|
7034
|
+
}
|
|
7035
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7036
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7037
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7038
|
+
return [
|
|
7039
|
+
{
|
|
7040
|
+
name: "XMLBlock",
|
|
7041
|
+
before: "HTMLBlock",
|
|
7042
|
+
parse: (cx, line) => {
|
|
7043
|
+
const match = openPattern.exec(line.text);
|
|
7044
|
+
if (!match) {
|
|
7045
|
+
return false;
|
|
7046
|
+
}
|
|
7047
|
+
if (selfClosePattern.test(line.text)) {
|
|
7048
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7049
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7050
|
+
cx.nextLine();
|
|
7051
|
+
return true;
|
|
7052
|
+
}
|
|
7053
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7054
|
+
return false;
|
|
7055
|
+
}
|
|
7056
|
+
const tagName = match[1];
|
|
7057
|
+
const closeTag = `</${tagName}>`;
|
|
7058
|
+
const start = cx.lineStart;
|
|
7059
|
+
if (line.text.includes(closeTag)) {
|
|
7060
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7061
|
+
cx.nextLine();
|
|
7062
|
+
return true;
|
|
7063
|
+
}
|
|
7064
|
+
let end = cx.lineStart + line.text.length;
|
|
7065
|
+
while (cx.nextLine()) {
|
|
7066
|
+
end = cx.lineStart + line.text.length;
|
|
7067
|
+
if (line.text.includes(closeTag)) {
|
|
7068
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7069
|
+
cx.nextLine();
|
|
7070
|
+
return true;
|
|
7071
|
+
}
|
|
7072
|
+
}
|
|
7073
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7074
|
+
return true;
|
|
7075
|
+
}
|
|
7076
|
+
}
|
|
7077
|
+
];
|
|
7078
|
+
};
|
|
6861
7079
|
var mixedParser = (registry) => {
|
|
6862
7080
|
const customTags = Object.keys(registry ?? {});
|
|
6863
7081
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6891,219 +7109,793 @@ var mixedParser = (registry) => {
|
|
|
6891
7109
|
});
|
|
6892
7110
|
};
|
|
6893
7111
|
|
|
6894
|
-
// src/extensions/tags/
|
|
6895
|
-
import { StateEffect as
|
|
6896
|
-
import { Decoration as Decoration14, EditorView as
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
var
|
|
6900
|
-
var
|
|
7112
|
+
// src/extensions/tags/fader.ts
|
|
7113
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7114
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7115
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7116
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7117
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7118
|
+
var fader = (options = {}) => {
|
|
7119
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7120
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7121
|
+
let lastCount = -1;
|
|
7122
|
+
const log12 = (expiries) => {
|
|
7123
|
+
if (expiries.length !== lastCount) {
|
|
7124
|
+
lastCount = expiries.length;
|
|
7125
|
+
}
|
|
7126
|
+
};
|
|
7127
|
+
const dequeue = StateEffect10.define();
|
|
7128
|
+
const fadeField = StateField12.define({
|
|
7129
|
+
create: () => ({
|
|
7130
|
+
decorations: Decoration14.none,
|
|
7131
|
+
expiries: [],
|
|
7132
|
+
batchStart: 0
|
|
7133
|
+
}),
|
|
7134
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
7135
|
+
for (const effect of tr.effects) {
|
|
7136
|
+
if (effect.is(dequeue)) {
|
|
7137
|
+
const now2 = effect.value;
|
|
7138
|
+
let removeCount = 0;
|
|
7139
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7140
|
+
removeCount++;
|
|
7141
|
+
}
|
|
7142
|
+
if (removeCount > 0) {
|
|
7143
|
+
expiries = expiries.slice(removeCount);
|
|
7144
|
+
let skipped = 0;
|
|
7145
|
+
decorations2 = decorations2.update({
|
|
7146
|
+
filter: () => {
|
|
7147
|
+
if (skipped < removeCount) {
|
|
7148
|
+
skipped++;
|
|
7149
|
+
return false;
|
|
7150
|
+
}
|
|
7151
|
+
return true;
|
|
7152
|
+
}
|
|
7153
|
+
});
|
|
7154
|
+
}
|
|
7155
|
+
}
|
|
7156
|
+
}
|
|
7157
|
+
if (!tr.docChanged) {
|
|
7158
|
+
log12(expiries);
|
|
7159
|
+
return {
|
|
7160
|
+
decorations: decorations2,
|
|
7161
|
+
expiries,
|
|
7162
|
+
batchStart
|
|
7163
|
+
};
|
|
7164
|
+
}
|
|
7165
|
+
let isReset = tr.state.doc.length === 0;
|
|
7166
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7167
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7168
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7169
|
+
isReset = true;
|
|
7170
|
+
}
|
|
7171
|
+
});
|
|
7172
|
+
}
|
|
7173
|
+
if (isReset) {
|
|
7174
|
+
log12([]);
|
|
7175
|
+
return {
|
|
7176
|
+
decorations: Decoration14.none,
|
|
7177
|
+
expiries: [],
|
|
7178
|
+
batchStart: 0
|
|
7179
|
+
};
|
|
7180
|
+
}
|
|
7181
|
+
const now = Date.now();
|
|
7182
|
+
const add = [];
|
|
7183
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7184
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7185
|
+
add.push({
|
|
7186
|
+
from: fromB,
|
|
7187
|
+
to: toB
|
|
7188
|
+
});
|
|
7189
|
+
}
|
|
7190
|
+
});
|
|
7191
|
+
if (add.length > 0) {
|
|
7192
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7193
|
+
if (canCoalesce) {
|
|
7194
|
+
let lastFrom = -1;
|
|
7195
|
+
let lastTo = -1;
|
|
7196
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7197
|
+
lastFrom = from;
|
|
7198
|
+
lastTo = to;
|
|
7199
|
+
});
|
|
7200
|
+
if (lastFrom >= 0) {
|
|
7201
|
+
decorations2 = decorations2.update({
|
|
7202
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7203
|
+
});
|
|
7204
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7205
|
+
const mergedTo = add[add.length - 1].to;
|
|
7206
|
+
decorations2 = decorations2.update({
|
|
7207
|
+
add: [
|
|
7208
|
+
Decoration14.mark({
|
|
7209
|
+
class: "cm-fader"
|
|
7210
|
+
}).range(mergedFrom, mergedTo)
|
|
7211
|
+
]
|
|
7212
|
+
});
|
|
7213
|
+
expiries = [
|
|
7214
|
+
...expiries.slice(0, -1),
|
|
7215
|
+
now + removalDelay
|
|
7216
|
+
];
|
|
7217
|
+
}
|
|
7218
|
+
} else {
|
|
7219
|
+
batchStart = now;
|
|
7220
|
+
expiries = [
|
|
7221
|
+
...expiries,
|
|
7222
|
+
now + removalDelay
|
|
7223
|
+
];
|
|
7224
|
+
decorations2 = decorations2.update({
|
|
7225
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7226
|
+
class: "cm-fader"
|
|
7227
|
+
}).range(from, to))
|
|
7228
|
+
});
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7231
|
+
log12(expiries);
|
|
7232
|
+
return {
|
|
7233
|
+
decorations: decorations2,
|
|
7234
|
+
expiries,
|
|
7235
|
+
batchStart
|
|
7236
|
+
};
|
|
7237
|
+
},
|
|
7238
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7239
|
+
});
|
|
7240
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7241
|
+
view;
|
|
7242
|
+
#timer;
|
|
7243
|
+
constructor(view) {
|
|
7244
|
+
this.view = view;
|
|
7245
|
+
this.#schedule();
|
|
7246
|
+
}
|
|
7247
|
+
update() {
|
|
7248
|
+
this.#schedule();
|
|
7249
|
+
}
|
|
7250
|
+
#schedule() {
|
|
7251
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7252
|
+
if (expiries.length === 0) {
|
|
7253
|
+
clearTimeout(this.#timer);
|
|
7254
|
+
this.#timer = void 0;
|
|
7255
|
+
return;
|
|
7256
|
+
}
|
|
7257
|
+
if (this.#timer !== void 0) {
|
|
7258
|
+
return;
|
|
7259
|
+
}
|
|
7260
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7261
|
+
this.#timer = setTimeout(() => {
|
|
7262
|
+
this.#timer = void 0;
|
|
7263
|
+
this.view.dispatch({
|
|
7264
|
+
effects: dequeue.of(Date.now())
|
|
7265
|
+
});
|
|
7266
|
+
}, delay);
|
|
7267
|
+
}
|
|
7268
|
+
destroy() {
|
|
7269
|
+
clearTimeout(this.#timer);
|
|
7270
|
+
}
|
|
7271
|
+
});
|
|
6901
7272
|
return [
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
7273
|
+
fadeField,
|
|
7274
|
+
cleanup,
|
|
7275
|
+
EditorView29.theme({
|
|
7276
|
+
".cm-fader": {
|
|
7277
|
+
animation: "fader 1s ease-out forwards"
|
|
7278
|
+
},
|
|
7279
|
+
"@keyframes fader": {
|
|
7280
|
+
"0%": {
|
|
7281
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7282
|
+
},
|
|
7283
|
+
"100%": {}
|
|
7284
|
+
}
|
|
7285
|
+
})
|
|
7286
|
+
];
|
|
7287
|
+
};
|
|
7288
|
+
|
|
7289
|
+
// src/extensions/tags/typewriter.ts
|
|
7290
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7291
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7292
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7293
|
+
var typewriterBypass = Annotation3.define();
|
|
7294
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7295
|
+
var CURSOR_LINGER = 3e3;
|
|
7296
|
+
var FRAME_BUDGET_MS = 4;
|
|
7297
|
+
var CHARS_PER_FRAME = 5;
|
|
7298
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7299
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7300
|
+
var typewriter = (options = {}) => {
|
|
7301
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7302
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7303
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7304
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7305
|
+
const suppressAppend = StateEffect11.define();
|
|
7306
|
+
const insertChunk = StateEffect11.define();
|
|
7307
|
+
const bufferField = StateField13.define({
|
|
7308
|
+
create: () => ({
|
|
7309
|
+
text: "",
|
|
7310
|
+
head: 0,
|
|
7311
|
+
insertAt: 0
|
|
7312
|
+
}),
|
|
6910
7313
|
update: (value, tr) => {
|
|
7314
|
+
let { text, head, insertAt } = value;
|
|
6911
7315
|
for (const effect of tr.effects) {
|
|
6912
|
-
if (effect.is(
|
|
6913
|
-
|
|
7316
|
+
if (effect.is(suppressAppend)) {
|
|
7317
|
+
if (text.length === head) {
|
|
7318
|
+
insertAt = effect.value.from;
|
|
7319
|
+
}
|
|
7320
|
+
text += effect.value.text;
|
|
7321
|
+
}
|
|
7322
|
+
if (effect.is(insertChunk)) {
|
|
7323
|
+
head += effect.value.text.length;
|
|
7324
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7325
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7326
|
+
text = text.slice(head);
|
|
7327
|
+
head = 0;
|
|
7328
|
+
}
|
|
6914
7329
|
}
|
|
6915
7330
|
}
|
|
6916
7331
|
if (tr.docChanged) {
|
|
6917
|
-
|
|
7332
|
+
let isReset = tr.state.doc.length === 0;
|
|
7333
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7334
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7335
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7336
|
+
isReset = true;
|
|
7337
|
+
}
|
|
7338
|
+
});
|
|
7339
|
+
}
|
|
7340
|
+
if (isReset) {
|
|
7341
|
+
return {
|
|
7342
|
+
text: "",
|
|
7343
|
+
head: 0,
|
|
7344
|
+
insertAt: 0
|
|
7345
|
+
};
|
|
7346
|
+
}
|
|
7347
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7348
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7349
|
+
}
|
|
6918
7350
|
}
|
|
6919
|
-
return
|
|
7351
|
+
return {
|
|
7352
|
+
text,
|
|
7353
|
+
head,
|
|
7354
|
+
insertAt
|
|
7355
|
+
};
|
|
6920
7356
|
}
|
|
6921
7357
|
});
|
|
6922
|
-
const
|
|
7358
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7359
|
+
if (!tr.docChanged) {
|
|
7360
|
+
return tr;
|
|
7361
|
+
}
|
|
7362
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7363
|
+
return tr;
|
|
7364
|
+
}
|
|
7365
|
+
let appendedText = "";
|
|
7366
|
+
let appendFrom = -1;
|
|
7367
|
+
let isAppendOnly = true;
|
|
7368
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7369
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7370
|
+
appendedText += inserted.sliceString(0);
|
|
7371
|
+
if (appendFrom === -1) {
|
|
7372
|
+
appendFrom = fromA;
|
|
7373
|
+
}
|
|
7374
|
+
} else {
|
|
7375
|
+
isAppendOnly = false;
|
|
7376
|
+
}
|
|
7377
|
+
});
|
|
7378
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7379
|
+
return tr;
|
|
7380
|
+
}
|
|
7381
|
+
return {
|
|
7382
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7383
|
+
effects: suppressAppend.of({
|
|
7384
|
+
from: appendFrom,
|
|
7385
|
+
text: appendedText
|
|
7386
|
+
})
|
|
7387
|
+
};
|
|
7388
|
+
});
|
|
7389
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6923
7390
|
view;
|
|
6924
|
-
|
|
7391
|
+
_raf;
|
|
7392
|
+
_activeStreamTag = null;
|
|
6925
7393
|
constructor(view) {
|
|
6926
7394
|
this.view = view;
|
|
6927
7395
|
}
|
|
6928
7396
|
update(update2) {
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
7397
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7398
|
+
const pending = text.length - head;
|
|
7399
|
+
if (pending === 0) {
|
|
7400
|
+
this._activeStreamTag = null;
|
|
7401
|
+
}
|
|
7402
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7403
|
+
this._start();
|
|
6936
7404
|
}
|
|
6937
7405
|
}
|
|
7406
|
+
_start() {
|
|
7407
|
+
queueMicrotask(() => {
|
|
7408
|
+
this.view.dispatch({
|
|
7409
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7410
|
+
annotations: typewriterBypass.of(true)
|
|
7411
|
+
});
|
|
7412
|
+
});
|
|
7413
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7414
|
+
}
|
|
7415
|
+
_tick = () => {
|
|
7416
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7417
|
+
const pending = text.length - head;
|
|
7418
|
+
if (pending === 0) {
|
|
7419
|
+
this.view.dispatch({
|
|
7420
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7421
|
+
annotations: typewriterBypass.of(true)
|
|
7422
|
+
});
|
|
7423
|
+
this._raf = void 0;
|
|
7424
|
+
return;
|
|
7425
|
+
}
|
|
7426
|
+
if (pending > flushThreshold) {
|
|
7427
|
+
const chunk = text.slice(head);
|
|
7428
|
+
this._activeStreamTag = null;
|
|
7429
|
+
this.view.dispatch({
|
|
7430
|
+
changes: {
|
|
7431
|
+
from: insertAt,
|
|
7432
|
+
insert: chunk
|
|
7433
|
+
},
|
|
7434
|
+
effects: insertChunk.of({
|
|
7435
|
+
from: insertAt,
|
|
7436
|
+
text: chunk
|
|
7437
|
+
})
|
|
7438
|
+
});
|
|
7439
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7440
|
+
return;
|
|
7441
|
+
}
|
|
7442
|
+
const startTime = performance.now();
|
|
7443
|
+
let pos = head;
|
|
7444
|
+
let activeTag = this._activeStreamTag;
|
|
7445
|
+
let charsEmitted = 0;
|
|
7446
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7447
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7448
|
+
if (result.count === 0) {
|
|
7449
|
+
break;
|
|
7450
|
+
}
|
|
7451
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7452
|
+
break;
|
|
7453
|
+
}
|
|
7454
|
+
if (result.enterTag) {
|
|
7455
|
+
activeTag = result.enterTag;
|
|
7456
|
+
}
|
|
7457
|
+
if (result.exitTag) {
|
|
7458
|
+
activeTag = null;
|
|
7459
|
+
}
|
|
7460
|
+
pos += result.count;
|
|
7461
|
+
charsEmitted += result.count;
|
|
7462
|
+
}
|
|
7463
|
+
const totalCount = pos - head;
|
|
7464
|
+
if (totalCount > 0) {
|
|
7465
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7466
|
+
this._activeStreamTag = activeTag;
|
|
7467
|
+
this.view.dispatch({
|
|
7468
|
+
changes: {
|
|
7469
|
+
from: insertAt,
|
|
7470
|
+
insert: chunk
|
|
7471
|
+
},
|
|
7472
|
+
effects: insertChunk.of({
|
|
7473
|
+
from: insertAt,
|
|
7474
|
+
text: chunk
|
|
7475
|
+
})
|
|
7476
|
+
});
|
|
7477
|
+
}
|
|
7478
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7479
|
+
};
|
|
6938
7480
|
destroy() {
|
|
6939
|
-
|
|
7481
|
+
if (this._raf !== void 0) {
|
|
7482
|
+
cancelAnimationFrame(this._raf);
|
|
7483
|
+
}
|
|
6940
7484
|
}
|
|
6941
7485
|
});
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
7486
|
+
return [
|
|
7487
|
+
bufferField,
|
|
7488
|
+
filter,
|
|
7489
|
+
drainPlugin,
|
|
7490
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7491
|
+
].filter(Boolean);
|
|
7492
|
+
};
|
|
7493
|
+
var typewriterCursor = (bufferField) => {
|
|
7494
|
+
const hideCursor = StateEffect11.define();
|
|
7495
|
+
const visibilityField = StateField13.define({
|
|
7496
|
+
create: () => ({
|
|
7497
|
+
visible: false,
|
|
7498
|
+
insertAt: 0,
|
|
7499
|
+
lastNonWsAt: 0
|
|
7500
|
+
}),
|
|
7501
|
+
update: (value, tr) => {
|
|
7502
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7503
|
+
const pending = text.length - head;
|
|
7504
|
+
if (pending > 0) {
|
|
7505
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7506
|
+
if (tr.docChanged) {
|
|
7507
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7508
|
+
const chunk = inserted.sliceString(0);
|
|
7509
|
+
if (chunk.trim().length > 0) {
|
|
7510
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7511
|
+
}
|
|
7512
|
+
});
|
|
7513
|
+
}
|
|
7514
|
+
return {
|
|
7515
|
+
visible: true,
|
|
7516
|
+
insertAt,
|
|
7517
|
+
lastNonWsAt
|
|
7518
|
+
};
|
|
7519
|
+
}
|
|
7520
|
+
for (const effect of tr.effects) {
|
|
7521
|
+
if (effect.is(hideCursor)) {
|
|
7522
|
+
return {
|
|
7523
|
+
...value,
|
|
7524
|
+
visible: false
|
|
7525
|
+
};
|
|
7526
|
+
}
|
|
6948
7527
|
}
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
7528
|
+
return value;
|
|
7529
|
+
}
|
|
7530
|
+
});
|
|
7531
|
+
const decorationField = StateField13.define({
|
|
7532
|
+
create: () => Decoration15.none,
|
|
7533
|
+
update: (_decorations, tr) => {
|
|
7534
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7535
|
+
if (!visible) {
|
|
7536
|
+
return Decoration15.none;
|
|
7537
|
+
}
|
|
7538
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7539
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7540
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7541
|
+
return Decoration15.set([
|
|
7542
|
+
Decoration15.widget({
|
|
6952
7543
|
widget: new CursorWidget(),
|
|
6953
7544
|
side: 1
|
|
6954
|
-
}).range(
|
|
7545
|
+
}).range(pos)
|
|
6955
7546
|
]);
|
|
6956
7547
|
},
|
|
6957
|
-
provide: (
|
|
7548
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7549
|
+
});
|
|
7550
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7551
|
+
view;
|
|
7552
|
+
_timer;
|
|
7553
|
+
constructor(view) {
|
|
7554
|
+
this.view = view;
|
|
7555
|
+
}
|
|
7556
|
+
update(update2) {
|
|
7557
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7558
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7559
|
+
const pending = text.length - head;
|
|
7560
|
+
if (pending > 0) {
|
|
7561
|
+
clearTimeout(this._timer);
|
|
7562
|
+
this._timer = void 0;
|
|
7563
|
+
} else if (visible && this._timer === void 0) {
|
|
7564
|
+
this._timer = setTimeout(() => {
|
|
7565
|
+
this.view.dispatch({
|
|
7566
|
+
effects: hideCursor.of(null)
|
|
7567
|
+
});
|
|
7568
|
+
this._timer = void 0;
|
|
7569
|
+
}, CURSOR_LINGER);
|
|
7570
|
+
}
|
|
7571
|
+
}
|
|
7572
|
+
destroy() {
|
|
7573
|
+
clearTimeout(this._timer);
|
|
7574
|
+
}
|
|
6958
7575
|
});
|
|
6959
7576
|
return [
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
7577
|
+
visibilityField,
|
|
7578
|
+
decorationField,
|
|
7579
|
+
timerPlugin
|
|
6963
7580
|
];
|
|
6964
7581
|
};
|
|
6965
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7582
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7583
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7584
|
+
// the blink animation isn't restarted on every transaction.
|
|
7585
|
+
eq(other) {
|
|
7586
|
+
return other instanceof _CursorWidget;
|
|
7587
|
+
}
|
|
6966
7588
|
toDOM() {
|
|
6967
|
-
const inner = Domino3.of("span").text("\
|
|
6968
|
-
animation: "blink
|
|
7589
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7590
|
+
animation: "blink 1s infinite",
|
|
7591
|
+
animationDelay: "250ms"
|
|
6969
7592
|
});
|
|
6970
7593
|
return Domino3.of("span").style({
|
|
6971
7594
|
opacity: "0.8"
|
|
6972
|
-
}).
|
|
7595
|
+
}).append(inner).root;
|
|
6973
7596
|
}
|
|
6974
7597
|
};
|
|
6975
|
-
var
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
7598
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7599
|
+
var TAG_NAME_PROBE = 64;
|
|
7600
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7601
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7602
|
+
if (start >= buffer.length) {
|
|
7603
|
+
return {
|
|
7604
|
+
count: 0
|
|
7605
|
+
};
|
|
7606
|
+
}
|
|
7607
|
+
if (activeStreamTag) {
|
|
7608
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7609
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7610
|
+
return {
|
|
7611
|
+
count: closeTag.length,
|
|
7612
|
+
exitTag: true
|
|
7613
|
+
};
|
|
7614
|
+
}
|
|
7615
|
+
if (buffer[start] === "<") {
|
|
7616
|
+
return {
|
|
7617
|
+
count: xmlElementLength(buffer, start)
|
|
7618
|
+
};
|
|
7619
|
+
}
|
|
7620
|
+
return {
|
|
7621
|
+
count: 1
|
|
7622
|
+
};
|
|
7623
|
+
}
|
|
7624
|
+
const ch = buffer[start];
|
|
7625
|
+
if (ch === "<") {
|
|
7626
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7627
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7628
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7629
|
+
const close = buffer.indexOf(">", start);
|
|
7630
|
+
if (close === -1) {
|
|
7631
|
+
return {
|
|
7632
|
+
count: 0
|
|
7633
|
+
};
|
|
6994
7634
|
}
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
isReset = true;
|
|
7000
|
-
}
|
|
7001
|
-
});
|
|
7635
|
+
if (buffer[close - 1] === "/") {
|
|
7636
|
+
return {
|
|
7637
|
+
count: close + 1 - start
|
|
7638
|
+
};
|
|
7002
7639
|
}
|
|
7003
|
-
|
|
7004
|
-
|
|
7640
|
+
return {
|
|
7641
|
+
count: close + 1 - start,
|
|
7642
|
+
enterTag: nameMatch[1]
|
|
7643
|
+
};
|
|
7644
|
+
}
|
|
7645
|
+
return {
|
|
7646
|
+
count: xmlElementLength(buffer, start)
|
|
7647
|
+
};
|
|
7648
|
+
}
|
|
7649
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7650
|
+
return {
|
|
7651
|
+
count: linkLength(buffer, start, start + 1)
|
|
7652
|
+
};
|
|
7653
|
+
}
|
|
7654
|
+
if (ch === "[") {
|
|
7655
|
+
return {
|
|
7656
|
+
count: linkLength(buffer, start, start)
|
|
7657
|
+
};
|
|
7658
|
+
}
|
|
7659
|
+
return {
|
|
7660
|
+
count: 1
|
|
7661
|
+
};
|
|
7662
|
+
};
|
|
7663
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7664
|
+
const close = buffer.indexOf(">", start);
|
|
7665
|
+
if (close === -1) {
|
|
7666
|
+
return 0;
|
|
7667
|
+
}
|
|
7668
|
+
if (buffer[close - 1] === "/") {
|
|
7669
|
+
return close + 1 - start;
|
|
7670
|
+
}
|
|
7671
|
+
if (buffer[start + 1] === "/") {
|
|
7672
|
+
return close + 1 - start;
|
|
7673
|
+
}
|
|
7674
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7675
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7676
|
+
if (!nameMatch) {
|
|
7677
|
+
return 1;
|
|
7678
|
+
}
|
|
7679
|
+
const tagName = nameMatch[1];
|
|
7680
|
+
let depth = 0;
|
|
7681
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7682
|
+
tagPattern.lastIndex = start;
|
|
7683
|
+
let match;
|
|
7684
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7685
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7686
|
+
const isClosing = match[1] === "/";
|
|
7687
|
+
if (isSelfClosing) {
|
|
7688
|
+
if (depth === 0) {
|
|
7689
|
+
return match.index + match[0].length - start;
|
|
7690
|
+
}
|
|
7691
|
+
} else if (isClosing) {
|
|
7692
|
+
depth--;
|
|
7693
|
+
if (depth === 0) {
|
|
7694
|
+
return match.index + match[0].length - start;
|
|
7005
7695
|
}
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7696
|
+
} else {
|
|
7697
|
+
depth++;
|
|
7698
|
+
}
|
|
7699
|
+
}
|
|
7700
|
+
return 0;
|
|
7701
|
+
};
|
|
7702
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7703
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7704
|
+
if (bracketClose === -1) {
|
|
7705
|
+
return 0;
|
|
7706
|
+
}
|
|
7707
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7708
|
+
return 0;
|
|
7709
|
+
}
|
|
7710
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7711
|
+
return 1;
|
|
7712
|
+
}
|
|
7713
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7714
|
+
if (parenClose === -1) {
|
|
7715
|
+
return 0;
|
|
7716
|
+
}
|
|
7717
|
+
return parenClose + 1 - start;
|
|
7718
|
+
};
|
|
7719
|
+
|
|
7720
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7721
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7722
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7723
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7724
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7725
|
+
class: lineClass
|
|
7726
|
+
}) : void 0;
|
|
7727
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7728
|
+
class: contentClass
|
|
7729
|
+
}) : void 0;
|
|
7730
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7731
|
+
const buildDecorations5 = (view) => {
|
|
7732
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7733
|
+
if (!text.includes(`<${tag}`)) {
|
|
7734
|
+
return Decoration16.none;
|
|
7735
|
+
}
|
|
7736
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7737
|
+
const ranges = [];
|
|
7738
|
+
tree.iterate({
|
|
7739
|
+
enter: (node) => {
|
|
7740
|
+
if (node.type.name !== "Element") {
|
|
7009
7741
|
return;
|
|
7010
7742
|
}
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7743
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7744
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7745
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7746
|
+
if (!openTag || !tagNameNode) {
|
|
7747
|
+
return;
|
|
7015
7748
|
}
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7749
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7750
|
+
return;
|
|
7751
|
+
}
|
|
7752
|
+
const contentFrom = openTag.to;
|
|
7753
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7754
|
+
if (hideDecoration) {
|
|
7755
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7756
|
+
if (closeTag) {
|
|
7757
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7758
|
+
}
|
|
7759
|
+
}
|
|
7760
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7761
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7762
|
+
}
|
|
7763
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7764
|
+
let pos = contentFrom;
|
|
7765
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7766
|
+
const line = view.state.doc.lineAt(pos);
|
|
7767
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7768
|
+
if (line.to >= contentTo) {
|
|
7769
|
+
break;
|
|
7770
|
+
}
|
|
7771
|
+
pos = line.to + 1;
|
|
7772
|
+
}
|
|
7773
|
+
}
|
|
7774
|
+
}
|
|
7775
|
+
});
|
|
7776
|
+
return Decoration16.set(ranges, true);
|
|
7777
|
+
};
|
|
7778
|
+
return ViewPlugin22.fromClass(class {
|
|
7779
|
+
decorations;
|
|
7027
7780
|
constructor(view) {
|
|
7028
|
-
this.
|
|
7781
|
+
this.decorations = buildDecorations5(view);
|
|
7029
7782
|
}
|
|
7030
7783
|
update(update2) {
|
|
7031
|
-
if (
|
|
7032
|
-
|
|
7784
|
+
if (update2.docChanged) {
|
|
7785
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7033
7786
|
}
|
|
7034
|
-
|
|
7035
|
-
|
|
7787
|
+
}
|
|
7788
|
+
}, {
|
|
7789
|
+
decorations: (instance) => instance.decorations
|
|
7790
|
+
});
|
|
7791
|
+
};
|
|
7792
|
+
|
|
7793
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7794
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7795
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7796
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7797
|
+
"OpenTag",
|
|
7798
|
+
"CloseTag",
|
|
7799
|
+
"SelfClosingTag",
|
|
7800
|
+
"MismatchedCloseTag"
|
|
7801
|
+
]);
|
|
7802
|
+
var xmlElementMark = Decoration17.mark({
|
|
7803
|
+
class: "cm-xml-element"
|
|
7804
|
+
});
|
|
7805
|
+
var xmlTagMark = Decoration17.mark({
|
|
7806
|
+
class: "cm-xml-tag"
|
|
7807
|
+
});
|
|
7808
|
+
var xmlContentMark = Decoration17.mark({
|
|
7809
|
+
class: "cm-xml-content"
|
|
7810
|
+
});
|
|
7811
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7812
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7813
|
+
const buildDecorations5 = (view) => {
|
|
7814
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7815
|
+
if (!text.includes("<")) {
|
|
7816
|
+
return Decoration17.none;
|
|
7817
|
+
}
|
|
7818
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7819
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7820
|
+
const ranges = [];
|
|
7821
|
+
tree.iterate({
|
|
7822
|
+
enter: (node) => {
|
|
7823
|
+
const name = node.type.name;
|
|
7824
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7825
|
+
if (skipSet) {
|
|
7826
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7827
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7828
|
+
return false;
|
|
7829
|
+
}
|
|
7830
|
+
}
|
|
7831
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7832
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7036
7833
|
return;
|
|
7037
7834
|
}
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7835
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7836
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7837
|
+
return;
|
|
7838
|
+
}
|
|
7839
|
+
if (name === "Element" && node.from < node.to) {
|
|
7840
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7841
|
+
if (openTag && skipSet) {
|
|
7842
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7843
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7844
|
+
return false;
|
|
7845
|
+
}
|
|
7846
|
+
}
|
|
7847
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7848
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7849
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7850
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7851
|
+
}
|
|
7041
7852
|
}
|
|
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
7853
|
}
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
}
|
|
7854
|
+
});
|
|
7855
|
+
return Decoration17.set(ranges, true);
|
|
7856
|
+
};
|
|
7062
7857
|
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"
|
|
7858
|
+
ViewPlugin23.fromClass(class {
|
|
7859
|
+
decorations;
|
|
7860
|
+
constructor(view) {
|
|
7861
|
+
this.decorations = buildDecorations5(view);
|
|
7862
|
+
}
|
|
7863
|
+
update(update2) {
|
|
7864
|
+
if (update2.docChanged) {
|
|
7865
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7081
7866
|
}
|
|
7082
7867
|
}
|
|
7868
|
+
}, {
|
|
7869
|
+
decorations: (instance) => instance.decorations
|
|
7870
|
+
}),
|
|
7871
|
+
EditorView31.baseTheme({
|
|
7872
|
+
".cm-xml-element": {
|
|
7873
|
+
backgroundColor: "var(--color-active-surface)",
|
|
7874
|
+
borderRadius: "0.25rem",
|
|
7875
|
+
padding: "0.25rem"
|
|
7876
|
+
},
|
|
7877
|
+
".cm-xml-tag": {
|
|
7878
|
+
color: "var(--color-blue-500)",
|
|
7879
|
+
fontFamily: "var(--font-mono)"
|
|
7880
|
+
},
|
|
7881
|
+
".cm-xml-content": {}
|
|
7083
7882
|
})
|
|
7084
7883
|
];
|
|
7085
7884
|
};
|
|
7086
7885
|
|
|
7087
7886
|
// src/extensions/tags/xml-tags.ts
|
|
7088
7887
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7089
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7090
|
-
import { Decoration as
|
|
7888
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7889
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7091
7890
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7092
|
-
import { log as
|
|
7891
|
+
import { log as log11 } from "@dxos/log";
|
|
7892
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7093
7893
|
|
|
7094
7894
|
// src/extensions/tags/xml-util.ts
|
|
7095
7895
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7096
|
-
var
|
|
7896
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7097
7897
|
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
|
-
});
|
|
7898
|
+
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
7899
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7108
7900
|
if (openTag) {
|
|
7109
7901
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7135,13 +7927,23 @@ var nodeToJson = (state, node) => {
|
|
|
7135
7927
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7136
7928
|
const children = [];
|
|
7137
7929
|
let child = node.node.firstChild;
|
|
7930
|
+
const appendText = (raw) => {
|
|
7931
|
+
if (raw.length === 0) {
|
|
7932
|
+
return;
|
|
7933
|
+
}
|
|
7934
|
+
const last = children[children.length - 1];
|
|
7935
|
+
if (typeof last === "string") {
|
|
7936
|
+
children[children.length - 1] = last + raw;
|
|
7937
|
+
} else {
|
|
7938
|
+
children.push(raw);
|
|
7939
|
+
}
|
|
7940
|
+
};
|
|
7138
7941
|
while (child) {
|
|
7139
7942
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7140
7943
|
if (child.type.name === "Text") {
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
}
|
|
7944
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7945
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7946
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7145
7947
|
} else if (child.type.name === "Element") {
|
|
7146
7948
|
const data = nodeToJson(state, child);
|
|
7147
7949
|
if (data) {
|
|
@@ -7151,26 +7953,63 @@ var nodeToJson = (state, node) => {
|
|
|
7151
7953
|
}
|
|
7152
7954
|
child = child.nextSibling;
|
|
7153
7955
|
}
|
|
7956
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7957
|
+
children[0] = children[0].trimStart();
|
|
7958
|
+
}
|
|
7154
7959
|
if (children.length > 0) {
|
|
7155
|
-
|
|
7960
|
+
const lastIndex = children.length - 1;
|
|
7961
|
+
const last = children[lastIndex];
|
|
7962
|
+
if (typeof last === "string") {
|
|
7963
|
+
children[lastIndex] = last.trimEnd();
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7967
|
+
if (trimmed.length > 0) {
|
|
7968
|
+
tag.children = trimmed;
|
|
7156
7969
|
}
|
|
7157
7970
|
}
|
|
7158
7971
|
return tag;
|
|
7159
7972
|
}
|
|
7160
7973
|
};
|
|
7974
|
+
var XML_NAMED_ENTITIES = {
|
|
7975
|
+
"<": "<",
|
|
7976
|
+
">": ">",
|
|
7977
|
+
"&": "&",
|
|
7978
|
+
""": '"',
|
|
7979
|
+
"'": "'"
|
|
7980
|
+
};
|
|
7981
|
+
var decodeXmlEntity = (raw) => {
|
|
7982
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
7983
|
+
if (named !== void 0) {
|
|
7984
|
+
return named;
|
|
7985
|
+
}
|
|
7986
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
7987
|
+
if (numeric) {
|
|
7988
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
7989
|
+
if (Number.isFinite(code)) {
|
|
7990
|
+
try {
|
|
7991
|
+
return String.fromCodePoint(code);
|
|
7992
|
+
} catch {
|
|
7993
|
+
}
|
|
7994
|
+
}
|
|
7995
|
+
}
|
|
7996
|
+
return raw;
|
|
7997
|
+
};
|
|
7161
7998
|
|
|
7162
7999
|
// src/extensions/tags/xml-tags.ts
|
|
7163
|
-
var
|
|
7164
|
-
var navigatePreviousEffect =
|
|
7165
|
-
var navigateNextEffect =
|
|
8000
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
8001
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8002
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7166
8003
|
var getXmlTextChild = (children) => {
|
|
7167
8004
|
const child = children?.[0];
|
|
7168
8005
|
return typeof child === "string" ? child : null;
|
|
7169
8006
|
};
|
|
7170
|
-
var
|
|
7171
|
-
var
|
|
7172
|
-
var
|
|
7173
|
-
var
|
|
8007
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8008
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8009
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8010
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8011
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8012
|
+
var widgetContextStateField = StateField14.define({
|
|
7174
8013
|
create: () => void 0,
|
|
7175
8014
|
update: (value, tr) => {
|
|
7176
8015
|
for (const effect of tr.effects) {
|
|
@@ -7181,7 +8020,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7181
8020
|
return value;
|
|
7182
8021
|
}
|
|
7183
8022
|
});
|
|
7184
|
-
var widgetStateMapStateField =
|
|
8023
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7185
8024
|
create: () => ({}),
|
|
7186
8025
|
update: (map, tr) => {
|
|
7187
8026
|
for (const effect of tr.effects) {
|
|
@@ -7190,15 +8029,10 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7190
8029
|
}
|
|
7191
8030
|
if (effect.is(xmlTagUpdateEffect)) {
|
|
7192
8031
|
const { id, value } = effect.value;
|
|
7193
|
-
|
|
8032
|
+
log11("widget updated", {
|
|
7194
8033
|
id,
|
|
7195
8034
|
value
|
|
7196
|
-
}, {
|
|
7197
|
-
F: __dxlog_file16,
|
|
7198
|
-
L: 153,
|
|
7199
|
-
S: void 0,
|
|
7200
|
-
C: (f, a) => f(...a)
|
|
7201
|
-
});
|
|
8035
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7202
8036
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7203
8037
|
return {
|
|
7204
8038
|
...map,
|
|
@@ -7225,15 +8059,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7225
8059
|
const widgets = /* @__PURE__ */ new Map();
|
|
7226
8060
|
const notifier = {
|
|
7227
8061
|
mounted: (state) => {
|
|
7228
|
-
|
|
8062
|
+
log11("widget mounted", {
|
|
7229
8063
|
id: state.id,
|
|
7230
8064
|
tag: state.props._tag
|
|
7231
|
-
}, {
|
|
7232
|
-
F: __dxlog_file16,
|
|
7233
|
-
L: 206,
|
|
7234
|
-
S: void 0,
|
|
7235
|
-
C: (f, a) => f(...a)
|
|
7236
|
-
});
|
|
8065
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7237
8066
|
widgets.set(state.id, state);
|
|
7238
8067
|
setWidgets?.([
|
|
7239
8068
|
...widgets.values()
|
|
@@ -7241,15 +8070,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7241
8070
|
},
|
|
7242
8071
|
unmounted: (id) => {
|
|
7243
8072
|
const state = widgets.get(id);
|
|
7244
|
-
|
|
8073
|
+
log11("widget unmounted", {
|
|
7245
8074
|
id,
|
|
7246
8075
|
tag: state?.props._tag
|
|
7247
|
-
}, {
|
|
7248
|
-
F: __dxlog_file16,
|
|
7249
|
-
L: 212,
|
|
7250
|
-
S: void 0,
|
|
7251
|
-
C: (f, a) => f(...a)
|
|
7252
|
-
});
|
|
8076
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7253
8077
|
widgets.delete(id);
|
|
7254
8078
|
setWidgets?.([
|
|
7255
8079
|
...widgets.values()
|
|
@@ -7258,7 +8082,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7258
8082
|
};
|
|
7259
8083
|
return notifier;
|
|
7260
8084
|
};
|
|
7261
|
-
var keyHandlers =
|
|
8085
|
+
var keyHandlers = keymap14.of([
|
|
7262
8086
|
{
|
|
7263
8087
|
key: "Mod-ArrowUp",
|
|
7264
8088
|
run: (view) => {
|
|
@@ -7279,7 +8103,7 @@ var keyHandlers = keymap13.of([
|
|
|
7279
8103
|
}
|
|
7280
8104
|
]);
|
|
7281
8105
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7282
|
-
return
|
|
8106
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7283
8107
|
update2.transactions.forEach((transaction) => {
|
|
7284
8108
|
for (const effect of transaction.effects) {
|
|
7285
8109
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7307,11 +8131,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7307
8131
|
anchor: line.from,
|
|
7308
8132
|
head: line.from
|
|
7309
8133
|
},
|
|
7310
|
-
effects:
|
|
7311
|
-
line: line.number,
|
|
7312
|
-
|
|
7313
|
-
offset: -16
|
|
7314
|
-
}
|
|
8134
|
+
effects: scrollerLineEffect.of({
|
|
8135
|
+
line: line.number - 1,
|
|
8136
|
+
offset: -16
|
|
7315
8137
|
})
|
|
7316
8138
|
});
|
|
7317
8139
|
continue;
|
|
@@ -7342,11 +8164,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7342
8164
|
anchor: line.to,
|
|
7343
8165
|
head: line.to
|
|
7344
8166
|
},
|
|
7345
|
-
effects:
|
|
7346
|
-
line: line.number,
|
|
7347
|
-
|
|
7348
|
-
offset: -16
|
|
7349
|
-
}
|
|
8167
|
+
effects: scrollerLineEffect.of({
|
|
8168
|
+
line: line.number - 1,
|
|
8169
|
+
offset: -16
|
|
7350
8170
|
})
|
|
7351
8171
|
});
|
|
7352
8172
|
} else {
|
|
@@ -7356,11 +8176,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7356
8176
|
anchor: line.to,
|
|
7357
8177
|
head: line.to
|
|
7358
8178
|
},
|
|
7359
|
-
effects:
|
|
7360
|
-
line: line.number,
|
|
7361
|
-
|
|
7362
|
-
position: "end"
|
|
7363
|
-
}
|
|
8179
|
+
effects: scrollerLineEffect.of({
|
|
8180
|
+
line: line.number - 1,
|
|
8181
|
+
position: "end"
|
|
7364
8182
|
})
|
|
7365
8183
|
});
|
|
7366
8184
|
}
|
|
@@ -7370,7 +8188,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7370
8188
|
});
|
|
7371
8189
|
});
|
|
7372
8190
|
};
|
|
7373
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8191
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7374
8192
|
update(update2) {
|
|
7375
8193
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7376
8194
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7397,19 +8215,25 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7397
8215
|
}
|
|
7398
8216
|
}
|
|
7399
8217
|
});
|
|
7400
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8218
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7401
8219
|
create: (state) => {
|
|
7402
8220
|
return buildDecorations4(state, {
|
|
7403
8221
|
from: 0,
|
|
7404
8222
|
to: state.doc.length
|
|
7405
8223
|
}, registry, notifier);
|
|
7406
8224
|
},
|
|
7407
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8225
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7408
8226
|
for (const effect of tr.effects) {
|
|
7409
8227
|
if (effect.is(xmlTagResetEffect)) {
|
|
8228
|
+
if (tr.docChanged) {
|
|
8229
|
+
return buildDecorations4(tr.state, {
|
|
8230
|
+
from: 0,
|
|
8231
|
+
to: tr.state.doc.length
|
|
8232
|
+
}, registry, notifier);
|
|
8233
|
+
}
|
|
7410
8234
|
return {
|
|
7411
8235
|
from: 0,
|
|
7412
|
-
decorations:
|
|
8236
|
+
decorations: Decoration18.none
|
|
7413
8237
|
};
|
|
7414
8238
|
}
|
|
7415
8239
|
}
|
|
@@ -7417,27 +8241,26 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7417
8241
|
const { state } = tr;
|
|
7418
8242
|
const reset = tr.changes.touchesRange(0, from);
|
|
7419
8243
|
if (reset) {
|
|
7420
|
-
|
|
8244
|
+
log11("document reset", {
|
|
7421
8245
|
from,
|
|
7422
8246
|
to: state.doc.length
|
|
7423
|
-
}, {
|
|
7424
|
-
F: __dxlog_file16,
|
|
7425
|
-
L: 371,
|
|
7426
|
-
S: void 0,
|
|
7427
|
-
C: (f, a) => f(...a)
|
|
7428
|
-
});
|
|
8247
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7429
8248
|
return buildDecorations4(state, {
|
|
7430
8249
|
from: 0,
|
|
7431
8250
|
to: state.doc.length
|
|
7432
8251
|
}, registry, notifier);
|
|
7433
8252
|
} else {
|
|
8253
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7434
8254
|
const result = buildDecorations4(state, {
|
|
7435
|
-
from,
|
|
8255
|
+
from: rebuildFrom,
|
|
7436
8256
|
to: state.doc.length
|
|
7437
8257
|
}, registry, notifier);
|
|
7438
8258
|
return {
|
|
7439
8259
|
from: result.from,
|
|
8260
|
+
streamingFrom: result.streamingFrom,
|
|
7440
8261
|
decorations: decorations2.update({
|
|
8262
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8263
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7441
8264
|
add: decorationSetToArray(result.decorations)
|
|
7442
8265
|
})
|
|
7443
8266
|
};
|
|
@@ -7445,12 +8268,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7445
8268
|
}
|
|
7446
8269
|
return {
|
|
7447
8270
|
from,
|
|
8271
|
+
streamingFrom,
|
|
7448
8272
|
decorations: decorations2
|
|
7449
8273
|
};
|
|
7450
8274
|
},
|
|
7451
8275
|
provide: (field) => [
|
|
7452
|
-
|
|
7453
|
-
|
|
8276
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8277
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7454
8278
|
]
|
|
7455
8279
|
});
|
|
7456
8280
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7461,10 +8285,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7461
8285
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7462
8286
|
return {
|
|
7463
8287
|
from: range.from,
|
|
7464
|
-
decorations:
|
|
8288
|
+
decorations: Decoration18.none
|
|
7465
8289
|
};
|
|
7466
8290
|
}
|
|
7467
8291
|
let last = range.from;
|
|
8292
|
+
let streamingFrom;
|
|
7468
8293
|
tree.iterate({
|
|
7469
8294
|
from: range.from,
|
|
7470
8295
|
to: range.to,
|
|
@@ -7477,21 +8302,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7477
8302
|
if (args) {
|
|
7478
8303
|
const def = registry[args._tag];
|
|
7479
8304
|
if (def) {
|
|
8305
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8306
|
+
return false;
|
|
8307
|
+
}
|
|
7480
8308
|
const { block, factory, Component } = def;
|
|
7481
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7482
8309
|
const nodeRange = {
|
|
7483
8310
|
from: node.node.from,
|
|
7484
8311
|
to: node.node.to
|
|
7485
8312
|
};
|
|
8313
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8314
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7486
8315
|
const props = {
|
|
7487
|
-
|
|
8316
|
+
id: widgetId,
|
|
7488
8317
|
range: nodeRange,
|
|
8318
|
+
context,
|
|
7489
8319
|
...args,
|
|
7490
8320
|
...widgetState
|
|
7491
8321
|
};
|
|
7492
|
-
const widget = factory ? factory(props) : Component ?
|
|
8322
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7493
8323
|
if (widget) {
|
|
7494
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8324
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7495
8325
|
widget,
|
|
7496
8326
|
block,
|
|
7497
8327
|
atomic: true,
|
|
@@ -7503,20 +8333,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7503
8333
|
}
|
|
7504
8334
|
}
|
|
7505
8335
|
} catch (err) {
|
|
7506
|
-
|
|
7507
|
-
F: __dxlog_file16,
|
|
7508
|
-
L: 456,
|
|
7509
|
-
S: void 0,
|
|
7510
|
-
C: (f, a) => f(...a)
|
|
7511
|
-
});
|
|
8336
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7512
8337
|
}
|
|
7513
8338
|
return false;
|
|
7514
8339
|
}
|
|
7515
8340
|
}
|
|
7516
8341
|
}
|
|
7517
8342
|
});
|
|
8343
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8344
|
+
if (streamingTagNames.length > 0) {
|
|
8345
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8346
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8347
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8348
|
+
let match;
|
|
8349
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8350
|
+
const tagName = match[1];
|
|
8351
|
+
const closeTag = `</${tagName}>`;
|
|
8352
|
+
const afterOpen = match.index + match[0].length;
|
|
8353
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8354
|
+
const absoluteFrom = range.from + match.index;
|
|
8355
|
+
const contentFrom = range.from + afterOpen;
|
|
8356
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8357
|
+
const def = registry[tagName];
|
|
8358
|
+
const props = {
|
|
8359
|
+
_tag: tagName,
|
|
8360
|
+
context,
|
|
8361
|
+
range: {
|
|
8362
|
+
from: absoluteFrom,
|
|
8363
|
+
to: range.to
|
|
8364
|
+
},
|
|
8365
|
+
children: innerText ? [
|
|
8366
|
+
innerText
|
|
8367
|
+
] : void 0
|
|
8368
|
+
};
|
|
8369
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8370
|
+
let attrMatch;
|
|
8371
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8372
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8373
|
+
}
|
|
8374
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8375
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8376
|
+
const mergedProps = {
|
|
8377
|
+
...props,
|
|
8378
|
+
id: widgetId,
|
|
8379
|
+
...widgetState
|
|
8380
|
+
};
|
|
8381
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8382
|
+
if (widget) {
|
|
8383
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8384
|
+
widget,
|
|
8385
|
+
block: def.block,
|
|
8386
|
+
atomic: true,
|
|
8387
|
+
inclusive: true,
|
|
8388
|
+
tag: tagName,
|
|
8389
|
+
streaming: true,
|
|
8390
|
+
contentFrom
|
|
8391
|
+
}));
|
|
8392
|
+
streamingFrom = absoluteFrom;
|
|
8393
|
+
last = absoluteFrom;
|
|
8394
|
+
}
|
|
8395
|
+
break;
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8398
|
+
}
|
|
7518
8399
|
return {
|
|
7519
8400
|
from: last,
|
|
8401
|
+
streamingFrom,
|
|
7520
8402
|
decorations: builder.finish()
|
|
7521
8403
|
};
|
|
7522
8404
|
};
|
|
@@ -7525,108 +8407,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7525
8407
|
Component;
|
|
7526
8408
|
props;
|
|
7527
8409
|
notifier;
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
S: this,
|
|
7535
|
-
A: [
|
|
7536
|
-
"id",
|
|
7537
|
-
""
|
|
7538
|
-
]
|
|
7539
|
-
});
|
|
8410
|
+
streaming;
|
|
8411
|
+
#root = null;
|
|
8412
|
+
#view;
|
|
8413
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8414
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8415
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7540
8416
|
}
|
|
7541
8417
|
get root() {
|
|
7542
|
-
return this
|
|
8418
|
+
return this.#root;
|
|
7543
8419
|
}
|
|
7544
8420
|
eq(other) {
|
|
8421
|
+
if (this.streaming) {
|
|
8422
|
+
return false;
|
|
8423
|
+
}
|
|
7545
8424
|
return this.id === other.id;
|
|
7546
8425
|
}
|
|
7547
8426
|
ignoreEvent() {
|
|
7548
8427
|
return true;
|
|
7549
8428
|
}
|
|
7550
|
-
toDOM(
|
|
7551
|
-
this
|
|
8429
|
+
toDOM(view) {
|
|
8430
|
+
this.#view = view;
|
|
8431
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8432
|
+
const props = Object.assign({}, this.props, {
|
|
8433
|
+
view
|
|
8434
|
+
});
|
|
7552
8435
|
this.notifier.mounted({
|
|
7553
8436
|
id: this.id,
|
|
7554
|
-
root: this
|
|
7555
|
-
props
|
|
8437
|
+
root: this.#root,
|
|
8438
|
+
props,
|
|
7556
8439
|
Component: this.Component
|
|
7557
8440
|
});
|
|
7558
|
-
return this
|
|
8441
|
+
return this.#root;
|
|
8442
|
+
}
|
|
8443
|
+
updateDOM(dom) {
|
|
8444
|
+
this.#root = dom;
|
|
8445
|
+
const props = Object.assign({}, this.props, {
|
|
8446
|
+
view: this.#view
|
|
8447
|
+
});
|
|
8448
|
+
this.notifier.mounted({
|
|
8449
|
+
id: this.id,
|
|
8450
|
+
root: this.#root,
|
|
8451
|
+
props,
|
|
8452
|
+
Component: this.Component
|
|
8453
|
+
});
|
|
8454
|
+
return true;
|
|
7559
8455
|
}
|
|
7560
8456
|
destroy(_dom) {
|
|
7561
8457
|
this.notifier.unmounted(this.id);
|
|
7562
|
-
this
|
|
8458
|
+
this.#root = null;
|
|
8459
|
+
this.#view = void 0;
|
|
7563
8460
|
}
|
|
7564
8461
|
};
|
|
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
8462
|
export {
|
|
7623
8463
|
Cursor,
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
EditorState3 as EditorState,
|
|
7627
|
-
EditorView30 as EditorView,
|
|
7628
|
-
EditorViewMode,
|
|
7629
|
-
EditorViewModes,
|
|
8464
|
+
EditorState4 as EditorState,
|
|
8465
|
+
EditorView33 as EditorView,
|
|
7630
8466
|
Inline,
|
|
7631
8467
|
InputModeExtensions,
|
|
7632
8468
|
List,
|
|
@@ -7643,6 +8479,7 @@ export {
|
|
|
7643
8479
|
addStyle,
|
|
7644
8480
|
annotations,
|
|
7645
8481
|
autoScroll,
|
|
8482
|
+
autoScrollEffect,
|
|
7646
8483
|
autocomplete,
|
|
7647
8484
|
automerge,
|
|
7648
8485
|
awareness,
|
|
@@ -7656,9 +8493,11 @@ export {
|
|
|
7656
8493
|
commentClickedEffect,
|
|
7657
8494
|
comments,
|
|
7658
8495
|
commentsState,
|
|
8496
|
+
compactSlots,
|
|
7659
8497
|
convertTreeToJson,
|
|
7660
8498
|
createBasicExtensions,
|
|
7661
8499
|
createComment,
|
|
8500
|
+
createCrawler,
|
|
7662
8501
|
createDataExtensions,
|
|
7663
8502
|
createEditorStateStore,
|
|
7664
8503
|
createEditorStateTransaction,
|
|
@@ -7678,12 +8517,12 @@ export {
|
|
|
7678
8517
|
defaultThemeSlots,
|
|
7679
8518
|
deleteItem,
|
|
7680
8519
|
documentId,
|
|
8520
|
+
documentSlots,
|
|
7681
8521
|
dropFile,
|
|
8522
|
+
editorClassNames,
|
|
7682
8523
|
editorInputMode,
|
|
7683
|
-
editorSlots,
|
|
7684
|
-
editorWidth,
|
|
7685
|
-
editorWithToolbarLayout,
|
|
7686
8524
|
extendedMarkdown,
|
|
8525
|
+
fader,
|
|
7687
8526
|
filterChars,
|
|
7688
8527
|
flattenRect,
|
|
7689
8528
|
focus,
|
|
@@ -7719,6 +8558,7 @@ export {
|
|
|
7719
8558
|
markdownTagsExtensions,
|
|
7720
8559
|
matchCompletion,
|
|
7721
8560
|
mention,
|
|
8561
|
+
mobileSlots,
|
|
7722
8562
|
modalStateEffect,
|
|
7723
8563
|
modalStateField,
|
|
7724
8564
|
moveItemDown,
|
|
@@ -7738,10 +8578,12 @@ export {
|
|
|
7738
8578
|
removeList,
|
|
7739
8579
|
removeStyle,
|
|
7740
8580
|
replacer,
|
|
8581
|
+
scrollPastEnd,
|
|
7741
8582
|
scrollThreadIntoView,
|
|
7742
|
-
scrollToBottomEffect,
|
|
7743
8583
|
scrollToLine,
|
|
7744
|
-
|
|
8584
|
+
scroller,
|
|
8585
|
+
scrollerCrawlEffect,
|
|
8586
|
+
scrollerLineEffect,
|
|
7745
8587
|
selectionState,
|
|
7746
8588
|
setBlockquote,
|
|
7747
8589
|
setComments,
|
|
@@ -7749,10 +8591,8 @@ export {
|
|
|
7749
8591
|
setSelection,
|
|
7750
8592
|
setStyle,
|
|
7751
8593
|
singleValueFacet,
|
|
7752
|
-
|
|
7753
|
-
stackItemContentEditorClassNames,
|
|
8594
|
+
snippets2 as snippets,
|
|
7754
8595
|
staticCompletion,
|
|
7755
|
-
streamer,
|
|
7756
8596
|
submit,
|
|
7757
8597
|
tabbable,
|
|
7758
8598
|
table,
|
|
@@ -7771,7 +8611,12 @@ export {
|
|
|
7771
8611
|
treeFacet,
|
|
7772
8612
|
typeahead,
|
|
7773
8613
|
typewriter,
|
|
8614
|
+
typewriterBypass,
|
|
8615
|
+
typewriterDrainingEffect,
|
|
7774
8616
|
wrapWithCatch,
|
|
8617
|
+
xmlBlockDecoration,
|
|
8618
|
+
xmlElementLength,
|
|
8619
|
+
xmlFormatting,
|
|
7775
8620
|
xmlTagContextEffect,
|
|
7776
8621
|
xmlTagResetEffect,
|
|
7777
8622
|
xmlTagUpdateEffect,
|