@dxos/ui-editor 0.8.4-main.fcc0d83b33 → 0.8.4-staging.60fe92afc8
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 +796 -614
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +796 -614
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/defaults.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/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/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/comments.d.ts +19 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -3
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +1 -1
- package/dist/types/src/extensions/json.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/preview/preview.d.ts +2 -2
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/{scroller.d.ts → scrolling/crawler.d.ts} +23 -8
- 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/spacing.d.ts +3 -0
- package/dist/types/src/extensions/spacing.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +54 -53
- package/src/defaults.ts +1 -2
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +9 -3
- 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.ts +2 -2
- package/src/extensions/index.ts +2 -3
- 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/{auto-scroll.ts → scrolling/auto-scroll.ts} +57 -28
- package/src/extensions/{scroller.ts → scrolling/crawler.ts} +48 -18
- 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/spacing.ts +15 -0
- package/src/extensions/tags/xml-formatting.ts +1 -1
- package/src/extensions/tags/xml-tags.ts +4 -4
- package/src/styles/theme.ts +11 -10
- 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.map +0 -1
- /package/dist/types/src/extensions/{auto-scroll.d.ts → scrolling/auto-scroll.d.ts} +0 -0
- /package/dist/types/src/extensions/{scroll-past-end.d.ts → scrolling/scroll-past-end.d.ts} +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
-
import { EditorView as
|
|
3
|
+
import { EditorView as EditorView35, keymap as keymap15 } from "@codemirror/view";
|
|
4
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
5
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
6
6
|
|
|
7
7
|
// src/defaults.ts
|
|
8
8
|
import { mx } from "@dxos/ui-theme";
|
|
9
|
-
var editorClassNames = (role) => mx("dx-attention-surface
|
|
9
|
+
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");
|
|
10
10
|
var documentSlots = {
|
|
11
11
|
content: {
|
|
12
12
|
/**
|
|
@@ -363,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
363
363
|
};
|
|
364
364
|
|
|
365
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
366
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
367
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
368
368
|
_timeout;
|
|
369
369
|
_decorations = Decoration3.none;
|
|
370
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
371
374
|
if (this._timeout) {
|
|
372
375
|
window.clearTimeout(this._timeout);
|
|
373
376
|
this._timeout = void 0;
|
|
374
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
375
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const lineStart = activeLine.from;
|
|
379
|
-
this._timeout = setTimeout(() => {
|
|
380
|
-
this._decorations = Decoration3.set([
|
|
381
|
-
Decoration3.widget({
|
|
382
|
-
widget: new PlaceholderWidget(content),
|
|
383
|
-
side: 1
|
|
384
|
-
}).range(lineStart)
|
|
385
|
-
]);
|
|
386
|
-
update2.view.update([]);
|
|
387
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
388
385
|
}
|
|
389
|
-
|
|
386
|
+
const lineStart = activeLine.from;
|
|
387
|
+
const view = update2.view;
|
|
388
|
+
this._timeout = setTimeout(() => {
|
|
389
|
+
this._decorations = Decoration3.set([
|
|
390
|
+
Decoration3.widget({
|
|
391
|
+
widget: new PlaceholderWidget(content),
|
|
392
|
+
side: 1
|
|
393
|
+
}).range(lineStart)
|
|
394
|
+
]);
|
|
395
|
+
view.update([]);
|
|
396
|
+
}, delay);
|
|
390
397
|
}
|
|
391
398
|
destroy() {
|
|
392
399
|
if (this._timeout) {
|
|
@@ -504,357 +511,26 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
504
511
|
];
|
|
505
512
|
};
|
|
506
513
|
|
|
507
|
-
// src/extensions/auto-scroll.ts
|
|
508
|
-
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
509
|
-
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
510
|
-
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
511
|
-
import { Domino } from "@dxos/ui";
|
|
512
|
-
import { getSize } from "@dxos/ui-theme";
|
|
513
|
-
|
|
514
|
-
// src/extensions/scroller.ts
|
|
515
|
-
import { StateEffect } from "@codemirror/state";
|
|
516
|
-
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
517
|
-
import { log as log2 } from "@dxos/log";
|
|
518
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
519
|
-
var scrollerLineEffect = StateEffect.define();
|
|
520
|
-
var scrollerCrawlEffect = StateEffect.define();
|
|
521
|
-
var scrollToLine = (view, options) => {
|
|
522
|
-
view.dispatch({
|
|
523
|
-
effects: scrollerLineEffect.of(options)
|
|
524
|
-
});
|
|
525
|
-
};
|
|
526
|
-
var scroller = ({ overScroll = 0 } = {}) => {
|
|
527
|
-
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
528
|
-
view;
|
|
529
|
-
crawler;
|
|
530
|
-
constructor(view) {
|
|
531
|
-
this.view = view;
|
|
532
|
-
this.crawler = createCrawler(this.view);
|
|
533
|
-
}
|
|
534
|
-
// No-op.
|
|
535
|
-
destroy() {
|
|
536
|
-
this.crawler.cancel();
|
|
537
|
-
}
|
|
538
|
-
cancel() {
|
|
539
|
-
this.crawler.cancel();
|
|
540
|
-
}
|
|
541
|
-
crawl(start = false) {
|
|
542
|
-
if (start) {
|
|
543
|
-
this.crawler.scroll();
|
|
544
|
-
} else {
|
|
545
|
-
this.crawler.cancel();
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
549
|
-
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
550
|
-
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
551
|
-
const doc = this.view.state.doc;
|
|
552
|
-
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
553
|
-
if (line >= 0 && line <= doc.lines - 1) {
|
|
554
|
-
const lineStart = doc.line(line + 1).from;
|
|
555
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
556
|
-
if (coords) {
|
|
557
|
-
const currentScrollTop = scrollTop;
|
|
558
|
-
const maxScrollTop = scrollHeight - clientHeight;
|
|
559
|
-
if (position === "end") {
|
|
560
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
561
|
-
} else {
|
|
562
|
-
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
563
|
-
}
|
|
564
|
-
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
requestAnimationFrame(() => {
|
|
568
|
-
this.view.scrollDOM.scrollTo({
|
|
569
|
-
top: targetScrollTop
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
});
|
|
574
|
-
return [
|
|
575
|
-
scrollPlugin,
|
|
576
|
-
// Listen for effect.s
|
|
577
|
-
EditorView4.updateListener.of((update2) => {
|
|
578
|
-
update2.transactions.forEach((transaction) => {
|
|
579
|
-
try {
|
|
580
|
-
const plugin = update2.view.plugin(scrollPlugin);
|
|
581
|
-
if (plugin) {
|
|
582
|
-
for (const effect of transaction.effects) {
|
|
583
|
-
if (effect.is(scrollerCrawlEffect)) {
|
|
584
|
-
plugin.crawl(effect.value);
|
|
585
|
-
} else if (effect.is(scrollerLineEffect)) {
|
|
586
|
-
plugin.scroll(effect.value);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
} catch (err) {
|
|
591
|
-
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
592
|
-
}
|
|
593
|
-
});
|
|
594
|
-
}),
|
|
595
|
-
// Styles.
|
|
596
|
-
EditorView4.theme({
|
|
597
|
-
".cm-scroller": {
|
|
598
|
-
overflowY: "scroll",
|
|
599
|
-
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
600
|
-
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
601
|
-
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
602
|
-
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
603
|
-
overflowAnchor: "auto"
|
|
604
|
-
},
|
|
605
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
606
|
-
display: "none"
|
|
607
|
-
},
|
|
608
|
-
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
609
|
-
background: "transparent",
|
|
610
|
-
transition: "background 0.15s"
|
|
611
|
-
},
|
|
612
|
-
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
613
|
-
background: "var(--color-scrollbar-thumb)"
|
|
614
|
-
},
|
|
615
|
-
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
616
|
-
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
617
|
-
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
618
|
-
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
619
|
-
// so the last line stays `overScroll` px above the viewport bottom.
|
|
620
|
-
".cm-content::after": {
|
|
621
|
-
content: '""',
|
|
622
|
-
display: "block",
|
|
623
|
-
height: `${overScroll}px`
|
|
624
|
-
},
|
|
625
|
-
".cm-scroll-button": {
|
|
626
|
-
position: "absolute",
|
|
627
|
-
bottom: "0.5rem",
|
|
628
|
-
right: "1rem"
|
|
629
|
-
}
|
|
630
|
-
})
|
|
631
|
-
];
|
|
632
|
-
};
|
|
633
|
-
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
634
|
-
const el = view.scrollDOM;
|
|
635
|
-
let currentTop = 0;
|
|
636
|
-
let velocity = 0;
|
|
637
|
-
let rafId = null;
|
|
638
|
-
let lastTime = 0;
|
|
639
|
-
function frame(now) {
|
|
640
|
-
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
641
|
-
lastTime = now;
|
|
642
|
-
const targetTop = el.scrollHeight - el.clientHeight;
|
|
643
|
-
const delta = targetTop - currentTop;
|
|
644
|
-
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
645
|
-
el.scrollTop = targetTop;
|
|
646
|
-
currentTop = targetTop;
|
|
647
|
-
velocity = 0;
|
|
648
|
-
rafId = null;
|
|
649
|
-
lastTime = 0;
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
653
|
-
velocity += accel * dt;
|
|
654
|
-
currentTop += velocity * dt;
|
|
655
|
-
el.scrollTop = currentTop;
|
|
656
|
-
rafId = requestAnimationFrame(frame);
|
|
657
|
-
}
|
|
658
|
-
return {
|
|
659
|
-
scroll: () => {
|
|
660
|
-
if (rafId === null) {
|
|
661
|
-
currentTop = el.scrollTop;
|
|
662
|
-
lastTime = 0;
|
|
663
|
-
rafId = requestAnimationFrame(frame);
|
|
664
|
-
}
|
|
665
|
-
},
|
|
666
|
-
cancel: () => {
|
|
667
|
-
if (rafId !== null) {
|
|
668
|
-
cancelAnimationFrame(rafId);
|
|
669
|
-
velocity = 0;
|
|
670
|
-
lastTime = 0;
|
|
671
|
-
rafId = null;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// src/extensions/auto-scroll.ts
|
|
678
|
-
var autoScrollEffect = StateEffect2.define();
|
|
679
|
-
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
680
|
-
let buttonContainer;
|
|
681
|
-
let isPinned = true;
|
|
682
|
-
let jumpPending = false;
|
|
683
|
-
let enabled = true;
|
|
684
|
-
let firstUpdate = true;
|
|
685
|
-
const setPinned = (pinned) => {
|
|
686
|
-
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
687
|
-
isPinned = pinned;
|
|
688
|
-
};
|
|
689
|
-
return [
|
|
690
|
-
// Update listener for scrolling when content changes.
|
|
691
|
-
EditorView5.updateListener.of((update2) => {
|
|
692
|
-
const { view, heightChanged, state, startState } = update2;
|
|
693
|
-
for (const tr of update2.transactions) {
|
|
694
|
-
for (const effect of tr.effects) {
|
|
695
|
-
if (effect.is(autoScrollEffect)) {
|
|
696
|
-
enabled = effect.value;
|
|
697
|
-
if (enabled) {
|
|
698
|
-
setPinned(true);
|
|
699
|
-
view.dispatch({
|
|
700
|
-
effects: scrollerCrawlEffect.of(true)
|
|
701
|
-
});
|
|
702
|
-
} else {
|
|
703
|
-
view.dispatch({
|
|
704
|
-
effects: scrollerCrawlEffect.of(false)
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
if (!enabled) {
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
|
-
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
714
|
-
firstUpdate = false;
|
|
715
|
-
jumpPending = true;
|
|
716
|
-
requestAnimationFrame(() => {
|
|
717
|
-
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
718
|
-
jumpPending = false;
|
|
719
|
-
});
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
firstUpdate = false;
|
|
723
|
-
if (jumpPending) {
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
if (heightChanged) {
|
|
727
|
-
if (isPinned) {
|
|
728
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
729
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
730
|
-
if (delta > 0) {
|
|
731
|
-
setPinned(true);
|
|
732
|
-
view.dispatch({
|
|
733
|
-
effects: scrollerCrawlEffect.of(true)
|
|
734
|
-
});
|
|
735
|
-
} else if (delta < -1) {
|
|
736
|
-
setPinned(false);
|
|
737
|
-
}
|
|
738
|
-
} else {
|
|
739
|
-
if (state.doc.length === 0) {
|
|
740
|
-
setPinned(true);
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}),
|
|
745
|
-
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
746
|
-
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
747
|
-
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
748
|
-
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
749
|
-
observer;
|
|
750
|
-
firstObservation = true;
|
|
751
|
-
destroyed = false;
|
|
752
|
-
constructor(view) {
|
|
753
|
-
const onResize = throttle(() => {
|
|
754
|
-
if (this.destroyed || !enabled) {
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
757
|
-
setPinned(true);
|
|
758
|
-
requestAnimationFrame(() => {
|
|
759
|
-
if (this.destroyed) {
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
|
-
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
763
|
-
view.dispatch({
|
|
764
|
-
effects: scrollerCrawlEffect.of(true)
|
|
765
|
-
});
|
|
766
|
-
});
|
|
767
|
-
}, 100);
|
|
768
|
-
this.observer = new ResizeObserver(() => {
|
|
769
|
-
if (this.firstObservation) {
|
|
770
|
-
this.firstObservation = false;
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
onResize();
|
|
774
|
-
});
|
|
775
|
-
this.observer.observe(view.scrollDOM);
|
|
776
|
-
}
|
|
777
|
-
destroy() {
|
|
778
|
-
this.destroyed = true;
|
|
779
|
-
this.observer.disconnect();
|
|
780
|
-
}
|
|
781
|
-
}) : [],
|
|
782
|
-
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
783
|
-
ViewPlugin6.fromClass(class {
|
|
784
|
-
cleanup;
|
|
785
|
-
constructor(view) {
|
|
786
|
-
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
787
|
-
requestAnimationFrame(() => {
|
|
788
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
789
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
790
|
-
const pinned = delta === 0;
|
|
791
|
-
setPinned(pinned);
|
|
792
|
-
if (!pinned) {
|
|
793
|
-
view.dispatch({
|
|
794
|
-
effects: scrollerCrawlEffect.of(false)
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
});
|
|
798
|
-
}, 500));
|
|
799
|
-
}
|
|
800
|
-
destroy() {
|
|
801
|
-
this.cleanup();
|
|
802
|
-
}
|
|
803
|
-
}),
|
|
804
|
-
// Scroll button.
|
|
805
|
-
ViewPlugin6.fromClass(class {
|
|
806
|
-
constructor(view) {
|
|
807
|
-
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
808
|
-
icon: "ph--arrow-down--regular"
|
|
809
|
-
});
|
|
810
|
-
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
811
|
-
"data-density": "fine"
|
|
812
|
-
}).append(icon).on("click", () => {
|
|
813
|
-
setPinned(true);
|
|
814
|
-
view.dispatch({
|
|
815
|
-
effects: scrollerLineEffect.of({
|
|
816
|
-
line: -1,
|
|
817
|
-
position: "end",
|
|
818
|
-
behavior: "smooth"
|
|
819
|
-
})
|
|
820
|
-
});
|
|
821
|
-
});
|
|
822
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
823
|
-
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
824
|
-
}
|
|
825
|
-
})
|
|
826
|
-
];
|
|
827
|
-
};
|
|
828
|
-
function createUserScrollDetector(element, onUserScroll) {
|
|
829
|
-
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
830
|
-
passive: true
|
|
831
|
-
}), addEventListener(element, "pointerdown", (event) => {
|
|
832
|
-
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
833
|
-
onUserScroll();
|
|
834
|
-
}
|
|
835
|
-
}));
|
|
836
|
-
}
|
|
837
|
-
|
|
838
514
|
// src/extensions/automerge/automerge.ts
|
|
839
515
|
import { next as A3 } from "@automerge/automerge";
|
|
840
516
|
import { StateField, Transaction as Transaction2 } from "@codemirror/state";
|
|
841
|
-
import { EditorView as
|
|
842
|
-
import { DocAccessor } from "@dxos/echo-
|
|
517
|
+
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
518
|
+
import { DocAccessor } from "@dxos/echo-client";
|
|
843
519
|
|
|
844
520
|
// src/extensions/state.ts
|
|
845
521
|
import { Transaction } from "@codemirror/state";
|
|
846
522
|
var initialSync = Transaction.userEvent.of("initial.sync");
|
|
847
523
|
|
|
848
524
|
// src/extensions/automerge/cursor.ts
|
|
849
|
-
import { fromCursor, toCursor } from "@dxos/echo-
|
|
850
|
-
import { log as
|
|
851
|
-
var
|
|
525
|
+
import { fromCursor, toCursor } from "@dxos/echo-client";
|
|
526
|
+
import { log as log2 } from "@dxos/log";
|
|
527
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
852
528
|
var cursorConverter = (accessor) => ({
|
|
853
529
|
toCursor: (pos, assoc) => {
|
|
854
530
|
try {
|
|
855
531
|
return toCursor(accessor, pos, assoc);
|
|
856
532
|
} catch (err) {
|
|
857
|
-
|
|
533
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
|
|
858
534
|
return "";
|
|
859
535
|
}
|
|
860
536
|
},
|
|
@@ -862,17 +538,17 @@ var cursorConverter = (accessor) => ({
|
|
|
862
538
|
try {
|
|
863
539
|
return fromCursor(accessor, cursor);
|
|
864
540
|
} catch (err) {
|
|
865
|
-
|
|
541
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
|
|
866
542
|
return 0;
|
|
867
543
|
}
|
|
868
544
|
}
|
|
869
545
|
});
|
|
870
546
|
|
|
871
547
|
// src/extensions/automerge/defs.ts
|
|
872
|
-
import { Annotation, StateEffect
|
|
548
|
+
import { Annotation, StateEffect } from "@codemirror/state";
|
|
873
549
|
var getPath = (state, field) => state.field(field).path;
|
|
874
550
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
875
|
-
var updateHeadsEffect =
|
|
551
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
876
552
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
877
553
|
newHeads
|
|
878
554
|
});
|
|
@@ -883,7 +559,7 @@ var isReconcile = (tr) => {
|
|
|
883
559
|
|
|
884
560
|
// src/extensions/automerge/sync.ts
|
|
885
561
|
import { next as A2 } from "@automerge/automerge";
|
|
886
|
-
import { log as
|
|
562
|
+
import { log as log3 } from "@dxos/log";
|
|
887
563
|
|
|
888
564
|
// src/extensions/automerge/update-automerge.ts
|
|
889
565
|
import { next as A } from "@automerge/automerge";
|
|
@@ -1024,7 +700,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
1024
700
|
};
|
|
1025
701
|
|
|
1026
702
|
// src/extensions/automerge/sync.ts
|
|
1027
|
-
var
|
|
703
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
1028
704
|
var Syncer = class {
|
|
1029
705
|
_handle;
|
|
1030
706
|
_state;
|
|
@@ -1047,7 +723,7 @@ var Syncer = class {
|
|
|
1047
723
|
this._pending = false;
|
|
1048
724
|
}
|
|
1049
725
|
onEditorChange(view) {
|
|
1050
|
-
|
|
726
|
+
log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
|
|
1051
727
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
1052
728
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
1053
729
|
if (newHeads) {
|
|
@@ -1058,7 +734,7 @@ var Syncer = class {
|
|
|
1058
734
|
}
|
|
1059
735
|
}
|
|
1060
736
|
onAutomergeChange(view) {
|
|
1061
|
-
|
|
737
|
+
log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
|
|
1062
738
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
1063
739
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
1064
740
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1111,7 +787,7 @@ var automerge = (accessor) => {
|
|
|
1111
787
|
// Track heads.
|
|
1112
788
|
syncState,
|
|
1113
789
|
// Reconcile external updates.
|
|
1114
|
-
|
|
790
|
+
ViewPlugin5.fromClass(class {
|
|
1115
791
|
_view;
|
|
1116
792
|
constructor(_view) {
|
|
1117
793
|
this._view = _view;
|
|
@@ -1142,7 +818,7 @@ var automerge = (accessor) => {
|
|
|
1142
818
|
};
|
|
1143
819
|
}),
|
|
1144
820
|
// Reconcile local updates.
|
|
1145
|
-
|
|
821
|
+
EditorView4.updateListener.of(({ view, changes, transactions }) => {
|
|
1146
822
|
if (!changes.empty) {
|
|
1147
823
|
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
|
|
1148
824
|
if (!isInitialSync) {
|
|
@@ -1155,10 +831,10 @@ var automerge = (accessor) => {
|
|
|
1155
831
|
|
|
1156
832
|
// src/extensions/awareness/awareness.ts
|
|
1157
833
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
1158
|
-
import { Decoration as Decoration5, EditorView as
|
|
834
|
+
import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1159
835
|
import { Event } from "@dxos/async";
|
|
1160
836
|
import { Context } from "@dxos/context";
|
|
1161
|
-
var
|
|
837
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1162
838
|
var dummyProvider = {
|
|
1163
839
|
remoteStateChange: new Event(),
|
|
1164
840
|
open: () => {
|
|
@@ -1174,14 +850,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
|
1174
850
|
var awareness = (provider = dummyProvider) => {
|
|
1175
851
|
return [
|
|
1176
852
|
awarenessProvider.of(provider),
|
|
1177
|
-
|
|
853
|
+
ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
|
|
1178
854
|
decorations: (value) => value.decorations
|
|
1179
855
|
}),
|
|
1180
856
|
styles
|
|
1181
857
|
];
|
|
1182
858
|
};
|
|
1183
859
|
var RemoteSelectionsDecorator = class {
|
|
1184
|
-
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F:
|
|
860
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
|
|
1185
861
|
_cursorConverter;
|
|
1186
862
|
_provider;
|
|
1187
863
|
_lastAnchor;
|
|
@@ -1330,7 +1006,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
|
|
|
1330
1006
|
return true;
|
|
1331
1007
|
}
|
|
1332
1008
|
};
|
|
1333
|
-
var styles =
|
|
1009
|
+
var styles = EditorView5.theme({
|
|
1334
1010
|
".cm-collab-selection": {},
|
|
1335
1011
|
".cm-collab-selectionLine": {
|
|
1336
1012
|
padding: 0,
|
|
@@ -1392,8 +1068,8 @@ var styles = EditorView7.theme({
|
|
|
1392
1068
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1393
1069
|
import { Context as Context2 } from "@dxos/context";
|
|
1394
1070
|
import { invariant } from "@dxos/invariant";
|
|
1395
|
-
import { log as
|
|
1396
|
-
var
|
|
1071
|
+
import { log as log4 } from "@dxos/log";
|
|
1072
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1397
1073
|
var DEBOUNCE_INTERVAL = 100;
|
|
1398
1074
|
var SpaceAwarenessProvider = class {
|
|
1399
1075
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1412,7 +1088,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1412
1088
|
this._info = info;
|
|
1413
1089
|
}
|
|
1414
1090
|
open() {
|
|
1415
|
-
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F:
|
|
1091
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
|
|
1416
1092
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1417
1093
|
if (this._localState) {
|
|
1418
1094
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1437,9 +1113,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1437
1113
|
void this._messenger.postMessage(this._channel, {
|
|
1438
1114
|
kind: "query"
|
|
1439
1115
|
}).catch((err) => {
|
|
1440
|
-
|
|
1116
|
+
log4.debug("failed to query awareness", {
|
|
1441
1117
|
err
|
|
1442
|
-
}, { "~LogMeta": "~LogMeta", F:
|
|
1118
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
|
|
1443
1119
|
});
|
|
1444
1120
|
}
|
|
1445
1121
|
close() {
|
|
@@ -1451,7 +1127,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1451
1127
|
return Array.from(this._remoteStates.values());
|
|
1452
1128
|
}
|
|
1453
1129
|
update(position) {
|
|
1454
|
-
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1130
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1455
1131
|
this._localState = {
|
|
1456
1132
|
peerId: this._peerId,
|
|
1457
1133
|
position,
|
|
@@ -1460,22 +1136,22 @@ var SpaceAwarenessProvider = class {
|
|
|
1460
1136
|
this._postTask.schedule();
|
|
1461
1137
|
}
|
|
1462
1138
|
_handleQueryMessage() {
|
|
1463
|
-
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1139
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1464
1140
|
this._postTask.schedule();
|
|
1465
1141
|
}
|
|
1466
1142
|
_handlePostMessage(message) {
|
|
1467
|
-
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F:
|
|
1143
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1468
1144
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1469
1145
|
this.remoteStateChange.emit();
|
|
1470
1146
|
}
|
|
1471
1147
|
};
|
|
1472
1148
|
|
|
1473
1149
|
// src/extensions/blast.ts
|
|
1474
|
-
import { EditorView as
|
|
1150
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1475
1151
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1476
|
-
import { throttle
|
|
1152
|
+
import { throttle } from "@dxos/async";
|
|
1477
1153
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1478
|
-
var
|
|
1154
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1479
1155
|
var defaultOptions = {
|
|
1480
1156
|
effect: 2,
|
|
1481
1157
|
maxParticles: 200,
|
|
@@ -1520,7 +1196,7 @@ var blast = (options = defaultOptions) => {
|
|
|
1520
1196
|
};
|
|
1521
1197
|
return [
|
|
1522
1198
|
// Cursor moved.
|
|
1523
|
-
|
|
1199
|
+
EditorView6.updateListener.of((update2) => {
|
|
1524
1200
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
1525
1201
|
if (blaster) {
|
|
1526
1202
|
blaster.destroy();
|
|
@@ -1593,7 +1269,7 @@ var Blaster = class {
|
|
|
1593
1269
|
return this._node;
|
|
1594
1270
|
}
|
|
1595
1271
|
initialize() {
|
|
1596
|
-
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1272
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1597
1273
|
this._canvas = document.createElement("canvas");
|
|
1598
1274
|
this._canvas.id = "code-blast-canvas";
|
|
1599
1275
|
this._canvas.style.position = "absolute";
|
|
@@ -1622,7 +1298,7 @@ var Blaster = class {
|
|
|
1622
1298
|
}
|
|
1623
1299
|
}
|
|
1624
1300
|
start() {
|
|
1625
|
-
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1301
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1626
1302
|
this._running = true;
|
|
1627
1303
|
this.loop();
|
|
1628
1304
|
}
|
|
@@ -1649,11 +1325,11 @@ var Blaster = class {
|
|
|
1649
1325
|
this.drawParticles();
|
|
1650
1326
|
requestAnimationFrame(this.loop.bind(this));
|
|
1651
1327
|
}
|
|
1652
|
-
shake =
|
|
1328
|
+
shake = throttle(({ time }) => {
|
|
1653
1329
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1654
1330
|
this._shakeTimeMax = time;
|
|
1655
1331
|
}, 100);
|
|
1656
|
-
spawn =
|
|
1332
|
+
spawn = throttle(({ element, point }) => {
|
|
1657
1333
|
const color = getRGBComponents(element, this._options.color);
|
|
1658
1334
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1659
1335
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1762,9 +1438,9 @@ var random = (min, max) => {
|
|
|
1762
1438
|
|
|
1763
1439
|
// src/extensions/blocks.ts
|
|
1764
1440
|
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1765
|
-
import { Decoration as Decoration6, EditorView as
|
|
1441
|
+
import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
1766
1442
|
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1767
|
-
var paragraphBlockPlugin =
|
|
1443
|
+
var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
|
|
1768
1444
|
decorations;
|
|
1769
1445
|
constructor(view) {
|
|
1770
1446
|
this.decorations = this.build(view);
|
|
@@ -1823,7 +1499,7 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
|
|
|
1823
1499
|
});
|
|
1824
1500
|
var blocks = () => [
|
|
1825
1501
|
paragraphBlockPlugin,
|
|
1826
|
-
|
|
1502
|
+
EditorView7.baseTheme({
|
|
1827
1503
|
".cm-line.block-line": {
|
|
1828
1504
|
paddingLeft: "0.75rem",
|
|
1829
1505
|
paddingRight: "0.75rem",
|
|
@@ -1857,13 +1533,13 @@ var blocks = () => [
|
|
|
1857
1533
|
];
|
|
1858
1534
|
|
|
1859
1535
|
// src/extensions/bookmarks.ts
|
|
1860
|
-
import { Prec as Prec3, StateEffect as
|
|
1536
|
+
import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1861
1537
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1862
|
-
import { log as
|
|
1863
|
-
var
|
|
1864
|
-
var addBookmark =
|
|
1865
|
-
var removeBookmark =
|
|
1866
|
-
var clearBookmarks =
|
|
1538
|
+
import { log as log5 } from "@dxos/log";
|
|
1539
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1540
|
+
var addBookmark = StateEffect2.define();
|
|
1541
|
+
var removeBookmark = StateEffect2.define();
|
|
1542
|
+
var clearBookmarks = StateEffect2.define();
|
|
1867
1543
|
var bookmarks = () => {
|
|
1868
1544
|
return [
|
|
1869
1545
|
bookmarksField,
|
|
@@ -1872,7 +1548,7 @@ var bookmarks = () => {
|
|
|
1872
1548
|
key: "Mod-ArrowUp",
|
|
1873
1549
|
run: (view) => {
|
|
1874
1550
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1875
|
-
|
|
1551
|
+
log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
|
|
1876
1552
|
return true;
|
|
1877
1553
|
}
|
|
1878
1554
|
},
|
|
@@ -1880,7 +1556,7 @@ var bookmarks = () => {
|
|
|
1880
1556
|
key: "Mod-ArrowDown",
|
|
1881
1557
|
run: (view) => {
|
|
1882
1558
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1883
|
-
|
|
1559
|
+
log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
|
|
1884
1560
|
return true;
|
|
1885
1561
|
}
|
|
1886
1562
|
}
|
|
@@ -1917,27 +1593,27 @@ var bookmarksField = StateField2.define({
|
|
|
1917
1593
|
|
|
1918
1594
|
// src/extensions/comments.ts
|
|
1919
1595
|
import { invertedEffects } from "@codemirror/commands";
|
|
1920
|
-
import { StateEffect as
|
|
1921
|
-
import { Decoration as Decoration7, EditorView as
|
|
1596
|
+
import { StateEffect as StateEffect3, StateField as StateField3 } from "@codemirror/state";
|
|
1597
|
+
import { Decoration as Decoration7, EditorView as EditorView9, ViewPlugin as ViewPlugin8, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1922
1598
|
import sortBy from "lodash.sortby";
|
|
1923
1599
|
import { debounce as debounce2 } from "@dxos/async";
|
|
1924
|
-
import { log as
|
|
1600
|
+
import { log as log6 } from "@dxos/log";
|
|
1925
1601
|
import { isNonNullable } from "@dxos/util";
|
|
1926
1602
|
|
|
1927
1603
|
// src/extensions/selection.ts
|
|
1928
1604
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1929
|
-
import { EditorView as
|
|
1605
|
+
import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
|
|
1930
1606
|
import { debounce } from "@dxos/async";
|
|
1931
1607
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1932
1608
|
import { isTruthy } from "@dxos/util";
|
|
1933
|
-
var
|
|
1609
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1934
1610
|
var documentId = singleValueFacet();
|
|
1935
1611
|
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1936
1612
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1937
1613
|
return {
|
|
1938
1614
|
selection,
|
|
1939
1615
|
scrollIntoView: !scrollTo,
|
|
1940
|
-
effects: scrollTo ?
|
|
1616
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
|
1941
1617
|
yMargin: 96
|
|
1942
1618
|
}) : void 0,
|
|
1943
1619
|
annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
|
|
@@ -1945,12 +1621,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1945
1621
|
};
|
|
1946
1622
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1947
1623
|
getState: (id) => {
|
|
1948
|
-
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1624
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
|
|
1949
1625
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1950
1626
|
return state ? JSON.parse(state) : void 0;
|
|
1951
1627
|
},
|
|
1952
1628
|
setState: (id, state) => {
|
|
1953
|
-
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F:
|
|
1629
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
|
|
1954
1630
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1955
1631
|
}
|
|
1956
1632
|
});
|
|
@@ -1963,7 +1639,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1963
1639
|
// setStateDebounced(id, {});
|
|
1964
1640
|
// },
|
|
1965
1641
|
// }),
|
|
1966
|
-
|
|
1642
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
|
1967
1643
|
const id = view.state.facet(documentId);
|
|
1968
1644
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
1969
1645
|
return;
|
|
@@ -2002,10 +1678,10 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2002
1678
|
};
|
|
2003
1679
|
|
|
2004
1680
|
// src/extensions/comments.ts
|
|
2005
|
-
var
|
|
2006
|
-
var setComments =
|
|
2007
|
-
var setSelection =
|
|
2008
|
-
var setCommentState =
|
|
1681
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1682
|
+
var setComments = StateEffect3.define();
|
|
1683
|
+
var setSelection = StateEffect3.define();
|
|
1684
|
+
var setCommentState = StateEffect3.define();
|
|
2009
1685
|
var commentsState = StateField3.define({
|
|
2010
1686
|
create: (state) => ({
|
|
2011
1687
|
id: state.facet(documentId),
|
|
@@ -2044,35 +1720,35 @@ var commentsState = StateField3.define({
|
|
|
2044
1720
|
return value;
|
|
2045
1721
|
}
|
|
2046
1722
|
});
|
|
2047
|
-
var styles2 =
|
|
2048
|
-
".cm-comment
|
|
2049
|
-
padding: "3px 0",
|
|
2050
|
-
color: "var(--color-cm-comment-text)",
|
|
2051
|
-
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2052
|
-
},
|
|
2053
|
-
".cm-comment > span, .cm-comment-current > span": {
|
|
1723
|
+
var styles2 = EditorView9.theme({
|
|
1724
|
+
".cm-comment > span": {
|
|
2054
1725
|
boxDecorationBreak: "clone",
|
|
2055
|
-
boxShadow: "0 0
|
|
1726
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-surface)",
|
|
2056
1727
|
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2057
|
-
color: "var(--color-cm-comment-text)",
|
|
1728
|
+
color: "var(--color-cm-comment-text) !important",
|
|
2058
1729
|
cursor: "pointer"
|
|
1730
|
+
},
|
|
1731
|
+
'.cm-comment[data-current="1"] > span': {
|
|
1732
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-current-surface)",
|
|
1733
|
+
backgroundColor: "var(--color-cm-comment-current-surface)"
|
|
2059
1734
|
}
|
|
2060
1735
|
});
|
|
2061
1736
|
var createCommentMark = (id, isCurrent) => Decoration7.mark({
|
|
2062
|
-
class:
|
|
1737
|
+
class: "cm-comment",
|
|
2063
1738
|
attributes: {
|
|
2064
1739
|
"data-testid": "cm-comment",
|
|
2065
|
-
"data-comment-id": id
|
|
1740
|
+
"data-comment-id": id,
|
|
1741
|
+
"data-current": isCurrent ? "1" : "0"
|
|
2066
1742
|
}
|
|
2067
1743
|
});
|
|
2068
|
-
var commentsDecorations =
|
|
1744
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
|
2069
1745
|
commentsState
|
|
2070
1746
|
], (state) => {
|
|
2071
1747
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
2072
1748
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2073
1749
|
const range = comment.range;
|
|
2074
1750
|
if (!range) {
|
|
2075
|
-
|
|
1751
|
+
log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
|
|
2076
1752
|
return void 0;
|
|
2077
1753
|
} else if (range.from === range.to) {
|
|
2078
1754
|
return void 0;
|
|
@@ -2082,8 +1758,8 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2082
1758
|
}).filter(isNonNullable);
|
|
2083
1759
|
return Decoration7.set(decorations2);
|
|
2084
1760
|
});
|
|
2085
|
-
var commentClickedEffect =
|
|
2086
|
-
var handleCommentClick =
|
|
1761
|
+
var commentClickedEffect = StateEffect3.define();
|
|
1762
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
|
2087
1763
|
click: (event, view) => {
|
|
2088
1764
|
let target = event.target;
|
|
2089
1765
|
const editorRoot = view.dom;
|
|
@@ -2122,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2122
1798
|
}
|
|
2123
1799
|
};
|
|
2124
1800
|
return [
|
|
2125
|
-
|
|
1801
|
+
EditorView9.domEventHandlers({
|
|
2126
1802
|
cut: handleTrack,
|
|
2127
1803
|
copy: handleTrack
|
|
2128
1804
|
}),
|
|
@@ -2144,7 +1820,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2144
1820
|
return effects;
|
|
2145
1821
|
}),
|
|
2146
1822
|
// Handle paste or the undo of comment deletion.
|
|
2147
|
-
|
|
1823
|
+
EditorView9.updateListener.of((update2) => {
|
|
2148
1824
|
const restore = [];
|
|
2149
1825
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
2150
1826
|
const tr = update2.transactions[i];
|
|
@@ -2200,7 +1876,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2200
1876
|
from: changes.mapPos(comment.from, 1),
|
|
2201
1877
|
to: changes.mapPos(comment.to, 1)
|
|
2202
1878
|
});
|
|
2203
|
-
var restoreCommentEffect =
|
|
1879
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
2204
1880
|
map: mapTrackedComment
|
|
2205
1881
|
});
|
|
2206
1882
|
var createComment = (view) => {
|
|
@@ -2286,7 +1962,7 @@ var comments = (options = {}) => {
|
|
|
2286
1962
|
//
|
|
2287
1963
|
// Track deleted ranges and update ranges for decorations.
|
|
2288
1964
|
//
|
|
2289
|
-
|
|
1965
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
|
2290
1966
|
let mod = false;
|
|
2291
1967
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
2292
1968
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -2318,7 +1994,7 @@ var comments = (options = {}) => {
|
|
|
2318
1994
|
//
|
|
2319
1995
|
// Track selection/proximity.
|
|
2320
1996
|
//
|
|
2321
|
-
|
|
1997
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
|
2322
1998
|
let min = Infinity;
|
|
2323
1999
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
2324
2000
|
const { head } = state.selection.main;
|
|
@@ -2354,34 +2030,41 @@ var comments = (options = {}) => {
|
|
|
2354
2030
|
options.onUpdate && trackPastedComments(options.onUpdate)
|
|
2355
2031
|
].filter(isNonNullable);
|
|
2356
2032
|
};
|
|
2357
|
-
var
|
|
2033
|
+
var isRangeVisible = (view, range) => {
|
|
2034
|
+
const from = view.coordsAtPos(range.from);
|
|
2035
|
+
const to = view.coordsAtPos(range.to);
|
|
2036
|
+
if (!from || !to) {
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
const { top, bottom } = view.scrollDOM.getBoundingClientRect();
|
|
2040
|
+
return from.top >= top && to.bottom <= bottom;
|
|
2041
|
+
};
|
|
2042
|
+
var scrollThreadIntoView = (view, id, { y = "center", yMargin } = {}) => {
|
|
2358
2043
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
2359
2044
|
if (!comment?.comment.cursor) {
|
|
2360
2045
|
return;
|
|
2361
2046
|
}
|
|
2362
2047
|
const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
|
|
2363
|
-
if (range) {
|
|
2364
|
-
|
|
2365
|
-
const currentScrollPosition = view.scrollDOM.scrollTop;
|
|
2366
|
-
const targetScrollPosition = view.coordsAtPos(range.from)?.top;
|
|
2367
|
-
const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
|
|
2368
|
-
const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
|
|
2369
|
-
if (needsScroll || needsSelectionUpdate) {
|
|
2370
|
-
view.dispatch({
|
|
2371
|
-
selection: needsSelectionUpdate ? {
|
|
2372
|
-
anchor: range.from
|
|
2373
|
-
} : void 0,
|
|
2374
|
-
effects: [
|
|
2375
|
-
needsScroll ? EditorView11.scrollIntoView(range.from, center ? {
|
|
2376
|
-
y: "center"
|
|
2377
|
-
} : void 0) : [],
|
|
2378
|
-
needsSelectionUpdate ? setSelection.of({
|
|
2379
|
-
current: id
|
|
2380
|
-
}) : []
|
|
2381
|
-
].flat()
|
|
2382
|
-
});
|
|
2383
|
-
}
|
|
2048
|
+
if (!range) {
|
|
2049
|
+
return;
|
|
2384
2050
|
}
|
|
2051
|
+
const { from, to } = view.state.selection.main;
|
|
2052
|
+
const needsSelectionUpdate = from !== range.from || to !== range.from;
|
|
2053
|
+
view.dispatch({
|
|
2054
|
+
selection: needsSelectionUpdate ? {
|
|
2055
|
+
anchor: range.from
|
|
2056
|
+
} : void 0,
|
|
2057
|
+
effects: [
|
|
2058
|
+
isRangeVisible(view, range) ? [] : EditorView9.scrollIntoView(range.from, {
|
|
2059
|
+
y,
|
|
2060
|
+
yMargin
|
|
2061
|
+
}),
|
|
2062
|
+
// Always mark this thread current so the highlight follows the selected thread.
|
|
2063
|
+
setSelection.of({
|
|
2064
|
+
current: id
|
|
2065
|
+
})
|
|
2066
|
+
].flat()
|
|
2067
|
+
});
|
|
2385
2068
|
};
|
|
2386
2069
|
var ExternalCommentSync = class {
|
|
2387
2070
|
unsubscribe;
|
|
@@ -2403,7 +2086,7 @@ var ExternalCommentSync = class {
|
|
|
2403
2086
|
this.unsubscribe();
|
|
2404
2087
|
};
|
|
2405
2088
|
};
|
|
2406
|
-
var createExternalCommentSync = (id, subscribe, getComments) =>
|
|
2089
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
|
|
2407
2090
|
constructor(view) {
|
|
2408
2091
|
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
2409
2092
|
}
|
|
@@ -2423,12 +2106,12 @@ var debugNodeLogger = (log12 = console.log) => {
|
|
|
2423
2106
|
};
|
|
2424
2107
|
|
|
2425
2108
|
// src/extensions/dnd.ts
|
|
2426
|
-
import { EditorView as
|
|
2109
|
+
import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
|
|
2427
2110
|
var dropFile = (options = {}) => {
|
|
2428
2111
|
return [
|
|
2429
2112
|
styles3,
|
|
2430
2113
|
dropCursor(),
|
|
2431
|
-
|
|
2114
|
+
EditorView10.domEventHandlers({
|
|
2432
2115
|
drop: (event, view) => {
|
|
2433
2116
|
event.preventDefault();
|
|
2434
2117
|
const files = event.dataTransfer?.files;
|
|
@@ -2447,7 +2130,7 @@ var dropFile = (options = {}) => {
|
|
|
2447
2130
|
})
|
|
2448
2131
|
];
|
|
2449
2132
|
};
|
|
2450
|
-
var styles3 =
|
|
2133
|
+
var styles3 = EditorView10.theme({
|
|
2451
2134
|
".cm-dropCursor": {
|
|
2452
2135
|
borderLeft: "2px solid var(--color-accent-text)",
|
|
2453
2136
|
color: "var(--color-accent-text)",
|
|
@@ -2464,15 +2147,15 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2464
2147
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2465
2148
|
import { searchKeymap } from "@codemirror/search";
|
|
2466
2149
|
import { EditorState } from "@codemirror/state";
|
|
2467
|
-
import { EditorView as
|
|
2150
|
+
import { EditorView as EditorView17, ViewPlugin as ViewPlugin13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2468
2151
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2469
2152
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2470
2153
|
import { generateName } from "@dxos/display-name";
|
|
2471
2154
|
import { log as log8 } from "@dxos/log";
|
|
2472
|
-
import { hexToHue, isTruthy as
|
|
2155
|
+
import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
|
|
2473
2156
|
|
|
2474
2157
|
// src/styles/theme.ts
|
|
2475
|
-
import { EditorView as
|
|
2158
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2476
2159
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2477
2160
|
var headings = {
|
|
2478
2161
|
1: {
|
|
@@ -2520,7 +2203,7 @@ var markdownTheme = {
|
|
|
2520
2203
|
fontWeight: "100 !important"
|
|
2521
2204
|
})
|
|
2522
2205
|
};
|
|
2523
|
-
var baseTheme =
|
|
2206
|
+
var baseTheme = EditorView11.baseTheme({
|
|
2524
2207
|
/**
|
|
2525
2208
|
* Outer frame.
|
|
2526
2209
|
*/
|
|
@@ -2532,7 +2215,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2532
2215
|
* Scroller
|
|
2533
2216
|
*/
|
|
2534
2217
|
".cm-scroller": {
|
|
2535
|
-
// Browser scroll-anchoring: see comment in `
|
|
2218
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
2536
2219
|
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2537
2220
|
// open/close) don't jump the user's view.
|
|
2538
2221
|
overflowAnchor: "auto"
|
|
@@ -2643,7 +2326,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2643
2326
|
textDecorationThickness: "1px",
|
|
2644
2327
|
textDecorationColor: "var(--color-separator)",
|
|
2645
2328
|
textUnderlineOffset: "2px",
|
|
2646
|
-
borderRadius: ".125rem"
|
|
2329
|
+
borderRadius: ".125rem",
|
|
2330
|
+
cursor: "pointer"
|
|
2647
2331
|
},
|
|
2648
2332
|
".cm-link > span": {
|
|
2649
2333
|
color: "var(--color-accent-text)"
|
|
@@ -2681,12 +2365,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2681
2365
|
padding: "4px"
|
|
2682
2366
|
},
|
|
2683
2367
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2684
|
-
background: "var(--color-
|
|
2685
|
-
color: "var(--color-base-
|
|
2368
|
+
background: "var(--color-current-surface)",
|
|
2369
|
+
color: "var(--color-base-fg)"
|
|
2686
2370
|
},
|
|
2687
2371
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2688
2372
|
paddingLeft: "4px !important",
|
|
2689
|
-
color: "var(--color-base-
|
|
2373
|
+
color: "var(--color-base-fg)"
|
|
2690
2374
|
},
|
|
2691
2375
|
/**
|
|
2692
2376
|
* Completion info.
|
|
@@ -2705,7 +2389,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2705
2389
|
padding: "0 4px"
|
|
2706
2390
|
},
|
|
2707
2391
|
".cm-completionMatchedText": {
|
|
2708
|
-
color: "var(--color-base-
|
|
2392
|
+
color: "var(--color-base-fg)",
|
|
2709
2393
|
textDecoration: "none !important"
|
|
2710
2394
|
},
|
|
2711
2395
|
/**
|
|
@@ -2740,7 +2424,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2740
2424
|
backgroundColor: "var(--color-input-surface)"
|
|
2741
2425
|
},
|
|
2742
2426
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2743
|
-
outline: "1px solid var(--color-
|
|
2427
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2744
2428
|
},
|
|
2745
2429
|
".cm-panel label": {
|
|
2746
2430
|
display: "inline-flex",
|
|
@@ -2753,15 +2437,15 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2753
2437
|
height: "8px",
|
|
2754
2438
|
marginRight: "6px !important",
|
|
2755
2439
|
padding: "2px !important",
|
|
2756
|
-
color: "var(--color-
|
|
2440
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2757
2441
|
},
|
|
2758
2442
|
".cm-panel button": {
|
|
2759
2443
|
"&:hover": {
|
|
2760
|
-
// TODO(burdon): Replace with layer and @apply bg-accent-
|
|
2761
|
-
backgroundColor: "var(--color-accent-
|
|
2444
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-bg-hover
|
|
2445
|
+
backgroundColor: "var(--color-accent-bg-hover) !important"
|
|
2762
2446
|
},
|
|
2763
2447
|
"&:active": {
|
|
2764
|
-
backgroundColor: "var(--color-accent-
|
|
2448
|
+
backgroundColor: "var(--color-accent-bg-hover)"
|
|
2765
2449
|
}
|
|
2766
2450
|
},
|
|
2767
2451
|
".cm-panel.cm-search": {
|
|
@@ -2769,14 +2453,14 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2769
2453
|
borderTop: "1px solid var(--color-separator)"
|
|
2770
2454
|
}
|
|
2771
2455
|
});
|
|
2772
|
-
var editorGutter =
|
|
2456
|
+
var editorGutter = EditorView11.theme({
|
|
2773
2457
|
".cm-gutters": {
|
|
2774
2458
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2775
2459
|
background: "var(--color-base-surface) !important",
|
|
2776
2460
|
paddingRight: "1rem"
|
|
2777
2461
|
}
|
|
2778
2462
|
});
|
|
2779
|
-
var createFontTheme = ({ monospace } = {}) =>
|
|
2463
|
+
var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
|
|
2780
2464
|
// Main content.
|
|
2781
2465
|
".cm-scroller": {
|
|
2782
2466
|
fontFamily: monospace ? fontMono : fontBody
|
|
@@ -2789,9 +2473,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2789
2473
|
});
|
|
2790
2474
|
|
|
2791
2475
|
// src/extensions/focus.ts
|
|
2792
|
-
import { StateEffect as
|
|
2793
|
-
import { EditorView as
|
|
2794
|
-
var focusEffect =
|
|
2476
|
+
import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
|
|
2477
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
|
2478
|
+
var focusEffect = StateEffect4.define();
|
|
2795
2479
|
var focusField = StateField5.define({
|
|
2796
2480
|
create: () => false,
|
|
2797
2481
|
update: (value, tr) => {
|
|
@@ -2800,38 +2484,422 @@ var focusField = StateField5.define({
|
|
|
2800
2484
|
return effect.value;
|
|
2801
2485
|
}
|
|
2802
2486
|
}
|
|
2803
|
-
return value;
|
|
2487
|
+
return value;
|
|
2488
|
+
}
|
|
2489
|
+
});
|
|
2490
|
+
var focus = [
|
|
2491
|
+
focusField,
|
|
2492
|
+
EditorView12.domEventHandlers({
|
|
2493
|
+
focus: (_event, view) => {
|
|
2494
|
+
requestAnimationFrame(() => view.dispatch({
|
|
2495
|
+
effects: focusEffect.of(true)
|
|
2496
|
+
}));
|
|
2497
|
+
},
|
|
2498
|
+
blur: (_event, view) => {
|
|
2499
|
+
requestAnimationFrame(() => view.dispatch({
|
|
2500
|
+
effects: focusEffect.of(false)
|
|
2501
|
+
}));
|
|
2502
|
+
}
|
|
2503
|
+
})
|
|
2504
|
+
];
|
|
2505
|
+
|
|
2506
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2507
|
+
import { StateEffect as StateEffect6 } from "@codemirror/state";
|
|
2508
|
+
import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
|
|
2509
|
+
import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
|
|
2510
|
+
import { Domino } from "@dxos/ui";
|
|
2511
|
+
import { getSize } from "@dxos/ui-theme";
|
|
2512
|
+
|
|
2513
|
+
// src/extensions/scrolling/crawler.ts
|
|
2514
|
+
import { StateEffect as StateEffect5 } from "@codemirror/state";
|
|
2515
|
+
import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
|
|
2516
|
+
import { log as log7 } from "@dxos/log";
|
|
2517
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
|
|
2518
|
+
var crawlerLineEffect = StateEffect5.define();
|
|
2519
|
+
var crawlerActiveEffect = StateEffect5.define();
|
|
2520
|
+
var scrollToLine = (view, options) => {
|
|
2521
|
+
view.dispatch({
|
|
2522
|
+
effects: crawlerLineEffect.of(options)
|
|
2523
|
+
});
|
|
2524
|
+
};
|
|
2525
|
+
var crawler = ({ overScroll = 0 } = {}) => {
|
|
2526
|
+
const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
|
|
2527
|
+
view;
|
|
2528
|
+
crawler;
|
|
2529
|
+
constructor(view) {
|
|
2530
|
+
this.view = view;
|
|
2531
|
+
this.crawler = createCrawler(this.view);
|
|
2532
|
+
}
|
|
2533
|
+
// No-op.
|
|
2534
|
+
destroy() {
|
|
2535
|
+
this.crawler.cancel();
|
|
2536
|
+
}
|
|
2537
|
+
cancel() {
|
|
2538
|
+
this.crawler.cancel();
|
|
2539
|
+
}
|
|
2540
|
+
crawl({ active, instant } = {
|
|
2541
|
+
active: false
|
|
2542
|
+
}) {
|
|
2543
|
+
if (active) {
|
|
2544
|
+
this.crawler.scroll(instant);
|
|
2545
|
+
} else {
|
|
2546
|
+
this.crawler.cancel();
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
2550
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
2551
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
2552
|
+
const doc = this.view.state.doc;
|
|
2553
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
2554
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
2555
|
+
const lineStart = doc.line(line + 1).from;
|
|
2556
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
2557
|
+
if (coords) {
|
|
2558
|
+
const currentScrollTop = scrollTop;
|
|
2559
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
2560
|
+
if (position === "end") {
|
|
2561
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
2562
|
+
} else {
|
|
2563
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
2564
|
+
}
|
|
2565
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
requestAnimationFrame(() => {
|
|
2569
|
+
this.view.scrollDOM.scrollTo({
|
|
2570
|
+
top: targetScrollTop
|
|
2571
|
+
});
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2575
|
+
return [
|
|
2576
|
+
crawlerPlugin,
|
|
2577
|
+
// Listen for effect.
|
|
2578
|
+
EditorView13.updateListener.of((update2) => {
|
|
2579
|
+
update2.transactions.forEach((transaction) => {
|
|
2580
|
+
try {
|
|
2581
|
+
const plugin = update2.view.plugin(crawlerPlugin);
|
|
2582
|
+
if (plugin) {
|
|
2583
|
+
for (const effect of transaction.effects) {
|
|
2584
|
+
if (effect.is(crawlerActiveEffect)) {
|
|
2585
|
+
plugin.crawl(effect.value);
|
|
2586
|
+
} else if (effect.is(crawlerLineEffect)) {
|
|
2587
|
+
plugin.scroll(effect.value);
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
} catch (err) {
|
|
2592
|
+
log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 105, S: void 0 });
|
|
2593
|
+
}
|
|
2594
|
+
});
|
|
2595
|
+
}),
|
|
2596
|
+
// Styles.
|
|
2597
|
+
EditorView13.theme({
|
|
2598
|
+
".cm-scroller": {
|
|
2599
|
+
overflowY: "scroll",
|
|
2600
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
2601
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
2602
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
2603
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
2604
|
+
overflowAnchor: "auto"
|
|
2605
|
+
},
|
|
2606
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
2607
|
+
display: "none"
|
|
2608
|
+
},
|
|
2609
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2610
|
+
background: "transparent",
|
|
2611
|
+
transition: "background 0.15s"
|
|
2612
|
+
},
|
|
2613
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2614
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2615
|
+
},
|
|
2616
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
2617
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
2618
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
2619
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
2620
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
2621
|
+
".cm-content::after": {
|
|
2622
|
+
content: '""',
|
|
2623
|
+
display: "block",
|
|
2624
|
+
height: `${overScroll}px`
|
|
2625
|
+
},
|
|
2626
|
+
".cm-scroll-button": {
|
|
2627
|
+
position: "absolute",
|
|
2628
|
+
bottom: "0.5rem",
|
|
2629
|
+
right: "1rem"
|
|
2630
|
+
}
|
|
2631
|
+
})
|
|
2632
|
+
];
|
|
2633
|
+
};
|
|
2634
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
2635
|
+
const el = view.scrollDOM;
|
|
2636
|
+
let currentTop = 0;
|
|
2637
|
+
let velocity = 0;
|
|
2638
|
+
let rafId = null;
|
|
2639
|
+
let lastTime = 0;
|
|
2640
|
+
let instant = false;
|
|
2641
|
+
function frame(now) {
|
|
2642
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
2643
|
+
lastTime = now;
|
|
2644
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
2645
|
+
const delta = targetTop - currentTop;
|
|
2646
|
+
if (instant) {
|
|
2647
|
+
el.scrollTop = targetTop;
|
|
2648
|
+
currentTop = targetTop;
|
|
2649
|
+
velocity = 0;
|
|
2650
|
+
if (Math.abs(delta) < snapThreshold) {
|
|
2651
|
+
rafId = null;
|
|
2652
|
+
lastTime = 0;
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
rafId = requestAnimationFrame(frame);
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
2659
|
+
el.scrollTop = targetTop;
|
|
2660
|
+
currentTop = targetTop;
|
|
2661
|
+
velocity = 0;
|
|
2662
|
+
rafId = null;
|
|
2663
|
+
lastTime = 0;
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
2667
|
+
velocity += accel * dt;
|
|
2668
|
+
currentTop += velocity * dt;
|
|
2669
|
+
el.scrollTop = currentTop;
|
|
2670
|
+
rafId = requestAnimationFrame(frame);
|
|
2804
2671
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
}
|
|
2672
|
+
return {
|
|
2673
|
+
scroll: (useInstant = false) => {
|
|
2674
|
+
instant = useInstant;
|
|
2675
|
+
if (rafId === null) {
|
|
2676
|
+
currentTop = el.scrollTop;
|
|
2677
|
+
lastTime = 0;
|
|
2678
|
+
rafId = requestAnimationFrame(frame);
|
|
2679
|
+
}
|
|
2813
2680
|
},
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2681
|
+
cancel: () => {
|
|
2682
|
+
if (rafId !== null) {
|
|
2683
|
+
cancelAnimationFrame(rafId);
|
|
2684
|
+
velocity = 0;
|
|
2685
|
+
lastTime = 0;
|
|
2686
|
+
rafId = null;
|
|
2687
|
+
}
|
|
2818
2688
|
}
|
|
2819
|
-
}
|
|
2820
|
-
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2693
|
+
var autoScrollEffect = StateEffect6.define();
|
|
2694
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
2695
|
+
let buttonContainer;
|
|
2696
|
+
let isPinned = true;
|
|
2697
|
+
let jumpPending = false;
|
|
2698
|
+
let enabled = true;
|
|
2699
|
+
let firstUpdate = true;
|
|
2700
|
+
let streamed = false;
|
|
2701
|
+
const setPinned = (pinned) => {
|
|
2702
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
2703
|
+
isPinned = pinned;
|
|
2704
|
+
};
|
|
2705
|
+
return [
|
|
2706
|
+
// Update listener for scrolling when content changes.
|
|
2707
|
+
EditorView14.updateListener.of((update2) => {
|
|
2708
|
+
const { view, heightChanged, state, startState } = update2;
|
|
2709
|
+
for (const tr of update2.transactions) {
|
|
2710
|
+
for (const effect of tr.effects) {
|
|
2711
|
+
if (effect.is(autoScrollEffect)) {
|
|
2712
|
+
enabled = effect.value;
|
|
2713
|
+
if (enabled) {
|
|
2714
|
+
setPinned(true);
|
|
2715
|
+
view.dispatch({
|
|
2716
|
+
effects: crawlerActiveEffect.of({
|
|
2717
|
+
active: true
|
|
2718
|
+
})
|
|
2719
|
+
});
|
|
2720
|
+
} else {
|
|
2721
|
+
view.dispatch({
|
|
2722
|
+
effects: crawlerActiveEffect.of({
|
|
2723
|
+
active: false
|
|
2724
|
+
})
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
if (!enabled) {
|
|
2731
|
+
return;
|
|
2732
|
+
}
|
|
2733
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
2734
|
+
firstUpdate = false;
|
|
2735
|
+
jumpPending = true;
|
|
2736
|
+
requestAnimationFrame(() => {
|
|
2737
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
2738
|
+
jumpPending = false;
|
|
2739
|
+
});
|
|
2740
|
+
return;
|
|
2741
|
+
}
|
|
2742
|
+
firstUpdate = false;
|
|
2743
|
+
if (jumpPending) {
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
if (heightChanged) {
|
|
2747
|
+
if (isPinned) {
|
|
2748
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2749
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2750
|
+
if (update2.docChanged) {
|
|
2751
|
+
streamed = true;
|
|
2752
|
+
}
|
|
2753
|
+
if (delta > 0) {
|
|
2754
|
+
setPinned(true);
|
|
2755
|
+
view.dispatch({
|
|
2756
|
+
effects: crawlerActiveEffect.of({
|
|
2757
|
+
active: true,
|
|
2758
|
+
instant: !streamed
|
|
2759
|
+
})
|
|
2760
|
+
});
|
|
2761
|
+
} else if (delta < -1) {
|
|
2762
|
+
setPinned(false);
|
|
2763
|
+
}
|
|
2764
|
+
} else {
|
|
2765
|
+
if (state.doc.length === 0) {
|
|
2766
|
+
setPinned(true);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
}),
|
|
2771
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
2772
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
2773
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
2774
|
+
scrollOnResize ? ViewPlugin10.fromClass(class {
|
|
2775
|
+
observer;
|
|
2776
|
+
firstObservation = true;
|
|
2777
|
+
destroyed = false;
|
|
2778
|
+
constructor(view) {
|
|
2779
|
+
const onResize = throttle2(() => {
|
|
2780
|
+
if (this.destroyed || !enabled) {
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
setPinned(true);
|
|
2784
|
+
requestAnimationFrame(() => {
|
|
2785
|
+
if (this.destroyed) {
|
|
2786
|
+
return;
|
|
2787
|
+
}
|
|
2788
|
+
view.scrollDOM.scrollTo({
|
|
2789
|
+
top: view.scrollDOM.scrollHeight,
|
|
2790
|
+
behavior: "instant"
|
|
2791
|
+
});
|
|
2792
|
+
view.dispatch({
|
|
2793
|
+
effects: crawlerActiveEffect.of({
|
|
2794
|
+
active: false
|
|
2795
|
+
})
|
|
2796
|
+
});
|
|
2797
|
+
});
|
|
2798
|
+
}, 50);
|
|
2799
|
+
this.observer = new ResizeObserver(() => {
|
|
2800
|
+
if (this.firstObservation) {
|
|
2801
|
+
this.firstObservation = false;
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
onResize();
|
|
2805
|
+
});
|
|
2806
|
+
this.observer.observe(view.scrollDOM);
|
|
2807
|
+
}
|
|
2808
|
+
destroy() {
|
|
2809
|
+
this.destroyed = true;
|
|
2810
|
+
this.observer.disconnect();
|
|
2811
|
+
}
|
|
2812
|
+
}) : [],
|
|
2813
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
2814
|
+
ViewPlugin10.fromClass(class {
|
|
2815
|
+
cleanup;
|
|
2816
|
+
constructor(view) {
|
|
2817
|
+
const onUserScroll = throttle2(() => {
|
|
2818
|
+
requestAnimationFrame(() => {
|
|
2819
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2820
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2821
|
+
const pinned = Math.abs(delta) <= 1;
|
|
2822
|
+
setPinned(pinned);
|
|
2823
|
+
if (!pinned) {
|
|
2824
|
+
view.dispatch({
|
|
2825
|
+
effects: crawlerActiveEffect.of({
|
|
2826
|
+
active: false
|
|
2827
|
+
})
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
});
|
|
2831
|
+
}, 500);
|
|
2832
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
2833
|
+
if (isPinned) {
|
|
2834
|
+
setPinned(false);
|
|
2835
|
+
view.dispatch({
|
|
2836
|
+
effects: crawlerActiveEffect.of({
|
|
2837
|
+
active: false
|
|
2838
|
+
})
|
|
2839
|
+
});
|
|
2840
|
+
}
|
|
2841
|
+
onUserScroll();
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
destroy() {
|
|
2845
|
+
this.cleanup();
|
|
2846
|
+
}
|
|
2847
|
+
}),
|
|
2848
|
+
// Scroll button.
|
|
2849
|
+
ViewPlugin10.fromClass(class {
|
|
2850
|
+
constructor(view) {
|
|
2851
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
2852
|
+
icon: "ph--arrow-down--regular"
|
|
2853
|
+
});
|
|
2854
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-bg").attributes({
|
|
2855
|
+
"data-density": "md"
|
|
2856
|
+
}).append(icon).on("click", () => {
|
|
2857
|
+
setPinned(true);
|
|
2858
|
+
view.dispatch({
|
|
2859
|
+
effects: [
|
|
2860
|
+
crawlerLineEffect.of({
|
|
2861
|
+
line: -1,
|
|
2862
|
+
position: "end",
|
|
2863
|
+
behavior: "smooth"
|
|
2864
|
+
}),
|
|
2865
|
+
// Re-engage the follower so it keeps tracking the bottom as content continues
|
|
2866
|
+
// to stream after the catch-up jump.
|
|
2867
|
+
crawlerActiveEffect.of({
|
|
2868
|
+
active: true,
|
|
2869
|
+
instant: !streamed
|
|
2870
|
+
})
|
|
2871
|
+
]
|
|
2872
|
+
});
|
|
2873
|
+
});
|
|
2874
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0 z-1").append(button).root;
|
|
2875
|
+
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
2876
|
+
}
|
|
2877
|
+
})
|
|
2878
|
+
];
|
|
2879
|
+
};
|
|
2880
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
2881
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
2882
|
+
passive: true
|
|
2883
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
2884
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
2885
|
+
onUserScroll();
|
|
2886
|
+
}
|
|
2887
|
+
}));
|
|
2888
|
+
}
|
|
2821
2889
|
|
|
2822
|
-
// src/extensions/scroll-past-end.ts
|
|
2890
|
+
// src/extensions/scrolling/scroll-past-end.ts
|
|
2823
2891
|
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2824
2892
|
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
style:
|
|
2893
|
+
_height = 1e3;
|
|
2894
|
+
_attrs = {
|
|
2895
|
+
style: `padding-bottom: ${this._height}px`
|
|
2828
2896
|
};
|
|
2829
2897
|
update({ view }) {
|
|
2830
2898
|
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2831
2899
|
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2832
|
-
if (height >= 0 && height !== this.
|
|
2833
|
-
this.
|
|
2834
|
-
this.
|
|
2900
|
+
if (height >= 0 && height !== this._height) {
|
|
2901
|
+
this._height = height;
|
|
2902
|
+
this._attrs = {
|
|
2835
2903
|
style: `padding-bottom: ${height}px`
|
|
2836
2904
|
};
|
|
2837
2905
|
}
|
|
@@ -2839,12 +2907,68 @@ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
|
2839
2907
|
});
|
|
2840
2908
|
var scrollPastEnd = () => [
|
|
2841
2909
|
scrollPastEndPlugin,
|
|
2842
|
-
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.
|
|
2910
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
|
|
2911
|
+
];
|
|
2912
|
+
|
|
2913
|
+
// src/extensions/scrolling/scrollbar-autohide.ts
|
|
2914
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12 } from "@codemirror/view";
|
|
2915
|
+
var scrollbarAutohide = ({ timeout = 800 } = {}) => [
|
|
2916
|
+
ViewPlugin12.fromClass(
|
|
2917
|
+
// NOTE: Uses TS `private`/plain fields rather than ES `#private`. CodeMirror's plugin lifecycle
|
|
2918
|
+
// (and the source/prebundled double-load in dev) can invoke `destroy` with a `this` that the
|
|
2919
|
+
// WeakMap-based `#private` transpilation rejects ("private field on non-instance"), crashing
|
|
2920
|
+
// editor teardown. Plain fields avoid the membership check.
|
|
2921
|
+
class {
|
|
2922
|
+
_scroller;
|
|
2923
|
+
_timer;
|
|
2924
|
+
constructor(view) {
|
|
2925
|
+
this._scroller = view.scrollDOM;
|
|
2926
|
+
this._scroller.addEventListener("scroll", this._handleScroll, {
|
|
2927
|
+
passive: true
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
destroy() {
|
|
2931
|
+
this._scroller.removeEventListener("scroll", this._handleScroll);
|
|
2932
|
+
clearTimeout(this._timer);
|
|
2933
|
+
this._scroller.classList.remove("cm-scrolling");
|
|
2934
|
+
}
|
|
2935
|
+
// Show the thumb while scrolling; remove the class once scrolling has been idle for `timeout`.
|
|
2936
|
+
_handleScroll = () => {
|
|
2937
|
+
this._scroller.classList.add("cm-scrolling");
|
|
2938
|
+
clearTimeout(this._timer);
|
|
2939
|
+
this._timer = setTimeout(() => this._scroller.classList.remove("cm-scrolling"), timeout);
|
|
2940
|
+
};
|
|
2941
|
+
}
|
|
2942
|
+
),
|
|
2943
|
+
EditorView16.theme({
|
|
2944
|
+
// Reveal the thumb only while actively scrolling.
|
|
2945
|
+
".cm-scroller.cm-scrolling::-webkit-scrollbar-thumb": {
|
|
2946
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2947
|
+
},
|
|
2948
|
+
// Suppress the base theme's hover-reveal (higher specificity via `:not(.cm-scrolling)`), so a
|
|
2949
|
+
// hovered/focused-but-idle editor keeps the thumb hidden.
|
|
2950
|
+
"&:hover .cm-scroller:not(.cm-scrolling)::-webkit-scrollbar-thumb": {
|
|
2951
|
+
background: "transparent"
|
|
2952
|
+
}
|
|
2953
|
+
})
|
|
2843
2954
|
];
|
|
2844
2955
|
|
|
2956
|
+
// src/extensions/scrolling/scroller.ts
|
|
2957
|
+
import { isTruthy as isTruthy2 } from "@dxos/util";
|
|
2958
|
+
var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
|
|
2959
|
+
return [
|
|
2960
|
+
crawler({
|
|
2961
|
+
overScroll
|
|
2962
|
+
}),
|
|
2963
|
+
autoScroll2 && autoScroll({
|
|
2964
|
+
scrollOnResize
|
|
2965
|
+
})
|
|
2966
|
+
].filter(isTruthy2);
|
|
2967
|
+
};
|
|
2968
|
+
|
|
2845
2969
|
// src/extensions/factories.ts
|
|
2846
2970
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2847
|
-
var tabbable =
|
|
2971
|
+
var tabbable = EditorView17.contentAttributes.of({
|
|
2848
2972
|
tabindex: "0"
|
|
2849
2973
|
});
|
|
2850
2974
|
var filterChars = (chars) => {
|
|
@@ -2897,7 +3021,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2897
3021
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2898
3022
|
return [
|
|
2899
3023
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2900
|
-
|
|
3024
|
+
EditorView17.exceptionSink.of((err) => {
|
|
2901
3025
|
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2902
3026
|
}),
|
|
2903
3027
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
@@ -2907,7 +3031,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2907
3031
|
props.drawSelection && drawSelection({
|
|
2908
3032
|
cursorBlinkRate: 1200
|
|
2909
3033
|
}),
|
|
2910
|
-
props.editable !== void 0 &&
|
|
3034
|
+
props.editable !== void 0 && EditorView17.editable.of(props.editable),
|
|
2911
3035
|
props.focus && focus,
|
|
2912
3036
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2913
3037
|
props.history && history(),
|
|
@@ -2915,7 +3039,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2915
3039
|
lineNumbers(),
|
|
2916
3040
|
editorGutter
|
|
2917
3041
|
],
|
|
2918
|
-
props.lineWrapping &&
|
|
3042
|
+
props.lineWrapping && EditorView17.lineWrapping,
|
|
2919
3043
|
props.placeholder && placeholder2(props.placeholder),
|
|
2920
3044
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2921
3045
|
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
@@ -2949,8 +3073,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2949
3073
|
preventDefault: true,
|
|
2950
3074
|
run: () => true
|
|
2951
3075
|
}
|
|
2952
|
-
].filter(
|
|
2953
|
-
].filter(
|
|
3076
|
+
].filter(isTruthy3))
|
|
3077
|
+
].filter(isTruthy3);
|
|
2954
3078
|
};
|
|
2955
3079
|
var grow = {
|
|
2956
3080
|
editor: {
|
|
@@ -2971,18 +3095,18 @@ var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, synta
|
|
|
2971
3095
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2972
3096
|
return [
|
|
2973
3097
|
baseTheme,
|
|
2974
|
-
|
|
3098
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
2975
3099
|
createFontTheme({
|
|
2976
3100
|
monospace
|
|
2977
3101
|
}),
|
|
2978
3102
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2979
|
-
slots.editor?.className &&
|
|
3103
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
2980
3104
|
class: slots.editor.className
|
|
2981
3105
|
}),
|
|
2982
|
-
slots.content?.className &&
|
|
3106
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
2983
3107
|
class: slots.content.className
|
|
2984
3108
|
}),
|
|
2985
|
-
(slots.scroller?.className || scrollbarThin) &&
|
|
3109
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin13.fromClass(class {
|
|
2986
3110
|
constructor(view) {
|
|
2987
3111
|
if (slots.scroller?.className) {
|
|
2988
3112
|
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
@@ -2992,7 +3116,7 @@ var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, synta
|
|
|
2992
3116
|
}
|
|
2993
3117
|
}
|
|
2994
3118
|
})
|
|
2995
|
-
].filter(
|
|
3119
|
+
].filter(isTruthy3);
|
|
2996
3120
|
};
|
|
2997
3121
|
var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
2998
3122
|
const extensions = [];
|
|
@@ -3018,7 +3142,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
3018
3142
|
|
|
3019
3143
|
// src/extensions/folding.ts
|
|
3020
3144
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
3021
|
-
import { EditorView as
|
|
3145
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
3022
3146
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
3023
3147
|
var folding = () => {
|
|
3024
3148
|
return [
|
|
@@ -3033,7 +3157,7 @@ var folding = () => {
|
|
|
3033
3157
|
}))).root;
|
|
3034
3158
|
}
|
|
3035
3159
|
}),
|
|
3036
|
-
|
|
3160
|
+
EditorView18.theme({
|
|
3037
3161
|
".cm-foldGutter": {
|
|
3038
3162
|
opacity: 0.3,
|
|
3039
3163
|
transition: "opacity 0.3s",
|
|
@@ -3047,7 +3171,7 @@ var folding = () => {
|
|
|
3047
3171
|
};
|
|
3048
3172
|
|
|
3049
3173
|
// src/extensions/hashtag.ts
|
|
3050
|
-
import { Decoration as Decoration8, EditorView as
|
|
3174
|
+
import { Decoration as Decoration8, EditorView as EditorView19, MatchDecorator, ViewPlugin as ViewPlugin14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3051
3175
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3052
3176
|
var TagWidget = class extends WidgetType4 {
|
|
3053
3177
|
_text;
|
|
@@ -3068,7 +3192,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3068
3192
|
})
|
|
3069
3193
|
});
|
|
3070
3194
|
var hashtag = () => [
|
|
3071
|
-
|
|
3195
|
+
ViewPlugin14.fromClass(class {
|
|
3072
3196
|
tags;
|
|
3073
3197
|
constructor(view) {
|
|
3074
3198
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3078,11 +3202,11 @@ var hashtag = () => [
|
|
|
3078
3202
|
}
|
|
3079
3203
|
}, {
|
|
3080
3204
|
decorations: (instance) => instance.tags,
|
|
3081
|
-
provide: (plugin) =>
|
|
3205
|
+
provide: (plugin) => EditorView19.atomicRanges.of((view) => {
|
|
3082
3206
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3083
3207
|
})
|
|
3084
3208
|
}),
|
|
3085
|
-
|
|
3209
|
+
EditorView19.theme({
|
|
3086
3210
|
".cm-tag": {
|
|
3087
3211
|
borderRadius: "4px",
|
|
3088
3212
|
marginRight: "6px",
|
|
@@ -3137,18 +3261,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3137
3261
|
};
|
|
3138
3262
|
|
|
3139
3263
|
// src/extensions/listener.ts
|
|
3140
|
-
import { EditorView as
|
|
3264
|
+
import { EditorView as EditorView20 } from "@codemirror/view";
|
|
3141
3265
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3142
3266
|
var listener = ({ onFocus, onChange }) => {
|
|
3143
3267
|
return [
|
|
3144
|
-
onFocus &&
|
|
3268
|
+
onFocus && EditorView20.focusChangeEffect.of((state, focusing) => {
|
|
3145
3269
|
onFocus({
|
|
3146
3270
|
id: state.facet(documentId),
|
|
3147
3271
|
focusing
|
|
3148
3272
|
});
|
|
3149
3273
|
return null;
|
|
3150
3274
|
}),
|
|
3151
|
-
onChange &&
|
|
3275
|
+
onChange && EditorView20.updateListener.of(({ state, docChanged }) => {
|
|
3152
3276
|
if (docChanged) {
|
|
3153
3277
|
onChange({
|
|
3154
3278
|
id: state.facet(documentId),
|
|
@@ -3163,7 +3287,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3163
3287
|
import { snippet } from "@codemirror/autocomplete";
|
|
3164
3288
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3165
3289
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3166
|
-
import { EditorView as
|
|
3290
|
+
import { EditorView as EditorView21, keymap as keymap8 } from "@codemirror/view";
|
|
3167
3291
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3168
3292
|
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;
|
|
3169
3293
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4252,7 +4376,7 @@ var getFormatting = (state) => {
|
|
|
4252
4376
|
};
|
|
4253
4377
|
};
|
|
4254
4378
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4255
|
-
return
|
|
4379
|
+
return EditorView21.updateListener.of(debounceAndThrottle((update2) => {
|
|
4256
4380
|
if (update2.docChanged || update2.selectionSet) {
|
|
4257
4381
|
onStateChange(getFormatting(update2.state));
|
|
4258
4382
|
}
|
|
@@ -4316,7 +4440,7 @@ import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lan
|
|
|
4316
4440
|
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4317
4441
|
import { languages } from "@codemirror/language-data";
|
|
4318
4442
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4319
|
-
import { isTruthy as
|
|
4443
|
+
import { isTruthy as isTruthy4 } from "@dxos/util";
|
|
4320
4444
|
|
|
4321
4445
|
// src/extensions/markdown/highlight.ts
|
|
4322
4446
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -4548,7 +4672,7 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4548
4672
|
...defaultKeymap2,
|
|
4549
4673
|
// TODO(burdon): Remove?
|
|
4550
4674
|
...completionKeymap
|
|
4551
|
-
].filter(
|
|
4675
|
+
].filter(isTruthy4))
|
|
4552
4676
|
];
|
|
4553
4677
|
};
|
|
4554
4678
|
var noFencedCodeFolding = {
|
|
@@ -4598,16 +4722,16 @@ var convertTreeToJson = (state) => {
|
|
|
4598
4722
|
|
|
4599
4723
|
// src/extensions/markdown/decorate.ts
|
|
4600
4724
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4601
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4602
|
-
import { Decoration as Decoration11, EditorView as
|
|
4725
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect8 } from "@codemirror/state";
|
|
4726
|
+
import { Decoration as Decoration11, EditorView as EditorView25, ViewPlugin as ViewPlugin17, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4603
4727
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4604
4728
|
|
|
4605
4729
|
// src/extensions/markdown/changes.ts
|
|
4606
4730
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4607
4731
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4608
|
-
import { ViewPlugin as
|
|
4732
|
+
import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
|
|
4609
4733
|
var adjustChanges = () => {
|
|
4610
|
-
return
|
|
4734
|
+
return ViewPlugin15.fromClass(class {
|
|
4611
4735
|
update(update2) {
|
|
4612
4736
|
const tree = syntaxTree4(update2.state);
|
|
4613
4737
|
const adjustments = [];
|
|
@@ -4748,15 +4872,19 @@ var getValidUrl = (str) => {
|
|
|
4748
4872
|
|
|
4749
4873
|
// src/extensions/markdown/image.ts
|
|
4750
4874
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4751
|
-
import { StateField as StateField7 } from "@codemirror/state";
|
|
4752
|
-
import { Decoration as Decoration9, EditorView as
|
|
4753
|
-
var
|
|
4875
|
+
import { StateEffect as StateEffect7, StateField as StateField7 } from "@codemirror/state";
|
|
4876
|
+
import { Decoration as Decoration9, EditorView as EditorView22, ViewPlugin as ViewPlugin16, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4877
|
+
var rebuildEffect = StateEffect7.define();
|
|
4878
|
+
var image = (options = {}) => {
|
|
4754
4879
|
return [
|
|
4755
4880
|
StateField7.define({
|
|
4756
4881
|
create: (state) => {
|
|
4757
|
-
return Decoration9.set(buildDecorations(state, 0, state.doc.length));
|
|
4882
|
+
return Decoration9.set(buildDecorations(state, 0, state.doc.length, options));
|
|
4758
4883
|
},
|
|
4759
4884
|
update: (value, tr) => {
|
|
4885
|
+
if (tr.effects.some((effect) => effect.is(rebuildEffect))) {
|
|
4886
|
+
return Decoration9.set(buildDecorations(tr.state, 0, tr.state.doc.length, options));
|
|
4887
|
+
}
|
|
4760
4888
|
if (!tr.docChanged && !tr.selection) {
|
|
4761
4889
|
return value;
|
|
4762
4890
|
}
|
|
@@ -4774,14 +4902,26 @@ var image = (_options = {}) => {
|
|
|
4774
4902
|
filterFrom: from,
|
|
4775
4903
|
filterTo: to,
|
|
4776
4904
|
filter: () => false,
|
|
4777
|
-
add: buildDecorations(tr.state, from, to)
|
|
4905
|
+
add: buildDecorations(tr.state, from, to, options)
|
|
4778
4906
|
});
|
|
4779
4907
|
},
|
|
4780
|
-
provide: (field) =>
|
|
4781
|
-
})
|
|
4908
|
+
provide: (field) => EditorView22.decorations.from(field)
|
|
4909
|
+
}),
|
|
4910
|
+
// Block-replace decorations have to live in a state field, but viewport changes are only
|
|
4911
|
+
// observable from a view plugin. Bridge the two by dispatching a rebuild effect whenever
|
|
4912
|
+
// the viewport extends so newly-parsed image nodes get widgetized without requiring focus.
|
|
4913
|
+
ViewPlugin16.define((view) => ({
|
|
4914
|
+
update: (update2) => {
|
|
4915
|
+
if (update2.viewportChanged) {
|
|
4916
|
+
queueMicrotask(() => view.dispatch({
|
|
4917
|
+
effects: rebuildEffect.of(void 0)
|
|
4918
|
+
}));
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
}))
|
|
4782
4922
|
];
|
|
4783
4923
|
};
|
|
4784
|
-
var buildDecorations = (state, from, to) => {
|
|
4924
|
+
var buildDecorations = (state, from, to, options = {}) => {
|
|
4785
4925
|
const decorations2 = [];
|
|
4786
4926
|
const cursor = state.selection.main.head;
|
|
4787
4927
|
syntaxTree5(state).iterate({
|
|
@@ -4794,6 +4934,12 @@ var buildDecorations = (state, from, to) => {
|
|
|
4794
4934
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4795
4935
|
return;
|
|
4796
4936
|
}
|
|
4937
|
+
if (options.skip?.({
|
|
4938
|
+
name: "Image",
|
|
4939
|
+
url
|
|
4940
|
+
})) {
|
|
4941
|
+
return;
|
|
4942
|
+
}
|
|
4797
4943
|
preloadImage(url);
|
|
4798
4944
|
decorations2.push(Decoration9.replace({
|
|
4799
4945
|
block: true,
|
|
@@ -4827,20 +4973,34 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4827
4973
|
const img = document.createElement("img");
|
|
4828
4974
|
img.setAttribute("src", this._url);
|
|
4829
4975
|
img.setAttribute("class", "cm-image");
|
|
4830
|
-
|
|
4831
|
-
|
|
4976
|
+
const focused = view.state.field(focusField);
|
|
4977
|
+
if (focused) {
|
|
4978
|
+
img.onload = () => {
|
|
4979
|
+
img.classList.add("cm-loaded-image");
|
|
4980
|
+
collapseIfTrackingPixel(img);
|
|
4981
|
+
};
|
|
4832
4982
|
} else {
|
|
4833
4983
|
img.classList.add("cm-loaded-image");
|
|
4984
|
+
img.onload = () => collapseIfTrackingPixel(img);
|
|
4834
4985
|
}
|
|
4986
|
+
img.onerror = () => collapseLine(img);
|
|
4835
4987
|
return img;
|
|
4836
4988
|
}
|
|
4837
4989
|
};
|
|
4990
|
+
var collapseIfTrackingPixel = (img) => {
|
|
4991
|
+
if (img.naturalWidth <= 1 && img.naturalHeight <= 1) {
|
|
4992
|
+
collapseLine(img);
|
|
4993
|
+
}
|
|
4994
|
+
};
|
|
4995
|
+
var collapseLine = (img) => {
|
|
4996
|
+
img.style.display = "none";
|
|
4997
|
+
};
|
|
4838
4998
|
|
|
4839
4999
|
// src/extensions/markdown/styles.ts
|
|
4840
|
-
import { EditorView as
|
|
5000
|
+
import { EditorView as EditorView23 } from "@codemirror/view";
|
|
4841
5001
|
var bulletListIndentationWidth = 24;
|
|
4842
5002
|
var orderedListIndentationWidth = 36;
|
|
4843
|
-
var formattingStyles =
|
|
5003
|
+
var formattingStyles = EditorView23.theme({
|
|
4844
5004
|
/**
|
|
4845
5005
|
* Horizontal rule.
|
|
4846
5006
|
*/
|
|
@@ -4995,12 +5155,12 @@ var formattingStyles = EditorView22.theme({
|
|
|
4995
5155
|
// src/extensions/markdown/table.ts
|
|
4996
5156
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4997
5157
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4998
|
-
import { Decoration as Decoration10, EditorView as
|
|
5158
|
+
import { Decoration as Decoration10, EditorView as EditorView24, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4999
5159
|
var table = (options = {}) => {
|
|
5000
5160
|
return StateField8.define({
|
|
5001
5161
|
create: (state) => update(state, options),
|
|
5002
5162
|
update: (_, tr) => update(tr.state, options),
|
|
5003
|
-
provide: (field) =>
|
|
5163
|
+
provide: (field) => EditorView24.decorations.from(field)
|
|
5004
5164
|
});
|
|
5005
5165
|
};
|
|
5006
5166
|
var update = (state, _options) => {
|
|
@@ -5591,10 +5751,10 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5591
5751
|
atomicDeco: atomicDeco.finish()
|
|
5592
5752
|
};
|
|
5593
5753
|
};
|
|
5594
|
-
var forceUpdate =
|
|
5754
|
+
var forceUpdate = StateEffect8.define();
|
|
5595
5755
|
var decorateMarkdown = (options = {}) => {
|
|
5596
5756
|
return [
|
|
5597
|
-
|
|
5757
|
+
ViewPlugin17.fromClass(class {
|
|
5598
5758
|
deco;
|
|
5599
5759
|
atomicDeco;
|
|
5600
5760
|
pendingUpdate;
|
|
@@ -5629,12 +5789,14 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5629
5789
|
}
|
|
5630
5790
|
}, {
|
|
5631
5791
|
provide: (plugin) => [
|
|
5632
|
-
Prec4.low(
|
|
5633
|
-
|
|
5634
|
-
|
|
5792
|
+
Prec4.low(EditorView25.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5793
|
+
EditorView25.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5794
|
+
EditorView25.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5635
5795
|
]
|
|
5636
5796
|
}),
|
|
5637
|
-
image(
|
|
5797
|
+
image({
|
|
5798
|
+
skip: options.skip ? (node) => !!options.skip?.(node) : void 0
|
|
5799
|
+
}),
|
|
5638
5800
|
table(),
|
|
5639
5801
|
adjustChanges(),
|
|
5640
5802
|
formattingStyles
|
|
@@ -5644,7 +5806,10 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5644
5806
|
// src/extensions/markdown/link.ts
|
|
5645
5807
|
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
5646
5808
|
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
|
5647
|
-
import {
|
|
5809
|
+
import { mx as mx6, surfaceShadow } from "@dxos/ui-theme";
|
|
5810
|
+
var tooltipClassName = mx6("inline-flex items-center p-1 max-w-64 text-sm bg-inverse-surface text-inverse-fg rounded-sm", surfaceShadow({
|
|
5811
|
+
elevation: "positioned"
|
|
5812
|
+
}));
|
|
5648
5813
|
var linkTooltip = (renderTooltip) => {
|
|
5649
5814
|
return hoverTooltip2((view, pos, side) => {
|
|
5650
5815
|
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
|
@@ -5666,7 +5831,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5666
5831
|
above: true,
|
|
5667
5832
|
create: () => {
|
|
5668
5833
|
const el = document.createElement("div");
|
|
5669
|
-
el.className =
|
|
5834
|
+
el.className = tooltipClassName;
|
|
5670
5835
|
renderTooltip(el, {
|
|
5671
5836
|
url: urlText
|
|
5672
5837
|
}, view);
|
|
@@ -5716,8 +5881,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5716
5881
|
};
|
|
5717
5882
|
|
|
5718
5883
|
// src/extensions/modal.ts
|
|
5719
|
-
import { StateEffect as
|
|
5720
|
-
var modalStateEffect =
|
|
5884
|
+
import { StateEffect as StateEffect9, StateField as StateField9 } from "@codemirror/state";
|
|
5885
|
+
var modalStateEffect = StateEffect9.define();
|
|
5721
5886
|
var modalStateField = StateField9.define({
|
|
5722
5887
|
create: () => false,
|
|
5723
5888
|
update: (value, tr) => {
|
|
@@ -6285,17 +6450,17 @@ var commands = () => keymap11.of([
|
|
|
6285
6450
|
|
|
6286
6451
|
// src/extensions/outliner/outliner.ts
|
|
6287
6452
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6288
|
-
import { Decoration as Decoration12, EditorView as
|
|
6289
|
-
import { mx as
|
|
6453
|
+
import { Decoration as Decoration12, EditorView as EditorView27, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
6454
|
+
import { mx as mx7 } from "@dxos/ui-theme";
|
|
6290
6455
|
|
|
6291
6456
|
// src/extensions/outliner/editor.ts
|
|
6292
6457
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6293
|
-
import { ViewPlugin as
|
|
6458
|
+
import { ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6294
6459
|
import { log as log10 } from "@dxos/log";
|
|
6295
6460
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6296
6461
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6297
6462
|
var initialize = () => {
|
|
6298
|
-
return
|
|
6463
|
+
return ViewPlugin18.fromClass(class {
|
|
6299
6464
|
constructor(view) {
|
|
6300
6465
|
const first = view.state.doc.lineAt(0);
|
|
6301
6466
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6463,10 +6628,10 @@ var editor = () => [
|
|
|
6463
6628
|
];
|
|
6464
6629
|
|
|
6465
6630
|
// src/extensions/outliner/menu.ts
|
|
6466
|
-
import { EditorView as
|
|
6631
|
+
import { EditorView as EditorView26, ViewPlugin as ViewPlugin19 } from "@codemirror/view";
|
|
6467
6632
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6468
6633
|
var menu = (options = {}) => [
|
|
6469
|
-
|
|
6634
|
+
ViewPlugin19.fromClass(class {
|
|
6470
6635
|
view;
|
|
6471
6636
|
tag;
|
|
6472
6637
|
rafId;
|
|
@@ -6528,7 +6693,7 @@ var menu = (options = {}) => [
|
|
|
6528
6693
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6529
6694
|
}
|
|
6530
6695
|
}),
|
|
6531
|
-
|
|
6696
|
+
EditorView26.theme({
|
|
6532
6697
|
".cm-popover-trigger": {
|
|
6533
6698
|
position: "fixed",
|
|
6534
6699
|
padding: "0",
|
|
@@ -6564,12 +6729,12 @@ var outliner = (_options = {}) => [
|
|
|
6564
6729
|
listPaddingLeft: 8
|
|
6565
6730
|
}),
|
|
6566
6731
|
// Researve space for menu.
|
|
6567
|
-
|
|
6732
|
+
EditorView27.contentAttributes.of({
|
|
6568
6733
|
class: "w-full !mr-[3rem]"
|
|
6569
6734
|
})
|
|
6570
6735
|
];
|
|
6571
6736
|
var decorations = () => [
|
|
6572
|
-
|
|
6737
|
+
ViewPlugin20.fromClass(class {
|
|
6573
6738
|
decorations = Decoration12.none;
|
|
6574
6739
|
constructor(view) {
|
|
6575
6740
|
this.updateDecorations(view.state, view);
|
|
@@ -6594,7 +6759,7 @@ var decorations = () => [
|
|
|
6594
6759
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6595
6760
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6596
6761
|
decorations2.push(Decoration12.line({
|
|
6597
|
-
class:
|
|
6762
|
+
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"))
|
|
6598
6763
|
}).range(line.from, line.from));
|
|
6599
6764
|
}
|
|
6600
6765
|
}
|
|
@@ -6604,7 +6769,7 @@ var decorations = () => [
|
|
|
6604
6769
|
decorations: (v) => v.decorations
|
|
6605
6770
|
}),
|
|
6606
6771
|
// Theme.
|
|
6607
|
-
|
|
6772
|
+
EditorView27.theme(Object.assign({
|
|
6608
6773
|
".cm-list-item": {
|
|
6609
6774
|
borderLeftWidth: "1px",
|
|
6610
6775
|
borderRightWidth: "1px",
|
|
@@ -6629,7 +6794,7 @@ var decorations = () => [
|
|
|
6629
6794
|
marginBottom: "2px"
|
|
6630
6795
|
},
|
|
6631
6796
|
".cm-list-item-focused": {
|
|
6632
|
-
borderColor: "var(--color-
|
|
6797
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6633
6798
|
},
|
|
6634
6799
|
"&:focus-within .cm-list-item-selected": {
|
|
6635
6800
|
borderColor: "var(--color-separator)"
|
|
@@ -6639,10 +6804,11 @@ var decorations = () => [
|
|
|
6639
6804
|
|
|
6640
6805
|
// src/extensions/preview/preview.ts
|
|
6641
6806
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6642
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as
|
|
6643
|
-
import { Decoration as Decoration13, EditorView as
|
|
6644
|
-
import {
|
|
6645
|
-
|
|
6807
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect10, StateField as StateField11 } from "@codemirror/state";
|
|
6808
|
+
import { Decoration as Decoration13, EditorView as EditorView28, ViewPlugin as ViewPlugin21, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6809
|
+
import { Entity } from "@dxos/echo";
|
|
6810
|
+
import { EID, URI } from "@dxos/keys";
|
|
6811
|
+
var labelResolvedEffect = StateEffect10.define();
|
|
6646
6812
|
var preview = (options = {}) => {
|
|
6647
6813
|
const viewRef = {
|
|
6648
6814
|
current: void 0
|
|
@@ -6659,11 +6825,11 @@ var preview = (options = {}) => {
|
|
|
6659
6825
|
return decorations2.map(tr.changes);
|
|
6660
6826
|
},
|
|
6661
6827
|
provide: (field) => [
|
|
6662
|
-
|
|
6663
|
-
|
|
6828
|
+
EditorView28.decorations.from(field),
|
|
6829
|
+
EditorView28.atomicRanges.of((view) => view.state.field(field))
|
|
6664
6830
|
]
|
|
6665
6831
|
}),
|
|
6666
|
-
|
|
6832
|
+
ViewPlugin21.define((view) => {
|
|
6667
6833
|
viewRef.current = view;
|
|
6668
6834
|
return {
|
|
6669
6835
|
destroy() {
|
|
@@ -6674,11 +6840,12 @@ var preview = (options = {}) => {
|
|
|
6674
6840
|
];
|
|
6675
6841
|
};
|
|
6676
6842
|
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6677
|
-
const
|
|
6678
|
-
|
|
6843
|
+
const echoUri = EID.tryParse(dxnStr);
|
|
6844
|
+
const dxnRef = echoUri ?? (dxnStr.startsWith("dxn:") ? URI.make(dxnStr) : void 0);
|
|
6845
|
+
if (!dxnRef) {
|
|
6679
6846
|
return;
|
|
6680
6847
|
}
|
|
6681
|
-
const ref = db.makeRef(
|
|
6848
|
+
const ref = db.makeRef(dxnRef);
|
|
6682
6849
|
const target = ref.target;
|
|
6683
6850
|
if (target) {
|
|
6684
6851
|
return Entity.getLabel(target);
|
|
@@ -6696,7 +6863,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6696
6863
|
switch (node.name) {
|
|
6697
6864
|
//
|
|
6698
6865
|
// Inline widget.
|
|
6699
|
-
// [Label](
|
|
6866
|
+
// [Label](echo:/123)
|
|
6700
6867
|
//
|
|
6701
6868
|
case "Link": {
|
|
6702
6869
|
const link = getLinkRef(state, node.node);
|
|
@@ -6715,7 +6882,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6715
6882
|
}
|
|
6716
6883
|
//
|
|
6717
6884
|
// Block widget (transclusion).
|
|
6718
|
-
// 
|
|
6719
6886
|
//
|
|
6720
6887
|
case "Image": {
|
|
6721
6888
|
if (options.addBlockContainer && options.removeBlockContainer) {
|
|
@@ -6739,7 +6906,7 @@ var getLinkRef = (state, node) => {
|
|
|
6739
6906
|
const urlNode = node.getChild("URL");
|
|
6740
6907
|
if (mark && urlNode) {
|
|
6741
6908
|
const dxn = state.sliceDoc(urlNode.from, urlNode.to);
|
|
6742
|
-
if (dxn.startsWith("dxn:")) {
|
|
6909
|
+
if (dxn.startsWith("dxn:") || dxn.startsWith("echo:")) {
|
|
6743
6910
|
const label = state.sliceDoc(mark[0].to, mark[1].from);
|
|
6744
6911
|
return {
|
|
6745
6912
|
block: state.sliceDoc(mark[0].from, mark[0].from + 1) === "!",
|
|
@@ -6783,7 +6950,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6783
6950
|
}
|
|
6784
6951
|
toDOM(_view) {
|
|
6785
6952
|
const root = document.createElement("div");
|
|
6786
|
-
root.classList.add("cm-preview-block", "dx-density-
|
|
6953
|
+
root.classList.add("cm-preview-block", "dx-density-md");
|
|
6787
6954
|
this._options.addBlockContainer?.({
|
|
6788
6955
|
link: this._link,
|
|
6789
6956
|
el: root
|
|
@@ -6799,7 +6966,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6799
6966
|
};
|
|
6800
6967
|
|
|
6801
6968
|
// src/extensions/replacer.ts
|
|
6802
|
-
import { EditorView as
|
|
6969
|
+
import { EditorView as EditorView29 } from "@codemirror/view";
|
|
6803
6970
|
var defaultReplacements = [
|
|
6804
6971
|
{
|
|
6805
6972
|
input: "--",
|
|
@@ -6862,7 +7029,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6862
7029
|
const sortedReplacements = [
|
|
6863
7030
|
...replacements
|
|
6864
7031
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6865
|
-
return
|
|
7032
|
+
return EditorView29.inputHandler.of((view, from, to, insert) => {
|
|
6866
7033
|
if (insert.length !== 1) {
|
|
6867
7034
|
return false;
|
|
6868
7035
|
}
|
|
@@ -6896,6 +7063,17 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6896
7063
|
});
|
|
6897
7064
|
};
|
|
6898
7065
|
|
|
7066
|
+
// src/extensions/spacing.ts
|
|
7067
|
+
import { EditorView as EditorView30 } from "@codemirror/view";
|
|
7068
|
+
function lineSpacing(verticalPadding = 2) {
|
|
7069
|
+
return EditorView30.theme({
|
|
7070
|
+
".cm-line": {
|
|
7071
|
+
paddingTop: `${verticalPadding}px`,
|
|
7072
|
+
paddingBottom: `${verticalPadding}px`
|
|
7073
|
+
}
|
|
7074
|
+
});
|
|
7075
|
+
}
|
|
7076
|
+
|
|
6899
7077
|
// src/extensions/snippets.ts
|
|
6900
7078
|
import { keymap as keymap12 } from "@codemirror/view";
|
|
6901
7079
|
var defaultItems = [
|
|
@@ -7108,8 +7286,8 @@ var mixedParser = (registry) => {
|
|
|
7108
7286
|
};
|
|
7109
7287
|
|
|
7110
7288
|
// src/extensions/tags/fader.ts
|
|
7111
|
-
import { StateEffect as
|
|
7112
|
-
import { Decoration as Decoration14, EditorView as
|
|
7289
|
+
import { StateEffect as StateEffect11, StateField as StateField12 } from "@codemirror/state";
|
|
7290
|
+
import { Decoration as Decoration14, EditorView as EditorView31, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7113
7291
|
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7114
7292
|
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7115
7293
|
var CLEANUP_INTERVAL = 1e3;
|
|
@@ -7122,7 +7300,7 @@ var fader = (options = {}) => {
|
|
|
7122
7300
|
lastCount = expiries.length;
|
|
7123
7301
|
}
|
|
7124
7302
|
};
|
|
7125
|
-
const dequeue =
|
|
7303
|
+
const dequeue = StateEffect11.define();
|
|
7126
7304
|
const fadeField = StateField12.define({
|
|
7127
7305
|
create: () => ({
|
|
7128
7306
|
decorations: Decoration14.none,
|
|
@@ -7233,9 +7411,9 @@ var fader = (options = {}) => {
|
|
|
7233
7411
|
batchStart
|
|
7234
7412
|
};
|
|
7235
7413
|
},
|
|
7236
|
-
provide: (f) =>
|
|
7414
|
+
provide: (f) => EditorView31.decorations.from(f, (value) => value.decorations)
|
|
7237
7415
|
});
|
|
7238
|
-
const cleanup =
|
|
7416
|
+
const cleanup = ViewPlugin22.fromClass(class {
|
|
7239
7417
|
view;
|
|
7240
7418
|
#timer;
|
|
7241
7419
|
constructor(view) {
|
|
@@ -7270,7 +7448,7 @@ var fader = (options = {}) => {
|
|
|
7270
7448
|
return [
|
|
7271
7449
|
fadeField,
|
|
7272
7450
|
cleanup,
|
|
7273
|
-
|
|
7451
|
+
EditorView31.theme({
|
|
7274
7452
|
".cm-fader": {
|
|
7275
7453
|
animation: "fader 1s ease-out forwards"
|
|
7276
7454
|
},
|
|
@@ -7285,11 +7463,11 @@ var fader = (options = {}) => {
|
|
|
7285
7463
|
};
|
|
7286
7464
|
|
|
7287
7465
|
// src/extensions/tags/typewriter.ts
|
|
7288
|
-
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as
|
|
7289
|
-
import { Decoration as Decoration15, EditorView as
|
|
7466
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect12, StateField as StateField13 } from "@codemirror/state";
|
|
7467
|
+
import { Decoration as Decoration15, EditorView as EditorView32, ViewPlugin as ViewPlugin23, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7290
7468
|
import { Domino as Domino3 } from "@dxos/ui";
|
|
7291
7469
|
var typewriterBypass = Annotation3.define();
|
|
7292
|
-
var typewriterDrainingEffect =
|
|
7470
|
+
var typewriterDrainingEffect = StateEffect12.define();
|
|
7293
7471
|
var CURSOR_LINGER = 3e3;
|
|
7294
7472
|
var FRAME_BUDGET_MS = 4;
|
|
7295
7473
|
var CHARS_PER_FRAME = 5;
|
|
@@ -7300,8 +7478,8 @@ var typewriter = (options = {}) => {
|
|
|
7300
7478
|
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7301
7479
|
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7302
7480
|
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7303
|
-
const suppressAppend =
|
|
7304
|
-
const insertChunk =
|
|
7481
|
+
const suppressAppend = StateEffect12.define();
|
|
7482
|
+
const insertChunk = StateEffect12.define();
|
|
7305
7483
|
const bufferField = StateField13.define({
|
|
7306
7484
|
create: () => ({
|
|
7307
7485
|
text: "",
|
|
@@ -7384,7 +7562,7 @@ var typewriter = (options = {}) => {
|
|
|
7384
7562
|
})
|
|
7385
7563
|
};
|
|
7386
7564
|
});
|
|
7387
|
-
const drainPlugin =
|
|
7565
|
+
const drainPlugin = ViewPlugin23.fromClass(class {
|
|
7388
7566
|
view;
|
|
7389
7567
|
_raf;
|
|
7390
7568
|
_activeStreamTag = null;
|
|
@@ -7489,7 +7667,7 @@ var typewriter = (options = {}) => {
|
|
|
7489
7667
|
].filter(Boolean);
|
|
7490
7668
|
};
|
|
7491
7669
|
var typewriterCursor = (bufferField) => {
|
|
7492
|
-
const hideCursor =
|
|
7670
|
+
const hideCursor = StateEffect12.define();
|
|
7493
7671
|
const visibilityField = StateField13.define({
|
|
7494
7672
|
create: () => ({
|
|
7495
7673
|
visible: false,
|
|
@@ -7543,9 +7721,9 @@ var typewriterCursor = (bufferField) => {
|
|
|
7543
7721
|
}).range(pos)
|
|
7544
7722
|
]);
|
|
7545
7723
|
},
|
|
7546
|
-
provide: (field) =>
|
|
7724
|
+
provide: (field) => EditorView32.decorations.from(field)
|
|
7547
7725
|
});
|
|
7548
|
-
const timerPlugin =
|
|
7726
|
+
const timerPlugin = ViewPlugin23.fromClass(class {
|
|
7549
7727
|
view;
|
|
7550
7728
|
_timer;
|
|
7551
7729
|
constructor(view) {
|
|
@@ -7717,7 +7895,7 @@ var linkLength = (buffer, start, bracketAt) => {
|
|
|
7717
7895
|
|
|
7718
7896
|
// src/extensions/tags/xml-block-decoration.ts
|
|
7719
7897
|
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7720
|
-
import { Decoration as Decoration16, ViewPlugin as
|
|
7898
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin24 } from "@codemirror/view";
|
|
7721
7899
|
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7722
7900
|
const lineDecoration = lineClass ? Decoration16.line({
|
|
7723
7901
|
class: lineClass
|
|
@@ -7773,7 +7951,7 @@ var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
|
7773
7951
|
});
|
|
7774
7952
|
return Decoration16.set(ranges, true);
|
|
7775
7953
|
};
|
|
7776
|
-
return
|
|
7954
|
+
return ViewPlugin24.fromClass(class {
|
|
7777
7955
|
decorations;
|
|
7778
7956
|
constructor(view) {
|
|
7779
7957
|
this.decorations = buildDecorations5(view);
|
|
@@ -7790,7 +7968,7 @@ var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
|
7790
7968
|
|
|
7791
7969
|
// src/extensions/tags/xml-formatting.ts
|
|
7792
7970
|
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7793
|
-
import { Decoration as Decoration17, EditorView as
|
|
7971
|
+
import { Decoration as Decoration17, EditorView as EditorView33, ViewPlugin as ViewPlugin25 } from "@codemirror/view";
|
|
7794
7972
|
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7795
7973
|
"OpenTag",
|
|
7796
7974
|
"CloseTag",
|
|
@@ -7853,7 +8031,7 @@ var xmlFormatting = ({ skip } = {}) => {
|
|
|
7853
8031
|
return Decoration17.set(ranges, true);
|
|
7854
8032
|
};
|
|
7855
8033
|
return [
|
|
7856
|
-
|
|
8034
|
+
ViewPlugin25.fromClass(class {
|
|
7857
8035
|
decorations;
|
|
7858
8036
|
constructor(view) {
|
|
7859
8037
|
this.decorations = buildDecorations5(view);
|
|
@@ -7866,9 +8044,9 @@ var xmlFormatting = ({ skip } = {}) => {
|
|
|
7866
8044
|
}, {
|
|
7867
8045
|
decorations: (instance) => instance.decorations
|
|
7868
8046
|
}),
|
|
7869
|
-
|
|
8047
|
+
EditorView33.baseTheme({
|
|
7870
8048
|
".cm-xml-element": {
|
|
7871
|
-
backgroundColor: "var(--color-
|
|
8049
|
+
backgroundColor: "var(--color-current-surface)",
|
|
7872
8050
|
borderRadius: "0.25rem",
|
|
7873
8051
|
padding: "0.25rem"
|
|
7874
8052
|
},
|
|
@@ -7883,8 +8061,8 @@ var xmlFormatting = ({ skip } = {}) => {
|
|
|
7883
8061
|
|
|
7884
8062
|
// src/extensions/tags/xml-tags.ts
|
|
7885
8063
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7886
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7887
|
-
import { Decoration as Decoration18, EditorView as
|
|
8064
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect13, StateField as StateField14 } from "@codemirror/state";
|
|
8065
|
+
import { Decoration as Decoration18, EditorView as EditorView34, ViewPlugin as ViewPlugin26, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7888
8066
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7889
8067
|
import { log as log11 } from "@dxos/log";
|
|
7890
8068
|
import { Domino as Domino4 } from "@dxos/ui";
|
|
@@ -7996,17 +8174,17 @@ var decodeXmlEntity = (raw) => {
|
|
|
7996
8174
|
|
|
7997
8175
|
// src/extensions/tags/xml-tags.ts
|
|
7998
8176
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7999
|
-
var navigatePreviousEffect =
|
|
8000
|
-
var navigateNextEffect =
|
|
8177
|
+
var navigatePreviousEffect = StateEffect13.define();
|
|
8178
|
+
var navigateNextEffect = StateEffect13.define();
|
|
8001
8179
|
var getXmlTextChild = (children) => {
|
|
8002
8180
|
const child = children?.[0];
|
|
8003
8181
|
return typeof child === "string" ? child : null;
|
|
8004
8182
|
};
|
|
8005
8183
|
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8006
8184
|
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8007
|
-
var xmlTagContextEffect =
|
|
8008
|
-
var xmlTagResetEffect =
|
|
8009
|
-
var xmlTagUpdateEffect =
|
|
8185
|
+
var xmlTagContextEffect = StateEffect13.define();
|
|
8186
|
+
var xmlTagResetEffect = StateEffect13.define();
|
|
8187
|
+
var xmlTagUpdateEffect = StateEffect13.define();
|
|
8010
8188
|
var widgetContextStateField = StateField14.define({
|
|
8011
8189
|
create: () => void 0,
|
|
8012
8190
|
update: (value, tr) => {
|
|
@@ -8101,7 +8279,7 @@ var keyHandlers = keymap14.of([
|
|
|
8101
8279
|
}
|
|
8102
8280
|
]);
|
|
8103
8281
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
8104
|
-
return
|
|
8282
|
+
return EditorView34.updateListener.of((update2) => {
|
|
8105
8283
|
update2.transactions.forEach((transaction) => {
|
|
8106
8284
|
for (const effect of transaction.effects) {
|
|
8107
8285
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -8129,7 +8307,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8129
8307
|
anchor: line.from,
|
|
8130
8308
|
head: line.from
|
|
8131
8309
|
},
|
|
8132
|
-
effects:
|
|
8310
|
+
effects: crawlerLineEffect.of({
|
|
8133
8311
|
line: line.number - 1,
|
|
8134
8312
|
offset: -16
|
|
8135
8313
|
})
|
|
@@ -8162,7 +8340,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8162
8340
|
anchor: line.to,
|
|
8163
8341
|
head: line.to
|
|
8164
8342
|
},
|
|
8165
|
-
effects:
|
|
8343
|
+
effects: crawlerLineEffect.of({
|
|
8166
8344
|
line: line.number - 1,
|
|
8167
8345
|
offset: -16
|
|
8168
8346
|
})
|
|
@@ -8174,7 +8352,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8174
8352
|
anchor: line.to,
|
|
8175
8353
|
head: line.to
|
|
8176
8354
|
},
|
|
8177
|
-
effects:
|
|
8355
|
+
effects: crawlerLineEffect.of({
|
|
8178
8356
|
line: line.number - 1,
|
|
8179
8357
|
position: "end"
|
|
8180
8358
|
})
|
|
@@ -8186,7 +8364,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8186
8364
|
});
|
|
8187
8365
|
});
|
|
8188
8366
|
};
|
|
8189
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8367
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin26.fromClass(class {
|
|
8190
8368
|
update(update2) {
|
|
8191
8369
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
8192
8370
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -8271,8 +8449,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8271
8449
|
};
|
|
8272
8450
|
},
|
|
8273
8451
|
provide: (field) => [
|
|
8274
|
-
|
|
8275
|
-
|
|
8452
|
+
EditorView34.decorations.from(field, (v) => v.decorations),
|
|
8453
|
+
EditorView34.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
8276
8454
|
]
|
|
8277
8455
|
});
|
|
8278
8456
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -8460,7 +8638,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8460
8638
|
export {
|
|
8461
8639
|
Cursor,
|
|
8462
8640
|
EditorState4 as EditorState,
|
|
8463
|
-
|
|
8641
|
+
EditorView35 as EditorView,
|
|
8464
8642
|
Inline,
|
|
8465
8643
|
InputModeExtensions,
|
|
8466
8644
|
List,
|
|
@@ -8493,6 +8671,9 @@ export {
|
|
|
8493
8671
|
commentsState,
|
|
8494
8672
|
compactSlots,
|
|
8495
8673
|
convertTreeToJson,
|
|
8674
|
+
crawler,
|
|
8675
|
+
crawlerActiveEffect,
|
|
8676
|
+
crawlerLineEffect,
|
|
8496
8677
|
createBasicExtensions,
|
|
8497
8678
|
createComment,
|
|
8498
8679
|
createCrawler,
|
|
@@ -8544,9 +8725,11 @@ export {
|
|
|
8544
8725
|
insertAtCursor,
|
|
8545
8726
|
insertAtLineStart,
|
|
8546
8727
|
insertTable,
|
|
8728
|
+
isRangeVisible,
|
|
8547
8729
|
itemToJSON,
|
|
8548
8730
|
join,
|
|
8549
8731
|
keymap15 as keymap,
|
|
8732
|
+
lineSpacing,
|
|
8550
8733
|
linkTooltip,
|
|
8551
8734
|
listItemToString,
|
|
8552
8735
|
listener,
|
|
@@ -8579,9 +8762,8 @@ export {
|
|
|
8579
8762
|
scrollPastEnd,
|
|
8580
8763
|
scrollThreadIntoView,
|
|
8581
8764
|
scrollToLine,
|
|
8765
|
+
scrollbarAutohide,
|
|
8582
8766
|
scroller,
|
|
8583
|
-
scrollerCrawlEffect,
|
|
8584
|
-
scrollerLineEffect,
|
|
8585
8767
|
selectionState,
|
|
8586
8768
|
setBlockquote,
|
|
8587
8769
|
setComments,
|