@dxos/ui-editor 0.8.4-main.dfabb4ec29 → 0.8.4-main.f466a3d56e

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.
Files changed (37) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/index.mjs +482 -458
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/node-esm/index.mjs +482 -458
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/types/src/extensions/index.d.ts +1 -3
  10. package/dist/types/src/extensions/index.d.ts.map +1 -1
  11. package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
  12. package/dist/types/src/extensions/{scroller.d.ts → scrolling/crawler.d.ts} +13 -6
  13. package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
  14. package/dist/types/src/extensions/scrolling/index.d.ts +5 -0
  15. package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
  16. package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
  17. package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
  18. package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
  19. package/dist/types/src/styles/theme.d.ts.map +1 -1
  20. package/dist/types/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +29 -29
  22. package/src/extensions/factories.ts +1 -1
  23. package/src/extensions/index.ts +1 -3
  24. package/src/extensions/outliner/outliner.ts +1 -1
  25. package/src/extensions/{auto-scroll.ts → scrolling/auto-scroll.ts} +30 -20
  26. package/src/extensions/{scroller.ts → scrolling/crawler.ts} +19 -12
  27. package/src/extensions/scrolling/index.ts +8 -0
  28. package/src/extensions/{scroll-past-end.ts → scrolling/scroll-past-end.ts} +6 -6
  29. package/src/extensions/scrolling/scroller.ts +27 -0
  30. package/src/extensions/tags/xml-formatting.ts +1 -1
  31. package/src/extensions/tags/xml-tags.ts +4 -4
  32. package/src/styles/theme.ts +8 -7
  33. package/dist/types/src/extensions/auto-scroll.d.ts.map +0 -1
  34. package/dist/types/src/extensions/scroll-past-end.d.ts.map +0 -1
  35. package/dist/types/src/extensions/scroller.d.ts.map +0 -1
  36. /package/dist/types/src/extensions/{auto-scroll.d.ts → scrolling/auto-scroll.d.ts} +0 -0
  37. /package/dist/types/src/extensions/{scroll-past-end.d.ts → scrolling/scroll-past-end.d.ts} +0 -0
@@ -511,344 +511,10 @@ var typeahead = ({ onComplete } = {}) => {
511
511
  ];
512
512
  };
513
513
 
