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