@dxos/ui-editor 0.8.4-main.fcfe5033a5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +1258 -1004
- 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 +1258 -1003
- 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.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +5 -2
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +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 +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +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 +19 -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 +3 -2
- 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/index.d.ts +3 -4
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +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/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 +13 -2
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/image.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/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 -2
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/replacer.d.ts.map +1 -1
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +83 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +6 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts +15 -0
- package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/spacing.d.ts +3 -0
- package/dist/types/src/extensions/spacing.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.map +1 -1
- package/dist/types/src/extensions/tags/index.d.ts +3 -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 +1 -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/theme.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +2 -2
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/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 +55 -57
- package/src/defaults.ts +6 -4
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +1 -1
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/automerge/sync.ts +1 -1
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/comments.ts +54 -31
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +22 -4
- package/src/extensions/index.ts +3 -4
- package/src/extensions/json.ts +1 -1
- package/src/extensions/markdown/decorate.ts +1 -1
- package/src/extensions/markdown/image.test.ts +54 -0
- package/src/extensions/markdown/image.ts +70 -9
- package/src/extensions/markdown/link.ts +7 -2
- package/src/extensions/outliner/outliner.ts +1 -1
- package/src/extensions/preview/preview.ts +14 -12
- package/src/extensions/scrolling/auto-scroll.ts +261 -0
- package/src/extensions/{scroller.ts → scrolling/crawler.ts} +89 -48
- package/src/extensions/scrolling/index.ts +9 -0
- package/src/extensions/{scroll-past-end.ts → scrolling/scroll-past-end.ts} +6 -6
- package/src/extensions/scrolling/scrollbar-autohide.ts +61 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/spacing.ts +15 -0
- package/src/extensions/tags/index.ts +3 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/{wire.test.ts → typewriter.test.ts} +2 -2
- 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 +6 -32
- package/src/extensions/tags/xml-util.test.ts +90 -3
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/theme.ts +23 -13
- package/src/typings.d.ts +8 -0
- package/dist/lib/browser/chunk-D724USEC.mjs +0 -34
- package/dist/lib/browser/chunk-D724USEC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JRVJWKQF.mjs +0 -36
- package/dist/lib/node-esm/chunk-JRVJWKQF.mjs.map +0 -7
- package/dist/types/src/extensions/auto-scroll.d.ts +0 -8
- package/dist/types/src/extensions/auto-scroll.d.ts.map +0 -1
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +0 -1
- package/dist/types/src/extensions/scroller.d.ts +0 -63
- package/dist/types/src/extensions/scroller.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/wire.d.ts +0 -23
- package/dist/types/src/extensions/tags/wire.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/wire.test.d.ts +0 -2
- package/dist/types/src/extensions/tags/wire.test.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/src/extensions/auto-scroll.ts +0 -179
- package/src/extensions/tags/wire.ts +0 -459
- package/src/extensions/typewriter.ts +0 -68
- /package/dist/types/src/extensions/{scroll-past-end.d.ts → scrolling/scroll-past-end.d.ts} +0 -0
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
EditorInputMode,
|
|
4
|
-
EditorInputModes,
|
|
5
|
-
EditorViewMode,
|
|
6
|
-
EditorViewModes
|
|
7
|
-
} from "./chunk-JRVJWKQF.mjs";
|
|
8
2
|
|
|
9
3
|
// src/index.ts
|
|
10
4
|
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
11
|
-
import { EditorView as
|
|
5
|
+
import { EditorView as EditorView35, keymap as keymap15 } from "@codemirror/view";
|
|
12
6
|
import { tags as tags2 } from "@lezer/highlight";
|
|
13
7
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
14
8
|
|
|
15
9
|
// src/defaults.ts
|
|
16
10
|
import { mx } from "@dxos/ui-theme";
|
|
17
|
-
var editorClassNames = (role) => mx("dx-attention-surface
|
|
11
|
+
var editorClassNames = (role) => mx("dx-attention-surface data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
18
12
|
var documentSlots = {
|
|
19
13
|
content: {
|
|
20
14
|
/**
|
|
@@ -24,8 +18,11 @@ var documentSlots = {
|
|
|
24
18
|
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
25
19
|
*/
|
|
26
20
|
className: mx(
|
|
27
|
-
//
|
|
28
|
-
|
|
21
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
22
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
23
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
24
|
+
// scroll until a click forces a re-measure.
|
|
25
|
+
"dx-inline-size-container",
|
|
29
26
|
// Wider margin for web (vs. mobile).
|
|
30
27
|
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
31
28
|
"mx-auto! w-full"
|
|
@@ -276,12 +273,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
276
273
|
} catch (err) {
|
|
277
274
|
log.catch(err, {
|
|
278
275
|
label
|
|
279
|
-
}, {
|
|
280
|
-
F: __dxlog_file,
|
|
281
|
-
L: 20,
|
|
282
|
-
S: void 0,
|
|
283
|
-
C: (f, a) => f(...a)
|
|
284
|
-
});
|
|
276
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
285
277
|
}
|
|
286
278
|
};
|
|
287
279
|
};
|
|
@@ -307,12 +299,7 @@ var logChanges = (trs) => {
|
|
|
307
299
|
if (changes.length) {
|
|
308
300
|
log("changes", {
|
|
309
301
|
changes
|
|
310
|
-
}, {
|
|
311
|
-
F: __dxlog_file,
|
|
312
|
-
L: 54,
|
|
313
|
-
S: void 0,
|
|
314
|
-
C: (f, a) => f(...a)
|
|
315
|
-
});
|
|
302
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
316
303
|
}
|
|
317
304
|
};
|
|
318
305
|
|
|
@@ -378,30 +365,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
378
365
|
};
|
|
379
366
|
|
|
380
367
|
// src/extensions/autocomplete/placeholder.ts
|
|
381
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
368
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
382
369
|
const plugin = ViewPlugin3.fromClass(class {
|
|
383
370
|
_timeout;
|
|
384
371
|
_decorations = Decoration3.none;
|
|
385
372
|
update(update2) {
|
|
373
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
386
376
|
if (this._timeout) {
|
|
387
377
|
window.clearTimeout(this._timeout);
|
|
388
378
|
this._timeout = void 0;
|
|
389
379
|
}
|
|
380
|
+
this._decorations = Decoration3.none;
|
|
381
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
390
384
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const lineStart = activeLine.from;
|
|
394
|
-
this._timeout = setTimeout(() => {
|
|
395
|
-
this._decorations = Decoration3.set([
|
|
396
|
-
Decoration3.widget({
|
|
397
|
-
widget: new PlaceholderWidget(content),
|
|
398
|
-
side: 1
|
|
399
|
-
}).range(lineStart)
|
|
400
|
-
]);
|
|
401
|
-
update2.view.update([]);
|
|
402
|
-
}, delay);
|
|
385
|
+
if (activeLine.text.trim() !== "") {
|
|
386
|
+
return;
|
|
403
387
|
}
|
|
404
|
-
|
|
388
|
+
const lineStart = activeLine.from;
|
|
389
|
+
const view = update2.view;
|
|
390
|
+
this._timeout = setTimeout(() => {
|
|
391
|
+
this._decorations = Decoration3.set([
|
|
392
|
+
Decoration3.widget({
|
|
393
|
+
widget: new PlaceholderWidget(content),
|
|
394
|
+
side: 1
|
|
395
|
+
}).range(lineStart)
|
|
396
|
+
]);
|
|
397
|
+
view.update([]);
|
|
398
|
+
}, delay);
|
|
405
399
|
}
|
|
406
400
|
destroy() {
|
|
407
401
|
if (this._timeout) {
|
|
@@ -519,321 +513,26 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
519
513
|
];
|
|
520
514
|
};
|
|
521
515
|
|
|
522
|
-
// src/extensions/auto-scroll.ts
|
|
523
|
-
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
524
|
-
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
525
|
-
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
526
|
-
import { Domino } from "@dxos/ui";
|
|
527
|
-
import { getSize } from "@dxos/ui-theme";
|
|
528
|
-
|
|
529
|
-
// src/extensions/scroller.ts
|
|
530
|
-
import { StateEffect } from "@codemirror/state";
|
|
531
|
-
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
532
|
-
import { log as log2 } from "@dxos/log";
|
|
533
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
534
|
-
var scrollerLineEffect = StateEffect.define();
|
|
535
|
-
var scrollerCrawlEffect = StateEffect.define();
|
|
536
|
-
var scrollToLine = (view, options) => {
|
|
537
|
-
view.dispatch({
|
|
538
|
-
effects: scrollerLineEffect.of(options)
|
|
539
|
-
});
|
|
540
|
-
};
|
|
541
|
-
var scroller = ({ overScroll = 0 } = {}) => {
|
|
542
|
-
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
543
|
-
view;
|
|
544
|
-
crawler;
|
|
545
|
-
constructor(view) {
|
|
546
|
-
this.view = view;
|
|
547
|
-
this.crawler = createCrawler(this.view);
|
|
548
|
-
}
|
|
549
|
-
// No-op.
|
|
550
|
-
destroy() {
|
|
551
|
-
this.crawler.cancel();
|
|
552
|
-
}
|
|
553
|
-
cancel() {
|
|
554
|
-
this.crawler.cancel();
|
|
555
|
-
}
|
|
556
|
-
crawl(start = false) {
|
|
557
|
-
if (start) {
|
|
558
|
-
this.crawler.scroll();
|
|
559
|
-
} else {
|
|
560
|
-
this.crawler.cancel();
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
564
|
-
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
565
|
-
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
566
|
-
const doc = this.view.state.doc;
|
|
567
|
-
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
568
|
-
if (line >= 0 && line <= doc.lines - 1) {
|
|
569
|
-
const lineStart = doc.line(line + 1).from;
|
|
570
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
571
|
-
if (coords) {
|
|
572
|
-
const currentScrollTop = scrollTop;
|
|
573
|
-
const maxScrollTop = scrollHeight - clientHeight;
|
|
574
|
-
if (position === "end") {
|
|
575
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
576
|
-
} else {
|
|
577
|
-
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
578
|
-
}
|
|
579
|
-
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
requestAnimationFrame(() => {
|
|
583
|
-
this.view.scrollDOM.scrollTo({
|
|
584
|
-
top: targetScrollTop
|
|
585
|
-
});
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
return [
|
|
590
|
-
scrollPlugin,
|
|
591
|
-
// Listen for effect.s
|
|
592
|
-
EditorView4.updateListener.of((update2) => {
|
|
593
|
-
update2.transactions.forEach((transaction) => {
|
|
594
|
-
try {
|
|
595
|
-
const plugin = update2.view.plugin(scrollPlugin);
|
|
596
|
-
if (plugin) {
|
|
597
|
-
for (const effect of transaction.effects) {
|
|
598
|
-
if (effect.is(scrollerCrawlEffect)) {
|
|
599
|
-
plugin.crawl(effect.value);
|
|
600
|
-
} else if (effect.is(scrollerLineEffect)) {
|
|
601
|
-
plugin.scroll(effect.value);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
} catch (err) {
|
|
606
|
-
log2.catch(err, void 0, {
|
|
607
|
-
F: __dxlog_file2,
|
|
608
|
-
L: 146,
|
|
609
|
-
S: void 0,
|
|
610
|
-
C: (f, a) => f(...a)
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
}),
|
|
615
|
-
// Styles.
|
|
616
|
-
EditorView4.theme({
|
|
617
|
-
".cm-content": {
|
|
618
|
-
paddingBottom: `${overScroll}px`
|
|
619
|
-
},
|
|
620
|
-
".cm-scroller": {
|
|
621
|
-
overflowY: "scroll",
|
|
622
|
-
overflowAnchor: "none",
|
|
623
|
-
paddingBottom: "0"
|
|
624
|
-
},
|
|
625
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
626
|
-
display: "none"
|
|
627
|
-
},
|
|
628
|
-
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
629
|
-
background: "transparent",
|
|
630
|
-
transition: "background 0.15s"
|
|
631
|
-
},
|
|
632
|
-
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
633
|
-
background: "var(--color-scrollbar-thumb)"
|
|
634
|
-
},
|
|
635
|
-
".cm-scroll-button": {
|
|
636
|
-
position: "absolute",
|
|
637
|
-
bottom: "0.5rem",
|
|
638
|
-
right: "1rem"
|
|
639
|
-
}
|
|
640
|
-
})
|
|
641
|
-
];
|
|
642
|
-
};
|
|
643
|
-
function createCrawler(view, accel = 0.15, maxVelocity = 1, snapThreshold = 0.5) {
|
|
644
|
-
const el = view.scrollDOM;
|
|
645
|
-
let currentTop = 0;
|
|
646
|
-
let velocity = 0;
|
|
647
|
-
let rafId = null;
|
|
648
|
-
function frame() {
|
|
649
|
-
const targetTop = el.scrollHeight - el.clientHeight;
|
|
650
|
-
const delta = targetTop - currentTop;
|
|
651
|
-
const absDelta = Math.abs(delta);
|
|
652
|
-
if (absDelta < snapThreshold && Math.abs(velocity) < snapThreshold) {
|
|
653
|
-
el.scrollTop = targetTop;
|
|
654
|
-
currentTop = targetTop;
|
|
655
|
-
velocity = 0;
|
|
656
|
-
rafId = null;
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
const stoppingDistance = velocity * velocity / (2 * accel);
|
|
660
|
-
const direction = Math.sign(delta);
|
|
661
|
-
if (velocity !== 0 && (absDelta <= stoppingDistance || direction !== Math.sign(velocity))) {
|
|
662
|
-
velocity -= Math.sign(velocity) * Math.min(accel, Math.abs(velocity));
|
|
663
|
-
} else {
|
|
664
|
-
velocity += direction * accel;
|
|
665
|
-
velocity = Math.sign(velocity) * Math.min(Math.abs(velocity), maxVelocity);
|
|
666
|
-
}
|
|
667
|
-
currentTop += velocity;
|
|
668
|
-
el.scrollTop = currentTop;
|
|
669
|
-
rafId = requestAnimationFrame(frame);
|
|
670
|
-
}
|
|
671
|
-
return {
|
|
672
|
-
scroll: () => {
|
|
673
|
-
if (rafId === null) {
|
|
674
|
-
currentTop = el.scrollTop;
|
|
675
|
-
rafId = requestAnimationFrame(frame);
|
|
676
|
-
}
|
|
677
|
-
},
|
|
678
|
-
cancel: () => {
|
|
679
|
-
if (rafId !== null) {
|
|
680
|
-
cancelAnimationFrame(rafId);
|
|
681
|
-
rafId = null;
|
|
682
|
-
velocity = 0;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
// src/extensions/auto-scroll.ts
|
|
689
|
-
var autoScrollEffect = StateEffect2.define();
|
|
690
|
-
var autoScroll = (_ = {}) => {
|
|
691
|
-
let buttonContainer;
|
|
692
|
-
let isPinned = true;
|
|
693
|
-
let jumpPending = false;
|
|
694
|
-
let enabled = true;
|
|
695
|
-
let firstUpdate = true;
|
|
696
|
-
const setPinned = (pinned) => {
|
|
697
|
-
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
698
|
-
isPinned = pinned;
|
|
699
|
-
};
|
|
700
|
-
return [
|
|
701
|
-
// Update listener for scrolling when content changes.
|
|
702
|
-
EditorView5.updateListener.of((update2) => {
|
|
703
|
-
const { view, heightChanged, state, startState } = update2;
|
|
704
|
-
for (const tr of update2.transactions) {
|
|
705
|
-
for (const effect of tr.effects) {
|
|
706
|
-
if (effect.is(autoScrollEffect)) {
|
|
707
|
-
enabled = effect.value;
|
|
708
|
-
if (enabled) {
|
|
709
|
-
setPinned(true);
|
|
710
|
-
view.dispatch({
|
|
711
|
-
effects: scrollerCrawlEffect.of(true)
|
|
712
|
-
});
|
|
713
|
-
} else {
|
|
714
|
-
view.dispatch({
|
|
715
|
-
effects: scrollerCrawlEffect.of(false)
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
if (!enabled) {
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
725
|
-
firstUpdate = false;
|
|
726
|
-
jumpPending = true;
|
|
727
|
-
requestAnimationFrame(() => {
|
|
728
|
-
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
729
|
-
jumpPending = false;
|
|
730
|
-
});
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
firstUpdate = false;
|
|
734
|
-
if (jumpPending) {
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
|
-
if (heightChanged) {
|
|
738
|
-
if (isPinned) {
|
|
739
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
740
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
741
|
-
if (delta > 0) {
|
|
742
|
-
setPinned(true);
|
|
743
|
-
view.dispatch({
|
|
744
|
-
effects: scrollerCrawlEffect.of(true)
|
|
745
|
-
});
|
|
746
|
-
} else if (delta < -1) {
|
|
747
|
-
setPinned(false);
|
|
748
|
-
}
|
|
749
|
-
} else {
|
|
750
|
-
if (state.doc.length === 0) {
|
|
751
|
-
setPinned(true);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
}),
|
|
756
|
-
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
757
|
-
ViewPlugin6.fromClass(class {
|
|
758
|
-
cleanup;
|
|
759
|
-
constructor(view) {
|
|
760
|
-
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
761
|
-
requestAnimationFrame(() => {
|
|
762
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
763
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
764
|
-
const pinned = delta === 0;
|
|
765
|
-
setPinned(pinned);
|
|
766
|
-
if (!pinned) {
|
|
767
|
-
view.dispatch({
|
|
768
|
-
effects: scrollerCrawlEffect.of(false)
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
});
|
|
772
|
-
}, 500));
|
|
773
|
-
}
|
|
774
|
-
destroy() {
|
|
775
|
-
this.cleanup();
|
|
776
|
-
}
|
|
777
|
-
}),
|
|
778
|
-
// Scroll button.
|
|
779
|
-
ViewPlugin6.fromClass(class {
|
|
780
|
-
constructor(view) {
|
|
781
|
-
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
782
|
-
icon: "ph--arrow-down--regular"
|
|
783
|
-
});
|
|
784
|
-
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
785
|
-
"data-density": "fine"
|
|
786
|
-
}).append(icon).on("click", () => {
|
|
787
|
-
setPinned(true);
|
|
788
|
-
view.dispatch({
|
|
789
|
-
effects: scrollerLineEffect.of({
|
|
790
|
-
line: -1,
|
|
791
|
-
position: "end",
|
|
792
|
-
behavior: "smooth"
|
|
793
|
-
})
|
|
794
|
-
});
|
|
795
|
-
});
|
|
796
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
797
|
-
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
798
|
-
}
|
|
799
|
-
})
|
|
800
|
-
];
|
|
801
|
-
};
|
|
802
|
-
function createUserScrollDetector(element, onUserScroll) {
|
|
803
|
-
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
804
|
-
passive: true
|
|
805
|
-
}), addEventListener(element, "pointerdown", (event) => {
|
|
806
|
-
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
807
|
-
onUserScroll();
|
|
808
|
-
}
|
|
809
|
-
}));
|
|
810
|
-
}
|
|
811
|
-
|
|
812
516
|
// src/extensions/automerge/automerge.ts
|
|
813
517
|
import { next as A3 } from "@automerge/automerge";
|
|
814
518
|
import { StateField, Transaction as Transaction2 } from "@codemirror/state";
|
|
815
|
-
import { EditorView as
|
|
816
|
-
import { DocAccessor } from "@dxos/echo-
|
|
519
|
+
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
520
|
+
import { DocAccessor } from "@dxos/echo-client";
|
|
817
521
|
|
|
818
522
|
// src/extensions/state.ts
|
|
819
523
|
import { Transaction } from "@codemirror/state";
|
|
820
524
|
var initialSync = Transaction.userEvent.of("initial.sync");
|
|
821
525
|
|
|
822
526
|
// src/extensions/automerge/cursor.ts
|
|
823
|
-
import { fromCursor, toCursor } from "@dxos/echo-
|
|
824
|
-
import { log as
|
|
825
|
-
var
|
|
527
|
+
import { fromCursor, toCursor } from "@dxos/echo-client";
|
|
528
|
+
import { log as log2 } from "@dxos/log";
|
|
529
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
826
530
|
var cursorConverter = (accessor) => ({
|
|
827
531
|
toCursor: (pos, assoc) => {
|
|
828
532
|
try {
|
|
829
533
|
return toCursor(accessor, pos, assoc);
|
|
830
534
|
} catch (err) {
|
|
831
|
-
|
|
832
|
-
F: __dxlog_file3,
|
|
833
|
-
L: 15,
|
|
834
|
-
S: void 0,
|
|
835
|
-
C: (f, a) => f(...a)
|
|
836
|
-
});
|
|
535
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
|
|
837
536
|
return "";
|
|
838
537
|
}
|
|
839
538
|
},
|
|
@@ -841,22 +540,17 @@ var cursorConverter = (accessor) => ({
|
|
|
841
540
|
try {
|
|
842
541
|
return fromCursor(accessor, cursor);
|
|
843
542
|
} catch (err) {
|
|
844
|
-
|
|
845
|
-
F: __dxlog_file3,
|
|
846
|
-
L: 24,
|
|
847
|
-
S: void 0,
|
|
848
|
-
C: (f, a) => f(...a)
|
|
849
|
-
});
|
|
543
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
|
|
850
544
|
return 0;
|
|
851
545
|
}
|
|
852
546
|
}
|
|
853
547
|
});
|
|
854
548
|
|
|
855
549
|
// src/extensions/automerge/defs.ts
|
|
856
|
-
import { Annotation, StateEffect
|
|
550
|
+
import { Annotation, StateEffect } from "@codemirror/state";
|
|
857
551
|
var getPath = (state, field) => state.field(field).path;
|
|
858
552
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
859
|
-
var updateHeadsEffect =
|
|
553
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
860
554
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
861
555
|
newHeads
|
|
862
556
|
});
|
|
@@ -867,7 +561,7 @@ var isReconcile = (tr) => {
|
|
|
867
561
|
|
|
868
562
|
// src/extensions/automerge/sync.ts
|
|
869
563
|
import { next as A2 } from "@automerge/automerge";
|
|
870
|
-
import { log as
|
|
564
|
+
import { log as log3 } from "@dxos/log";
|
|
871
565
|
|
|
872
566
|
// src/extensions/automerge/update-automerge.ts
|
|
873
567
|
import { next as A } from "@automerge/automerge";
|
|
@@ -1008,7 +702,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
1008
702
|
};
|
|
1009
703
|
|
|
1010
704
|
// src/extensions/automerge/sync.ts
|
|
1011
|
-
var
|
|
705
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
1012
706
|
var Syncer = class {
|
|
1013
707
|
_handle;
|
|
1014
708
|
_state;
|
|
@@ -1031,12 +725,7 @@ var Syncer = class {
|
|
|
1031
725
|
this._pending = false;
|
|
1032
726
|
}
|
|
1033
727
|
onEditorChange(view) {
|
|
1034
|
-
|
|
1035
|
-
F: __dxlog_file4,
|
|
1036
|
-
L: 45,
|
|
1037
|
-
S: this,
|
|
1038
|
-
C: (f, a) => f(...a)
|
|
1039
|
-
});
|
|
728
|
+
log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
|
|
1040
729
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
1041
730
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
1042
731
|
if (newHeads) {
|
|
@@ -1047,12 +736,7 @@ var Syncer = class {
|
|
|
1047
736
|
}
|
|
1048
737
|
}
|
|
1049
738
|
onAutomergeChange(view) {
|
|
1050
|
-
|
|
1051
|
-
F: __dxlog_file4,
|
|
1052
|
-
L: 60,
|
|
1053
|
-
S: this,
|
|
1054
|
-
C: (f, a) => f(...a)
|
|
1055
|
-
});
|
|
739
|
+
log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
|
|
1056
740
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
1057
741
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
1058
742
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1105,7 +789,7 @@ var automerge = (accessor) => {
|
|
|
1105
789
|
// Track heads.
|
|
1106
790
|
syncState,
|
|
1107
791
|
// Reconcile external updates.
|
|
1108
|
-
|
|
792
|
+
ViewPlugin5.fromClass(class {
|
|
1109
793
|
_view;
|
|
1110
794
|
constructor(_view) {
|
|
1111
795
|
this._view = _view;
|
|
@@ -1136,7 +820,7 @@ var automerge = (accessor) => {
|
|
|
1136
820
|
};
|
|
1137
821
|
}),
|
|
1138
822
|
// Reconcile local updates.
|
|
1139
|
-
|
|
823
|
+
EditorView4.updateListener.of(({ view, changes, transactions }) => {
|
|
1140
824
|
if (!changes.empty) {
|
|
1141
825
|
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
|
|
1142
826
|
if (!isInitialSync) {
|
|
@@ -1149,10 +833,10 @@ var automerge = (accessor) => {
|
|
|
1149
833
|
|
|
1150
834
|
// src/extensions/awareness/awareness.ts
|
|
1151
835
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
1152
|
-
import { Decoration as Decoration5, EditorView as
|
|
836
|
+
import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1153
837
|
import { Event } from "@dxos/async";
|
|
1154
838
|
import { Context } from "@dxos/context";
|
|
1155
|
-
var
|
|
839
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1156
840
|
var dummyProvider = {
|
|
1157
841
|
remoteStateChange: new Event(),
|
|
1158
842
|
open: () => {
|
|
@@ -1168,17 +852,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
|
1168
852
|
var awareness = (provider = dummyProvider) => {
|
|
1169
853
|
return [
|
|
1170
854
|
awarenessProvider.of(provider),
|
|
1171
|
-
|
|
855
|
+
ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
|
|
1172
856
|
decorations: (value) => value.decorations
|
|
1173
857
|
}),
|
|
1174
858
|
styles
|
|
1175
859
|
];
|
|
1176
860
|
};
|
|
1177
861
|
var RemoteSelectionsDecorator = class {
|
|
1178
|
-
_ctx = new Context(void 0, {
|
|
1179
|
-
F: __dxlog_file5,
|
|
1180
|
-
L: 80
|
|
1181
|
-
});
|
|
862
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
|
|
1182
863
|
_cursorConverter;
|
|
1183
864
|
_provider;
|
|
1184
865
|
_lastAnchor;
|
|
@@ -1327,7 +1008,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
|
|
|
1327
1008
|
return true;
|
|
1328
1009
|
}
|
|
1329
1010
|
};
|
|
1330
|
-
var styles =
|
|
1011
|
+
var styles = EditorView5.theme({
|
|
1331
1012
|
".cm-collab-selection": {},
|
|
1332
1013
|
".cm-collab-selectionLine": {
|
|
1333
1014
|
padding: 0,
|
|
@@ -1389,8 +1070,8 @@ var styles = EditorView7.theme({
|
|
|
1389
1070
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1390
1071
|
import { Context as Context2 } from "@dxos/context";
|
|
1391
1072
|
import { invariant } from "@dxos/invariant";
|
|
1392
|
-
import { log as
|
|
1393
|
-
var
|
|
1073
|
+
import { log as log4 } from "@dxos/log";
|
|
1074
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1394
1075
|
var DEBOUNCE_INTERVAL = 100;
|
|
1395
1076
|
var SpaceAwarenessProvider = class {
|
|
1396
1077
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1409,10 +1090,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1409
1090
|
this._info = info;
|
|
1410
1091
|
}
|
|
1411
1092
|
open() {
|
|
1412
|
-
this._ctx = new Context2(void 0, {
|
|
1413
|
-
F: __dxlog_file6,
|
|
1414
|
-
L: 57
|
|
1415
|
-
});
|
|
1093
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
|
|
1416
1094
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1417
1095
|
if (this._localState) {
|
|
1418
1096
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1437,14 +1115,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1437
1115
|
void this._messenger.postMessage(this._channel, {
|
|
1438
1116
|
kind: "query"
|
|
1439
1117
|
}).catch((err) => {
|
|
1440
|
-
|
|
1118
|
+
log4.debug("failed to query awareness", {
|
|
1441
1119
|
err
|
|
1442
|
-
}, {
|
|
1443
|
-
F: __dxlog_file6,
|
|
1444
|
-
L: 91,
|
|
1445
|
-
S: this,
|
|
1446
|
-
C: (f, a) => f(...a)
|
|
1447
|
-
});
|
|
1120
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
|
|
1448
1121
|
});
|
|
1449
1122
|
}
|
|
1450
1123
|
close() {
|
|
@@ -1456,15 +1129,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1456
1129
|
return Array.from(this._remoteStates.values());
|
|
1457
1130
|
}
|
|
1458
1131
|
update(position) {
|
|
1459
|
-
invariant(this._postTask, void 0, {
|
|
1460
|
-
F: __dxlog_file6,
|
|
1461
|
-
L: 106,
|
|
1462
|
-
S: this,
|
|
1463
|
-
A: [
|
|
1464
|
-
"this._postTask",
|
|
1465
|
-
""
|
|
1466
|
-
]
|
|
1467
|
-
});
|
|
1132
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1468
1133
|
this._localState = {
|
|
1469
1134
|
peerId: this._peerId,
|
|
1470
1135
|
position,
|
|
@@ -1473,38 +1138,22 @@ var SpaceAwarenessProvider = class {
|
|
|
1473
1138
|
this._postTask.schedule();
|
|
1474
1139
|
}
|
|
1475
1140
|
_handleQueryMessage() {
|
|
1476
|
-
invariant(this._postTask, void 0, {
|
|
1477
|
-
F: __dxlog_file6,
|
|
1478
|
-
L: 117,
|
|
1479
|
-
S: this,
|
|
1480
|
-
A: [
|
|
1481
|
-
"this._postTask",
|
|
1482
|
-
""
|
|
1483
|
-
]
|
|
1484
|
-
});
|
|
1141
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1485
1142
|
this._postTask.schedule();
|
|
1486
1143
|
}
|
|
1487
1144
|
_handlePostMessage(message) {
|
|
1488
|
-
invariant(message.kind === "post", void 0, {
|
|
1489
|
-
F: __dxlog_file6,
|
|
1490
|
-
L: 122,
|
|
1491
|
-
S: this,
|
|
1492
|
-
A: [
|
|
1493
|
-
"message.kind === 'post'",
|
|
1494
|
-
""
|
|
1495
|
-
]
|
|
1496
|
-
});
|
|
1145
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1497
1146
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1498
1147
|
this.remoteStateChange.emit();
|
|
1499
1148
|
}
|
|
1500
1149
|
};
|
|
1501
1150
|
|
|
1502
1151
|
// src/extensions/blast.ts
|
|
1503
|
-
import { EditorView as
|
|
1152
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1504
1153
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1505
|
-
import { throttle
|
|
1154
|
+
import { throttle } from "@dxos/async";
|
|
1506
1155
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1507
|
-
var
|
|
1156
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1508
1157
|
var defaultOptions = {
|
|
1509
1158
|
effect: 2,
|
|
1510
1159
|
maxParticles: 200,
|
|
@@ -1549,7 +1198,7 @@ var blast = (options = defaultOptions) => {
|
|
|
1549
1198
|
};
|
|
1550
1199
|
return [
|
|
1551
1200
|
// Cursor moved.
|
|
1552
|
-
|
|
1201
|
+
EditorView6.updateListener.of((update2) => {
|
|
1553
1202
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
1554
1203
|
if (blaster) {
|
|
1555
1204
|
blaster.destroy();
|
|
@@ -1622,15 +1271,7 @@ var Blaster = class {
|
|
|
1622
1271
|
return this._node;
|
|
1623
1272
|
}
|
|
1624
1273
|
initialize() {
|
|
1625
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1626
|
-
F: __dxlog_file7,
|
|
1627
|
-
L: 142,
|
|
1628
|
-
S: this,
|
|
1629
|
-
A: [
|
|
1630
|
-
"!this._canvas && !this._ctx",
|
|
1631
|
-
""
|
|
1632
|
-
]
|
|
1633
|
-
});
|
|
1274
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1634
1275
|
this._canvas = document.createElement("canvas");
|
|
1635
1276
|
this._canvas.id = "code-blast-canvas";
|
|
1636
1277
|
this._canvas.style.position = "absolute";
|
|
@@ -1659,15 +1300,7 @@ var Blaster = class {
|
|
|
1659
1300
|
}
|
|
1660
1301
|
}
|
|
1661
1302
|
start() {
|
|
1662
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1663
|
-
F: __dxlog_file7,
|
|
1664
|
-
L: 181,
|
|
1665
|
-
S: this,
|
|
1666
|
-
A: [
|
|
1667
|
-
"this._canvas && this._ctx",
|
|
1668
|
-
""
|
|
1669
|
-
]
|
|
1670
|
-
});
|
|
1303
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1671
1304
|
this._running = true;
|
|
1672
1305
|
this.loop();
|
|
1673
1306
|
}
|
|
@@ -1694,11 +1327,11 @@ var Blaster = class {
|
|
|
1694
1327
|
this.drawParticles();
|
|
1695
1328
|
requestAnimationFrame(this.loop.bind(this));
|
|
1696
1329
|
}
|
|
1697
|
-
shake =
|
|
1330
|
+
shake = throttle(({ time }) => {
|
|
1698
1331
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1699
1332
|
this._shakeTimeMax = time;
|
|
1700
1333
|
}, 100);
|
|
1701
|
-
spawn =
|
|
1334
|
+
spawn = throttle(({ element, point }) => {
|
|
1702
1335
|
const color = getRGBComponents(element, this._options.color);
|
|
1703
1336
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1704
1337
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1807,9 +1440,9 @@ var random = (min, max) => {
|
|
|
1807
1440
|
|
|
1808
1441
|
// src/extensions/blocks.ts
|
|
1809
1442
|
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1810
|
-
import { Decoration as Decoration6, EditorView as
|
|
1443
|
+
import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
1811
1444
|
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1812
|
-
var paragraphBlockPlugin =
|
|
1445
|
+
var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
|
|
1813
1446
|
decorations;
|
|
1814
1447
|
constructor(view) {
|
|
1815
1448
|
this.decorations = this.build(view);
|
|
@@ -1868,7 +1501,7 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
|
|
|
1868
1501
|
});
|
|
1869
1502
|
var blocks = () => [
|
|
1870
1503
|
paragraphBlockPlugin,
|
|
1871
|
-
|
|
1504
|
+
EditorView7.baseTheme({
|
|
1872
1505
|
".cm-line.block-line": {
|
|
1873
1506
|
paddingLeft: "0.75rem",
|
|
1874
1507
|
paddingRight: "0.75rem",
|
|
@@ -1902,13 +1535,13 @@ var blocks = () => [
|
|
|
1902
1535
|
];
|
|
1903
1536
|
|
|
1904
1537
|
// src/extensions/bookmarks.ts
|
|
1905
|
-
import { Prec as Prec3, StateEffect as
|
|
1538
|
+
import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1906
1539
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1907
|
-
import { log as
|
|
1908
|
-
var
|
|
1909
|
-
var addBookmark =
|
|
1910
|
-
var removeBookmark =
|
|
1911
|
-
var clearBookmarks =
|
|
1540
|
+
import { log as log5 } from "@dxos/log";
|
|
1541
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1542
|
+
var addBookmark = StateEffect2.define();
|
|
1543
|
+
var removeBookmark = StateEffect2.define();
|
|
1544
|
+
var clearBookmarks = StateEffect2.define();
|
|
1912
1545
|
var bookmarks = () => {
|
|
1913
1546
|
return [
|
|
1914
1547
|
bookmarksField,
|
|
@@ -1917,12 +1550,7 @@ var bookmarks = () => {
|
|
|
1917
1550
|
key: "Mod-ArrowUp",
|
|
1918
1551
|
run: (view) => {
|
|
1919
1552
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1920
|
-
|
|
1921
|
-
F: __dxlog_file8,
|
|
1922
|
-
L: 29,
|
|
1923
|
-
S: void 0,
|
|
1924
|
-
C: (f, a) => f(...a)
|
|
1925
|
-
});
|
|
1553
|
+
log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
|
|
1926
1554
|
return true;
|
|
1927
1555
|
}
|
|
1928
1556
|
},
|
|
@@ -1930,12 +1558,7 @@ var bookmarks = () => {
|
|
|
1930
1558
|
key: "Mod-ArrowDown",
|
|
1931
1559
|
run: (view) => {
|
|
1932
1560
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1933
|
-
|
|
1934
|
-
F: __dxlog_file8,
|
|
1935
|
-
L: 37,
|
|
1936
|
-
S: void 0,
|
|
1937
|
-
C: (f, a) => f(...a)
|
|
1938
|
-
});
|
|
1561
|
+
log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
|
|
1939
1562
|
return true;
|
|
1940
1563
|
}
|
|
1941
1564
|
}
|
|
@@ -1972,27 +1595,27 @@ var bookmarksField = StateField2.define({
|
|
|
1972
1595
|
|
|
1973
1596
|
// src/extensions/comments.ts
|
|
1974
1597
|
import { invertedEffects } from "@codemirror/commands";
|
|
1975
|
-
import { StateEffect as
|
|
1976
|
-
import { Decoration as Decoration7, EditorView as
|
|
1598
|
+
import { StateEffect as StateEffect3, StateField as StateField3 } from "@codemirror/state";
|
|
1599
|
+
import { Decoration as Decoration7, EditorView as EditorView9, ViewPlugin as ViewPlugin8, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1977
1600
|
import sortBy from "lodash.sortby";
|
|
1978
1601
|
import { debounce as debounce2 } from "@dxos/async";
|
|
1979
|
-
import { log as
|
|
1602
|
+
import { log as log6 } from "@dxos/log";
|
|
1980
1603
|
import { isNonNullable } from "@dxos/util";
|
|
1981
1604
|
|
|
1982
1605
|
// src/extensions/selection.ts
|
|
1983
1606
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1984
|
-
import { EditorView as
|
|
1607
|
+
import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
|
|
1985
1608
|
import { debounce } from "@dxos/async";
|
|
1986
1609
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1987
1610
|
import { isTruthy } from "@dxos/util";
|
|
1988
|
-
var
|
|
1611
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1989
1612
|
var documentId = singleValueFacet();
|
|
1990
1613
|
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1991
1614
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1992
1615
|
return {
|
|
1993
1616
|
selection,
|
|
1994
1617
|
scrollIntoView: !scrollTo,
|
|
1995
|
-
effects: scrollTo ?
|
|
1618
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
|
1996
1619
|
yMargin: 96
|
|
1997
1620
|
}) : void 0,
|
|
1998
1621
|
annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
|
|
@@ -2000,28 +1623,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
2000
1623
|
};
|
|
2001
1624
|
var createEditorStateStore = (keyPrefix) => ({
|
|
2002
1625
|
getState: (id) => {
|
|
2003
|
-
invariant3(id, void 0, {
|
|
2004
|
-
F: __dxlog_file9,
|
|
2005
|
-
L: 47,
|
|
2006
|
-
S: void 0,
|
|
2007
|
-
A: [
|
|
2008
|
-
"id",
|
|
2009
|
-
""
|
|
2010
|
-
]
|
|
2011
|
-
});
|
|
1626
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
|
|
2012
1627
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
2013
1628
|
return state ? JSON.parse(state) : void 0;
|
|
2014
1629
|
},
|
|
2015
1630
|
setState: (id, state) => {
|
|
2016
|
-
invariant3(id, void 0, {
|
|
2017
|
-
F: __dxlog_file9,
|
|
2018
|
-
L: 53,
|
|
2019
|
-
S: void 0,
|
|
2020
|
-
A: [
|
|
2021
|
-
"id",
|
|
2022
|
-
""
|
|
2023
|
-
]
|
|
2024
|
-
});
|
|
1631
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
|
|
2025
1632
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
2026
1633
|
}
|
|
2027
1634
|
});
|
|
@@ -2034,7 +1641,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2034
1641
|
// setStateDebounced(id, {});
|
|
2035
1642
|
// },
|
|
2036
1643
|
// }),
|
|
2037
|
-
|
|
1644
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
|
2038
1645
|
const id = view.state.facet(documentId);
|
|
2039
1646
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
2040
1647
|
return;
|
|
@@ -2073,10 +1680,10 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2073
1680
|
};
|
|
2074
1681
|
|
|
2075
1682
|
// src/extensions/comments.ts
|
|
2076
|
-
var
|
|
2077
|
-
var setComments =
|
|
2078
|
-
var setSelection =
|
|
2079
|
-
var setCommentState =
|
|
1683
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1684
|
+
var setComments = StateEffect3.define();
|
|
1685
|
+
var setSelection = StateEffect3.define();
|
|
1686
|
+
var setCommentState = StateEffect3.define();
|
|
2080
1687
|
var commentsState = StateField3.define({
|
|
2081
1688
|
create: (state) => ({
|
|
2082
1689
|
id: state.facet(documentId),
|
|
@@ -2115,40 +1722,35 @@ var commentsState = StateField3.define({
|
|
|
2115
1722
|
return value;
|
|
2116
1723
|
}
|
|
2117
1724
|
});
|
|
2118
|
-
var styles2 =
|
|
2119
|
-
".cm-comment
|
|
2120
|
-
padding: "3px 0",
|
|
2121
|
-
color: "var(--color-cm-comment-text)",
|
|
2122
|
-
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2123
|
-
},
|
|
2124
|
-
".cm-comment > span, .cm-comment-current > span": {
|
|
1725
|
+
var styles2 = EditorView9.theme({
|
|
1726
|
+
".cm-comment > span": {
|
|
2125
1727
|
boxDecorationBreak: "clone",
|
|
2126
|
-
boxShadow: "0 0
|
|
1728
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-surface)",
|
|
2127
1729
|
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2128
|
-
color: "var(--color-cm-comment-text)",
|
|
1730
|
+
color: "var(--color-cm-comment-text) !important",
|
|
2129
1731
|
cursor: "pointer"
|
|
1732
|
+
},
|
|
1733
|
+
'.cm-comment[data-current="1"] > span': {
|
|
1734
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-current-surface)",
|
|
1735
|
+
backgroundColor: "var(--color-cm-comment-current-surface)"
|
|
2130
1736
|
}
|
|
2131
1737
|
});
|
|
2132
1738
|
var createCommentMark = (id, isCurrent) => Decoration7.mark({
|
|
2133
|
-
class:
|
|
1739
|
+
class: "cm-comment",
|
|
2134
1740
|
attributes: {
|
|
2135
1741
|
"data-testid": "cm-comment",
|
|
2136
|
-
"data-comment-id": id
|
|
1742
|
+
"data-comment-id": id,
|
|
1743
|
+
"data-current": isCurrent ? "1" : "0"
|
|
2137
1744
|
}
|
|
2138
1745
|
});
|
|
2139
|
-
var commentsDecorations =
|
|
1746
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
|
2140
1747
|
commentsState
|
|
2141
1748
|
], (state) => {
|
|
2142
1749
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
2143
1750
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2144
1751
|
const range = comment.range;
|
|
2145
1752
|
if (!range) {
|
|
2146
|
-
|
|
2147
|
-
F: __dxlog_file10,
|
|
2148
|
-
L: 139,
|
|
2149
|
-
S: void 0,
|
|
2150
|
-
C: (f, a) => f(...a)
|
|
2151
|
-
});
|
|
1753
|
+
log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
|
|
2152
1754
|
return void 0;
|
|
2153
1755
|
} else if (range.from === range.to) {
|
|
2154
1756
|
return void 0;
|
|
@@ -2158,8 +1760,8 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2158
1760
|
}).filter(isNonNullable);
|
|
2159
1761
|
return Decoration7.set(decorations2);
|
|
2160
1762
|
});
|
|
2161
|
-
var commentClickedEffect =
|
|
2162
|
-
var handleCommentClick =
|
|
1763
|
+
var commentClickedEffect = StateEffect3.define();
|
|
1764
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
|
2163
1765
|
click: (event, view) => {
|
|
2164
1766
|
let target = event.target;
|
|
2165
1767
|
const editorRoot = view.dom;
|
|
@@ -2198,7 +1800,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2198
1800
|
}
|
|
2199
1801
|
};
|
|
2200
1802
|
return [
|
|
2201
|
-
|
|
1803
|
+
EditorView9.domEventHandlers({
|
|
2202
1804
|
cut: handleTrack,
|
|
2203
1805
|
copy: handleTrack
|
|
2204
1806
|
}),
|
|
@@ -2220,7 +1822,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2220
1822
|
return effects;
|
|
2221
1823
|
}),
|
|
2222
1824
|
// Handle paste or the undo of comment deletion.
|
|
2223
|
-
|
|
1825
|
+
EditorView9.updateListener.of((update2) => {
|
|
2224
1826
|
const restore = [];
|
|
2225
1827
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
2226
1828
|
const tr = update2.transactions[i];
|
|
@@ -2276,7 +1878,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2276
1878
|
from: changes.mapPos(comment.from, 1),
|
|
2277
1879
|
to: changes.mapPos(comment.to, 1)
|
|
2278
1880
|
});
|
|
2279
|
-
var restoreCommentEffect =
|
|
1881
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
2280
1882
|
map: mapTrackedComment
|
|
2281
1883
|
});
|
|
2282
1884
|
var createComment = (view) => {
|
|
@@ -2362,7 +1964,7 @@ var comments = (options = {}) => {
|
|
|
2362
1964
|
//
|
|
2363
1965
|
// Track deleted ranges and update ranges for decorations.
|
|
2364
1966
|
//
|
|
2365
|
-
|
|
1967
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
|
2366
1968
|
let mod = false;
|
|
2367
1969
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
2368
1970
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -2394,7 +1996,7 @@ var comments = (options = {}) => {
|
|
|
2394
1996
|
//
|
|
2395
1997
|
// Track selection/proximity.
|
|
2396
1998
|
//
|
|
2397
|
-
|
|
1999
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
|
2398
2000
|
let min = Infinity;
|
|
2399
2001
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
2400
2002
|
const { head } = state.selection.main;
|
|
@@ -2430,34 +2032,41 @@ var comments = (options = {}) => {
|
|
|
2430
2032
|
options.onUpdate && trackPastedComments(options.onUpdate)
|
|
2431
2033
|
].filter(isNonNullable);
|
|
2432
2034
|
};
|
|
2433
|
-
var
|
|
2035
|
+
var isRangeVisible = (view, range) => {
|
|
2036
|
+
const from = view.coordsAtPos(range.from);
|
|
2037
|
+
const to = view.coordsAtPos(range.to);
|
|
2038
|
+
if (!from || !to) {
|
|
2039
|
+
return false;
|
|
2040
|
+
}
|
|
2041
|
+
const { top, bottom } = view.scrollDOM.getBoundingClientRect();
|
|
2042
|
+
return from.top >= top && to.bottom <= bottom;
|
|
2043
|
+
};
|
|
2044
|
+
var scrollThreadIntoView = (view, id, { y = "center", yMargin } = {}) => {
|
|
2434
2045
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
2435
2046
|
if (!comment?.comment.cursor) {
|
|
2436
2047
|
return;
|
|
2437
2048
|
}
|
|
2438
2049
|
const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
|
|
2439
|
-
if (range) {
|
|
2440
|
-
|
|
2441
|
-
const currentScrollPosition = view.scrollDOM.scrollTop;
|
|
2442
|
-
const targetScrollPosition = view.coordsAtPos(range.from)?.top;
|
|
2443
|
-
const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
|
|
2444
|
-
const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
|
|
2445
|
-
if (needsScroll || needsSelectionUpdate) {
|
|
2446
|
-
view.dispatch({
|
|
2447
|
-
selection: needsSelectionUpdate ? {
|
|
2448
|
-
anchor: range.from
|
|
2449
|
-
} : void 0,
|
|
2450
|
-
effects: [
|
|
2451
|
-
needsScroll ? EditorView11.scrollIntoView(range.from, center ? {
|
|
2452
|
-
y: "center"
|
|
2453
|
-
} : void 0) : [],
|
|
2454
|
-
needsSelectionUpdate ? setSelection.of({
|
|
2455
|
-
current: id
|
|
2456
|
-
}) : []
|
|
2457
|
-
].flat()
|
|
2458
|
-
});
|
|
2459
|
-
}
|
|
2050
|
+
if (!range) {
|
|
2051
|
+
return;
|
|
2460
2052
|
}
|
|
2053
|
+
const { from, to } = view.state.selection.main;
|
|
2054
|
+
const needsSelectionUpdate = from !== range.from || to !== range.from;
|
|
2055
|
+
view.dispatch({
|
|
2056
|
+
selection: needsSelectionUpdate ? {
|
|
2057
|
+
anchor: range.from
|
|
2058
|
+
} : void 0,
|
|
2059
|
+
effects: [
|
|
2060
|
+
isRangeVisible(view, range) ? [] : EditorView9.scrollIntoView(range.from, {
|
|
2061
|
+
y,
|
|
2062
|
+
yMargin
|
|
2063
|
+
}),
|
|
2064
|
+
// Always mark this thread current so the highlight follows the selected thread.
|
|
2065
|
+
setSelection.of({
|
|
2066
|
+
current: id
|
|
2067
|
+
})
|
|
2068
|
+
].flat()
|
|
2069
|
+
});
|
|
2461
2070
|
};
|
|
2462
2071
|
var ExternalCommentSync = class {
|
|
2463
2072
|
unsubscribe;
|
|
@@ -2479,7 +2088,7 @@ var ExternalCommentSync = class {
|
|
|
2479
2088
|
this.unsubscribe();
|
|
2480
2089
|
};
|
|
2481
2090
|
};
|
|
2482
|
-
var createExternalCommentSync = (id, subscribe, getComments) =>
|
|
2091
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
|
|
2483
2092
|
constructor(view) {
|
|
2484
2093
|
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
2485
2094
|
}
|
|
@@ -2499,12 +2108,12 @@ var debugNodeLogger = (log12 = console.log) => {
|
|
|
2499
2108
|
};
|
|
2500
2109
|
|
|
2501
2110
|
// src/extensions/dnd.ts
|
|
2502
|
-
import { EditorView as
|
|
2111
|
+
import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
|
|
2503
2112
|
var dropFile = (options = {}) => {
|
|
2504
2113
|
return [
|
|
2505
2114
|
styles3,
|
|
2506
2115
|
dropCursor(),
|
|
2507
|
-
|
|
2116
|
+
EditorView10.domEventHandlers({
|
|
2508
2117
|
drop: (event, view) => {
|
|
2509
2118
|
event.preventDefault();
|
|
2510
2119
|
const files = event.dataTransfer?.files;
|
|
@@ -2523,7 +2132,7 @@ var dropFile = (options = {}) => {
|
|
|
2523
2132
|
})
|
|
2524
2133
|
];
|
|
2525
2134
|
};
|
|
2526
|
-
var styles3 =
|
|
2135
|
+
var styles3 = EditorView10.theme({
|
|
2527
2136
|
".cm-dropCursor": {
|
|
2528
2137
|
borderLeft: "2px solid var(--color-accent-text)",
|
|
2529
2138
|
color: "var(--color-accent-text)",
|
|
@@ -2540,15 +2149,15 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2540
2149
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2541
2150
|
import { searchKeymap } from "@codemirror/search";
|
|
2542
2151
|
import { EditorState } from "@codemirror/state";
|
|
2543
|
-
import { EditorView as
|
|
2152
|
+
import { EditorView as EditorView17, ViewPlugin as ViewPlugin13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2544
2153
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2545
2154
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2546
2155
|
import { generateName } from "@dxos/display-name";
|
|
2547
2156
|
import { log as log8 } from "@dxos/log";
|
|
2548
|
-
import { hexToHue, isTruthy as
|
|
2157
|
+
import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
|
|
2549
2158
|
|
|
2550
2159
|
// src/styles/theme.ts
|
|
2551
|
-
import { EditorView as
|
|
2160
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2552
2161
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2553
2162
|
var headings = {
|
|
2554
2163
|
1: {
|
|
@@ -2596,7 +2205,7 @@ var markdownTheme = {
|
|
|
2596
2205
|
fontWeight: "100 !important"
|
|
2597
2206
|
})
|
|
2598
2207
|
};
|
|
2599
|
-
var baseTheme =
|
|
2208
|
+
var baseTheme = EditorView11.baseTheme({
|
|
2600
2209
|
/**
|
|
2601
2210
|
* Outer frame.
|
|
2602
2211
|
*/
|
|
@@ -2608,12 +2217,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2608
2217
|
* Scroller
|
|
2609
2218
|
*/
|
|
2610
2219
|
".cm-scroller": {
|
|
2611
|
-
|
|
2220
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
2221
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2222
|
+
// open/close) don't jump the user's view.
|
|
2223
|
+
overflowAnchor: "auto"
|
|
2612
2224
|
},
|
|
2613
2225
|
".cm-scroller::-webkit-scrollbar": {
|
|
2614
|
-
width: "8px"
|
|
2226
|
+
width: "var(--scrollbar-size,8px)",
|
|
2227
|
+
height: "var(--scrollbar-size,8px)"
|
|
2228
|
+
},
|
|
2229
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2230
|
+
background: "transparent"
|
|
2231
|
+
},
|
|
2232
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2233
|
+
background: "transparent"
|
|
2615
2234
|
},
|
|
2616
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2617
2235
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2618
2236
|
background: "transparent",
|
|
2619
2237
|
transition: "background 0.15s"
|
|
@@ -2650,7 +2268,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2650
2268
|
* Height is set to match the corresponding line (which may have wrapped).
|
|
2651
2269
|
*/
|
|
2652
2270
|
".cm-gutterElement": {
|
|
2653
|
-
lineHeight:
|
|
2271
|
+
lineHeight: "24px",
|
|
2654
2272
|
fontSize: "12px"
|
|
2655
2273
|
},
|
|
2656
2274
|
/**
|
|
@@ -2710,7 +2328,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2710
2328
|
textDecorationThickness: "1px",
|
|
2711
2329
|
textDecorationColor: "var(--color-separator)",
|
|
2712
2330
|
textUnderlineOffset: "2px",
|
|
2713
|
-
borderRadius: ".125rem"
|
|
2331
|
+
borderRadius: ".125rem",
|
|
2332
|
+
cursor: "pointer"
|
|
2714
2333
|
},
|
|
2715
2334
|
".cm-link > span": {
|
|
2716
2335
|
color: "var(--color-accent-text)"
|
|
@@ -2748,12 +2367,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2748
2367
|
padding: "4px"
|
|
2749
2368
|
},
|
|
2750
2369
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2751
|
-
background: "var(--color-
|
|
2752
|
-
color: "var(--color-base-
|
|
2370
|
+
background: "var(--color-current-surface)",
|
|
2371
|
+
color: "var(--color-base-fg)"
|
|
2753
2372
|
},
|
|
2754
2373
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2755
2374
|
paddingLeft: "4px !important",
|
|
2756
|
-
color: "var(--color-base-
|
|
2375
|
+
color: "var(--color-base-fg)"
|
|
2757
2376
|
},
|
|
2758
2377
|
/**
|
|
2759
2378
|
* Completion info.
|
|
@@ -2772,7 +2391,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2772
2391
|
padding: "0 4px"
|
|
2773
2392
|
},
|
|
2774
2393
|
".cm-completionMatchedText": {
|
|
2775
|
-
color: "var(--color-base-
|
|
2394
|
+
color: "var(--color-base-fg)",
|
|
2776
2395
|
textDecoration: "none !important"
|
|
2777
2396
|
},
|
|
2778
2397
|
/**
|
|
@@ -2807,7 +2426,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2807
2426
|
backgroundColor: "var(--color-input-surface)"
|
|
2808
2427
|
},
|
|
2809
2428
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2810
|
-
outline: "1px solid var(--color-
|
|
2429
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2811
2430
|
},
|
|
2812
2431
|
".cm-panel label": {
|
|
2813
2432
|
display: "inline-flex",
|
|
@@ -2820,15 +2439,15 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2820
2439
|
height: "8px",
|
|
2821
2440
|
marginRight: "6px !important",
|
|
2822
2441
|
padding: "2px !important",
|
|
2823
|
-
color: "var(--color-
|
|
2442
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2824
2443
|
},
|
|
2825
2444
|
".cm-panel button": {
|
|
2826
2445
|
"&:hover": {
|
|
2827
|
-
// TODO(burdon): Replace with layer and @apply bg-accent-
|
|
2828
|
-
backgroundColor: "var(--color-accent-
|
|
2446
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-bg-hover
|
|
2447
|
+
backgroundColor: "var(--color-accent-bg-hover) !important"
|
|
2829
2448
|
},
|
|
2830
2449
|
"&:active": {
|
|
2831
|
-
backgroundColor: "var(--color-accent-
|
|
2450
|
+
backgroundColor: "var(--color-accent-bg-hover)"
|
|
2832
2451
|
}
|
|
2833
2452
|
},
|
|
2834
2453
|
".cm-panel.cm-search": {
|
|
@@ -2836,14 +2455,14 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2836
2455
|
borderTop: "1px solid var(--color-separator)"
|
|
2837
2456
|
}
|
|
2838
2457
|
});
|
|
2839
|
-
var editorGutter =
|
|
2458
|
+
var editorGutter = EditorView11.theme({
|
|
2840
2459
|
".cm-gutters": {
|
|
2841
2460
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2842
2461
|
background: "var(--color-base-surface) !important",
|
|
2843
2462
|
paddingRight: "1rem"
|
|
2844
2463
|
}
|
|
2845
2464
|
});
|
|
2846
|
-
var createFontTheme = ({ monospace } = {}) =>
|
|
2465
|
+
var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
|
|
2847
2466
|
// Main content.
|
|
2848
2467
|
".cm-scroller": {
|
|
2849
2468
|
fontFamily: monospace ? fontMono : fontBody
|
|
@@ -2856,9 +2475,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2856
2475
|
});
|
|
2857
2476
|
|
|
2858
2477
|
// src/extensions/focus.ts
|
|
2859
|
-
import { StateEffect as
|
|
2860
|
-
import { EditorView as
|
|
2861
|
-
var focusEffect =
|
|
2478
|
+
import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
|
|
2479
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
|
2480
|
+
var focusEffect = StateEffect4.define();
|
|
2862
2481
|
var focusField = StateField5.define({
|
|
2863
2482
|
create: () => false,
|
|
2864
2483
|
update: (value, tr) => {
|
|
@@ -2872,7 +2491,7 @@ var focusField = StateField5.define({
|
|
|
2872
2491
|
});
|
|
2873
2492
|
var focus = [
|
|
2874
2493
|
focusField,
|
|
2875
|
-
|
|
2494
|
+
EditorView12.domEventHandlers({
|
|
2876
2495
|
focus: (_event, view) => {
|
|
2877
2496
|
requestAnimationFrame(() => view.dispatch({
|
|
2878
2497
|
effects: focusEffect.of(true)
|
|
@@ -2886,19 +2505,403 @@ var focus = [
|
|
|
2886
2505
|
})
|
|
2887
2506
|
];
|
|
2888
2507
|
|
|
2889
|
-
// src/extensions/scroll
|
|
2508
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2509
|
+
import { StateEffect as StateEffect6 } from "@codemirror/state";
|
|
2510
|
+
import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
|
|
2511
|
+
import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
|
|
2512
|
+
import { Domino } from "@dxos/ui";
|
|
2513
|
+
import { getSize } from "@dxos/ui-theme";
|
|
2514
|
+
|
|
2515
|
+
// src/extensions/scrolling/crawler.ts
|
|
2516
|
+
import { StateEffect as StateEffect5 } from "@codemirror/state";
|
|
2517
|
+
import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
|
|
2518
|
+
import { log as log7 } from "@dxos/log";
|
|
2519
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
|
|
2520
|
+
var crawlerLineEffect = StateEffect5.define();
|
|
2521
|
+
var crawlerActiveEffect = StateEffect5.define();
|
|
2522
|
+
var scrollToLine = (view, options) => {
|
|
2523
|
+
view.dispatch({
|
|
2524
|
+
effects: crawlerLineEffect.of(options)
|
|
2525
|
+
});
|
|
2526
|
+
};
|
|
2527
|
+
var crawler = ({ overScroll = 0 } = {}) => {
|
|
2528
|
+
const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
|
|
2529
|
+
view;
|
|
2530
|
+
crawler;
|
|
2531
|
+
constructor(view) {
|
|
2532
|
+
this.view = view;
|
|
2533
|
+
this.crawler = createCrawler(this.view);
|
|
2534
|
+
}
|
|
2535
|
+
// No-op.
|
|
2536
|
+
destroy() {
|
|
2537
|
+
this.crawler.cancel();
|
|
2538
|
+
}
|
|
2539
|
+
cancel() {
|
|
2540
|
+
this.crawler.cancel();
|
|
2541
|
+
}
|
|
2542
|
+
crawl({ active, instant } = {
|
|
2543
|
+
active: false
|
|
2544
|
+
}) {
|
|
2545
|
+
if (active) {
|
|
2546
|
+
this.crawler.scroll(instant);
|
|
2547
|
+
} else {
|
|
2548
|
+
this.crawler.cancel();
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
2552
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
2553
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
2554
|
+
const doc = this.view.state.doc;
|
|
2555
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
2556
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
2557
|
+
const lineStart = doc.line(line + 1).from;
|
|
2558
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
2559
|
+
if (coords) {
|
|
2560
|
+
const currentScrollTop = scrollTop;
|
|
2561
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
2562
|
+
if (position === "end") {
|
|
2563
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
2564
|
+
} else {
|
|
2565
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
2566
|
+
}
|
|
2567
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
requestAnimationFrame(() => {
|
|
2571
|
+
this.view.scrollDOM.scrollTo({
|
|
2572
|
+
top: targetScrollTop
|
|
2573
|
+
});
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
return [
|
|
2578
|
+
crawlerPlugin,
|
|
2579
|
+
// Listen for effect.
|
|
2580
|
+
EditorView13.updateListener.of((update2) => {
|
|
2581
|
+
update2.transactions.forEach((transaction) => {
|
|
2582
|
+
try {
|
|
2583
|
+
const plugin = update2.view.plugin(crawlerPlugin);
|
|
2584
|
+
if (plugin) {
|
|
2585
|
+
for (const effect of transaction.effects) {
|
|
2586
|
+
if (effect.is(crawlerActiveEffect)) {
|
|
2587
|
+
plugin.crawl(effect.value);
|
|
2588
|
+
} else if (effect.is(crawlerLineEffect)) {
|
|
2589
|
+
plugin.scroll(effect.value);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
} catch (err) {
|
|
2594
|
+
log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 105, S: void 0 });
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2597
|
+
}),
|
|
2598
|
+
// Styles.
|
|
2599
|
+
EditorView13.theme({
|
|
2600
|
+
".cm-scroller": {
|
|
2601
|
+
overflowY: "scroll",
|
|
2602
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
2603
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
2604
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
2605
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
2606
|
+
overflowAnchor: "auto"
|
|
2607
|
+
},
|
|
2608
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
2609
|
+
display: "none"
|
|
2610
|
+
},
|
|
2611
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2612
|
+
background: "transparent",
|
|
2613
|
+
transition: "background 0.15s"
|
|
2614
|
+
},
|
|
2615
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2616
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2617
|
+
},
|
|
2618
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
2619
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
2620
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
2621
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
2622
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
2623
|
+
".cm-content::after": {
|
|
2624
|
+
content: '""',
|
|
2625
|
+
display: "block",
|
|
2626
|
+
height: `${overScroll}px`
|
|
2627
|
+
},
|
|
2628
|
+
".cm-scroll-button": {
|
|
2629
|
+
position: "absolute",
|
|
2630
|
+
bottom: "0.5rem",
|
|
2631
|
+
right: "1rem"
|
|
2632
|
+
}
|
|
2633
|
+
})
|
|
2634
|
+
];
|
|
2635
|
+
};
|
|
2636
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
2637
|
+
const el = view.scrollDOM;
|
|
2638
|
+
let currentTop = 0;
|
|
2639
|
+
let velocity = 0;
|
|
2640
|
+
let rafId = null;
|
|
2641
|
+
let lastTime = 0;
|
|
2642
|
+
let instant = false;
|
|
2643
|
+
function frame(now) {
|
|
2644
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
2645
|
+
lastTime = now;
|
|
2646
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
2647
|
+
const delta = targetTop - currentTop;
|
|
2648
|
+
if (instant) {
|
|
2649
|
+
el.scrollTop = targetTop;
|
|
2650
|
+
currentTop = targetTop;
|
|
2651
|
+
velocity = 0;
|
|
2652
|
+
if (Math.abs(delta) < snapThreshold) {
|
|
2653
|
+
rafId = null;
|
|
2654
|
+
lastTime = 0;
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
rafId = requestAnimationFrame(frame);
|
|
2658
|
+
return;
|
|
2659
|
+
}
|
|
2660
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
2661
|
+
el.scrollTop = targetTop;
|
|
2662
|
+
currentTop = targetTop;
|
|
2663
|
+
velocity = 0;
|
|
2664
|
+
rafId = null;
|
|
2665
|
+
lastTime = 0;
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
2669
|
+
velocity += accel * dt;
|
|
2670
|
+
currentTop += velocity * dt;
|
|
2671
|
+
el.scrollTop = currentTop;
|
|
2672
|
+
rafId = requestAnimationFrame(frame);
|
|
2673
|
+
}
|
|
2674
|
+
return {
|
|
2675
|
+
scroll: (useInstant = false) => {
|
|
2676
|
+
instant = useInstant;
|
|
2677
|
+
if (rafId === null) {
|
|
2678
|
+
currentTop = el.scrollTop;
|
|
2679
|
+
lastTime = 0;
|
|
2680
|
+
rafId = requestAnimationFrame(frame);
|
|
2681
|
+
}
|
|
2682
|
+
},
|
|
2683
|
+
cancel: () => {
|
|
2684
|
+
if (rafId !== null) {
|
|
2685
|
+
cancelAnimationFrame(rafId);
|
|
2686
|
+
velocity = 0;
|
|
2687
|
+
lastTime = 0;
|
|
2688
|
+
rafId = null;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2694
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2695
|
+
var autoScrollEffect = StateEffect6.define();
|
|
2696
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
2697
|
+
let buttonContainer;
|
|
2698
|
+
let isPinned = true;
|
|
2699
|
+
let jumpPending = false;
|
|
2700
|
+
let enabled = true;
|
|
2701
|
+
let firstUpdate = true;
|
|
2702
|
+
let streamed = false;
|
|
2703
|
+
const setPinned = (pinned) => {
|
|
2704
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
2705
|
+
isPinned = pinned;
|
|
2706
|
+
};
|
|
2707
|
+
return [
|
|
2708
|
+
// Update listener for scrolling when content changes.
|
|
2709
|
+
EditorView14.updateListener.of((update2) => {
|
|
2710
|
+
const { view, heightChanged, state, startState } = update2;
|
|
2711
|
+
for (const tr of update2.transactions) {
|
|
2712
|
+
for (const effect of tr.effects) {
|
|
2713
|
+
if (effect.is(autoScrollEffect)) {
|
|
2714
|
+
enabled = effect.value;
|
|
2715
|
+
if (enabled) {
|
|
2716
|
+
setPinned(true);
|
|
2717
|
+
view.dispatch({
|
|
2718
|
+
effects: crawlerActiveEffect.of({
|
|
2719
|
+
active: true
|
|
2720
|
+
})
|
|
2721
|
+
});
|
|
2722
|
+
} else {
|
|
2723
|
+
view.dispatch({
|
|
2724
|
+
effects: crawlerActiveEffect.of({
|
|
2725
|
+
active: false
|
|
2726
|
+
})
|
|
2727
|
+
});
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
if (!enabled) {
|
|
2733
|
+
return;
|
|
2734
|
+
}
|
|
2735
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
2736
|
+
firstUpdate = false;
|
|
2737
|
+
jumpPending = true;
|
|
2738
|
+
requestAnimationFrame(() => {
|
|
2739
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
2740
|
+
jumpPending = false;
|
|
2741
|
+
});
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
firstUpdate = false;
|
|
2745
|
+
if (jumpPending) {
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
if (heightChanged) {
|
|
2749
|
+
if (isPinned) {
|
|
2750
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2751
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2752
|
+
if (update2.docChanged) {
|
|
2753
|
+
streamed = true;
|
|
2754
|
+
}
|
|
2755
|
+
if (delta > 0) {
|
|
2756
|
+
setPinned(true);
|
|
2757
|
+
view.dispatch({
|
|
2758
|
+
effects: crawlerActiveEffect.of({
|
|
2759
|
+
active: true,
|
|
2760
|
+
instant: !streamed
|
|
2761
|
+
})
|
|
2762
|
+
});
|
|
2763
|
+
} else if (delta < -1) {
|
|
2764
|
+
setPinned(false);
|
|
2765
|
+
}
|
|
2766
|
+
} else {
|
|
2767
|
+
if (state.doc.length === 0) {
|
|
2768
|
+
setPinned(true);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
}),
|
|
2773
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
2774
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
2775
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
2776
|
+
scrollOnResize ? ViewPlugin10.fromClass(class {
|
|
2777
|
+
observer;
|
|
2778
|
+
firstObservation = true;
|
|
2779
|
+
destroyed = false;
|
|
2780
|
+
constructor(view) {
|
|
2781
|
+
const onResize = throttle2(() => {
|
|
2782
|
+
if (this.destroyed || !enabled) {
|
|
2783
|
+
return;
|
|
2784
|
+
}
|
|
2785
|
+
setPinned(true);
|
|
2786
|
+
requestAnimationFrame(() => {
|
|
2787
|
+
if (this.destroyed) {
|
|
2788
|
+
return;
|
|
2789
|
+
}
|
|
2790
|
+
view.scrollDOM.scrollTo({
|
|
2791
|
+
top: view.scrollDOM.scrollHeight,
|
|
2792
|
+
behavior: "instant"
|
|
2793
|
+
});
|
|
2794
|
+
view.dispatch({
|
|
2795
|
+
effects: crawlerActiveEffect.of({
|
|
2796
|
+
active: false
|
|
2797
|
+
})
|
|
2798
|
+
});
|
|
2799
|
+
});
|
|
2800
|
+
}, 50);
|
|
2801
|
+
this.observer = new ResizeObserver(() => {
|
|
2802
|
+
if (this.firstObservation) {
|
|
2803
|
+
this.firstObservation = false;
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
onResize();
|
|
2807
|
+
});
|
|
2808
|
+
this.observer.observe(view.scrollDOM);
|
|
2809
|
+
}
|
|
2810
|
+
destroy() {
|
|
2811
|
+
this.destroyed = true;
|
|
2812
|
+
this.observer.disconnect();
|
|
2813
|
+
}
|
|
2814
|
+
}) : [],
|
|
2815
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
2816
|
+
ViewPlugin10.fromClass(class {
|
|
2817
|
+
cleanup;
|
|
2818
|
+
constructor(view) {
|
|
2819
|
+
const onUserScroll = throttle2(() => {
|
|
2820
|
+
requestAnimationFrame(() => {
|
|
2821
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2822
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2823
|
+
const pinned = Math.abs(delta) <= 1;
|
|
2824
|
+
setPinned(pinned);
|
|
2825
|
+
if (!pinned) {
|
|
2826
|
+
view.dispatch({
|
|
2827
|
+
effects: crawlerActiveEffect.of({
|
|
2828
|
+
active: false
|
|
2829
|
+
})
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
}, 500);
|
|
2834
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
2835
|
+
if (isPinned) {
|
|
2836
|
+
setPinned(false);
|
|
2837
|
+
view.dispatch({
|
|
2838
|
+
effects: crawlerActiveEffect.of({
|
|
2839
|
+
active: false
|
|
2840
|
+
})
|
|
2841
|
+
});
|
|
2842
|
+
}
|
|
2843
|
+
onUserScroll();
|
|
2844
|
+
});
|
|
2845
|
+
}
|
|
2846
|
+
destroy() {
|
|
2847
|
+
this.cleanup();
|
|
2848
|
+
}
|
|
2849
|
+
}),
|
|
2850
|
+
// Scroll button.
|
|
2851
|
+
ViewPlugin10.fromClass(class {
|
|
2852
|
+
constructor(view) {
|
|
2853
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
2854
|
+
icon: "ph--arrow-down--regular"
|
|
2855
|
+
});
|
|
2856
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-bg").attributes({
|
|
2857
|
+
"data-density": "md"
|
|
2858
|
+
}).append(icon).on("click", () => {
|
|
2859
|
+
setPinned(true);
|
|
2860
|
+
view.dispatch({
|
|
2861
|
+
effects: [
|
|
2862
|
+
crawlerLineEffect.of({
|
|
2863
|
+
line: -1,
|
|
2864
|
+
position: "end",
|
|
2865
|
+
behavior: "smooth"
|
|
2866
|
+
}),
|
|
2867
|
+
// Re-engage the follower so it keeps tracking the bottom as content continues
|
|
2868
|
+
// to stream after the catch-up jump.
|
|
2869
|
+
crawlerActiveEffect.of({
|
|
2870
|
+
active: true,
|
|
2871
|
+
instant: !streamed
|
|
2872
|
+
})
|
|
2873
|
+
]
|
|
2874
|
+
});
|
|
2875
|
+
});
|
|
2876
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0 z-1").append(button).root;
|
|
2877
|
+
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
2878
|
+
}
|
|
2879
|
+
})
|
|
2880
|
+
];
|
|
2881
|
+
};
|
|
2882
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
2883
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
2884
|
+
passive: true
|
|
2885
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
2886
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
2887
|
+
onUserScroll();
|
|
2888
|
+
}
|
|
2889
|
+
}));
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
// src/extensions/scrolling/scroll-past-end.ts
|
|
2890
2893
|
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2891
2894
|
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
style:
|
|
2895
|
+
_height = 1e3;
|
|
2896
|
+
_attrs = {
|
|
2897
|
+
style: `padding-bottom: ${this._height}px`
|
|
2895
2898
|
};
|
|
2896
2899
|
update({ view }) {
|
|
2897
2900
|
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2898
2901
|
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2899
|
-
if (height >= 0 && height !== this.
|
|
2900
|
-
this.
|
|
2901
|
-
this.
|
|
2902
|
+
if (height >= 0 && height !== this._height) {
|
|
2903
|
+
this._height = height;
|
|
2904
|
+
this._attrs = {
|
|
2902
2905
|
style: `padding-bottom: ${height}px`
|
|
2903
2906
|
};
|
|
2904
2907
|
}
|
|
@@ -2906,12 +2909,68 @@ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
|
2906
2909
|
});
|
|
2907
2910
|
var scrollPastEnd = () => [
|
|
2908
2911
|
scrollPastEndPlugin,
|
|
2909
|
-
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.
|
|
2912
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
|
|
2910
2913
|
];
|
|
2911
2914
|
|
|
2915
|
+
// src/extensions/scrolling/scrollbar-autohide.ts
|
|
2916
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12 } from "@codemirror/view";
|
|
2917
|
+
var scrollbarAutohide = ({ timeout = 800 } = {}) => [
|
|
2918
|
+
ViewPlugin12.fromClass(
|
|
2919
|
+
// NOTE: Uses TS `private`/plain fields rather than ES `#private`. CodeMirror's plugin lifecycle
|
|
2920
|
+
// (and the source/prebundled double-load in dev) can invoke `destroy` with a `this` that the
|
|
2921
|
+
// WeakMap-based `#private` transpilation rejects ("private field on non-instance"), crashing
|
|
2922
|
+
// editor teardown. Plain fields avoid the membership check.
|
|
2923
|
+
class {
|
|
2924
|
+
_scroller;
|
|
2925
|
+
_timer;
|
|
2926
|
+
constructor(view) {
|
|
2927
|
+
this._scroller = view.scrollDOM;
|
|
2928
|
+
this._scroller.addEventListener("scroll", this._handleScroll, {
|
|
2929
|
+
passive: true
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
destroy() {
|
|
2933
|
+
this._scroller.removeEventListener("scroll", this._handleScroll);
|
|
2934
|
+
clearTimeout(this._timer);
|
|
2935
|
+
this._scroller.classList.remove("cm-scrolling");
|
|
2936
|
+
}
|
|
2937
|
+
// Show the thumb while scrolling; remove the class once scrolling has been idle for `timeout`.
|
|
2938
|
+
_handleScroll = () => {
|
|
2939
|
+
this._scroller.classList.add("cm-scrolling");
|
|
2940
|
+
clearTimeout(this._timer);
|
|
2941
|
+
this._timer = setTimeout(() => this._scroller.classList.remove("cm-scrolling"), timeout);
|
|
2942
|
+
};
|
|
2943
|
+
}
|
|
2944
|
+
),
|
|
2945
|
+
EditorView16.theme({
|
|
2946
|
+
// Reveal the thumb only while actively scrolling.
|
|
2947
|
+
".cm-scroller.cm-scrolling::-webkit-scrollbar-thumb": {
|
|
2948
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2949
|
+
},
|
|
2950
|
+
// Suppress the base theme's hover-reveal (higher specificity via `:not(.cm-scrolling)`), so a
|
|
2951
|
+
// hovered/focused-but-idle editor keeps the thumb hidden.
|
|
2952
|
+
"&:hover .cm-scroller:not(.cm-scrolling)::-webkit-scrollbar-thumb": {
|
|
2953
|
+
background: "transparent"
|
|
2954
|
+
}
|
|
2955
|
+
})
|
|
2956
|
+
];
|
|
2957
|
+
|
|
2958
|
+
// src/extensions/scrolling/scroller.ts
|
|
2959
|
+
import { isTruthy as isTruthy2 } from "@dxos/util";
|
|
2960
|
+
var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
|
|
2961
|
+
return [
|
|
2962
|
+
crawler({
|
|
2963
|
+
overScroll
|
|
2964
|
+
}),
|
|
2965
|
+
autoScroll2 && autoScroll({
|
|
2966
|
+
scrollOnResize
|
|
2967
|
+
})
|
|
2968
|
+
].filter(isTruthy2);
|
|
2969
|
+
};
|
|
2970
|
+
|
|
2912
2971
|
// src/extensions/factories.ts
|
|
2913
2972
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2914
|
-
var tabbable =
|
|
2973
|
+
var tabbable = EditorView17.contentAttributes.of({
|
|
2915
2974
|
tabindex: "0"
|
|
2916
2975
|
});
|
|
2917
2976
|
var filterChars = (chars) => {
|
|
@@ -2964,13 +3023,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2964
3023
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2965
3024
|
return [
|
|
2966
3025
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2967
|
-
|
|
2968
|
-
log8.catch(err, void 0, {
|
|
2969
|
-
F: __dxlog_file11,
|
|
2970
|
-
L: 130,
|
|
2971
|
-
S: void 0,
|
|
2972
|
-
C: (f, a) => f(...a)
|
|
2973
|
-
});
|
|
3026
|
+
EditorView17.exceptionSink.of((err) => {
|
|
3027
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2974
3028
|
}),
|
|
2975
3029
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2976
3030
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2979,7 +3033,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2979
3033
|
props.drawSelection && drawSelection({
|
|
2980
3034
|
cursorBlinkRate: 1200
|
|
2981
3035
|
}),
|
|
2982
|
-
props.editable !== void 0 &&
|
|
3036
|
+
props.editable !== void 0 && EditorView17.editable.of(props.editable),
|
|
2983
3037
|
props.focus && focus,
|
|
2984
3038
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2985
3039
|
props.history && history(),
|
|
@@ -2987,9 +3041,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2987
3041
|
lineNumbers(),
|
|
2988
3042
|
editorGutter
|
|
2989
3043
|
],
|
|
2990
|
-
props.lineWrapping &&
|
|
3044
|
+
props.lineWrapping && EditorView17.lineWrapping,
|
|
2991
3045
|
props.placeholder && placeholder2(props.placeholder),
|
|
2992
3046
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
3047
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
3048
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
3049
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
3050
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
3051
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
3052
|
+
// depend on being able to populate the doc themselves.
|
|
3053
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2993
3054
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2994
3055
|
props.tabbable && tabbable,
|
|
2995
3056
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -3014,8 +3075,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
3014
3075
|
preventDefault: true,
|
|
3015
3076
|
run: () => true
|
|
3016
3077
|
}
|
|
3017
|
-
].filter(
|
|
3018
|
-
].filter(
|
|
3078
|
+
].filter(isTruthy3))
|
|
3079
|
+
].filter(isTruthy3);
|
|
3019
3080
|
};
|
|
3020
3081
|
var grow = {
|
|
3021
3082
|
editor: {
|
|
@@ -3032,29 +3093,32 @@ var defaultStyles = {
|
|
|
3032
3093
|
dark: vscodeDarkStyle,
|
|
3033
3094
|
light: vscodeLightStyle
|
|
3034
3095
|
};
|
|
3035
|
-
var createThemeExtensions = ({ monospace,
|
|
3096
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
3036
3097
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
3037
3098
|
return [
|
|
3038
3099
|
baseTheme,
|
|
3039
|
-
|
|
3100
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
3040
3101
|
createFontTheme({
|
|
3041
3102
|
monospace
|
|
3042
3103
|
}),
|
|
3043
3104
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
3044
|
-
slots.editor?.className &&
|
|
3105
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
3045
3106
|
class: slots.editor.className
|
|
3046
3107
|
}),
|
|
3047
|
-
slots.content?.className &&
|
|
3108
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3048
3109
|
class: slots.content.className
|
|
3049
3110
|
}),
|
|
3050
|
-
slots.scroller?.className &&
|
|
3111
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin13.fromClass(class {
|
|
3051
3112
|
constructor(view) {
|
|
3052
3113
|
if (slots.scroller?.className) {
|
|
3053
3114
|
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
3054
3115
|
}
|
|
3116
|
+
if (scrollbarThin) {
|
|
3117
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3118
|
+
}
|
|
3055
3119
|
}
|
|
3056
3120
|
})
|
|
3057
|
-
].filter(
|
|
3121
|
+
].filter(isTruthy3);
|
|
3058
3122
|
};
|
|
3059
3123
|
var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
3060
3124
|
const extensions = [];
|
|
@@ -3080,7 +3144,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
3080
3144
|
|
|
3081
3145
|
// src/extensions/folding.ts
|
|
3082
3146
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
3083
|
-
import { EditorView as
|
|
3147
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
3084
3148
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
3085
3149
|
var folding = () => {
|
|
3086
3150
|
return [
|
|
@@ -3095,7 +3159,7 @@ var folding = () => {
|
|
|
3095
3159
|
}))).root;
|
|
3096
3160
|
}
|
|
3097
3161
|
}),
|
|
3098
|
-
|
|
3162
|
+
EditorView18.theme({
|
|
3099
3163
|
".cm-foldGutter": {
|
|
3100
3164
|
opacity: 0.3,
|
|
3101
3165
|
transition: "opacity 0.3s",
|
|
@@ -3109,7 +3173,7 @@ var folding = () => {
|
|
|
3109
3173
|
};
|
|
3110
3174
|
|
|
3111
3175
|
// src/extensions/hashtag.ts
|
|
3112
|
-
import { Decoration as Decoration8, EditorView as
|
|
3176
|
+
import { Decoration as Decoration8, EditorView as EditorView19, MatchDecorator, ViewPlugin as ViewPlugin14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3113
3177
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3114
3178
|
var TagWidget = class extends WidgetType4 {
|
|
3115
3179
|
_text;
|
|
@@ -3130,7 +3194,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3130
3194
|
})
|
|
3131
3195
|
});
|
|
3132
3196
|
var hashtag = () => [
|
|
3133
|
-
|
|
3197
|
+
ViewPlugin14.fromClass(class {
|
|
3134
3198
|
tags;
|
|
3135
3199
|
constructor(view) {
|
|
3136
3200
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3140,11 +3204,11 @@ var hashtag = () => [
|
|
|
3140
3204
|
}
|
|
3141
3205
|
}, {
|
|
3142
3206
|
decorations: (instance) => instance.tags,
|
|
3143
|
-
provide: (plugin) =>
|
|
3207
|
+
provide: (plugin) => EditorView19.atomicRanges.of((view) => {
|
|
3144
3208
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3145
3209
|
})
|
|
3146
3210
|
}),
|
|
3147
|
-
|
|
3211
|
+
EditorView19.theme({
|
|
3148
3212
|
".cm-tag": {
|
|
3149
3213
|
borderRadius: "4px",
|
|
3150
3214
|
marginRight: "6px",
|
|
@@ -3199,18 +3263,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3199
3263
|
};
|
|
3200
3264
|
|
|
3201
3265
|
// src/extensions/listener.ts
|
|
3202
|
-
import { EditorView as
|
|
3266
|
+
import { EditorView as EditorView20 } from "@codemirror/view";
|
|
3203
3267
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3204
3268
|
var listener = ({ onFocus, onChange }) => {
|
|
3205
3269
|
return [
|
|
3206
|
-
onFocus &&
|
|
3270
|
+
onFocus && EditorView20.focusChangeEffect.of((state, focusing) => {
|
|
3207
3271
|
onFocus({
|
|
3208
3272
|
id: state.facet(documentId),
|
|
3209
3273
|
focusing
|
|
3210
3274
|
});
|
|
3211
3275
|
return null;
|
|
3212
3276
|
}),
|
|
3213
|
-
onChange &&
|
|
3277
|
+
onChange && EditorView20.updateListener.of(({ state, docChanged }) => {
|
|
3214
3278
|
if (docChanged) {
|
|
3215
3279
|
onChange({
|
|
3216
3280
|
id: state.facet(documentId),
|
|
@@ -3225,7 +3289,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3225
3289
|
import { snippet } from "@codemirror/autocomplete";
|
|
3226
3290
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3227
3291
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3228
|
-
import { EditorView as
|
|
3292
|
+
import { EditorView as EditorView21, keymap as keymap8 } from "@codemirror/view";
|
|
3229
3293
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3230
3294
|
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;
|
|
3231
3295
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4314,7 +4378,7 @@ var getFormatting = (state) => {
|
|
|
4314
4378
|
};
|
|
4315
4379
|
};
|
|
4316
4380
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4317
|
-
return
|
|
4381
|
+
return EditorView21.updateListener.of(debounceAndThrottle((update2) => {
|
|
4318
4382
|
if (update2.docChanged || update2.selectionSet) {
|
|
4319
4383
|
onStateChange(getFormatting(update2.state));
|
|
4320
4384
|
}
|
|
@@ -4378,7 +4442,7 @@ import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lan
|
|
|
4378
4442
|
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4379
4443
|
import { languages } from "@codemirror/language-data";
|
|
4380
4444
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4381
|
-
import { isTruthy as
|
|
4445
|
+
import { isTruthy as isTruthy4 } from "@dxos/util";
|
|
4382
4446
|
|
|
4383
4447
|
// src/extensions/markdown/highlight.ts
|
|
4384
4448
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -4610,7 +4674,7 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4610
4674
|
...defaultKeymap2,
|
|
4611
4675
|
// TODO(burdon): Remove?
|
|
4612
4676
|
...completionKeymap
|
|
4613
|
-
].filter(
|
|
4677
|
+
].filter(isTruthy4))
|
|
4614
4678
|
];
|
|
4615
4679
|
};
|
|
4616
4680
|
var noFencedCodeFolding = {
|
|
@@ -4660,16 +4724,16 @@ var convertTreeToJson = (state) => {
|
|
|
4660
4724
|
|
|
4661
4725
|
// src/extensions/markdown/decorate.ts
|
|
4662
4726
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4663
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4664
|
-
import { Decoration as Decoration11, EditorView as
|
|
4727
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect8 } from "@codemirror/state";
|
|
4728
|
+
import { Decoration as Decoration11, EditorView as EditorView25, ViewPlugin as ViewPlugin17, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4665
4729
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4666
4730
|
|
|
4667
4731
|
// src/extensions/markdown/changes.ts
|
|
4668
4732
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4669
4733
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4670
|
-
import { ViewPlugin as
|
|
4734
|
+
import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
|
|
4671
4735
|
var adjustChanges = () => {
|
|
4672
|
-
return
|
|
4736
|
+
return ViewPlugin15.fromClass(class {
|
|
4673
4737
|
update(update2) {
|
|
4674
4738
|
const tree = syntaxTree4(update2.state);
|
|
4675
4739
|
const adjustments = [];
|
|
@@ -4810,15 +4874,19 @@ var getValidUrl = (str) => {
|
|
|
4810
4874
|
|
|
4811
4875
|
// src/extensions/markdown/image.ts
|
|
4812
4876
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4813
|
-
import { StateField as StateField7 } from "@codemirror/state";
|
|
4814
|
-
import { Decoration as Decoration9, EditorView as
|
|
4815
|
-
var
|
|
4877
|
+
import { StateEffect as StateEffect7, StateField as StateField7 } from "@codemirror/state";
|
|
4878
|
+
import { Decoration as Decoration9, EditorView as EditorView22, ViewPlugin as ViewPlugin16, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4879
|
+
var rebuildEffect = StateEffect7.define();
|
|
4880
|
+
var image = (options = {}) => {
|
|
4816
4881
|
return [
|
|
4817
4882
|
StateField7.define({
|
|
4818
4883
|
create: (state) => {
|
|
4819
|
-
return Decoration9.set(buildDecorations(state, 0, state.doc.length));
|
|
4884
|
+
return Decoration9.set(buildDecorations(state, 0, state.doc.length, options));
|
|
4820
4885
|
},
|
|
4821
4886
|
update: (value, tr) => {
|
|
4887
|
+
if (tr.effects.some((effect) => effect.is(rebuildEffect))) {
|
|
4888
|
+
return Decoration9.set(buildDecorations(tr.state, 0, tr.state.doc.length, options));
|
|
4889
|
+
}
|
|
4822
4890
|
if (!tr.docChanged && !tr.selection) {
|
|
4823
4891
|
return value;
|
|
4824
4892
|
}
|
|
@@ -4836,14 +4904,26 @@ var image = (_options = {}) => {
|
|
|
4836
4904
|
filterFrom: from,
|
|
4837
4905
|
filterTo: to,
|
|
4838
4906
|
filter: () => false,
|
|
4839
|
-
add: buildDecorations(tr.state, from, to)
|
|
4907
|
+
add: buildDecorations(tr.state, from, to, options)
|
|
4840
4908
|
});
|
|
4841
4909
|
},
|
|
4842
|
-
provide: (field) =>
|
|
4843
|
-
})
|
|
4910
|
+
provide: (field) => EditorView22.decorations.from(field)
|
|
4911
|
+
}),
|
|
4912
|
+
// Block-replace decorations have to live in a state field, but viewport changes are only
|
|
4913
|
+
// observable from a view plugin. Bridge the two by dispatching a rebuild effect whenever
|
|
4914
|
+
// the viewport extends so newly-parsed image nodes get widgetized without requiring focus.
|
|
4915
|
+
ViewPlugin16.define((view) => ({
|
|
4916
|
+
update: (update2) => {
|
|
4917
|
+
if (update2.viewportChanged) {
|
|
4918
|
+
queueMicrotask(() => view.dispatch({
|
|
4919
|
+
effects: rebuildEffect.of(void 0)
|
|
4920
|
+
}));
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
}))
|
|
4844
4924
|
];
|
|
4845
4925
|
};
|
|
4846
|
-
var buildDecorations = (state, from, to) => {
|
|
4926
|
+
var buildDecorations = (state, from, to, options = {}) => {
|
|
4847
4927
|
const decorations2 = [];
|
|
4848
4928
|
const cursor = state.selection.main.head;
|
|
4849
4929
|
syntaxTree5(state).iterate({
|
|
@@ -4856,6 +4936,12 @@ var buildDecorations = (state, from, to) => {
|
|
|
4856
4936
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4857
4937
|
return;
|
|
4858
4938
|
}
|
|
4939
|
+
if (options.skip?.({
|
|
4940
|
+
name: "Image",
|
|
4941
|
+
url
|
|
4942
|
+
})) {
|
|
4943
|
+
return;
|
|
4944
|
+
}
|
|
4859
4945
|
preloadImage(url);
|
|
4860
4946
|
decorations2.push(Decoration9.replace({
|
|
4861
4947
|
block: true,
|
|
@@ -4889,20 +4975,34 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4889
4975
|
const img = document.createElement("img");
|
|
4890
4976
|
img.setAttribute("src", this._url);
|
|
4891
4977
|
img.setAttribute("class", "cm-image");
|
|
4892
|
-
|
|
4893
|
-
|
|
4978
|
+
const focused = view.state.field(focusField);
|
|
4979
|
+
if (focused) {
|
|
4980
|
+
img.onload = () => {
|
|
4981
|
+
img.classList.add("cm-loaded-image");
|
|
4982
|
+
collapseIfTrackingPixel(img);
|
|
4983
|
+
};
|
|
4894
4984
|
} else {
|
|
4895
4985
|
img.classList.add("cm-loaded-image");
|
|
4986
|
+
img.onload = () => collapseIfTrackingPixel(img);
|
|
4896
4987
|
}
|
|
4988
|
+
img.onerror = () => collapseLine(img);
|
|
4897
4989
|
return img;
|
|
4898
4990
|
}
|
|
4899
4991
|
};
|
|
4992
|
+
var collapseIfTrackingPixel = (img) => {
|
|
4993
|
+
if (img.naturalWidth <= 1 && img.naturalHeight <= 1) {
|
|
4994
|
+
collapseLine(img);
|
|
4995
|
+
}
|
|
4996
|
+
};
|
|
4997
|
+
var collapseLine = (img) => {
|
|
4998
|
+
img.style.display = "none";
|
|
4999
|
+
};
|
|
4900
5000
|
|
|
4901
5001
|
// src/extensions/markdown/styles.ts
|
|
4902
|
-
import { EditorView as
|
|
5002
|
+
import { EditorView as EditorView23 } from "@codemirror/view";
|
|
4903
5003
|
var bulletListIndentationWidth = 24;
|
|
4904
5004
|
var orderedListIndentationWidth = 36;
|
|
4905
|
-
var formattingStyles =
|
|
5005
|
+
var formattingStyles = EditorView23.theme({
|
|
4906
5006
|
/**
|
|
4907
5007
|
* Horizontal rule.
|
|
4908
5008
|
*/
|
|
@@ -5057,12 +5157,12 @@ var formattingStyles = EditorView22.theme({
|
|
|
5057
5157
|
// src/extensions/markdown/table.ts
|
|
5058
5158
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
5059
5159
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
5060
|
-
import { Decoration as Decoration10, EditorView as
|
|
5160
|
+
import { Decoration as Decoration10, EditorView as EditorView24, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
5061
5161
|
var table = (options = {}) => {
|
|
5062
5162
|
return StateField8.define({
|
|
5063
5163
|
create: (state) => update(state, options),
|
|
5064
5164
|
update: (_, tr) => update(tr.state, options),
|
|
5065
|
-
provide: (field) =>
|
|
5165
|
+
provide: (field) => EditorView24.decorations.from(field)
|
|
5066
5166
|
});
|
|
5067
5167
|
};
|
|
5068
5168
|
var update = (state, _options) => {
|
|
@@ -5308,15 +5408,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5308
5408
|
const { state } = view;
|
|
5309
5409
|
const headerLevels = [];
|
|
5310
5410
|
const getHeaderLevels = (node, level) => {
|
|
5311
|
-
invariant4(level > 0, void 0, {
|
|
5312
|
-
F: __dxlog_file12,
|
|
5313
|
-
L: 177,
|
|
5314
|
-
S: void 0,
|
|
5315
|
-
A: [
|
|
5316
|
-
"level > 0",
|
|
5317
|
-
""
|
|
5318
|
-
]
|
|
5319
|
-
});
|
|
5411
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5320
5412
|
if (level > headerLevels.length) {
|
|
5321
5413
|
const len = headerLevels.length;
|
|
5322
5414
|
headerLevels.length = level;
|
|
@@ -5347,15 +5439,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5347
5439
|
listLevels.pop();
|
|
5348
5440
|
};
|
|
5349
5441
|
const getCurrentListLevel = () => {
|
|
5350
|
-
invariant4(listLevels.length, void 0, {
|
|
5351
|
-
F: __dxlog_file12,
|
|
5352
|
-
L: 199,
|
|
5353
|
-
S: void 0,
|
|
5354
|
-
A: [
|
|
5355
|
-
"listLevels.length",
|
|
5356
|
-
""
|
|
5357
|
-
]
|
|
5358
|
-
});
|
|
5442
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5359
5443
|
return listLevels[listLevels.length - 1];
|
|
5360
5444
|
};
|
|
5361
5445
|
const enterNode = (node) => {
|
|
@@ -5669,10 +5753,10 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5669
5753
|
atomicDeco: atomicDeco.finish()
|
|
5670
5754
|
};
|
|
5671
5755
|
};
|
|
5672
|
-
var forceUpdate =
|
|
5756
|
+
var forceUpdate = StateEffect8.define();
|
|
5673
5757
|
var decorateMarkdown = (options = {}) => {
|
|
5674
5758
|
return [
|
|
5675
|
-
|
|
5759
|
+
ViewPlugin17.fromClass(class {
|
|
5676
5760
|
deco;
|
|
5677
5761
|
atomicDeco;
|
|
5678
5762
|
pendingUpdate;
|
|
@@ -5707,12 +5791,14 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5707
5791
|
}
|
|
5708
5792
|
}, {
|
|
5709
5793
|
provide: (plugin) => [
|
|
5710
|
-
Prec4.low(
|
|
5711
|
-
|
|
5712
|
-
|
|
5794
|
+
Prec4.low(EditorView25.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5795
|
+
EditorView25.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5796
|
+
EditorView25.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5713
5797
|
]
|
|
5714
5798
|
}),
|
|
5715
|
-
image(
|
|
5799
|
+
image({
|
|
5800
|
+
skip: options.skip ? (node) => !!options.skip?.(node) : void 0
|
|
5801
|
+
}),
|
|
5716
5802
|
table(),
|
|
5717
5803
|
adjustChanges(),
|
|
5718
5804
|
formattingStyles
|
|
@@ -5722,7 +5808,10 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5722
5808
|
// src/extensions/markdown/link.ts
|
|
5723
5809
|
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
5724
5810
|
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
|
5725
|
-
import {
|
|
5811
|
+
import { mx as mx6, surfaceShadow } from "@dxos/ui-theme";
|
|
5812
|
+
var tooltipClassName = mx6("inline-flex items-center p-1 max-w-64 text-sm bg-inverse-surface text-inverse-fg rounded-sm", surfaceShadow({
|
|
5813
|
+
elevation: "positioned"
|
|
5814
|
+
}));
|
|
5726
5815
|
var linkTooltip = (renderTooltip) => {
|
|
5727
5816
|
return hoverTooltip2((view, pos, side) => {
|
|
5728
5817
|
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
|
@@ -5744,7 +5833,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5744
5833
|
above: true,
|
|
5745
5834
|
create: () => {
|
|
5746
5835
|
const el = document.createElement("div");
|
|
5747
|
-
el.className =
|
|
5836
|
+
el.className = tooltipClassName;
|
|
5748
5837
|
renderTooltip(el, {
|
|
5749
5838
|
url: urlText
|
|
5750
5839
|
}, view);
|
|
@@ -5777,12 +5866,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5777
5866
|
(context) => {
|
|
5778
5867
|
log9.info("completion context", {
|
|
5779
5868
|
context
|
|
5780
|
-
}, {
|
|
5781
|
-
F: __dxlog_file13,
|
|
5782
|
-
L: 27,
|
|
5783
|
-
S: void 0,
|
|
5784
|
-
C: (f, a) => f(...a)
|
|
5785
|
-
});
|
|
5869
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5786
5870
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5787
5871
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5788
5872
|
return null;
|
|
@@ -5799,8 +5883,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5799
5883
|
};
|
|
5800
5884
|
|
|
5801
5885
|
// src/extensions/modal.ts
|
|
5802
|
-
import { StateEffect as
|
|
5803
|
-
var modalStateEffect =
|
|
5886
|
+
import { StateEffect as StateEffect9, StateField as StateField9 } from "@codemirror/state";
|
|
5887
|
+
var modalStateEffect = StateEffect9.define();
|
|
5804
5888
|
var modalStateField = StateField9.define({
|
|
5805
5889
|
create: () => false,
|
|
5806
5890
|
update: (value, tr) => {
|
|
@@ -6015,15 +6099,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6015
6099
|
break;
|
|
6016
6100
|
}
|
|
6017
6101
|
case "BulletList": {
|
|
6018
|
-
invariant5(current, void 0, {
|
|
6019
|
-
F: __dxlog_file14,
|
|
6020
|
-
L: 219,
|
|
6021
|
-
S: void 0,
|
|
6022
|
-
A: [
|
|
6023
|
-
"current",
|
|
6024
|
-
""
|
|
6025
|
-
]
|
|
6026
|
-
});
|
|
6102
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
6027
6103
|
parent = current;
|
|
6028
6104
|
if (current) {
|
|
6029
6105
|
current.lineRange.to = current.node.from;
|
|
@@ -6032,15 +6108,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6032
6108
|
break;
|
|
6033
6109
|
}
|
|
6034
6110
|
case "ListItem": {
|
|
6035
|
-
invariant5(parent, void 0, {
|
|
6036
|
-
F: __dxlog_file14,
|
|
6037
|
-
L: 228,
|
|
6038
|
-
S: void 0,
|
|
6039
|
-
A: [
|
|
6040
|
-
"parent",
|
|
6041
|
-
""
|
|
6042
|
-
]
|
|
6043
|
-
});
|
|
6111
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
6044
6112
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
6045
6113
|
const docRange = {
|
|
6046
6114
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -6074,42 +6142,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
6074
6142
|
break;
|
|
6075
6143
|
}
|
|
6076
6144
|
case "ListMark": {
|
|
6077
|
-
invariant5(current, void 0, {
|
|
6078
|
-
F: __dxlog_file14,
|
|
6079
|
-
L: 272,
|
|
6080
|
-
S: void 0,
|
|
6081
|
-
A: [
|
|
6082
|
-
"current",
|
|
6083
|
-
""
|
|
6084
|
-
]
|
|
6085
|
-
});
|
|
6145
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
6086
6146
|
current.type = "bullet";
|
|
6087
6147
|
current.contentRange.from = node.from + "- ".length;
|
|
6088
6148
|
break;
|
|
6089
6149
|
}
|
|
6090
6150
|
case "Task": {
|
|
6091
|
-
invariant5(current, void 0, {
|
|
6092
|
-
F: __dxlog_file14,
|
|
6093
|
-
L: 278,
|
|
6094
|
-
S: void 0,
|
|
6095
|
-
A: [
|
|
6096
|
-
"current",
|
|
6097
|
-
""
|
|
6098
|
-
]
|
|
6099
|
-
});
|
|
6151
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
6100
6152
|
current.type = "task";
|
|
6101
6153
|
break;
|
|
6102
6154
|
}
|
|
6103
6155
|
case "TaskMarker": {
|
|
6104
|
-
invariant5(current, void 0, {
|
|
6105
|
-
F: __dxlog_file14,
|
|
6106
|
-
L: 283,
|
|
6107
|
-
S: void 0,
|
|
6108
|
-
A: [
|
|
6109
|
-
"current",
|
|
6110
|
-
""
|
|
6111
|
-
]
|
|
6112
|
-
});
|
|
6156
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
6113
6157
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
6114
6158
|
break;
|
|
6115
6159
|
}
|
|
@@ -6117,29 +6161,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
6117
6161
|
},
|
|
6118
6162
|
leave: (node) => {
|
|
6119
6163
|
if (node.name === "BulletList") {
|
|
6120
|
-
invariant5(parent, void 0, {
|
|
6121
|
-
F: __dxlog_file14,
|
|
6122
|
-
L: 291,
|
|
6123
|
-
S: void 0,
|
|
6124
|
-
A: [
|
|
6125
|
-
"parent",
|
|
6126
|
-
""
|
|
6127
|
-
]
|
|
6128
|
-
});
|
|
6164
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
6129
6165
|
prevSiblings[level--] = void 0;
|
|
6130
6166
|
parent = parent.parent;
|
|
6131
6167
|
}
|
|
6132
6168
|
}
|
|
6133
6169
|
});
|
|
6134
|
-
invariant5(tree, void 0, {
|
|
6135
|
-
F: __dxlog_file14,
|
|
6136
|
-
L: 298,
|
|
6137
|
-
S: void 0,
|
|
6138
|
-
A: [
|
|
6139
|
-
"tree",
|
|
6140
|
-
""
|
|
6141
|
-
]
|
|
6142
|
-
});
|
|
6170
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
6143
6171
|
return tree;
|
|
6144
6172
|
};
|
|
6145
6173
|
return [
|
|
@@ -6424,17 +6452,17 @@ var commands = () => keymap11.of([
|
|
|
6424
6452
|
|
|
6425
6453
|
// src/extensions/outliner/outliner.ts
|
|
6426
6454
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6427
|
-
import { Decoration as Decoration12, EditorView as
|
|
6428
|
-
import { mx as
|
|
6455
|
+
import { Decoration as Decoration12, EditorView as EditorView27, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
6456
|
+
import { mx as mx7 } from "@dxos/ui-theme";
|
|
6429
6457
|
|
|
6430
6458
|
// src/extensions/outliner/editor.ts
|
|
6431
6459
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6432
|
-
import { ViewPlugin as
|
|
6460
|
+
import { ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6433
6461
|
import { log as log10 } from "@dxos/log";
|
|
6434
6462
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6435
6463
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6436
6464
|
var initialize = () => {
|
|
6437
|
-
return
|
|
6465
|
+
return ViewPlugin18.fromClass(class {
|
|
6438
6466
|
constructor(view) {
|
|
6439
6467
|
const first = view.state.doc.lineAt(0);
|
|
6440
6468
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6581,35 +6609,20 @@ var editor = () => [
|
|
|
6581
6609
|
text: insert.toString(),
|
|
6582
6610
|
length: insert.length
|
|
6583
6611
|
}
|
|
6584
|
-
}, {
|
|
6585
|
-
F: __dxlog_file15,
|
|
6586
|
-
L: 164,
|
|
6587
|
-
S: void 0,
|
|
6588
|
-
C: (f, a) => f(...a)
|
|
6589
|
-
});
|
|
6612
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6590
6613
|
}
|
|
6591
6614
|
});
|
|
6592
6615
|
if (changes.length > 0) {
|
|
6593
6616
|
log10("modified,", {
|
|
6594
6617
|
changes
|
|
6595
|
-
}, {
|
|
6596
|
-
F: __dxlog_file15,
|
|
6597
|
-
L: 175,
|
|
6598
|
-
S: void 0,
|
|
6599
|
-
C: (f, a) => f(...a)
|
|
6600
|
-
});
|
|
6618
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6601
6619
|
return [
|
|
6602
6620
|
{
|
|
6603
6621
|
changes
|
|
6604
6622
|
}
|
|
6605
6623
|
];
|
|
6606
6624
|
} else if (cancel) {
|
|
6607
|
-
log10("cancel", void 0, {
|
|
6608
|
-
F: __dxlog_file15,
|
|
6609
|
-
L: 178,
|
|
6610
|
-
S: void 0,
|
|
6611
|
-
C: (f, a) => f(...a)
|
|
6612
|
-
});
|
|
6625
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6613
6626
|
return [];
|
|
6614
6627
|
}
|
|
6615
6628
|
return tr;
|
|
@@ -6617,10 +6630,10 @@ var editor = () => [
|
|
|
6617
6630
|
];
|
|
6618
6631
|
|
|
6619
6632
|
// src/extensions/outliner/menu.ts
|
|
6620
|
-
import { EditorView as
|
|
6633
|
+
import { EditorView as EditorView26, ViewPlugin as ViewPlugin19 } from "@codemirror/view";
|
|
6621
6634
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6622
6635
|
var menu = (options = {}) => [
|
|
6623
|
-
|
|
6636
|
+
ViewPlugin19.fromClass(class {
|
|
6624
6637
|
view;
|
|
6625
6638
|
tag;
|
|
6626
6639
|
rafId;
|
|
@@ -6682,7 +6695,7 @@ var menu = (options = {}) => [
|
|
|
6682
6695
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6683
6696
|
}
|
|
6684
6697
|
}),
|
|
6685
|
-
|
|
6698
|
+
EditorView26.theme({
|
|
6686
6699
|
".cm-popover-trigger": {
|
|
6687
6700
|
position: "fixed",
|
|
6688
6701
|
padding: "0",
|
|
@@ -6718,12 +6731,12 @@ var outliner = (_options = {}) => [
|
|
|
6718
6731
|
listPaddingLeft: 8
|
|
6719
6732
|
}),
|
|
6720
6733
|
// Researve space for menu.
|
|
6721
|
-
|
|
6734
|
+
EditorView27.contentAttributes.of({
|
|
6722
6735
|
class: "w-full !mr-[3rem]"
|
|
6723
6736
|
})
|
|
6724
6737
|
];
|
|
6725
6738
|
var decorations = () => [
|
|
6726
|
-
|
|
6739
|
+
ViewPlugin20.fromClass(class {
|
|
6727
6740
|
decorations = Decoration12.none;
|
|
6728
6741
|
constructor(view) {
|
|
6729
6742
|
this.updateDecorations(view.state, view);
|
|
@@ -6748,7 +6761,7 @@ var decorations = () => [
|
|
|
6748
6761
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6749
6762
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6750
6763
|
decorations2.push(Decoration12.line({
|
|
6751
|
-
class:
|
|
6764
|
+
class: mx7("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"))
|
|
6752
6765
|
}).range(line.from, line.from));
|
|
6753
6766
|
}
|
|
6754
6767
|
}
|
|
@@ -6758,7 +6771,7 @@ var decorations = () => [
|
|
|
6758
6771
|
decorations: (v) => v.decorations
|
|
6759
6772
|
}),
|
|
6760
6773
|
// Theme.
|
|
6761
|
-
|
|
6774
|
+
EditorView27.theme(Object.assign({
|
|
6762
6775
|
".cm-list-item": {
|
|
6763
6776
|
borderLeftWidth: "1px",
|
|
6764
6777
|
borderRightWidth: "1px",
|
|
@@ -6783,7 +6796,7 @@ var decorations = () => [
|
|
|
6783
6796
|
marginBottom: "2px"
|
|
6784
6797
|
},
|
|
6785
6798
|
".cm-list-item-focused": {
|
|
6786
|
-
borderColor: "var(--color-
|
|
6799
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6787
6800
|
},
|
|
6788
6801
|
"&:focus-within .cm-list-item-selected": {
|
|
6789
6802
|
borderColor: "var(--color-separator)"
|
|
@@ -6793,10 +6806,11 @@ var decorations = () => [
|
|
|
6793
6806
|
|
|
6794
6807
|
// src/extensions/preview/preview.ts
|
|
6795
6808
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6796
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as
|
|
6797
|
-
import { Decoration as Decoration13, EditorView as
|
|
6798
|
-
import {
|
|
6799
|
-
|
|
6809
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect10, StateField as StateField11 } from "@codemirror/state";
|
|
6810
|
+
import { Decoration as Decoration13, EditorView as EditorView28, ViewPlugin as ViewPlugin21, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6811
|
+
import { Entity } from "@dxos/echo";
|
|
6812
|
+
import { EID, URI } from "@dxos/keys";
|
|
6813
|
+
var labelResolvedEffect = StateEffect10.define();
|
|
6800
6814
|
var preview = (options = {}) => {
|
|
6801
6815
|
const viewRef = {
|
|
6802
6816
|
current: void 0
|
|
@@ -6813,11 +6827,11 @@ var preview = (options = {}) => {
|
|
|
6813
6827
|
return decorations2.map(tr.changes);
|
|
6814
6828
|
},
|
|
6815
6829
|
provide: (field) => [
|
|
6816
|
-
|
|
6817
|
-
|
|
6830
|
+
EditorView28.decorations.from(field),
|
|
6831
|
+
EditorView28.atomicRanges.of((view) => view.state.field(field))
|
|
6818
6832
|
]
|
|
6819
6833
|
}),
|
|
6820
|
-
|
|
6834
|
+
ViewPlugin21.define((view) => {
|
|
6821
6835
|
viewRef.current = view;
|
|
6822
6836
|
return {
|
|
6823
6837
|
destroy() {
|
|
@@ -6828,11 +6842,12 @@ var preview = (options = {}) => {
|
|
|
6828
6842
|
];
|
|
6829
6843
|
};
|
|
6830
6844
|
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6831
|
-
const
|
|
6832
|
-
|
|
6845
|
+
const echoUri = EID.tryParse(dxnStr);
|
|
6846
|
+
const dxnRef = echoUri ?? (dxnStr.startsWith("dxn:") ? URI.make(dxnStr) : void 0);
|
|
6847
|
+
if (!dxnRef) {
|
|
6833
6848
|
return;
|
|
6834
6849
|
}
|
|
6835
|
-
const ref = db.makeRef(
|
|
6850
|
+
const ref = db.makeRef(dxnRef);
|
|
6836
6851
|
const target = ref.target;
|
|
6837
6852
|
if (target) {
|
|
6838
6853
|
return Entity.getLabel(target);
|
|
@@ -6850,7 +6865,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6850
6865
|
switch (node.name) {
|
|
6851
6866
|
//
|
|
6852
6867
|
// Inline widget.
|
|
6853
|
-
// [Label](
|
|
6868
|
+
// [Label](echo:/123)
|
|
6854
6869
|
//
|
|
6855
6870
|
case "Link": {
|
|
6856
6871
|
const link = getLinkRef(state, node.node);
|
|
@@ -6869,7 +6884,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6869
6884
|
}
|
|
6870
6885
|
//
|
|
6871
6886
|
// Block widget (transclusion).
|
|
6872
|
-
// 
|
|
6873
6888
|
//
|
|
6874
6889
|
case "Image": {
|
|
6875
6890
|
if (options.addBlockContainer && options.removeBlockContainer) {
|
|
@@ -6893,7 +6908,7 @@ var getLinkRef = (state, node) => {
|
|
|
6893
6908
|
const urlNode = node.getChild("URL");
|
|
6894
6909
|
if (mark && urlNode) {
|
|
6895
6910
|
const dxn = state.sliceDoc(urlNode.from, urlNode.to);
|
|
6896
|
-
if (dxn.startsWith("dxn:")) {
|
|
6911
|
+
if (dxn.startsWith("dxn:") || dxn.startsWith("echo:")) {
|
|
6897
6912
|
const label = state.sliceDoc(mark[0].to, mark[1].from);
|
|
6898
6913
|
return {
|
|
6899
6914
|
block: state.sliceDoc(mark[0].from, mark[0].from + 1) === "!",
|
|
@@ -6937,7 +6952,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6937
6952
|
}
|
|
6938
6953
|
toDOM(_view) {
|
|
6939
6954
|
const root = document.createElement("div");
|
|
6940
|
-
root.classList.add("cm-preview-block", "dx-density-
|
|
6955
|
+
root.classList.add("cm-preview-block", "dx-density-md");
|
|
6941
6956
|
this._options.addBlockContainer?.({
|
|
6942
6957
|
link: this._link,
|
|
6943
6958
|
el: root
|
|
@@ -6953,7 +6968,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6953
6968
|
};
|
|
6954
6969
|
|
|
6955
6970
|
// src/extensions/replacer.ts
|
|
6956
|
-
import { EditorView as
|
|
6971
|
+
import { EditorView as EditorView29 } from "@codemirror/view";
|
|
6957
6972
|
var defaultReplacements = [
|
|
6958
6973
|
{
|
|
6959
6974
|
input: "--",
|
|
@@ -7016,7 +7031,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
7016
7031
|
const sortedReplacements = [
|
|
7017
7032
|
...replacements
|
|
7018
7033
|
].sort((a, b) => b.input.length - a.input.length);
|
|
7019
|
-
return
|
|
7034
|
+
return EditorView29.inputHandler.of((view, from, to, insert) => {
|
|
7020
7035
|
if (insert.length !== 1) {
|
|
7021
7036
|
return false;
|
|
7022
7037
|
}
|
|
@@ -7050,12 +7065,80 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
7050
7065
|
});
|
|
7051
7066
|
};
|
|
7052
7067
|
|
|
7068
|
+
// src/extensions/spacing.ts
|
|
7069
|
+
import { EditorView as EditorView30 } from "@codemirror/view";
|
|
7070
|
+
function lineSpacing(verticalPadding = 2) {
|
|
7071
|
+
return EditorView30.theme({
|
|
7072
|
+
".cm-line": {
|
|
7073
|
+
paddingTop: `${verticalPadding}px`,
|
|
7074
|
+
paddingBottom: `${verticalPadding}px`
|
|
7075
|
+
}
|
|
7076
|
+
});
|
|
7077
|
+
}
|
|
7078
|
+
|
|
7079
|
+
// src/extensions/snippets.ts
|
|
7080
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
7081
|
+
var defaultItems = [
|
|
7082
|
+
"hello world!",
|
|
7083
|
+
"this is a test.",
|
|
7084
|
+
"this is [DXOS](https://dxos.org)"
|
|
7085
|
+
];
|
|
7086
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7087
|
+
let timer;
|
|
7088
|
+
let index = 0;
|
|
7089
|
+
return [
|
|
7090
|
+
keymap12.of([
|
|
7091
|
+
{
|
|
7092
|
+
// Reset.
|
|
7093
|
+
key: "alt-meta-'",
|
|
7094
|
+
run: () => {
|
|
7095
|
+
clearTimeout(timer);
|
|
7096
|
+
index = 0;
|
|
7097
|
+
return true;
|
|
7098
|
+
}
|
|
7099
|
+
},
|
|
7100
|
+
{
|
|
7101
|
+
// Next snippet.
|
|
7102
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
7103
|
+
key: "Shift-Meta-'",
|
|
7104
|
+
run: (view) => {
|
|
7105
|
+
clearTimeout(timer);
|
|
7106
|
+
const text = items[index++];
|
|
7107
|
+
if (index === items?.length) {
|
|
7108
|
+
index = 0;
|
|
7109
|
+
}
|
|
7110
|
+
let offset = 0;
|
|
7111
|
+
const insert = (delayMs = 0) => {
|
|
7112
|
+
timer = setTimeout(() => {
|
|
7113
|
+
const pos = view.state.selection.main.head;
|
|
7114
|
+
view.dispatch({
|
|
7115
|
+
changes: {
|
|
7116
|
+
from: pos,
|
|
7117
|
+
insert: text[offset++]
|
|
7118
|
+
},
|
|
7119
|
+
selection: {
|
|
7120
|
+
anchor: pos + 1
|
|
7121
|
+
}
|
|
7122
|
+
});
|
|
7123
|
+
if (offset < text.length) {
|
|
7124
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
7125
|
+
}
|
|
7126
|
+
}, delayMs);
|
|
7127
|
+
};
|
|
7128
|
+
insert();
|
|
7129
|
+
return true;
|
|
7130
|
+
}
|
|
7131
|
+
}
|
|
7132
|
+
])
|
|
7133
|
+
];
|
|
7134
|
+
};
|
|
7135
|
+
|
|
7053
7136
|
// src/extensions/submit.ts
|
|
7054
7137
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
7055
|
-
import { keymap as
|
|
7138
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
7056
7139
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
7057
7140
|
return [
|
|
7058
|
-
Prec6.highest(
|
|
7141
|
+
Prec6.highest(keymap13.of([
|
|
7059
7142
|
{
|
|
7060
7143
|
key: "Enter",
|
|
7061
7144
|
preventDefault: true,
|
|
@@ -7205,8 +7288,8 @@ var mixedParser = (registry) => {
|
|
|
7205
7288
|
};
|
|
7206
7289
|
|
|
7207
7290
|
// src/extensions/tags/fader.ts
|
|
7208
|
-
import { StateEffect as
|
|
7209
|
-
import { Decoration as Decoration14, EditorView as
|
|
7291
|
+
import { StateEffect as StateEffect11, StateField as StateField12 } from "@codemirror/state";
|
|
7292
|
+
import { Decoration as Decoration14, EditorView as EditorView31, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7210
7293
|
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7211
7294
|
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7212
7295
|
var CLEANUP_INTERVAL = 1e3;
|
|
@@ -7219,7 +7302,7 @@ var fader = (options = {}) => {
|
|
|
7219
7302
|
lastCount = expiries.length;
|
|
7220
7303
|
}
|
|
7221
7304
|
};
|
|
7222
|
-
const dequeue =
|
|
7305
|
+
const dequeue = StateEffect11.define();
|
|
7223
7306
|
const fadeField = StateField12.define({
|
|
7224
7307
|
create: () => ({
|
|
7225
7308
|
decorations: Decoration14.none,
|
|
@@ -7330,9 +7413,9 @@ var fader = (options = {}) => {
|
|
|
7330
7413
|
batchStart
|
|
7331
7414
|
};
|
|
7332
7415
|
},
|
|
7333
|
-
provide: (f) =>
|
|
7416
|
+
provide: (f) => EditorView31.decorations.from(f, (value) => value.decorations)
|
|
7334
7417
|
});
|
|
7335
|
-
const cleanup =
|
|
7418
|
+
const cleanup = ViewPlugin22.fromClass(class {
|
|
7336
7419
|
view;
|
|
7337
7420
|
#timer;
|
|
7338
7421
|
constructor(view) {
|
|
@@ -7367,7 +7450,7 @@ var fader = (options = {}) => {
|
|
|
7367
7450
|
return [
|
|
7368
7451
|
fadeField,
|
|
7369
7452
|
cleanup,
|
|
7370
|
-
|
|
7453
|
+
EditorView31.theme({
|
|
7371
7454
|
".cm-fader": {
|
|
7372
7455
|
animation: "fader 1s ease-out forwards"
|
|
7373
7456
|
},
|
|
@@ -7381,36 +7464,46 @@ var fader = (options = {}) => {
|
|
|
7381
7464
|
];
|
|
7382
7465
|
};
|
|
7383
7466
|
|
|
7384
|
-
// src/extensions/tags/
|
|
7385
|
-
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as
|
|
7386
|
-
import { Decoration as Decoration15, EditorView as
|
|
7467
|
+
// src/extensions/tags/typewriter.ts
|
|
7468
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect12, StateField as StateField13 } from "@codemirror/state";
|
|
7469
|
+
import { Decoration as Decoration15, EditorView as EditorView32, ViewPlugin as ViewPlugin23, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7387
7470
|
import { Domino as Domino3 } from "@dxos/ui";
|
|
7388
|
-
var
|
|
7389
|
-
var
|
|
7471
|
+
var typewriterBypass = Annotation3.define();
|
|
7472
|
+
var typewriterDrainingEffect = StateEffect12.define();
|
|
7390
7473
|
var CURSOR_LINGER = 3e3;
|
|
7391
|
-
var
|
|
7392
|
-
|
|
7393
|
-
|
|
7474
|
+
var FRAME_BUDGET_MS = 4;
|
|
7475
|
+
var CHARS_PER_FRAME = 5;
|
|
7476
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7477
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7478
|
+
var typewriter = (options = {}) => {
|
|
7394
7479
|
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7395
|
-
const
|
|
7396
|
-
const
|
|
7480
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7481
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7482
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7483
|
+
const suppressAppend = StateEffect12.define();
|
|
7484
|
+
const insertChunk = StateEffect12.define();
|
|
7397
7485
|
const bufferField = StateField13.define({
|
|
7398
7486
|
create: () => ({
|
|
7399
7487
|
text: "",
|
|
7488
|
+
head: 0,
|
|
7400
7489
|
insertAt: 0
|
|
7401
7490
|
}),
|
|
7402
7491
|
update: (value, tr) => {
|
|
7403
|
-
let { text, insertAt } = value;
|
|
7492
|
+
let { text, head, insertAt } = value;
|
|
7404
7493
|
for (const effect of tr.effects) {
|
|
7405
7494
|
if (effect.is(suppressAppend)) {
|
|
7406
|
-
text
|
|
7407
|
-
if (text.length === effect.value.text.length) {
|
|
7495
|
+
if (text.length === head) {
|
|
7408
7496
|
insertAt = effect.value.from;
|
|
7409
7497
|
}
|
|
7498
|
+
text += effect.value.text;
|
|
7410
7499
|
}
|
|
7411
7500
|
if (effect.is(insertChunk)) {
|
|
7412
|
-
|
|
7501
|
+
head += effect.value.text.length;
|
|
7413
7502
|
insertAt = effect.value.from + effect.value.text.length;
|
|
7503
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7504
|
+
text = text.slice(head);
|
|
7505
|
+
head = 0;
|
|
7506
|
+
}
|
|
7414
7507
|
}
|
|
7415
7508
|
}
|
|
7416
7509
|
if (tr.docChanged) {
|
|
@@ -7425,6 +7518,7 @@ var wire = (options = {}) => {
|
|
|
7425
7518
|
if (isReset) {
|
|
7426
7519
|
return {
|
|
7427
7520
|
text: "",
|
|
7521
|
+
head: 0,
|
|
7428
7522
|
insertAt: 0
|
|
7429
7523
|
};
|
|
7430
7524
|
}
|
|
@@ -7434,6 +7528,7 @@ var wire = (options = {}) => {
|
|
|
7434
7528
|
}
|
|
7435
7529
|
return {
|
|
7436
7530
|
text,
|
|
7531
|
+
head,
|
|
7437
7532
|
insertAt
|
|
7438
7533
|
};
|
|
7439
7534
|
}
|
|
@@ -7442,7 +7537,7 @@ var wire = (options = {}) => {
|
|
|
7442
7537
|
if (!tr.docChanged) {
|
|
7443
7538
|
return tr;
|
|
7444
7539
|
}
|
|
7445
|
-
if (tr.annotation(
|
|
7540
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7446
7541
|
return tr;
|
|
7447
7542
|
}
|
|
7448
7543
|
let appendedText = "";
|
|
@@ -7469,42 +7564,84 @@ var wire = (options = {}) => {
|
|
|
7469
7564
|
})
|
|
7470
7565
|
};
|
|
7471
7566
|
});
|
|
7472
|
-
const drainPlugin =
|
|
7567
|
+
const drainPlugin = ViewPlugin23.fromClass(class {
|
|
7473
7568
|
view;
|
|
7474
|
-
|
|
7475
|
-
|
|
7569
|
+
_raf;
|
|
7570
|
+
_activeStreamTag = null;
|
|
7476
7571
|
constructor(view) {
|
|
7477
7572
|
this.view = view;
|
|
7478
|
-
this.#start();
|
|
7479
7573
|
}
|
|
7480
7574
|
update(update2) {
|
|
7481
|
-
const
|
|
7482
|
-
|
|
7483
|
-
|
|
7575
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7576
|
+
const pending = text.length - head;
|
|
7577
|
+
if (pending === 0) {
|
|
7578
|
+
this._activeStreamTag = null;
|
|
7484
7579
|
}
|
|
7485
|
-
if (
|
|
7486
|
-
this
|
|
7580
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7581
|
+
this._start();
|
|
7487
7582
|
}
|
|
7488
7583
|
}
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7584
|
+
_start() {
|
|
7585
|
+
queueMicrotask(() => {
|
|
7586
|
+
this.view.dispatch({
|
|
7587
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7588
|
+
annotations: typewriterBypass.of(true)
|
|
7589
|
+
});
|
|
7590
|
+
});
|
|
7591
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7592
|
+
}
|
|
7593
|
+
_tick = () => {
|
|
7594
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7595
|
+
const pending = text.length - head;
|
|
7596
|
+
if (pending === 0) {
|
|
7597
|
+
this.view.dispatch({
|
|
7598
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7599
|
+
annotations: typewriterBypass.of(true)
|
|
7600
|
+
});
|
|
7601
|
+
this._raf = void 0;
|
|
7602
|
+
return;
|
|
7603
|
+
}
|
|
7604
|
+
if (pending > flushThreshold) {
|
|
7605
|
+
const chunk = text.slice(head);
|
|
7606
|
+
this._activeStreamTag = null;
|
|
7607
|
+
this.view.dispatch({
|
|
7608
|
+
changes: {
|
|
7609
|
+
from: insertAt,
|
|
7610
|
+
insert: chunk
|
|
7611
|
+
},
|
|
7612
|
+
effects: insertChunk.of({
|
|
7613
|
+
from: insertAt,
|
|
7614
|
+
text: chunk
|
|
7615
|
+
})
|
|
7616
|
+
});
|
|
7617
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7618
|
+
return;
|
|
7619
|
+
}
|
|
7620
|
+
const startTime = performance.now();
|
|
7621
|
+
let pos = head;
|
|
7622
|
+
let activeTag = this._activeStreamTag;
|
|
7623
|
+
let charsEmitted = 0;
|
|
7624
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7625
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7498
7626
|
if (result.count === 0) {
|
|
7499
|
-
|
|
7627
|
+
break;
|
|
7628
|
+
}
|
|
7629
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7630
|
+
break;
|
|
7500
7631
|
}
|
|
7501
7632
|
if (result.enterTag) {
|
|
7502
|
-
|
|
7633
|
+
activeTag = result.enterTag;
|
|
7503
7634
|
}
|
|
7504
7635
|
if (result.exitTag) {
|
|
7505
|
-
|
|
7636
|
+
activeTag = null;
|
|
7506
7637
|
}
|
|
7507
|
-
|
|
7638
|
+
pos += result.count;
|
|
7639
|
+
charsEmitted += result.count;
|
|
7640
|
+
}
|
|
7641
|
+
const totalCount = pos - head;
|
|
7642
|
+
if (totalCount > 0) {
|
|
7643
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7644
|
+
this._activeStreamTag = activeTag;
|
|
7508
7645
|
this.view.dispatch({
|
|
7509
7646
|
changes: {
|
|
7510
7647
|
from: insertAt,
|
|
@@ -7515,21 +7652,24 @@ var wire = (options = {}) => {
|
|
|
7515
7652
|
text: chunk
|
|
7516
7653
|
})
|
|
7517
7654
|
});
|
|
7518
|
-
}
|
|
7519
|
-
|
|
7655
|
+
}
|
|
7656
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7657
|
+
};
|
|
7520
7658
|
destroy() {
|
|
7521
|
-
|
|
7659
|
+
if (this._raf !== void 0) {
|
|
7660
|
+
cancelAnimationFrame(this._raf);
|
|
7661
|
+
}
|
|
7522
7662
|
}
|
|
7523
7663
|
});
|
|
7524
7664
|
return [
|
|
7525
7665
|
bufferField,
|
|
7526
7666
|
filter,
|
|
7527
7667
|
drainPlugin,
|
|
7528
|
-
options.cursor &&
|
|
7668
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7529
7669
|
].filter(Boolean);
|
|
7530
7670
|
};
|
|
7531
|
-
var
|
|
7532
|
-
const hideCursor =
|
|
7671
|
+
var typewriterCursor = (bufferField) => {
|
|
7672
|
+
const hideCursor = StateEffect12.define();
|
|
7533
7673
|
const visibilityField = StateField13.define({
|
|
7534
7674
|
create: () => ({
|
|
7535
7675
|
visible: false,
|
|
@@ -7537,8 +7677,9 @@ var wireCursor = (bufferField) => {
|
|
|
7537
7677
|
lastNonWsAt: 0
|
|
7538
7678
|
}),
|
|
7539
7679
|
update: (value, tr) => {
|
|
7540
|
-
const { text, insertAt } = tr.state.field(bufferField);
|
|
7541
|
-
|
|
7680
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7681
|
+
const pending = text.length - head;
|
|
7682
|
+
if (pending > 0) {
|
|
7542
7683
|
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7543
7684
|
if (tr.docChanged) {
|
|
7544
7685
|
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
@@ -7572,8 +7713,8 @@ var wireCursor = (bufferField) => {
|
|
|
7572
7713
|
if (!visible) {
|
|
7573
7714
|
return Decoration15.none;
|
|
7574
7715
|
}
|
|
7575
|
-
const { text } = tr.state.field(bufferField);
|
|
7576
|
-
const cursorAt = text.length >
|
|
7716
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7717
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7577
7718
|
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7578
7719
|
return Decoration15.set([
|
|
7579
7720
|
Decoration15.widget({
|
|
@@ -7582,31 +7723,32 @@ var wireCursor = (bufferField) => {
|
|
|
7582
7723
|
}).range(pos)
|
|
7583
7724
|
]);
|
|
7584
7725
|
},
|
|
7585
|
-
provide: (field) =>
|
|
7726
|
+
provide: (field) => EditorView32.decorations.from(field)
|
|
7586
7727
|
});
|
|
7587
|
-
const timerPlugin =
|
|
7728
|
+
const timerPlugin = ViewPlugin23.fromClass(class {
|
|
7588
7729
|
view;
|
|
7589
|
-
|
|
7730
|
+
_timer;
|
|
7590
7731
|
constructor(view) {
|
|
7591
7732
|
this.view = view;
|
|
7592
7733
|
}
|
|
7593
7734
|
update(update2) {
|
|
7594
|
-
const { text } = update2.state.field(bufferField);
|
|
7735
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7595
7736
|
const { visible } = update2.state.field(visibilityField);
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
this
|
|
7599
|
-
|
|
7600
|
-
|
|
7737
|
+
const pending = text.length - head;
|
|
7738
|
+
if (pending > 0) {
|
|
7739
|
+
clearTimeout(this._timer);
|
|
7740
|
+
this._timer = void 0;
|
|
7741
|
+
} else if (visible && this._timer === void 0) {
|
|
7742
|
+
this._timer = setTimeout(() => {
|
|
7601
7743
|
this.view.dispatch({
|
|
7602
7744
|
effects: hideCursor.of(null)
|
|
7603
7745
|
});
|
|
7604
|
-
this
|
|
7746
|
+
this._timer = void 0;
|
|
7605
7747
|
}, CURSOR_LINGER);
|
|
7606
7748
|
}
|
|
7607
7749
|
}
|
|
7608
7750
|
destroy() {
|
|
7609
|
-
clearTimeout(this
|
|
7751
|
+
clearTimeout(this._timer);
|
|
7610
7752
|
}
|
|
7611
7753
|
});
|
|
7612
7754
|
return [
|
|
@@ -7615,7 +7757,12 @@ var wireCursor = (bufferField) => {
|
|
|
7615
7757
|
timerPlugin
|
|
7616
7758
|
];
|
|
7617
7759
|
};
|
|
7618
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7760
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7761
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7762
|
+
// the blink animation isn't restarted on every transaction.
|
|
7763
|
+
eq(other) {
|
|
7764
|
+
return other instanceof _CursorWidget;
|
|
7765
|
+
}
|
|
7619
7766
|
toDOM() {
|
|
7620
7767
|
const inner = Domino3.of("span").text("\u2217").style({
|
|
7621
7768
|
animation: "blink 1s infinite",
|
|
@@ -7627,35 +7774,37 @@ var CursorWidget = class extends WidgetType9 {
|
|
|
7627
7774
|
}
|
|
7628
7775
|
};
|
|
7629
7776
|
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7777
|
+
var TAG_NAME_PROBE = 64;
|
|
7630
7778
|
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7631
|
-
var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
7632
|
-
if (buffer.length
|
|
7779
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7780
|
+
if (start >= buffer.length) {
|
|
7633
7781
|
return {
|
|
7634
7782
|
count: 0
|
|
7635
7783
|
};
|
|
7636
7784
|
}
|
|
7637
7785
|
if (activeStreamTag) {
|
|
7638
7786
|
const closeTag = `</${activeStreamTag}>`;
|
|
7639
|
-
if (buffer.startsWith(closeTag)) {
|
|
7787
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7640
7788
|
return {
|
|
7641
7789
|
count: closeTag.length,
|
|
7642
7790
|
exitTag: true
|
|
7643
7791
|
};
|
|
7644
7792
|
}
|
|
7645
|
-
if (buffer[
|
|
7793
|
+
if (buffer[start] === "<") {
|
|
7646
7794
|
return {
|
|
7647
|
-
count: xmlElementLength(buffer)
|
|
7795
|
+
count: xmlElementLength(buffer, start)
|
|
7648
7796
|
};
|
|
7649
7797
|
}
|
|
7650
7798
|
return {
|
|
7651
7799
|
count: 1
|
|
7652
7800
|
};
|
|
7653
7801
|
}
|
|
7654
|
-
const ch = buffer[
|
|
7802
|
+
const ch = buffer[start];
|
|
7655
7803
|
if (ch === "<") {
|
|
7656
|
-
const
|
|
7804
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7805
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7657
7806
|
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7658
|
-
const close = buffer.indexOf(">");
|
|
7807
|
+
const close = buffer.indexOf(">", start);
|
|
7659
7808
|
if (close === -1) {
|
|
7660
7809
|
return {
|
|
7661
7810
|
count: 0
|
|
@@ -7663,62 +7812,64 @@ var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
|
7663
7812
|
}
|
|
7664
7813
|
if (buffer[close - 1] === "/") {
|
|
7665
7814
|
return {
|
|
7666
|
-
count: close + 1
|
|
7815
|
+
count: close + 1 - start
|
|
7667
7816
|
};
|
|
7668
7817
|
}
|
|
7669
7818
|
return {
|
|
7670
|
-
count: close + 1,
|
|
7819
|
+
count: close + 1 - start,
|
|
7671
7820
|
enterTag: nameMatch[1]
|
|
7672
7821
|
};
|
|
7673
7822
|
}
|
|
7674
7823
|
return {
|
|
7675
|
-
count: xmlElementLength(buffer)
|
|
7824
|
+
count: xmlElementLength(buffer, start)
|
|
7676
7825
|
};
|
|
7677
7826
|
}
|
|
7678
|
-
if (ch === "!" && buffer.length > 1 && buffer[1] === "[") {
|
|
7827
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7679
7828
|
return {
|
|
7680
|
-
count: linkLength(buffer, 1)
|
|
7829
|
+
count: linkLength(buffer, start, start + 1)
|
|
7681
7830
|
};
|
|
7682
7831
|
}
|
|
7683
7832
|
if (ch === "[") {
|
|
7684
7833
|
return {
|
|
7685
|
-
count: linkLength(buffer,
|
|
7834
|
+
count: linkLength(buffer, start, start)
|
|
7686
7835
|
};
|
|
7687
7836
|
}
|
|
7688
7837
|
return {
|
|
7689
7838
|
count: 1
|
|
7690
7839
|
};
|
|
7691
7840
|
};
|
|
7692
|
-
var xmlElementLength = (buffer) => {
|
|
7693
|
-
const close = buffer.indexOf(">");
|
|
7841
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7842
|
+
const close = buffer.indexOf(">", start);
|
|
7694
7843
|
if (close === -1) {
|
|
7695
7844
|
return 0;
|
|
7696
7845
|
}
|
|
7697
7846
|
if (buffer[close - 1] === "/") {
|
|
7698
|
-
return close + 1;
|
|
7847
|
+
return close + 1 - start;
|
|
7699
7848
|
}
|
|
7700
|
-
if (buffer[1] === "/") {
|
|
7701
|
-
return close + 1;
|
|
7849
|
+
if (buffer[start + 1] === "/") {
|
|
7850
|
+
return close + 1 - start;
|
|
7702
7851
|
}
|
|
7703
|
-
const
|
|
7852
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7853
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7704
7854
|
if (!nameMatch) {
|
|
7705
7855
|
return 1;
|
|
7706
7856
|
}
|
|
7707
7857
|
const tagName = nameMatch[1];
|
|
7708
7858
|
let depth = 0;
|
|
7709
7859
|
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7860
|
+
tagPattern.lastIndex = start;
|
|
7710
7861
|
let match;
|
|
7711
7862
|
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7712
7863
|
const isSelfClosing = match[0].endsWith("/>");
|
|
7713
7864
|
const isClosing = match[1] === "/";
|
|
7714
7865
|
if (isSelfClosing) {
|
|
7715
7866
|
if (depth === 0) {
|
|
7716
|
-
return match.index + match[0].length;
|
|
7867
|
+
return match.index + match[0].length - start;
|
|
7717
7868
|
}
|
|
7718
7869
|
} else if (isClosing) {
|
|
7719
7870
|
depth--;
|
|
7720
7871
|
if (depth === 0) {
|
|
7721
|
-
return match.index + match[0].length;
|
|
7872
|
+
return match.index + match[0].length - start;
|
|
7722
7873
|
}
|
|
7723
7874
|
} else {
|
|
7724
7875
|
depth++;
|
|
@@ -7726,8 +7877,8 @@ var xmlElementLength = (buffer) => {
|
|
|
7726
7877
|
}
|
|
7727
7878
|
return 0;
|
|
7728
7879
|
};
|
|
7729
|
-
var linkLength = (buffer,
|
|
7730
|
-
const bracketClose = buffer.indexOf("]",
|
|
7880
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7881
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7731
7882
|
if (bracketClose === -1) {
|
|
7732
7883
|
return 0;
|
|
7733
7884
|
}
|
|
@@ -7741,13 +7892,179 @@ var linkLength = (buffer, offset) => {
|
|
|
7741
7892
|
if (parenClose === -1) {
|
|
7742
7893
|
return 0;
|
|
7743
7894
|
}
|
|
7744
|
-
return parenClose + 1;
|
|
7895
|
+
return parenClose + 1 - start;
|
|
7896
|
+
};
|
|
7897
|
+
|
|
7898
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7899
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7900
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin24 } from "@codemirror/view";
|
|
7901
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7902
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7903
|
+
class: lineClass
|
|
7904
|
+
}) : void 0;
|
|
7905
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7906
|
+
class: contentClass
|
|
7907
|
+
}) : void 0;
|
|
7908
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7909
|
+
const buildDecorations5 = (view) => {
|
|
7910
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7911
|
+
if (!text.includes(`<${tag}`)) {
|
|
7912
|
+
return Decoration16.none;
|
|
7913
|
+
}
|
|
7914
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7915
|
+
const ranges = [];
|
|
7916
|
+
tree.iterate({
|
|
7917
|
+
enter: (node) => {
|
|
7918
|
+
if (node.type.name !== "Element") {
|
|
7919
|
+
return;
|
|
7920
|
+
}
|
|
7921
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7922
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7923
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7924
|
+
if (!openTag || !tagNameNode) {
|
|
7925
|
+
return;
|
|
7926
|
+
}
|
|
7927
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7928
|
+
return;
|
|
7929
|
+
}
|
|
7930
|
+
const contentFrom = openTag.to;
|
|
7931
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7932
|
+
if (hideDecoration) {
|
|
7933
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7934
|
+
if (closeTag) {
|
|
7935
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7936
|
+
}
|
|
7937
|
+
}
|
|
7938
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7939
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7940
|
+
}
|
|
7941
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7942
|
+
let pos = contentFrom;
|
|
7943
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7944
|
+
const line = view.state.doc.lineAt(pos);
|
|
7945
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7946
|
+
if (line.to >= contentTo) {
|
|
7947
|
+
break;
|
|
7948
|
+
}
|
|
7949
|
+
pos = line.to + 1;
|
|
7950
|
+
}
|
|
7951
|
+
}
|
|
7952
|
+
}
|
|
7953
|
+
});
|
|
7954
|
+
return Decoration16.set(ranges, true);
|
|
7955
|
+
};
|
|
7956
|
+
return ViewPlugin24.fromClass(class {
|
|
7957
|
+
decorations;
|
|
7958
|
+
constructor(view) {
|
|
7959
|
+
this.decorations = buildDecorations5(view);
|
|
7960
|
+
}
|
|
7961
|
+
update(update2) {
|
|
7962
|
+
if (update2.docChanged) {
|
|
7963
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
}, {
|
|
7967
|
+
decorations: (instance) => instance.decorations
|
|
7968
|
+
});
|
|
7969
|
+
};
|
|
7970
|
+
|
|
7971
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7972
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7973
|
+
import { Decoration as Decoration17, EditorView as EditorView33, ViewPlugin as ViewPlugin25 } from "@codemirror/view";
|
|
7974
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7975
|
+
"OpenTag",
|
|
7976
|
+
"CloseTag",
|
|
7977
|
+
"SelfClosingTag",
|
|
7978
|
+
"MismatchedCloseTag"
|
|
7979
|
+
]);
|
|
7980
|
+
var xmlElementMark = Decoration17.mark({
|
|
7981
|
+
class: "cm-xml-element"
|
|
7982
|
+
});
|
|
7983
|
+
var xmlTagMark = Decoration17.mark({
|
|
7984
|
+
class: "cm-xml-tag"
|
|
7985
|
+
});
|
|
7986
|
+
var xmlContentMark = Decoration17.mark({
|
|
7987
|
+
class: "cm-xml-content"
|
|
7988
|
+
});
|
|
7989
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7990
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7991
|
+
const buildDecorations5 = (view) => {
|
|
7992
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7993
|
+
if (!text.includes("<")) {
|
|
7994
|
+
return Decoration17.none;
|
|
7995
|
+
}
|
|
7996
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7997
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7998
|
+
const ranges = [];
|
|
7999
|
+
tree.iterate({
|
|
8000
|
+
enter: (node) => {
|
|
8001
|
+
const name = node.type.name;
|
|
8002
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
8003
|
+
if (skipSet) {
|
|
8004
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
8005
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
8006
|
+
return false;
|
|
8007
|
+
}
|
|
8008
|
+
}
|
|
8009
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
8010
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
8011
|
+
return;
|
|
8012
|
+
}
|
|
8013
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
8014
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
8015
|
+
return;
|
|
8016
|
+
}
|
|
8017
|
+
if (name === "Element" && node.from < node.to) {
|
|
8018
|
+
const openTag = node.node.getChild("OpenTag");
|
|
8019
|
+
if (openTag && skipSet) {
|
|
8020
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
8021
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
8022
|
+
return false;
|
|
8023
|
+
}
|
|
8024
|
+
}
|
|
8025
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
8026
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
8027
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
8028
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
8029
|
+
}
|
|
8030
|
+
}
|
|
8031
|
+
}
|
|
8032
|
+
});
|
|
8033
|
+
return Decoration17.set(ranges, true);
|
|
8034
|
+
};
|
|
8035
|
+
return [
|
|
8036
|
+
ViewPlugin25.fromClass(class {
|
|
8037
|
+
decorations;
|
|
8038
|
+
constructor(view) {
|
|
8039
|
+
this.decorations = buildDecorations5(view);
|
|
8040
|
+
}
|
|
8041
|
+
update(update2) {
|
|
8042
|
+
if (update2.docChanged) {
|
|
8043
|
+
this.decorations = buildDecorations5(update2.view);
|
|
8044
|
+
}
|
|
8045
|
+
}
|
|
8046
|
+
}, {
|
|
8047
|
+
decorations: (instance) => instance.decorations
|
|
8048
|
+
}),
|
|
8049
|
+
EditorView33.baseTheme({
|
|
8050
|
+
".cm-xml-element": {
|
|
8051
|
+
backgroundColor: "var(--color-current-surface)",
|
|
8052
|
+
borderRadius: "0.25rem",
|
|
8053
|
+
padding: "0.25rem"
|
|
8054
|
+
},
|
|
8055
|
+
".cm-xml-tag": {
|
|
8056
|
+
color: "var(--color-blue-500)",
|
|
8057
|
+
fontFamily: "var(--font-mono)"
|
|
8058
|
+
},
|
|
8059
|
+
".cm-xml-content": {}
|
|
8060
|
+
})
|
|
8061
|
+
];
|
|
7745
8062
|
};
|
|
7746
8063
|
|
|
7747
8064
|
// src/extensions/tags/xml-tags.ts
|
|
7748
8065
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7749
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7750
|
-
import { Decoration as
|
|
8066
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect13, StateField as StateField14 } from "@codemirror/state";
|
|
8067
|
+
import { Decoration as Decoration18, EditorView as EditorView34, ViewPlugin as ViewPlugin26, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7751
8068
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7752
8069
|
import { log as log11 } from "@dxos/log";
|
|
7753
8070
|
import { Domino as Domino4 } from "@dxos/ui";
|
|
@@ -7756,15 +8073,7 @@ import { Domino as Domino4 } from "@dxos/ui";
|
|
|
7756
8073
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7757
8074
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7758
8075
|
var nodeToJson = (state, node) => {
|
|
7759
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7760
|
-
F: __dxlog_file16,
|
|
7761
|
-
L: 18,
|
|
7762
|
-
S: void 0,
|
|
7763
|
-
A: [
|
|
7764
|
-
"node.type.name === 'Element'",
|
|
7765
|
-
"'Node is not an Element'"
|
|
7766
|
-
]
|
|
7767
|
-
});
|
|
8076
|
+
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'"] });
|
|
7768
8077
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7769
8078
|
if (openTag) {
|
|
7770
8079
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7796,13 +8105,23 @@ var nodeToJson = (state, node) => {
|
|
|
7796
8105
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7797
8106
|
const children = [];
|
|
7798
8107
|
let child = node.node.firstChild;
|
|
8108
|
+
const appendText = (raw) => {
|
|
8109
|
+
if (raw.length === 0) {
|
|
8110
|
+
return;
|
|
8111
|
+
}
|
|
8112
|
+
const last = children[children.length - 1];
|
|
8113
|
+
if (typeof last === "string") {
|
|
8114
|
+
children[children.length - 1] = last + raw;
|
|
8115
|
+
} else {
|
|
8116
|
+
children.push(raw);
|
|
8117
|
+
}
|
|
8118
|
+
};
|
|
7799
8119
|
while (child) {
|
|
7800
8120
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7801
8121
|
if (child.type.name === "Text") {
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
}
|
|
8122
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
8123
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
8124
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7806
8125
|
} else if (child.type.name === "Element") {
|
|
7807
8126
|
const data = nodeToJson(state, child);
|
|
7808
8127
|
if (data) {
|
|
@@ -7812,27 +8131,62 @@ var nodeToJson = (state, node) => {
|
|
|
7812
8131
|
}
|
|
7813
8132
|
child = child.nextSibling;
|
|
7814
8133
|
}
|
|
8134
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
8135
|
+
children[0] = children[0].trimStart();
|
|
8136
|
+
}
|
|
7815
8137
|
if (children.length > 0) {
|
|
7816
|
-
|
|
8138
|
+
const lastIndex = children.length - 1;
|
|
8139
|
+
const last = children[lastIndex];
|
|
8140
|
+
if (typeof last === "string") {
|
|
8141
|
+
children[lastIndex] = last.trimEnd();
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
8145
|
+
if (trimmed.length > 0) {
|
|
8146
|
+
tag.children = trimmed;
|
|
7817
8147
|
}
|
|
7818
8148
|
}
|
|
7819
8149
|
return tag;
|
|
7820
8150
|
}
|
|
7821
8151
|
};
|
|
8152
|
+
var XML_NAMED_ENTITIES = {
|
|
8153
|
+
"<": "<",
|
|
8154
|
+
">": ">",
|
|
8155
|
+
"&": "&",
|
|
8156
|
+
""": '"',
|
|
8157
|
+
"'": "'"
|
|
8158
|
+
};
|
|
8159
|
+
var decodeXmlEntity = (raw) => {
|
|
8160
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
8161
|
+
if (named !== void 0) {
|
|
8162
|
+
return named;
|
|
8163
|
+
}
|
|
8164
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
8165
|
+
if (numeric) {
|
|
8166
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
8167
|
+
if (Number.isFinite(code)) {
|
|
8168
|
+
try {
|
|
8169
|
+
return String.fromCodePoint(code);
|
|
8170
|
+
} catch {
|
|
8171
|
+
}
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
return raw;
|
|
8175
|
+
};
|
|
7822
8176
|
|
|
7823
8177
|
// src/extensions/tags/xml-tags.ts
|
|
7824
8178
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7825
|
-
var navigatePreviousEffect =
|
|
7826
|
-
var navigateNextEffect =
|
|
8179
|
+
var navigatePreviousEffect = StateEffect13.define();
|
|
8180
|
+
var navigateNextEffect = StateEffect13.define();
|
|
7827
8181
|
var getXmlTextChild = (children) => {
|
|
7828
8182
|
const child = children?.[0];
|
|
7829
8183
|
return typeof child === "string" ? child : null;
|
|
7830
8184
|
};
|
|
7831
8185
|
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
7832
8186
|
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7833
|
-
var xmlTagContextEffect =
|
|
7834
|
-
var xmlTagResetEffect =
|
|
7835
|
-
var xmlTagUpdateEffect =
|
|
8187
|
+
var xmlTagContextEffect = StateEffect13.define();
|
|
8188
|
+
var xmlTagResetEffect = StateEffect13.define();
|
|
8189
|
+
var xmlTagUpdateEffect = StateEffect13.define();
|
|
7836
8190
|
var widgetContextStateField = StateField14.define({
|
|
7837
8191
|
create: () => void 0,
|
|
7838
8192
|
update: (value, tr) => {
|
|
@@ -7856,12 +8210,7 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7856
8210
|
log11("widget updated", {
|
|
7857
8211
|
id,
|
|
7858
8212
|
value
|
|
7859
|
-
}, {
|
|
7860
|
-
F: __dxlog_file17,
|
|
7861
|
-
L: 184,
|
|
7862
|
-
S: void 0,
|
|
7863
|
-
C: (f, a) => f(...a)
|
|
7864
|
-
});
|
|
8213
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7865
8214
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7866
8215
|
return {
|
|
7867
8216
|
...map,
|
|
@@ -7872,25 +8221,16 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7872
8221
|
return map;
|
|
7873
8222
|
}
|
|
7874
8223
|
});
|
|
7875
|
-
var
|
|
7876
|
-
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2, paragraphToWidgetGapRem } = {}) => {
|
|
8224
|
+
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2 } = {}) => {
|
|
7877
8225
|
const notifier = createWidgetMap(setWidgets);
|
|
7878
8226
|
const widgetDecorationsField = createWidgetDecorationsField(registry, notifier);
|
|
7879
|
-
const paragraphGapTheme = paragraphToWidgetGapRem != null && paragraphToWidgetGapRem > 0 ? EditorView31.baseTheme({
|
|
7880
|
-
[`& .cm-content > .cm-line:not(:has([${XML_WIDGET_DATA_ATTR}])) + .cm-line:has([${XML_WIDGET_DATA_ATTR}])`]: {
|
|
7881
|
-
marginTop: `${paragraphToWidgetGapRem}rem`
|
|
7882
|
-
}
|
|
7883
|
-
}) : null;
|
|
7884
8227
|
return [
|
|
7885
8228
|
widgetContextStateField,
|
|
7886
8229
|
widgetStateMapStateField,
|
|
7887
8230
|
widgetDecorationsField,
|
|
7888
8231
|
createWidgetUpdatePlugin(widgetDecorationsField, notifier),
|
|
7889
8232
|
createNavigationEffectPlugin(widgetDecorationsField, bookmarks2),
|
|
7890
|
-
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7891
|
-
...paragraphGapTheme ? [
|
|
7892
|
-
paragraphGapTheme
|
|
7893
|
-
] : []
|
|
8233
|
+
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7894
8234
|
];
|
|
7895
8235
|
};
|
|
7896
8236
|
var createWidgetMap = (setWidgets) => {
|
|
@@ -7900,12 +8240,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7900
8240
|
log11("widget mounted", {
|
|
7901
8241
|
id: state.id,
|
|
7902
8242
|
tag: state.props._tag
|
|
7903
|
-
}, {
|
|
7904
|
-
F: __dxlog_file17,
|
|
7905
|
-
L: 261,
|
|
7906
|
-
S: void 0,
|
|
7907
|
-
C: (f, a) => f(...a)
|
|
7908
|
-
});
|
|
8243
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7909
8244
|
widgets.set(state.id, state);
|
|
7910
8245
|
setWidgets?.([
|
|
7911
8246
|
...widgets.values()
|
|
@@ -7916,12 +8251,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7916
8251
|
log11("widget unmounted", {
|
|
7917
8252
|
id,
|
|
7918
8253
|
tag: state?.props._tag
|
|
7919
|
-
}, {
|
|
7920
|
-
F: __dxlog_file17,
|
|
7921
|
-
L: 267,
|
|
7922
|
-
S: void 0,
|
|
7923
|
-
C: (f, a) => f(...a)
|
|
7924
|
-
});
|
|
8254
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7925
8255
|
widgets.delete(id);
|
|
7926
8256
|
setWidgets?.([
|
|
7927
8257
|
...widgets.values()
|
|
@@ -7930,7 +8260,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7930
8260
|
};
|
|
7931
8261
|
return notifier;
|
|
7932
8262
|
};
|
|
7933
|
-
var keyHandlers =
|
|
8263
|
+
var keyHandlers = keymap14.of([
|
|
7934
8264
|
{
|
|
7935
8265
|
key: "Mod-ArrowUp",
|
|
7936
8266
|
run: (view) => {
|
|
@@ -7951,7 +8281,7 @@ var keyHandlers = keymap13.of([
|
|
|
7951
8281
|
}
|
|
7952
8282
|
]);
|
|
7953
8283
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7954
|
-
return
|
|
8284
|
+
return EditorView34.updateListener.of((update2) => {
|
|
7955
8285
|
update2.transactions.forEach((transaction) => {
|
|
7956
8286
|
for (const effect of transaction.effects) {
|
|
7957
8287
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7979,7 +8309,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7979
8309
|
anchor: line.from,
|
|
7980
8310
|
head: line.from
|
|
7981
8311
|
},
|
|
7982
|
-
effects:
|
|
8312
|
+
effects: crawlerLineEffect.of({
|
|
7983
8313
|
line: line.number - 1,
|
|
7984
8314
|
offset: -16
|
|
7985
8315
|
})
|
|
@@ -8012,7 +8342,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8012
8342
|
anchor: line.to,
|
|
8013
8343
|
head: line.to
|
|
8014
8344
|
},
|
|
8015
|
-
effects:
|
|
8345
|
+
effects: crawlerLineEffect.of({
|
|
8016
8346
|
line: line.number - 1,
|
|
8017
8347
|
offset: -16
|
|
8018
8348
|
})
|
|
@@ -8024,7 +8354,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8024
8354
|
anchor: line.to,
|
|
8025
8355
|
head: line.to
|
|
8026
8356
|
},
|
|
8027
|
-
effects:
|
|
8357
|
+
effects: crawlerLineEffect.of({
|
|
8028
8358
|
line: line.number - 1,
|
|
8029
8359
|
position: "end"
|
|
8030
8360
|
})
|
|
@@ -8036,7 +8366,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8036
8366
|
});
|
|
8037
8367
|
});
|
|
8038
8368
|
};
|
|
8039
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8369
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin26.fromClass(class {
|
|
8040
8370
|
update(update2) {
|
|
8041
8371
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
8042
8372
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -8081,7 +8411,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8081
8411
|
}
|
|
8082
8412
|
return {
|
|
8083
8413
|
from: 0,
|
|
8084
|
-
decorations:
|
|
8414
|
+
decorations: Decoration18.none
|
|
8085
8415
|
};
|
|
8086
8416
|
}
|
|
8087
8417
|
}
|
|
@@ -8092,12 +8422,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8092
8422
|
log11("document reset", {
|
|
8093
8423
|
from,
|
|
8094
8424
|
to: state.doc.length
|
|
8095
|
-
}, {
|
|
8096
|
-
F: __dxlog_file17,
|
|
8097
|
-
L: 429,
|
|
8098
|
-
S: void 0,
|
|
8099
|
-
C: (f, a) => f(...a)
|
|
8100
|
-
});
|
|
8425
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
8101
8426
|
return buildDecorations4(state, {
|
|
8102
8427
|
from: 0,
|
|
8103
8428
|
to: state.doc.length
|
|
@@ -8126,8 +8451,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8126
8451
|
};
|
|
8127
8452
|
},
|
|
8128
8453
|
provide: (field) => [
|
|
8129
|
-
|
|
8130
|
-
|
|
8454
|
+
EditorView34.decorations.from(field, (v) => v.decorations),
|
|
8455
|
+
EditorView34.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
8131
8456
|
]
|
|
8132
8457
|
});
|
|
8133
8458
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -8138,7 +8463,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8138
8463
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
8139
8464
|
return {
|
|
8140
8465
|
from: range.from,
|
|
8141
|
-
decorations:
|
|
8466
|
+
decorations: Decoration18.none
|
|
8142
8467
|
};
|
|
8143
8468
|
}
|
|
8144
8469
|
let last = range.from;
|
|
@@ -8174,7 +8499,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8174
8499
|
};
|
|
8175
8500
|
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
8176
8501
|
if (widget) {
|
|
8177
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8502
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
8178
8503
|
widget,
|
|
8179
8504
|
block,
|
|
8180
8505
|
atomic: true,
|
|
@@ -8186,12 +8511,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8186
8511
|
}
|
|
8187
8512
|
}
|
|
8188
8513
|
} catch (err) {
|
|
8189
|
-
log11.catch(err, void 0, {
|
|
8190
|
-
F: __dxlog_file17,
|
|
8191
|
-
L: 538,
|
|
8192
|
-
S: void 0,
|
|
8193
|
-
C: (f, a) => f(...a)
|
|
8194
|
-
});
|
|
8514
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
8195
8515
|
}
|
|
8196
8516
|
return false;
|
|
8197
8517
|
}
|
|
@@ -8238,7 +8558,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8238
8558
|
};
|
|
8239
8559
|
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8240
8560
|
if (widget) {
|
|
8241
|
-
builder.add(absoluteFrom, range.to,
|
|
8561
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8242
8562
|
widget,
|
|
8243
8563
|
block: def.block,
|
|
8244
8564
|
atomic: true,
|
|
@@ -8270,15 +8590,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8270
8590
|
#view;
|
|
8271
8591
|
constructor(id, Component, props, notifier, streaming) {
|
|
8272
8592
|
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8273
|
-
invariant7(id, void 0, {
|
|
8274
|
-
F: __dxlog_file17,
|
|
8275
|
-
L: 641,
|
|
8276
|
-
S: this,
|
|
8277
|
-
A: [
|
|
8278
|
-
"id",
|
|
8279
|
-
""
|
|
8280
|
-
]
|
|
8281
|
-
});
|
|
8593
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
8282
8594
|
}
|
|
8283
8595
|
get root() {
|
|
8284
8596
|
return this.#root;
|
|
@@ -8294,9 +8606,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8294
8606
|
}
|
|
8295
8607
|
toDOM(view) {
|
|
8296
8608
|
this.#view = view;
|
|
8297
|
-
this.#root = Domino4.of("div").classNames("min-h-[24px]").
|
|
8298
|
-
[XML_WIDGET_DATA_ATTR]: ""
|
|
8299
|
-
}).root;
|
|
8609
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8300
8610
|
const props = Object.assign({}, this.props, {
|
|
8301
8611
|
view
|
|
8302
8612
|
});
|
|
@@ -8327,71 +8637,10 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8327
8637
|
this.#view = void 0;
|
|
8328
8638
|
}
|
|
8329
8639
|
};
|
|
8330
|
-
|
|
8331
|
-
// src/extensions/typewriter.ts
|
|
8332
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
8333
|
-
var defaultItems = [
|
|
8334
|
-
"hello world!",
|
|
8335
|
-
"this is a test.",
|
|
8336
|
-
"this is [DXOS](https://dxos.org)"
|
|
8337
|
-
];
|
|
8338
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
8339
|
-
let t;
|
|
8340
|
-
let idx = 0;
|
|
8341
|
-
return [
|
|
8342
|
-
keymap14.of([
|
|
8343
|
-
{
|
|
8344
|
-
// Reset.
|
|
8345
|
-
key: "alt-meta-'",
|
|
8346
|
-
run: () => {
|
|
8347
|
-
clearTimeout(t);
|
|
8348
|
-
idx = 0;
|
|
8349
|
-
return true;
|
|
8350
|
-
}
|
|
8351
|
-
},
|
|
8352
|
-
{
|
|
8353
|
-
// Next prompt.
|
|
8354
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
8355
|
-
key: "Shift-Meta-'",
|
|
8356
|
-
run: (view) => {
|
|
8357
|
-
clearTimeout(t);
|
|
8358
|
-
const text = items[idx++];
|
|
8359
|
-
if (idx === items?.length) {
|
|
8360
|
-
idx = 0;
|
|
8361
|
-
}
|
|
8362
|
-
let i = 0;
|
|
8363
|
-
const insert = (d = 0) => {
|
|
8364
|
-
t = setTimeout(() => {
|
|
8365
|
-
const pos = view.state.selection.main.head;
|
|
8366
|
-
view.dispatch({
|
|
8367
|
-
changes: {
|
|
8368
|
-
from: pos,
|
|
8369
|
-
insert: text[i++]
|
|
8370
|
-
},
|
|
8371
|
-
selection: {
|
|
8372
|
-
anchor: pos + 1
|
|
8373
|
-
}
|
|
8374
|
-
});
|
|
8375
|
-
if (i < text.length) {
|
|
8376
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
8377
|
-
}
|
|
8378
|
-
}, d);
|
|
8379
|
-
};
|
|
8380
|
-
insert();
|
|
8381
|
-
return true;
|
|
8382
|
-
}
|
|
8383
|
-
}
|
|
8384
|
-
])
|
|
8385
|
-
];
|
|
8386
|
-
};
|
|
8387
8640
|
export {
|
|
8388
8641
|
Cursor,
|
|
8389
|
-
EditorInputMode,
|
|
8390
|
-
EditorInputModes,
|
|
8391
8642
|
EditorState4 as EditorState,
|
|
8392
|
-
|
|
8393
|
-
EditorViewMode,
|
|
8394
|
-
EditorViewModes,
|
|
8643
|
+
EditorView35 as EditorView,
|
|
8395
8644
|
Inline,
|
|
8396
8645
|
InputModeExtensions,
|
|
8397
8646
|
List,
|
|
@@ -8400,7 +8649,6 @@ export {
|
|
|
8400
8649
|
SpaceAwarenessProvider,
|
|
8401
8650
|
TextKind,
|
|
8402
8651
|
Tree,
|
|
8403
|
-
XML_WIDGET_DATA_ATTR,
|
|
8404
8652
|
addBlockquote,
|
|
8405
8653
|
addBookmark,
|
|
8406
8654
|
addCodeblock,
|
|
@@ -8425,6 +8673,9 @@ export {
|
|
|
8425
8673
|
commentsState,
|
|
8426
8674
|
compactSlots,
|
|
8427
8675
|
convertTreeToJson,
|
|
8676
|
+
crawler,
|
|
8677
|
+
crawlerActiveEffect,
|
|
8678
|
+
crawlerLineEffect,
|
|
8428
8679
|
createBasicExtensions,
|
|
8429
8680
|
createComment,
|
|
8430
8681
|
createCrawler,
|
|
@@ -8476,9 +8727,11 @@ export {
|
|
|
8476
8727
|
insertAtCursor,
|
|
8477
8728
|
insertAtLineStart,
|
|
8478
8729
|
insertTable,
|
|
8730
|
+
isRangeVisible,
|
|
8479
8731
|
itemToJSON,
|
|
8480
8732
|
join,
|
|
8481
8733
|
keymap15 as keymap,
|
|
8734
|
+
lineSpacing,
|
|
8482
8735
|
linkTooltip,
|
|
8483
8736
|
listItemToString,
|
|
8484
8737
|
listener,
|
|
@@ -8511,9 +8764,8 @@ export {
|
|
|
8511
8764
|
scrollPastEnd,
|
|
8512
8765
|
scrollThreadIntoView,
|
|
8513
8766
|
scrollToLine,
|
|
8767
|
+
scrollbarAutohide,
|
|
8514
8768
|
scroller,
|
|
8515
|
-
scrollerCrawlEffect,
|
|
8516
|
-
scrollerLineEffect,
|
|
8517
8769
|
selectionState,
|
|
8518
8770
|
setBlockquote,
|
|
8519
8771
|
setComments,
|
|
@@ -8521,6 +8773,7 @@ export {
|
|
|
8521
8773
|
setSelection,
|
|
8522
8774
|
setStyle,
|
|
8523
8775
|
singleValueFacet,
|
|
8776
|
+
snippets2 as snippets,
|
|
8524
8777
|
staticCompletion,
|
|
8525
8778
|
submit,
|
|
8526
8779
|
tabbable,
|
|
@@ -8540,10 +8793,12 @@ export {
|
|
|
8540
8793
|
treeFacet,
|
|
8541
8794
|
typeahead,
|
|
8542
8795
|
typewriter,
|
|
8543
|
-
|
|
8544
|
-
|
|
8796
|
+
typewriterBypass,
|
|
8797
|
+
typewriterDrainingEffect,
|
|
8545
8798
|
wrapWithCatch,
|
|
8799
|
+
xmlBlockDecoration,
|
|
8546
8800
|
xmlElementLength,
|
|
8801
|
+
xmlFormatting,
|
|
8547
8802
|
xmlTagContextEffect,
|
|
8548
8803
|
xmlTagResetEffect,
|
|
8549
8804
|
xmlTagUpdateEffect,
|