514
- // src/extensions/auto-scroll.ts
515
- import { StateEffect as StateEffect2 } from "@codemirror/state";
516
- import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
517
- import { addEventListener, combine, throttle } from "@dxos/async";
518
- import { Domino } from "@dxos/ui";
519
- import { getSize } from "@dxos/ui-theme";
520
-
521
- // src/extensions/scroller.ts
522
- import { StateEffect } from "@codemirror/state";
523
- import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
524
- import { log as log2 } from "@dxos/log";
525
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
526
- var scrollerLineEffect = StateEffect.define();
527
- var scrollerCrawlEffect = StateEffect.define();
528
- var scrollToLine = (view, options) => {
529
- view.dispatch({
530
- effects: scrollerLineEffect.of(options)
531
- });
532
- };
533
- var scroller = ({ overScroll = 0 } = {}) => {
534
- const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
535
- view;
536
- crawler;
537
- constructor(view) {
538
- this.view = view;
539
- this.crawler = createCrawler(this.view);
540
- }
541
- // No-op.
542
- destroy() {
543
- this.crawler.cancel();
544
- }
545
- cancel() {
546
- this.crawler.cancel();
547
- }
548
- crawl(start = false) {
549
- if (start) {
550
- this.crawler.scroll();
551
- } else {
552
- this.crawler.cancel();
553
- }
554
- }
555
- scroll({ line, offset = 0, position, behavior = "instant" }) {
556
- const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
557
- const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
558
- const doc = this.view.state.doc;
559
- let targetScrollTop = scrollHeight - clientHeight + offset;
560
- if (line >= 0 && line <= doc.lines - 1) {
561
- const lineStart = doc.line(line + 1).from;
562
- const coords = this.view.coordsAtPos(lineStart);
563
- if (coords) {
564
- const currentScrollTop = scrollTop;
565
- const maxScrollTop = scrollHeight - clientHeight;
566
- if (position === "end") {
567
- targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
568
- } else {
569
- targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
570
- }
571
- targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
572
- }
573
- }
574
- requestAnimationFrame(() => {
575
- this.view.scrollDOM.scrollTo({
576
- top: targetScrollTop
577
- });
578
- });
579
- }
580
- });
581
- return [
582
- scrollPlugin,
583
- // Listen for effect.
584
- EditorView4.updateListener.of((update2) => {
585
- update2.transactions.forEach((transaction) => {
586
- try {
587
- const plugin = update2.view.plugin(scrollPlugin);
588
- if (plugin) {
589
- for (const effect of transaction.effects) {
590
- if (effect.is(scrollerCrawlEffect)) {
591
- plugin.crawl(effect.value);
592
- } else if (effect.is(scrollerLineEffect)) {
593
- plugin.scroll(effect.value);
594
- }
595
- }
596
- }
597
- } catch (err) {
598
- log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
599
- }
600
- });
601
- }),
602
- // Styles.
603
- EditorView4.theme({
604
- ".cm-scroller": {
605
- overflowY: "scroll",
606
- // Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
607
- // expanding their TogglePanel), the browser picks a stable element near the viewport
608
- // top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
609
- // logic still has the final word when pinned (forces scrollTop to scrollHeight).
610
- overflowAnchor: "auto"
611
- },
612
- ".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
613
- display: "none"
614
- },
615
- ".cm-scroller::-webkit-scrollbar-thumb": {
616
- background: "transparent",
617
- transition: "background 0.15s"
618
- },
619
- "&:hover .cm-scroller::-webkit-scrollbar-thumb": {
620
- background: "var(--color-scrollbar-thumb)"
621
- },
622
- // Spacer below the last text line. Implemented as a real block pseudo-element
623
- // (rather than `padding-bottom` on `.cm-content`) so it materializes in the
624
- // scroller's `scrollHeight` regardless of how `padding` is reset by the base
625
- // theme or downstream classes — this is what gives auto-scroll its head-room
626
- // so the last line stays `overScroll` px above the viewport bottom.
627
- ".cm-content::after": {
628
- content: '""',
629
- display: "block",
630
- height: `${overScroll}px`
631
- },
632
- ".cm-scroll-button": {
633
- position: "absolute",
634
- bottom: "0.5rem",
635
- right: "1rem"
636
- }
637
- })
638
- ];
639
- };
640
- function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
641
- const el = view.scrollDOM;
642
- let currentTop = 0;
643
- let velocity = 0;
644
- let rafId = null;
645
- let lastTime = 0;
646
- function frame(now) {
647
- const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
648
- lastTime = now;
649
- const targetTop = el.scrollHeight - el.clientHeight;
650
- const delta = targetTop - currentTop;
651
- if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
652
- el.scrollTop = targetTop;
653
- currentTop = targetTop;
654
- velocity = 0;
655
- rafId = null;
656
- lastTime = 0;
657
- return;
658
- }
659
- const accel = omega * omega * delta - 2 * omega * velocity;
660
- velocity += accel * dt;
661
- currentTop += velocity * dt;
662
- el.scrollTop = currentTop;
663
- rafId = requestAnimationFrame(frame);
664
- }
665
- return {
666
- scroll: () => {
667
- if (rafId === null) {
668
- currentTop = el.scrollTop;
669
- lastTime = 0;
670
- rafId = requestAnimationFrame(frame);
671
- }
672
- },
673
- cancel: () => {
674
- if (rafId !== null) {
675
- cancelAnimationFrame(rafId);
676
- velocity = 0;
677
- lastTime = 0;
678
- rafId = null;
679
- }
680
- }
681
- };
682
- }
683
-
684
- // src/extensions/auto-scroll.ts
685
- var autoScrollEffect = StateEffect2.define();
686
- var autoScroll = ({ scrollOnResize = true } = {}) => {
687
- let buttonContainer;
688
- let isPinned = true;
689
- let jumpPending = false;
690
- let enabled = true;
691
- let firstUpdate = true;
692
- const setPinned = (pinned) => {
693
- buttonContainer?.classList.toggle("opacity-0", pinned);
694
- isPinned = pinned;
695
- };
696
- return [
697
- // Update listener for scrolling when content changes.
698
- EditorView5.updateListener.of((update2) => {
699
- const { view, heightChanged, state, startState } = update2;
700
- for (const tr of update2.transactions) {
701
- for (const effect of tr.effects) {
702
- if (effect.is(autoScrollEffect)) {
703
- enabled = effect.value;
704
- if (enabled) {
705
- setPinned(true);
706
- view.dispatch({
707
- effects: scrollerCrawlEffect.of(true)
708
- });
709
- } else {
710
- view.dispatch({
711
- effects: scrollerCrawlEffect.of(false)
712
- });
713
- }
714
- }
715
- }
716
- }
717
- if (!enabled) {
718
- return;
719
- }
720
- if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
721
- firstUpdate = false;
722
- jumpPending = true;
723
- requestAnimationFrame(() => {
724
- view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
725
- jumpPending = false;
726
- });
727
- return;
728
- }
729
- firstUpdate = false;
730
- if (jumpPending) {
731
- return;
732
- }
733
- if (heightChanged) {
734
- if (isPinned) {
735
- const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
736
- const delta = scrollHeight - scrollTop - clientHeight;
737
- if (delta > 0) {
738
- setPinned(true);
739
- view.dispatch({
740
- effects: scrollerCrawlEffect.of(true)
741
- });
742
- } else if (delta < -1) {
743
- setPinned(false);
744
- }
745
- } else {
746
- if (state.doc.length === 0) {
747
- setPinned(true);
748
- }
749
- }
750
- }
751
- }),
752
- // Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
753
- // window resize). Doc-driven height changes are handled by the updateListener above; this
754
- // observer covers the case where the viewport changes while the doc length is unchanged.
755
- scrollOnResize ? ViewPlugin6.fromClass(class {
756
- observer;
757
- firstObservation = true;
758
- destroyed = false;
759
- constructor(view) {
760
- const onResize = throttle(() => {
761
- if (this.destroyed || !enabled) {
762
- return;
763
- }
764
- setPinned(true);
765
- requestAnimationFrame(() => {
766
- if (this.destroyed) {
767
- return;
768
- }
769
- view.scrollDOM.scrollTo({
770
- top: view.scrollDOM.scrollHeight,
771
- behavior: "instant"
772
- });
773
- view.dispatch({
774
- effects: scrollerCrawlEffect.of(false)
775
- });
776
- });
777
- }, 50);
778
- this.observer = new ResizeObserver(() => {
779
- if (this.firstObservation) {
780
- this.firstObservation = false;
781
- return;
782
- }
783
- onResize();
784
- });
785
- this.observer.observe(view.scrollDOM);
786
- }
787
- destroy() {
788
- this.destroyed = true;
789
- this.observer.disconnect();
790
- }
791
- }) : [],
792
- // Detect user scroll and unpin (or re-pin if scrolled to the bottom).
793
- ViewPlugin6.fromClass(class {
794
- cleanup;
795
- constructor(view) {
796
- this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
797
- requestAnimationFrame(() => {
798
- const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
799
- const delta = scrollHeight - scrollTop - clientHeight;
800
- const pinned = delta === 0;
801
- setPinned(pinned);
802
- if (!pinned) {
803
- view.dispatch({
804
- effects: scrollerCrawlEffect.of(false)
805
- });
806
- }
807
- });
808
- }, 500));
809
- }
810
- destroy() {
811
- this.cleanup();
812
- }
813
- }),
814
- // Scroll button.
815
- ViewPlugin6.fromClass(class {
816
- constructor(view) {
817
- const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
818
- icon: "ph--arrow-down--regular"
819
- });
820
- const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
821
- "data-density": "fine"
822
- }).append(icon).on("click", () => {
823
- setPinned(true);
824
- view.dispatch({
825
- effects: scrollerLineEffect.of({
826
- line: -1,
827
- position: "end",
828
- behavior: "smooth"
829
- })
830
- });
831
- });
832
- buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
833
- view.scrollDOM.parentElement.appendChild(buttonContainer);
834
- }
835
- })
836
- ];
837
- };
838
- function createUserScrollDetector(element, onUserScroll) {
839
- return combine(addEventListener(element, "wheel", () => onUserScroll(), {
840
- passive: true
841
- }), addEventListener(element, "pointerdown", (event) => {
842
- if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
843
- onUserScroll();
844
- }
845
- }));
846
- }
847
-
848
514
  // src/extensions/automerge/automerge.ts
849
515
  import { next as A3 } from "@automerge/automerge";
850
516
  import { StateField, Transaction as Transaction2 } from "@codemirror/state";
