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