851
- import { EditorView as EditorView6, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
517
+ import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
852
518
  import { DocAccessor } from "@dxos/echo-db";
853
519
 
854
520
  // src/extensions/state.ts
@@ -857,14 +523,14 @@ var initialSync = Transaction.userEvent.of("initial.sync");
857
523
 
858
524
  // src/extensions/automerge/cursor.ts
859
525
  import { fromCursor, toCursor } from "@dxos/echo-db";
860
- import { log as log3 } from "@dxos/log";
861
- var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
526
+ import { log as log2 } from "@dxos/log";
527
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
862
528
  var cursorConverter = (accessor) => ({
863
529
  toCursor: (pos, assoc) => {
864
530
  try {
865
531
  return toCursor(accessor, pos, assoc);
866
532
  } catch (err) {
867
- log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
533
+ log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
868
534
  return "";
869
535
  }
870
536
  },
@@ -872,17 +538,17 @@ var cursorConverter = (accessor) => ({
872
538
  try {
873
539
  return fromCursor(accessor, cursor);
874
540
  } catch (err) {
875
- log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
541
+ log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
876
542
  return 0;
877
543
  }
878
544
  }
879
545
  });
880
546
 
881
547
  // src/extensions/automerge/defs.ts
882
- import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
548
+ import { Annotation, StateEffect } from "@codemirror/state";
883
549
  var getPath = (state, field) => state.field(field).path;
884
550
  var getLastHeads = (state, field) => state.field(field).lastHeads;
885
- var updateHeadsEffect = StateEffect3.define({});
551
+ var updateHeadsEffect = StateEffect.define({});
886
552
  var updateHeads = (newHeads) => updateHeadsEffect.of({
887
553
  newHeads
888
554
  });
@@ -893,7 +559,7 @@ var isReconcile = (tr) => {
893
559
 
894
560
  // src/extensions/automerge/sync.ts
895
561
  import { next as A2 } from "@automerge/automerge";
896
- import { log as log4 } from "@dxos/log";
562
+ import { log as log3 } from "@dxos/log";
897
563
 
898
564
  // src/extensions/automerge/update-automerge.ts
899
565
  import { next as A } from "@automerge/automerge";
@@ -1034,7 +700,7 @@ var charPath = (textPath, candidatePath) => {
1034
700
  };
1035
701
 
1036
702
  // src/extensions/automerge/sync.ts
1037
- var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
703
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
1038
704
  var Syncer = class {
1039
705
  _handle;
1040
706
  _state;
@@ -1057,7 +723,7 @@ var Syncer = class {
1057
723
  this._pending = false;
1058
724
  }
1059
725
  onEditorChange(view) {
1060
- log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
726
+ log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
1061
727
  const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
1062
728
  const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
1063
729
  if (newHeads) {
@@ -1068,7 +734,7 @@ var Syncer = class {
1068
734
  }
1069
735
  }
1070
736
  onAutomergeChange(view) {
1071
- log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
737
+ log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
1072
738
  const oldHeads = getLastHeads(view.state, this._state);
1073
739
  const newHeads = A2.getHeads(this._handle.doc());
1074
740
  const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
@@ -1121,7 +787,7 @@ var automerge = (accessor) => {
1121
787
  // Track heads.
1122
788
  syncState,
1123
789
  // Reconcile external updates.
1124
- ViewPlugin7.fromClass(class {
790
+ ViewPlugin5.fromClass(class {
1125
791
  _view;
1126
792
  constructor(_view) {
1127
793
  this._view = _view;
@@ -1152,7 +818,7 @@ var automerge = (accessor) => {
1152
818
  };
1153
819
  }),
1154
820
  // Reconcile local updates.
1155
- EditorView6.updateListener.of(({ view, changes, transactions }) => {
821
+ EditorView4.updateListener.of(({ view, changes, transactions }) => {
1156
822
  if (!changes.empty) {
1157
823
  const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
1158
824
  if (!isInitialSync) {
@@ -1165,10 +831,10 @@ var automerge = (accessor) => {
1165
831
 
1166
832
  // src/extensions/awareness/awareness.ts
1167
833
  import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
1168
- import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
834
+ import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
1169
835
  import { Event } from "@dxos/async";
1170
836
  import { Context } from "@dxos/context";
1171
- var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
837
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
1172
838
  var dummyProvider = {
1173
839
  remoteStateChange: new Event(),
1174
840
  open: () => {
@@ -1184,14 +850,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
1184
850
  var awareness = (provider = dummyProvider) => {
1185
851
  return [
1186
852
  awarenessProvider.of(provider),
1187
- ViewPlugin8.fromClass(RemoteSelectionsDecorator, {
853
+ ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
1188
854
  decorations: (value) => value.decorations
1189
855
  }),
1190
856
  styles
1191
857
  ];
1192
858
  };
1193
859
  var RemoteSelectionsDecorator = class {
1194
- _ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
860
+ _ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
1195
861
  _cursorConverter;
1196
862
  _provider;
1197
863
  _lastAnchor;
@@ -1340,7 +1006,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
1340
1006
  return true;
1341
1007
  }
1342
1008
  };
1343
- var styles = EditorView7.theme({
1009
+ var styles = EditorView5.theme({
1344
1010
  ".cm-collab-selection": {},
1345
1011
  ".cm-collab-selectionLine": {
1346
1012
  padding: 0,
@@ -1402,8 +1068,8 @@ var styles = EditorView7.theme({
1402
1068
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
1403
1069
  import { Context as Context2 } from "@dxos/context";
1404
1070
  import { invariant } from "@dxos/invariant";
1405
- import { log as log5 } from "@dxos/log";
1406
- var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
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";
1407
1073
  var DEBOUNCE_INTERVAL = 100;
1408
1074
  var SpaceAwarenessProvider = class {
1409
1075
  _remoteStates = /* @__PURE__ */ new Map();
@@ -1422,7 +1088,7 @@ var SpaceAwarenessProvider = class {
1422
1088
  this._info = info;
1423
1089
  }
1424
1090
  open() {
1425
- this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
1091
+ this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
1426
1092
  this._postTask = new DeferredTask(this._ctx, async () => {
1427
1093
  if (this._localState) {
1428
1094
  await this._messenger.postMessage(this._channel, {
@@ -1447,9 +1113,9 @@ var SpaceAwarenessProvider = class {
1447
1113
  void this._messenger.postMessage(this._channel, {
1448
1114
  kind: "query"
1449
1115
  }).catch((err) => {
1450
- log5.debug("failed to query awareness", {
1116
+ log4.debug("failed to query awareness", {
1451
1117
  err
1452
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
1118
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
1453
1119
  });
1454
1120
  }
1455
1121
  close() {
@@ -1461,7 +1127,7 @@ var SpaceAwarenessProvider = class {
1461
1127
  return Array.from(this._remoteStates.values());
1462
1128
  }
1463
1129
  update(position) {
1464
- invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
1130
+ invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
1465
1131
  this._localState = {
1466
1132
  peerId: this._peerId,
1467
1133
  position,
@@ -1470,22 +1136,22 @@ var SpaceAwarenessProvider = class {
1470
1136
  this._postTask.schedule();
1471
1137
  }
1472
1138
  _handleQueryMessage() {
1473
- invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
1139
+ invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
1474
1140
  this._postTask.schedule();
1475
1141
  }
1476
1142
  _handlePostMessage(message) {
1477
- invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
1143
+ invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
1478
1144
  this._remoteStates.set(message.state.peerId, message.state);
1479
1145
  this.remoteStateChange.emit();
1480
1146
  }
1481
1147
  };
1482
1148
 
1483
1149
  // src/extensions/blast.ts
1484
- import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1150
+ import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
1485
1151
  import defaultsDeep from "lodash.defaultsdeep";
1486
- import { throttle as throttle2 } from "@dxos/async";
1152
+ import { throttle } from "@dxos/async";
1487
1153
  import { invariant as invariant2 } from "@dxos/invariant";
1488
- var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
1154
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
1489
1155
  var defaultOptions = {
1490
1156
  effect: 2,
1491
1157
  maxParticles: 200,
@@ -1530,7 +1196,7 @@ var blast = (options = defaultOptions) => {
1530
1196
  };
1531
1197
  return [
1532
1198
  // Cursor moved.
1533
- EditorView8.updateListener.of((update2) => {
1199
+ EditorView6.updateListener.of((update2) => {
1534
1200
  if (blaster?.node !== update2.view.scrollDOM) {
1535
1201
  if (blaster) {
1536
1202
  blaster.destroy();
@@ -1603,7 +1269,7 @@ var Blaster = class {
1603
1269
  return this._node;
1604
1270
  }
1605
1271
  initialize() {
1606
- invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
1272
+ invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
1607
1273
  this._canvas = document.createElement("canvas");
1608
1274
  this._canvas.id = "code-blast-canvas";
1609
1275
  this._canvas.style.position = "absolute";
@@ -1632,7 +1298,7 @@ var Blaster = class {
1632
1298
  }
1633
1299
  }
1634
1300
  start() {
1635
- invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
1301
+ invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
1636
1302
  this._running = true;
1637
1303
  this.loop();
1638
1304
  }
@@ -1659,11 +1325,11 @@ var Blaster = class {
1659
1325
  this.drawParticles();
1660
1326
  requestAnimationFrame(this.loop.bind(this));
1661
1327
  }
1662
- shake = throttle2(({ time }) => {
1328
+ shake = throttle(({ time }) => {
1663
1329
  this._shakeTime = this._shakeTimeMax || time;
1664
1330
  this._shakeTimeMax = time;
1665
1331
  }, 100);
1666
- spawn = throttle2(({ element, point }) => {
1332
+ spawn = throttle(({ element, point }) => {
1667
1333
  const color = getRGBComponents(element, this._options.color);
1668
1334
  const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
1669
1335
  const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
@@ -1772,9 +1438,9 @@ var random = (min, max) => {
1772
1438
 
1773
1439
  // src/extensions/blocks.ts
1774
1440
  import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
1775
- import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
1441
+ import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
1776
1442
  import { mx as mx2 } from "@dxos/ui-theme";
1777
- var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
1443
+ var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
1778
1444
  decorations;
1779
1445
  constructor(view) {
1780
1446
  this.decorations = this.build(view);
@@ -1833,7 +1499,7 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
1833
1499
  });
1834
1500
  var blocks = () => [
1835
1501
  paragraphBlockPlugin,
1836
- EditorView9.baseTheme({
1502
+ EditorView7.baseTheme({
1837
1503
  ".cm-line.block-line": {
1838
1504
  paddingLeft: "0.75rem",
1839
1505
  paddingRight: "0.75rem",
@@ -1867,13 +1533,13 @@ var blocks = () => [
1867
1533
  ];
1868
1534
 
1869
1535
  // src/extensions/bookmarks.ts
1870
- import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
1536
+ import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
1871
1537
  import { keymap as keymap4 } from "@codemirror/view";
1872
- import { log as log6 } from "@dxos/log";
1873
- var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
1874
- var addBookmark = StateEffect4.define();
1875
- var removeBookmark = StateEffect4.define();
1876
- var clearBookmarks = StateEffect4.define();
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();
1877
1543
  var bookmarks = () => {
1878
1544
  return [
1879
1545
  bookmarksField,
@@ -1882,7 +1548,7 @@ var bookmarks = () => {
1882
1548
  key: "Mod-ArrowUp",
1883
1549
  run: (view) => {
1884
1550
  const bookmarks2 = view.state.field(bookmarksField);
1885
- log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
1551
+ log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
1886
1552
  return true;
1887
1553
  }
1888
1554
  },
@@ -1890,7 +1556,7 @@ var bookmarks = () => {
1890
1556
  key: "Mod-ArrowDown",
1891
1557
  run: (view) => {
1892
1558
  const bookmarks2 = view.state.field(bookmarksField);
1893
- log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
1559
+ log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
1894
1560
  return true;
1895
1561
  }
1896
1562
  }
@@ -1927,27 +1593,27 @@ var bookmarksField = StateField2.define({
1927
1593
 
1928
1594
  // src/extensions/comments.ts
1929
1595
  import { invertedEffects } from "@codemirror/commands";
1930
- import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
1931
- import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
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";
1932
1598
  import sortBy from "lodash.sortby";
1933
1599
  import { debounce as debounce2 } from "@dxos/async";
1934
- import { log as log7 } from "@dxos/log";
1600
+ import { log as log6 } from "@dxos/log";
1935
1601
  import { isNonNullable } from "@dxos/util";
1936
1602
 
1937
1603
  // src/extensions/selection.ts
1938
1604
  import { Transaction as Transaction3 } from "@codemirror/state";
1939
- import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view";
1605
+ import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
1940
1606
  import { debounce } from "@dxos/async";
1941
1607
  import { invariant as invariant3 } from "@dxos/invariant";
1942
1608
  import { isTruthy } from "@dxos/util";
1943
- var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
1609
+ var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
1944
1610
  var documentId = singleValueFacet();
1945
1611
  var stateRestoreAnnotation = "org.dxos.cm.state-restore";
1946
1612
  var createEditorStateTransaction = ({ scrollTo, selection }) => {
1947
1613
  return {
1948
1614
  selection,
1949
1615
  scrollIntoView: !scrollTo,
1950
- effects: scrollTo ? EditorView10.scrollIntoView(scrollTo, {
1616
+ effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
1951
1617
  yMargin: 96
1952
1618
  }) : void 0,
1953
1619
  annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
@@ -1955,12 +1621,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1955
1621
  };
1956
1622
  var createEditorStateStore = (keyPrefix) => ({
1957
1623
  getState: (id) => {
1958
- invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
1624
+ invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
1959
1625
  const state = localStorage.getItem(`${keyPrefix}/${id}`);
1960
1626
  return state ? JSON.parse(state) : void 0;
1961
1627
  },
1962
1628
  setState: (id, state) => {
1963
- invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
1629
+ invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
1964
1630
  localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
1965
1631
  }
1966
1632
  });
@@ -1973,7 +1639,7 @@ var selectionState = ({ getState, setState } = {}) => {
1973
1639
  // setStateDebounced(id, {});
1974
1640
  // },
1975
1641
  // }),
1976
- EditorView10.updateListener.of(({ view, transactions }) => {
1642
+ EditorView8.updateListener.of(({ view, transactions }) => {
1977
1643
  const id = view.state.facet(documentId);
1978
1644
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1979
1645
  return;
@@ -2012,10 +1678,10 @@ var selectionState = ({ getState, setState } = {}) => {
2012
1678
  };
2013
1679
 
2014
1680
  // src/extensions/comments.ts
2015
- var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
2016
- var setComments = StateEffect5.define();
2017
- var setSelection = StateEffect5.define();
2018
- var setCommentState = StateEffect5.define();
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();
2019
1685
  var commentsState = StateField3.define({
2020
1686
  create: (state) => ({
2021
1687
  id: state.facet(documentId),
@@ -2054,7 +1720,7 @@ var commentsState = StateField3.define({
2054
1720
  return value;
2055
1721
  }
2056
1722
  });
2057
- var styles2 = EditorView11.theme({
1723
+ var styles2 = EditorView9.theme({
2058
1724
  ".cm-comment, .cm-comment-current": {
2059
1725
  padding: "3px 0",
2060
1726
  color: "var(--color-cm-comment-text)",
@@ -2075,14 +1741,14 @@ var createCommentMark = (id, isCurrent) => Decoration7.mark({
2075
1741
  "data-comment-id": id
2076
1742
  }
2077
1743
  });
2078
- var commentsDecorations = EditorView11.decorations.compute([
1744
+ var commentsDecorations = EditorView9.decorations.compute([
2079
1745
  commentsState
2080
1746
  ], (state) => {
2081
1747
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
2082
1748
  const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2083
1749
  const range = comment.range;
2084
1750
  if (!range) {
2085
- log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
1751
+ log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
2086
1752
  return void 0;
2087
1753
  } else if (range.from === range.to) {
2088
1754
  return void 0;
@@ -2092,8 +1758,8 @@ var commentsDecorations = EditorView11.decorations.compute([
2092
1758
  }).filter(isNonNullable);
2093
1759
  return Decoration7.set(decorations2);
2094
1760
  });
2095
- var commentClickedEffect = StateEffect5.define();
2096
- var handleCommentClick = EditorView11.domEventHandlers({
1761
+ var commentClickedEffect = StateEffect3.define();
1762
+ var handleCommentClick = EditorView9.domEventHandlers({
2097
1763
  click: (event, view) => {
2098
1764
  let target = event.target;
2099
1765
  const editorRoot = view.dom;
@@ -2132,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
2132
1798
  }
2133
1799
  };
2134
1800
  return [
2135
- EditorView11.domEventHandlers({
1801
+ EditorView9.domEventHandlers({
2136
1802
  cut: handleTrack,
2137
1803
  copy: handleTrack
2138
1804
  }),
@@ -2154,7 +1820,7 @@ var trackPastedComments = (onUpdate) => {
2154
1820
  return effects;
2155
1821
  }),
2156
1822
  // Handle paste or the undo of comment deletion.
2157
- EditorView11.updateListener.of((update2) => {
1823
+ EditorView9.updateListener.of((update2) => {
2158
1824
  const restore = [];
2159
1825
  for (let i = 0; i < update2.transactions.length; i++) {
2160
1826
  const tr = update2.transactions[i];
@@ -2210,7 +1876,7 @@ var mapTrackedComment = (comment, changes) => ({
2210
1876
  from: changes.mapPos(comment.from, 1),
2211
1877
  to: changes.mapPos(comment.to, 1)
2212
1878
  });
2213
- var restoreCommentEffect = StateEffect5.define({
1879
+ var restoreCommentEffect = StateEffect3.define({
2214
1880
  map: mapTrackedComment
2215
1881
  });
2216
1882
  var createComment = (view) => {
@@ -2296,7 +1962,7 @@ var comments = (options = {}) => {
2296
1962
  //
2297
1963
  // Track deleted ranges and update ranges for decorations.
2298
1964
  //
2299
- EditorView11.updateListener.of(({ view, state, changes }) => {
1965
+ EditorView9.updateListener.of(({ view, state, changes }) => {
2300
1966
  let mod = false;
2301
1967
  const { comments: comments2, ...value } = state.field(commentsState);
2302
1968
  changes.iterChanges((from, to, from2, to2) => {
@@ -2328,7 +1994,7 @@ var comments = (options = {}) => {
2328
1994
  //
2329
1995
  // Track selection/proximity.
2330
1996
  //
2331
- EditorView11.updateListener.of(({ view, state }) => {
1997
+ EditorView9.updateListener.of(({ view, state }) => {
2332
1998
  let min = Infinity;
2333
1999
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2334
2000
  const { head } = state.selection.main;
@@ -2382,7 +2048,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2382
2048
  anchor: range.from
2383
2049
  } : void 0,
2384
2050
  effects: [
2385
- needsScroll ? EditorView11.scrollIntoView(range.from, center ? {
2051
+ needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2386
2052
  y: "center"
2387
2053
  } : void 0) : [],
2388
2054
  needsSelectionUpdate ? setSelection.of({
@@ -2413,7 +2079,7 @@ var ExternalCommentSync = class {
2413
2079
  this.unsubscribe();
2414
2080
  };
2415
2081
  };
2416
- var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fromClass(class {
2082
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
2417
2083
  constructor(view) {
2418
2084
  return new ExternalCommentSync(view, id, subscribe, getComments);
2419
2085
  }
@@ -2433,12 +2099,12 @@ var debugNodeLogger = (log12 = console.log) => {
2433
2099
  };
2434
2100
 
2435
2101
  // src/extensions/dnd.ts
2436
- import { EditorView as EditorView12, dropCursor } from "@codemirror/view";
2102
+ import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
2437
2103
  var dropFile = (options = {}) => {
2438
2104
  return [
2439
2105
  styles3,
2440
2106
  dropCursor(),
2441
- EditorView12.domEventHandlers({
2107
+ EditorView10.domEventHandlers({
2442
2108
  drop: (event, view) => {
2443
2109
  event.preventDefault();
2444
2110
  const files = event.dataTransfer?.files;
@@ -2457,7 +2123,7 @@ var dropFile = (options = {}) => {
2457
2123
  })
2458
2124
  ];
2459
2125
  };
2460
- var styles3 = EditorView12.theme({
2126
+ var styles3 = EditorView10.theme({
2461
2127
  ".cm-dropCursor": {
2462
2128
  borderLeft: "2px solid var(--color-accent-text)",
2463
2129
  color: "var(--color-accent-text)",
@@ -2479,10 +2145,10 @@ import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode"
2479
2145
  import defaultsDeep2 from "lodash.defaultsdeep";
2480
2146
  import { generateName } from "@dxos/display-name";
2481
2147
  import { log as log8 } from "@dxos/log";
2482
- import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
2148
+ import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
2483
2149
 
2484
2150
  // src/styles/theme.ts
2485
- import { EditorView as EditorView13 } from "@codemirror/view";
2151
+ import { EditorView as EditorView11 } from "@codemirror/view";
2486
2152
  import { mx as mx3 } from "@dxos/ui-theme";
2487
2153
  var headings = {
2488
2154
  1: {
@@ -2530,7 +2196,7 @@ var markdownTheme = {
2530
2196
  fontWeight: "100 !important"
2531
2197
  })
2532
2198
  };
2533
- var baseTheme = EditorView13.baseTheme({
2199
+ var baseTheme = EditorView11.baseTheme({
2534
2200
  /**
2535
2201
  * Outer frame.
2536
2202
  */
@@ -2542,7 +2208,7 @@ var baseTheme = EditorView13.baseTheme({
2542
2208
  * Scroller
2543
2209
  */
2544
2210
  ".cm-scroller": {
2545
- // Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
2211
+ // Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
2546
2212
  // stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
2547
2213
  // open/close) don't jump the user's view.
2548
2214
  overflowAnchor: "auto"
@@ -2653,7 +2319,8 @@ var baseTheme = EditorView13.baseTheme({
2653
2319
  textDecorationThickness: "1px",
2654
2320
  textDecorationColor: "var(--color-separator)",
2655
2321
  textUnderlineOffset: "2px",
2656
- borderRadius: ".125rem"
2322
+ borderRadius: ".125rem",
2323
+ cursor: "pointer"
2657
2324
  },
2658
2325
  ".cm-link > span": {
2659
2326
  color: "var(--color-accent-text)"
@@ -2691,12 +2358,12 @@ var baseTheme = EditorView13.baseTheme({
2691
2358
  padding: "4px"
2692
2359
  },
2693
2360
  ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
2694
- background: "var(--color-active-surface)",
2695
- color: "var(--color-base-surface-text)"
2361
+ background: "var(--color-current-surface)",
2362
+ color: "var(--color-base-foreground)"
2696
2363
  },
2697
2364
  ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2698
2365
  paddingLeft: "4px !important",
2699
- color: "var(--color-base-surface-text)"
2366
+ color: "var(--color-base-foreground)"
2700
2367
  },
2701
2368
  /**
2702
2369
  * Completion info.
@@ -2715,7 +2382,7 @@ var baseTheme = EditorView13.baseTheme({
2715
2382
  padding: "0 4px"
2716
2383
  },
2717
2384
  ".cm-completionMatchedText": {
2718
- color: "var(--color-base-surface-text)",
2385
+ color: "var(--color-base-foreground)",
2719
2386
  textDecoration: "none !important"
2720
2387
  },
2721
2388
  /**
@@ -2750,7 +2417,7 @@ var baseTheme = EditorView13.baseTheme({
2750
2417
  backgroundColor: "var(--color-input-surface)"
2751
2418
  },
2752
2419
  ".cm-panel input:focus, .cm-panel button:focus": {
2753
- outline: "1px solid var(--color-neutral-focus-indicator)"
2420
+ outline: "1px solid var(--color-focus-ring-subtle)"
2754
2421
  },
2755
2422
  ".cm-panel label": {
2756
2423
  display: "inline-flex",
@@ -2763,7 +2430,7 @@ var baseTheme = EditorView13.baseTheme({
2763
2430
  height: "8px",
2764
2431
  marginRight: "6px !important",
2765
2432
  padding: "2px !important",
2766
- color: "var(--color-neutral-focus-indicator)"
2433
+ color: "var(--color-focus-ring-subtle)"
2767
2434
  },
2768
2435
  ".cm-panel button": {
2769
2436
  "&:hover": {
@@ -2779,14 +2446,14 @@ var baseTheme = EditorView13.baseTheme({
2779
2446
  borderTop: "1px solid var(--color-separator)"
2780
2447
  }
2781
2448
  });
2782
- var editorGutter = EditorView13.theme({
2449
+ var editorGutter = EditorView11.theme({
2783
2450
  ".cm-gutters": {
2784
2451
  // NOTE: Non-transparent background required to cover content if scrolling horizontally.
2785
2452
  background: "var(--color-base-surface) !important",
2786
2453
  paddingRight: "1rem"
2787
2454
  }
2788
2455
  });
2789
- var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
2456
+ var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
2790
2457
  // Main content.
2791
2458
  ".cm-scroller": {
2792
2459
  fontFamily: monospace ? fontMono : fontBody
@@ -2799,9 +2466,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
2799
2466
  });
2800
2467
 
2801
2468
  // src/extensions/focus.ts
2802
- import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
2803
- import { EditorView as EditorView14 } from "@codemirror/view";
2804
- var focusEffect = StateEffect6.define();
2469
+ import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
2470
+ import { EditorView as EditorView12 } from "@codemirror/view";
2471
+ var focusEffect = StateEffect4.define();
2805
2472
  var focusField = StateField5.define({
2806
2473
  create: () => false,
2807
2474
  update: (value, tr) => {
@@ -2810,38 +2477,381 @@ var focusField = StateField5.define({
2810
2477
  return effect.value;
2811
2478
  }
2812
2479
  }
2813
- return value;
2480
+ return value;
2481
+ }
2482
+ });
2483
+ var focus = [
2484
+ focusField,
2485
+ EditorView12.domEventHandlers({
2486
+ focus: (_event, view) => {
2487
+ requestAnimationFrame(() => view.dispatch({
2488
+ effects: focusEffect.of(true)
2489
+ }));
2490
+ },
2491
+ blur: (_event, view) => {
2492
+ requestAnimationFrame(() => view.dispatch({
2493
+ effects: focusEffect.of(false)
2494
+ }));
2495
+ }
2496
+ })
2497
+ ];
2498
+
2499
+ // src/extensions/scrolling/auto-scroll.ts
2500
+ import { StateEffect as StateEffect6 } from "@codemirror/state";
2501
+ import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
2502
+ import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
2503
+ import { Domino } from "@dxos/ui";
2504
+ import { getSize } from "@dxos/ui-theme";
2505
+
2506
+ // src/extensions/scrolling/crawler.ts
2507
+ import { StateEffect as StateEffect5 } from "@codemirror/state";
2508
+ import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
2509
+ import { log as log7 } from "@dxos/log";
2510
+ var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
2511
+ var crawlerLineEffect = StateEffect5.define();
2512
+ var crawlerActiveEffect = StateEffect5.define();
2513
+ var scrollToLine = (view, options) => {
2514
+ view.dispatch({
2515
+ effects: crawlerLineEffect.of(options)
2516
+ });
2517
+ };
2518
+ var crawler = ({ overScroll = 0 } = {}) => {
2519
+ const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
2520
+ view;
2521
+ crawler;
2522
+ constructor(view) {
2523
+ this.view = view;
2524
+ this.crawler = createCrawler(this.view);
2525
+ }
2526
+ // No-op.
2527
+ destroy() {
2528
+ this.crawler.cancel();
2529
+ }
2530
+ cancel() {
2531
+ this.crawler.cancel();
2532
+ }
2533
+ crawl(start = false) {
2534
+ if (start) {
2535
+ this.crawler.scroll();
2536
+ } else {
2537
+ this.crawler.cancel();
2538
+ }
2539
+ }
2540
+ scroll({ line, offset = 0, position, behavior = "instant" }) {
2541
+ const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
2542
+ const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
2543
+ const doc = this.view.state.doc;
2544
+ let targetScrollTop = scrollHeight - clientHeight + offset;
2545
+ if (line >= 0 && line <= doc.lines - 1) {
2546
+ const lineStart = doc.line(line + 1).from;
2547
+ const coords = this.view.coordsAtPos(lineStart);
2548
+ if (coords) {
2549
+ const currentScrollTop = scrollTop;
2550
+ const maxScrollTop = scrollHeight - clientHeight;
2551
+ if (position === "end") {
2552
+ targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
2553
+ } else {
2554
+ targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
2555
+ }
2556
+ targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
2557
+ }
2558
+ }
2559
+ requestAnimationFrame(() => {
2560
+ this.view.scrollDOM.scrollTo({
2561
+ top: targetScrollTop
2562
+ });
2563
+ });
2564
+ }
2565
+ });
2566
+ return [
2567
+ crawlerPlugin,
2568
+ // Listen for effect.
2569
+ EditorView13.updateListener.of((update2) => {
2570
+ update2.transactions.forEach((transaction) => {
2571
+ try {
2572
+ const plugin = update2.view.plugin(crawlerPlugin);
2573
+ if (plugin) {
2574
+ for (const effect of transaction.effects) {
2575
+ if (effect.is(crawlerActiveEffect)) {
2576
+ plugin.crawl(effect.value);
2577
+ } else if (effect.is(crawlerLineEffect)) {
2578
+ plugin.scroll(effect.value);
2579
+ }
2580
+ }
2581
+ }
2582
+ } catch (err) {
2583
+ log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 98, S: void 0 });
2584
+ }
2585
+ });
2586
+ }),
2587
+ // Styles.
2588
+ EditorView13.theme({
2589
+ ".cm-scroller": {
2590
+ overflowY: "scroll",
2591
+ // Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
2592
+ // expanding their TogglePanel), the browser picks a stable element near the viewport
2593
+ // top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
2594
+ // logic still has the final word when pinned (forces scrollTop to scrollHeight).
2595
+ overflowAnchor: "auto"
2596
+ },
2597
+ ".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
2598
+ display: "none"
2599
+ },
2600
+ ".cm-scroller::-webkit-scrollbar-thumb": {
2601
+ background: "transparent",
2602
+ transition: "background 0.15s"
2603
+ },
2604
+ "&:hover .cm-scroller::-webkit-scrollbar-thumb": {
2605
+ background: "var(--color-scrollbar-thumb)"
2606
+ },
2607
+ // Spacer below the last text line. Implemented as a real block pseudo-element
2608
+ // (rather than `padding-bottom` on `.cm-content`) so it materializes in the
2609
+ // scroller's `scrollHeight` regardless of how `padding` is reset by the base
2610
+ // theme or downstream classes — this is what gives auto-scroll its head-room
2611
+ // so the last line stays `overScroll` px above the viewport bottom.
2612
+ ".cm-content::after": {
2613
+ content: '""',
2614
+ display: "block",
2615
+ height: `${overScroll}px`
2616
+ },
2617
+ ".cm-scroll-button": {
2618
+ position: "absolute",
2619
+ bottom: "0.5rem",
2620
+ right: "1rem"
2621
+ }
2622
+ })
2623
+ ];
2624
+ };
2625
+ function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
2626
+ const el = view.scrollDOM;
2627
+ let currentTop = 0;
2628
+ let velocity = 0;
2629
+ let rafId = null;
2630
+ let lastTime = 0;
2631
+ function frame(now) {
2632
+ const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
2633
+ lastTime = now;
2634
+ const targetTop = el.scrollHeight - el.clientHeight;
2635
+ const delta = targetTop - currentTop;
2636
+ if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
2637
+ el.scrollTop = targetTop;
2638
+ currentTop = targetTop;
2639
+ velocity = 0;
2640
+ rafId = null;
2641
+ lastTime = 0;
2642
+ return;
2643
+ }
2644
+ const accel = omega * omega * delta - 2 * omega * velocity;
2645
+ velocity += accel * dt;
2646
+ currentTop += velocity * dt;
2647
+ el.scrollTop = currentTop;
2648
+ rafId = requestAnimationFrame(frame);
2814
2649
  }
2815
- });
2816
- var focus = [
2817
- focusField,
2818
- EditorView14.domEventHandlers({
2819
- focus: (_event, view) => {
2820
- requestAnimationFrame(() => view.dispatch({
2821
- effects: focusEffect.of(true)
2822
- }));
2650
+ return {
2651
+ scroll: () => {
2652
+ if (rafId === null) {
2653
+ currentTop = el.scrollTop;
2654
+ lastTime = 0;
2655
+ rafId = requestAnimationFrame(frame);
2656
+ }
2823
2657
  },
2824
- blur: (_event, view) => {
2825
- requestAnimationFrame(() => view.dispatch({
2826
- effects: focusEffect.of(false)
2827
- }));
2658
+ cancel: () => {
2659
+ if (rafId !== null) {
2660
+ cancelAnimationFrame(rafId);
2661
+ velocity = 0;
2662
+ lastTime = 0;
2663
+ rafId = null;
2664
+ }
2828
2665
  }
2829
- })
2830
- ];
2666
+ };
2667
+ }
2668
+
2669
+ // src/extensions/scrolling/auto-scroll.ts
2670
+ var autoScrollEffect = StateEffect6.define();
2671
+ var autoScroll = ({ scrollOnResize = true } = {}) => {
2672
+ let buttonContainer;
2673
+ let isPinned = true;
2674
+ let jumpPending = false;
2675
+ let enabled = true;
2676
+ let firstUpdate = true;
2677
+ const setPinned = (pinned) => {
2678
+ buttonContainer?.classList.toggle("opacity-0", pinned);
2679
+ isPinned = pinned;
2680
+ };
2681
+ return [
2682
+ // Update listener for scrolling when content changes.
2683
+ EditorView14.updateListener.of((update2) => {
2684
+ const { view, heightChanged, state, startState } = update2;
2685
+ for (const tr of update2.transactions) {
2686
+ for (const effect of tr.effects) {
2687
+ if (effect.is(autoScrollEffect)) {
2688
+ enabled = effect.value;
2689
+ if (enabled) {
2690
+ setPinned(true);
2691
+ view.dispatch({
2692
+ effects: crawlerActiveEffect.of(true)
2693
+ });
2694
+ } else {
2695
+ view.dispatch({
2696
+ effects: crawlerActiveEffect.of(false)
2697
+ });
2698
+ }
2699
+ }
2700
+ }
2701
+ }
2702
+ if (!enabled) {
2703
+ return;
2704
+ }
2705
+ if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
2706
+ firstUpdate = false;
2707
+ jumpPending = true;
2708
+ requestAnimationFrame(() => {
2709
+ view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
2710
+ jumpPending = false;
2711
+ });
2712
+ return;
2713
+ }
2714
+ firstUpdate = false;
2715
+ if (jumpPending) {
2716
+ return;
2717
+ }
2718
+ if (heightChanged) {
2719
+ if (isPinned) {
2720
+ const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
2721
+ const delta = scrollHeight - scrollTop - clientHeight;
2722
+ if (delta > 0) {
2723
+ setPinned(true);
2724
+ view.dispatch({
2725
+ effects: crawlerActiveEffect.of(true)
2726
+ });
2727
+ } else if (delta < -1) {
2728
+ setPinned(false);
2729
+ }
2730
+ } else {
2731
+ if (state.doc.length === 0) {
2732
+ setPinned(true);
2733
+ }
2734
+ }
2735
+ }
2736
+ }),
2737
+ // Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
2738
+ // window resize). Doc-driven height changes are handled by the updateListener above; this
2739
+ // observer covers the case where the viewport changes while the doc length is unchanged.
2740
+ scrollOnResize ? ViewPlugin10.fromClass(class {
2741
+ observer;
2742
+ firstObservation = true;
2743
+ destroyed = false;
2744
+ constructor(view) {
2745
+ const onResize = throttle2(() => {
2746
+ if (this.destroyed || !enabled) {
2747
+ return;
2748
+ }
2749
+ setPinned(true);
2750
+ requestAnimationFrame(() => {
2751
+ if (this.destroyed) {
2752
+ return;
2753
+ }
2754
+ view.scrollDOM.scrollTo({
2755
+ top: view.scrollDOM.scrollHeight,
2756
+ behavior: "instant"
2757
+ });
2758
+ view.dispatch({
2759
+ effects: crawlerActiveEffect.of(false)
2760
+ });
2761
+ });
2762
+ }, 50);
2763
+ this.observer = new ResizeObserver(() => {
2764
+ if (this.firstObservation) {
2765
+ this.firstObservation = false;
2766
+ return;
2767
+ }
2768
+ onResize();
2769
+ });
2770
+ this.observer.observe(view.scrollDOM);
2771
+ }
2772
+ destroy() {
2773
+ this.destroyed = true;
2774
+ this.observer.disconnect();
2775
+ }
2776
+ }) : [],
2777
+ // Detect user scroll and unpin (or re-pin if scrolled to the bottom).
2778
+ ViewPlugin10.fromClass(class {
2779
+ cleanup;
2780
+ constructor(view) {
2781
+ const onUserScroll = throttle2(() => {
2782
+ requestAnimationFrame(() => {
2783
+ const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
2784
+ const delta = scrollHeight - scrollTop - clientHeight;
2785
+ const pinned = Math.abs(delta) <= 1;
2786
+ setPinned(pinned);
2787
+ if (!pinned) {
2788
+ view.dispatch({
2789
+ effects: crawlerActiveEffect.of(false)
2790
+ });
2791
+ }
2792
+ });
2793
+ }, 500);
2794
+ this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
2795
+ if (isPinned) {
2796
+ setPinned(false);
2797
+ view.dispatch({
2798
+ effects: crawlerActiveEffect.of(false)
2799
+ });
2800
+ }
2801
+ onUserScroll();
2802
+ });
2803
+ }
2804
+ destroy() {
2805
+ this.cleanup();
2806
+ }
2807
+ }),
2808
+ // Scroll button.
2809
+ ViewPlugin10.fromClass(class {
2810
+ constructor(view) {
2811
+ const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
2812
+ icon: "ph--arrow-down--regular"
2813
+ });
2814
+ const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
2815
+ "data-density": "fine"
2816
+ }).append(icon).on("click", () => {
2817
+ setPinned(true);
2818
+ view.dispatch({
2819
+ effects: crawlerLineEffect.of({
2820
+ line: -1,
2821
+ position: "end",
2822
+ behavior: "smooth"
2823
+ })
2824
+ });
2825
+ });
2826
+ buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
2827
+ view.scrollDOM.parentElement.appendChild(buttonContainer);
2828
+ }
2829
+ })
2830
+ ];
2831
+ };
2832
+ function createUserScrollDetector(element, onUserScroll) {
2833
+ return combine(addEventListener(element, "wheel", () => onUserScroll(), {
2834
+ passive: true
2835
+ }), addEventListener(element, "pointerdown", (event) => {
2836
+ if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
2837
+ onUserScroll();
2838
+ }
2839
+ }));
2840
+ }
2831
2841
 
2832
- // src/extensions/scroll-past-end.ts
2842
+ // src/extensions/scrolling/scroll-past-end.ts
2833
2843
  import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
2834
2844
  var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
2835
- height = 1e3;
2836
- attrs = {
2837
- style: "padding-bottom: 1000px"
2845
+ _height = 1e3;
2846
+ _attrs = {
2847
+ style: `padding-bottom: ${this._height}px`
2838
2848
  };
2839
2849
  update({ view }) {
2840
2850
  const lastLineBlock = view.lineBlockAt(view.state.doc.length);
2841
2851
  const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
2842
- if (height >= 0 && height !== this.height) {
2843
- this.height = height;
2844
- this.attrs = {
2852
+ if (height >= 0 && height !== this._height) {
2853
+ this._height = height;
2854
+ this._attrs = {
2845
2855
  style: `padding-bottom: ${height}px`
2846
2856
  };
2847
2857
  }
@@ -2849,9 +2859,22 @@ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
2849
2859
  });
2850
2860
  var scrollPastEnd = () => [
2851
2861
  scrollPastEndPlugin,
2852
- EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
2862
+ EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
2853
2863
  ];
2854
2864
 
2865
+ // src/extensions/scrolling/scroller.ts
2866
+ import { isTruthy as isTruthy2 } from "@dxos/util";
2867
+ var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
2868
+ return [
2869
+ crawler({
2870
+ overScroll
2871
+ }),
2872
+ autoScroll2 && autoScroll({
2873
+ scrollOnResize
2874
+ })
2875
+ ].filter(isTruthy2);
2876
+ };
2877
+
2855
2878
  // src/extensions/factories.ts
2856
2879
  var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
2857
2880
  var tabbable = EditorView16.contentAttributes.of({
@@ -2959,8 +2982,8 @@ var createBasicExtensions = (propsProp) => {
2959
2982
  preventDefault: true,
2960
2983
  run: () => true
2961
2984
  }
2962
- ].filter(isTruthy2))
2963
- ].filter(isTruthy2);
2985
+ ].filter(isTruthy3))
2986
+ ].filter(isTruthy3);
2964
2987
  };
2965
2988
  var grow = {
2966
2989
  editor: {
@@ -3002,7 +3025,7 @@ var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, synta
3002
3025
  }
3003
3026
  }
3004
3027
  })
3005
- ].filter(isTruthy2);
3028
+ ].filter(isTruthy3);
3006
3029
  };
3007
3030
  var createDataExtensions = ({ id, text, messenger, identity }) => {
3008
3031
  const extensions = [];
@@ -4326,7 +4349,7 @@ import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lan
4326
4349
  import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
4327
4350
  import { languages } from "@codemirror/language-data";
4328
4351
  import { keymap as keymap9 } from "@codemirror/view";
4329
- import { isTruthy as isTruthy3 } from "@dxos/util";
4352
+ import { isTruthy as isTruthy4 } from "@dxos/util";
4330
4353
 
4331
4354
  // src/extensions/markdown/highlight.ts
4332
4355
  import { markdownLanguage } from "@codemirror/lang-markdown";
@@ -4558,7 +4581,7 @@ var createMarkdownExtensions = (options = {}) => {
4558
4581
  ...defaultKeymap2,
4559
4582
  // TODO(burdon): Remove?
4560
4583
  ...completionKeymap
4561
- ].filter(isTruthy3))
4584
+ ].filter(isTruthy4))
4562
4585
  ];
4563
4586
  };
4564
4587
  var noFencedCodeFolding = {
@@ -6639,7 +6662,7 @@ var decorations = () => [
6639
6662
  marginBottom: "2px"
6640
6663
  },
6641
6664
  ".cm-list-item-focused": {
6642
- borderColor: "var(--color-neutral-focus-indicator)"
6665
+ borderColor: "var(--color-focus-ring-subtle)"
6643
6666
  },
6644
6667
  "&:focus-within .cm-list-item-selected": {
6645
6668
  borderColor: "var(--color-separator)"
@@ -7878,7 +7901,7 @@ var xmlFormatting = ({ skip } = {}) => {
7878
7901
  }),
7879
7902
  EditorView31.baseTheme({
7880
7903
  ".cm-xml-element": {
7881
- backgroundColor: "var(--color-active-surface)",
7904
+ backgroundColor: "var(--color-current-surface)",
7882
7905
  borderRadius: "0.25rem",
7883
7906
  padding: "0.25rem"
7884
7907
  },
@@ -8139,7 +8162,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8139
8162
  anchor: line.from,
8140
8163
  head: line.from
8141
8164
  },
8142
- effects: scrollerLineEffect.of({
8165
+ effects: crawlerLineEffect.of({
8143
8166
  line: line.number - 1,
8144
8167
  offset: -16
8145
8168
  })
@@ -8172,7 +8195,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8172
8195
  anchor: line.to,
8173
8196
  head: line.to
8174
8197
  },
8175
- effects: scrollerLineEffect.of({
8198
+ effects: crawlerLineEffect.of({
8176
8199
  line: line.number - 1,
8177
8200
  offset: -16
8178
8201
  })
@@ -8184,7 +8207,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8184
8207
  anchor: line.to,
8185
8208
  head: line.to
8186
8209
  },
8187
- effects: scrollerLineEffect.of({
8210
+ effects: crawlerLineEffect.of({
8188
8211
  line: line.number - 1,
8189
8212
  position: "end"
8190
8213
  })
@@ -8503,6 +8526,9 @@ export {
8503
8526
  commentsState,
8504
8527
  compactSlots,
8505
8528
  convertTreeToJson,
8529
+ crawler,
8530
+ crawlerActiveEffect,
8531
+ crawlerLineEffect,
8506
8532
  createBasicExtensions,
8507
8533
  createComment,
8508
8534
  createCrawler,
@@ -8590,8 +8616,6 @@ export {
8590
8616
  scrollThreadIntoView,
8591
8617
  scrollToLine,
8592
8618
  scroller,
8593
- scrollerCrawlEffect,
8594
- scrollerLineEffect,
8595
8619
  selectionState,
8596
8620
  setBlockquote,
8597
8621
  setComments,