@pierre/diffs 1.3.0-beta.10 → 1.3.0-beta.11

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 (67) hide show
  1. package/dist/components/CodeView.d.ts.map +1 -1
  2. package/dist/components/CodeView.js +1 -16
  3. package/dist/components/CodeView.js.map +1 -1
  4. package/dist/components/File.d.ts +2 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +6 -2
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts +8 -2
  9. package/dist/components/FileDiff.d.ts.map +1 -1
  10. package/dist/components/FileDiff.js +26 -8
  11. package/dist/components/FileDiff.js.map +1 -1
  12. package/dist/components/VirtualizedFileDiff.d.ts +1 -0
  13. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  14. package/dist/components/VirtualizedFileDiff.js +4 -0
  15. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  16. package/dist/editor/editStack.d.ts +5 -0
  17. package/dist/editor/editStack.d.ts.map +1 -1
  18. package/dist/editor/editStack.js +53 -12
  19. package/dist/editor/editStack.js.map +1 -1
  20. package/dist/editor/editor.d.ts.map +1 -1
  21. package/dist/editor/editor.js +52 -32
  22. package/dist/editor/editor.js.map +1 -1
  23. package/dist/editor/editor2.js +1 -1
  24. package/dist/editor/marker.d.ts +3 -3
  25. package/dist/editor/marker.d.ts.map +1 -1
  26. package/dist/editor/marker.js +89 -89
  27. package/dist/editor/marker.js.map +1 -1
  28. package/dist/editor/pieceTable.d.ts.map +1 -1
  29. package/dist/editor/pieceTable.js +55 -20
  30. package/dist/editor/pieceTable.js.map +1 -1
  31. package/dist/editor/popover.js +4 -0
  32. package/dist/editor/popover.js.map +1 -1
  33. package/dist/editor/selection.d.ts +2 -2
  34. package/dist/editor/selection.d.ts.map +1 -1
  35. package/dist/editor/selection.js +2 -2
  36. package/dist/editor/selection.js.map +1 -1
  37. package/dist/editor/textDocument.js +1 -1
  38. package/dist/editor/textDocument.js.map +1 -1
  39. package/dist/editor/tokenizer.d.ts.map +1 -1
  40. package/dist/editor/tokenizer.js +7 -2
  41. package/dist/editor/tokenizer.js.map +1 -1
  42. package/dist/index.d.ts +2 -2
  43. package/dist/managers/InteractionManager.d.ts +18 -7
  44. package/dist/managers/InteractionManager.d.ts.map +1 -1
  45. package/dist/managers/InteractionManager.js +154 -99
  46. package/dist/managers/InteractionManager.js.map +1 -1
  47. package/dist/react/index.d.ts +2 -2
  48. package/dist/react/utils/useFileDiffInstance.js +1 -6
  49. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  50. package/dist/react/utils/useFileInstance.js +1 -4
  51. package/dist/react/utils/useFileInstance.js.map +1 -1
  52. package/dist/ssr/index.d.ts +2 -2
  53. package/dist/style.js +1 -1
  54. package/dist/types.d.ts +7 -1
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/utils/computeFileOffsets.d.ts.map +1 -1
  57. package/dist/utils/computeFileOffsets.js +34 -5
  58. package/dist/utils/computeFileOffsets.js.map +1 -1
  59. package/dist/utils/isGutterUtilityPath.d.ts +5 -0
  60. package/dist/utils/isGutterUtilityPath.d.ts.map +1 -0
  61. package/dist/utils/isGutterUtilityPath.js +12 -0
  62. package/dist/utils/isGutterUtilityPath.js.map +1 -0
  63. package/dist/worker/worker-portable.js +34 -5
  64. package/dist/worker/worker-portable.js.map +1 -1
  65. package/dist/worker/worker.js +34 -5
  66. package/dist/worker/worker.js.map +1 -1
  67. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
+ import { dequeueRender, queueRender } from "./UniversalRenderingManager.js";
1
2
  import { areSelectionsEqual } from "../utils/areSelectionsEqual.js";
2
3
  import { areSelectionPointsEqual } from "../utils/areSelectionPointsEqual.js";
3
4
  import { createGutterUtilityElement } from "../utils/createGutterUtilityElement.js";
5
+ import { isGutterUtilityPath } from "../utils/isGutterUtilityPath.js";
4
6
  import { toHtml } from "hast-util-to-html";
5
7
  //#region src/managers/InteractionManager.ts
6
8
  var InteractionManager = class {
@@ -18,13 +20,15 @@ var InteractionManager = class {
18
20
  hasPointerListeners = false;
19
21
  hasDocumentPointerListeners = false;
20
22
  selectedRange = null;
21
- activeLineHighlightSide;
22
- activeLineNumberOnly = false;
23
- editorAttached = false;
23
+ selectedRangeHighlightSide;
24
+ selectedRangeLineNumberOnly = false;
25
+ editorActiveLine = null;
26
+ editorActiveLineSide;
27
+ editorLineNumberOnly = false;
24
28
  proposedSelectedRange;
25
- renderedSelectionRange;
29
+ renderedSelectedLinesState;
30
+ renderedEditorActiveLineState;
26
31
  selectionAnchor;
27
- queuedSelectionRender;
28
32
  pointerSession = { mode: "idle" };
29
33
  constructor(mode, options) {
30
34
  this.mode = mode;
@@ -50,13 +54,11 @@ var InteractionManager = class {
50
54
  this.clearHoveredToken();
51
55
  this.detachDocumentPointerListeners();
52
56
  this.clearPointerSession();
53
- if (this.queuedSelectionRender != null) {
54
- cancelAnimationFrame(this.queuedSelectionRender);
55
- this.queuedSelectionRender = void 0;
56
- }
57
+ dequeueRender(this.renderSelection);
57
58
  this.interactiveLinesAttr = false;
58
59
  this.interactiveLineNumbersAttr = false;
59
60
  this.hasPointerListeners = false;
61
+ this.setSelectionDirty();
60
62
  }
61
63
  setup(pre) {
62
64
  this.setSelectionDirty();
@@ -83,27 +85,33 @@ var InteractionManager = class {
83
85
  this.placeUtility();
84
86
  }
85
87
  setSelectionDirty() {
86
- this.renderedSelectionRange = void 0;
87
- }
88
- setEditorAttached(attached) {
89
- if (this.editorAttached === attached) return;
90
- this.editorAttached = attached;
91
- this.setSelectionDirty();
92
- this.renderSelection();
88
+ this.renderedSelectedLinesState = void 0;
89
+ this.renderedEditorActiveLineState = void 0;
93
90
  }
94
91
  isSelectionDirty() {
95
- return this.renderedSelectionRange === null;
92
+ return this.renderedSelectedLinesState === void 0 || this.renderedEditorActiveLineState === void 0;
96
93
  }
97
94
  setSelection(range, options) {
98
95
  const isRangeChange = !(range === this.selectedRange || areSelectionsEqual(range ?? void 0, this.selectedRange ?? void 0));
99
- if (!this.isSelectionDirty() && !isRangeChange) return;
96
+ const lineNumberOnly = options?.lineNumberOnly ?? false;
97
+ const isStyleChange = options?.activeLineSide !== this.selectedRangeHighlightSide || lineNumberOnly !== this.selectedRangeLineNumberOnly;
98
+ if (!this.isSelectionDirty() && !isRangeChange && !isStyleChange) return;
100
99
  this.proposedSelectedRange = void 0;
101
100
  this.selectedRange = range;
102
- this.activeLineHighlightSide = options?.activeLineSide;
103
- this.activeLineNumberOnly = options?.lineNumberOnly ?? false;
101
+ this.selectedRangeHighlightSide = options?.activeLineSide;
102
+ this.selectedRangeLineNumberOnly = lineNumberOnly;
104
103
  this.renderSelection();
105
104
  this.placeUtility();
106
- if (isRangeChange && options?.notify !== false) this.notifySelectionCommitted();
105
+ if (isRangeChange && options?.notify !== false) this.notifySelectionCommitted(range);
106
+ }
107
+ setEditorActiveLine(lineNumber, { lineNumberOnly = false, side } = {}) {
108
+ const isLineChange = lineNumber !== this.editorActiveLine;
109
+ const isStyleChange = side !== this.editorActiveLineSide || lineNumberOnly !== this.editorLineNumberOnly;
110
+ if (!this.isSelectionDirty() && !isLineChange && !isStyleChange) return;
111
+ this.editorActiveLine = lineNumber;
112
+ this.editorActiveLineSide = side;
113
+ this.editorLineNumberOnly = lineNumberOnly;
114
+ this.renderSelection();
107
115
  }
108
116
  getSelection() {
109
117
  return this.selectedRange;
@@ -351,7 +359,7 @@ var InteractionManager = class {
351
359
  this.attachDocumentPointerListeners();
352
360
  }
353
361
  startGutterSelectionFromPointerDown(event) {
354
- const { enableLineSelection = false, onGutterUtilityClick } = this.options;
362
+ const { onGutterUtilityClick } = this.options;
355
363
  if (onGutterUtilityClick == null) return;
356
364
  const selectedEndpoints = this.currentSelectionEnds();
357
365
  const point = selectedEndpoints?.bottom ?? this.resolveSelectionPoint(event, {
@@ -368,18 +376,15 @@ var InteractionManager = class {
368
376
  anchor,
369
377
  current: point
370
378
  };
371
- if (enableLineSelection) {
372
- this.selectionAnchor = {
373
- lineNumber: anchor.lineNumber,
374
- side: anchor.side
375
- };
376
- this.updateSelection(point.lineNumber, point.side, false);
377
- this.notifySelectionStart(this.getCurrentSelectionRange());
378
- }
379
+ this.selectionAnchor = {
380
+ lineNumber: anchor.lineNumber,
381
+ side: anchor.side
382
+ };
383
+ this.updateSelection(point.lineNumber, point.side, false);
384
+ this.notifySelectionStart(this.getCurrentSelectionRange());
379
385
  this.attachDocumentPointerListeners();
380
386
  }
381
387
  handleDocumentPointerMove = (event) => {
382
- const { enableLineSelection = false } = this.options;
383
388
  switch (this.pointerSession.mode) {
384
389
  case "idle": return;
385
390
  case "gutterSelecting": {
@@ -388,7 +393,7 @@ var InteractionManager = class {
388
393
  const point = this.resolveSelectionPoint(event, { source: "coordinates-first" });
389
394
  if (point == null) return;
390
395
  this.pointerSession.current = point;
391
- if (enableLineSelection === true) this.updateSelection(point.lineNumber, point.side);
396
+ this.updateSelection(point.lineNumber, point.side);
392
397
  return;
393
398
  }
394
399
  case "selecting": {
@@ -427,24 +432,24 @@ var InteractionManager = class {
427
432
  }
428
433
  };
429
434
  handleDocumentPointerUp = (event) => {
430
- const { enableLineSelection = false, onGutterUtilityClick } = this.options;
435
+ const { onGutterUtilityClick } = this.options;
431
436
  switch (this.pointerSession.mode) {
432
437
  case "idle": return;
433
438
  case "gutterSelecting": {
434
- if (event.pointerId !== this.pointerSession.pointerId) return;
439
+ const { pointerSession: session } = this;
440
+ if (event.pointerId !== session.pointerId) return;
435
441
  event.preventDefault();
436
442
  const point = this.resolveSelectionPoint(event, { source: "coordinates-first" });
437
443
  if (point != null) {
438
- this.pointerSession.current = point;
439
- if (enableLineSelection) this.updateSelection(point.lineNumber, point.side);
444
+ session.current = point;
445
+ this.updateSelection(point.lineNumber, point.side);
440
446
  }
441
- onGutterUtilityClick?.(this.buildSelectedLineRange(this.pointerSession.anchor, this.pointerSession.current));
447
+ const completedRange = this.buildSelectedLineRange(session.anchor, session.current);
448
+ onGutterUtilityClick?.({ ...completedRange });
442
449
  this.selectionAnchor = void 0;
443
- if (enableLineSelection) {
444
- this.notifySelectionEnd(this.getCurrentSelectionRange());
445
- this.notifySelectionCommitted();
446
- this.clearProposedSelection();
447
- }
450
+ this.notifySelectionEnd(completedRange);
451
+ this.notifySelectionCommitted(completedRange);
452
+ this.clearProposedSelection();
448
453
  this.clearPointerSession();
449
454
  this.detachDocumentPointerListeners();
450
455
  return;
@@ -457,7 +462,7 @@ var InteractionManager = class {
457
462
  this.clearPendingSingleLineState();
458
463
  this.detachDocumentPointerListeners();
459
464
  this.notifySelectionEnd(this.getCurrentSelectionRange());
460
- this.notifySelectionCommitted();
465
+ this.notifySelectionCommitted(this.getCurrentSelectionRange());
461
466
  this.clearProposedSelection();
462
467
  return;
463
468
  case "selecting":
@@ -467,7 +472,7 @@ var InteractionManager = class {
467
472
  this.detachDocumentPointerListeners();
468
473
  this.clearPointerSession();
469
474
  this.notifySelectionEnd(this.getCurrentSelectionRange());
470
- this.notifySelectionCommitted();
475
+ this.notifySelectionCommitted(this.getCurrentSelectionRange());
471
476
  this.clearProposedSelection();
472
477
  }
473
478
  };
@@ -720,12 +725,12 @@ var InteractionManager = class {
720
725
  nextRange = this.buildSelectionRange(anchorLine, currentLine, anchorSide, side);
721
726
  }
722
727
  if (areSelectionsEqual(previousRange ?? void 0, nextRange ?? void 0)) return;
723
- this.activeLineHighlightSide = void 0;
724
- this.activeLineNumberOnly = false;
728
+ this.selectedRangeHighlightSide = void 0;
729
+ this.selectedRangeLineNumberOnly = false;
725
730
  if (this.options.controlledSelection === true) this.proposedSelectedRange = nextRange;
726
731
  else {
727
732
  this.selectedRange = nextRange;
728
- this.queuedSelectionRender ??= requestAnimationFrame(this.renderSelection);
733
+ queueRender(this.renderSelection);
729
734
  }
730
735
  this.placeUtility();
731
736
  if (emitChange) this.notifySelectionChangeDelta();
@@ -739,70 +744,121 @@ var InteractionManager = class {
739
744
  end: split ? finalIndexes[1] : finalIndexes[0]
740
745
  } : void 0;
741
746
  }
742
- highlightLineNumberOnly() {
743
- if (this.activeLineHighlightSide != null) return this.activeLineNumberOnly;
744
- return this.activeLineNumberOnly || this.editorAttached;
747
+ getSelectionRenderState() {
748
+ return {
749
+ selectedLines: {
750
+ range: this.selectedRange,
751
+ highlightSide: this.selectedRangeHighlightSide,
752
+ lineNumberOnly: this.selectedRangeLineNumberOnly
753
+ },
754
+ editorActiveLine: {
755
+ range: this.editorActiveLine == null ? null : {
756
+ start: this.editorActiveLine,
757
+ end: this.editorActiveLine,
758
+ side: this.editorActiveLineSide
759
+ },
760
+ highlightSide: this.editorActiveLineSide,
761
+ lineNumberOnly: this.editorLineNumberOnly
762
+ }
763
+ };
745
764
  }
746
- renderSelection = () => {
747
- if (this.queuedSelectionRender != null) {
748
- cancelAnimationFrame(this.queuedSelectionRender);
749
- this.queuedSelectionRender = void 0;
765
+ resolveLineRenderRange(state, split, source) {
766
+ if (state.range == null) return;
767
+ const rowRange = this.getIndexesFromSelection(state.range, split);
768
+ if (rowRange == null) {
769
+ console.error({
770
+ rowRange,
771
+ range: state.range
772
+ });
773
+ throw new Error(`InteractionManager.renderSelection: No valid ${source} rowRange`);
750
774
  }
751
- if (this.pre == null || this.renderedSelectionRange === this.selectedRange) return;
752
- const allSelected = this.pre.querySelectorAll("[data-selected-line]");
753
- for (const element of allSelected) element.removeAttribute("data-selected-line");
754
- this.renderedSelectionRange = this.selectedRange;
755
- if (this.selectedRange == null) return;
775
+ return rowRange;
776
+ }
777
+ getLineRenderColumns(selectedLines, selectedRowRange, editorActiveLine, editorRowRange) {
778
+ if (this.pre == null || selectedRowRange == null && editorRowRange == null) return [];
756
779
  const { children: codeElements } = this.pre;
757
- if (codeElements.length === 0) return;
758
780
  if (codeElements.length > 2) {
759
781
  console.error(codeElements);
760
782
  throw new Error("InteractionManager.renderSelection: Somehow there are more than 2 code elements...");
761
783
  }
762
- const split = this.pre.getAttribute("data-diff-type") === "split";
763
- const rowRange = this.getIndexesFromSelection(this.selectedRange, split);
764
- if (rowRange == null) {
765
- console.error({
766
- rowRange,
767
- selectedRange: this.selectedRange
768
- });
769
- throw new Error("InteractionManager.renderSelection: No valid rowRange");
770
- }
771
- const isSingle = rowRange.start === rowRange.end;
772
- const first = Math.min(rowRange.start, rowRange.end);
773
- const last = Math.max(rowRange.start, rowRange.end);
774
- const numberOnly = this.highlightLineNumberOnly();
784
+ const columns = [];
775
785
  for (const code of codeElements) {
776
- const side = this.activeLineHighlightSide;
777
- if (side != null && (side === "additions" && code.hasAttribute("data-deletions") || side === "deletions" && code.hasAttribute("data-additions"))) continue;
786
+ const side = code.hasAttribute("data-deletions") ? "deletions" : code.hasAttribute("data-additions") ? "additions" : void 0;
787
+ const renderSelectedLines = selectedLines != null && selectedRowRange != null && (selectedLines.highlightSide == null || side == null || selectedLines.highlightSide === side);
788
+ const renderEditorActiveLine = editorActiveLine != null && editorRowRange != null && (editorActiveLine.highlightSide == null || side == null || editorActiveLine.highlightSide === side);
789
+ if (!renderSelectedLines && !renderEditorActiveLine) continue;
778
790
  const [gutter, content] = code.children;
791
+ if (!(gutter instanceof HTMLElement) || !(content instanceof HTMLElement)) throw new Error("InteractionManager.renderSelection: missing gutter or content element");
792
+ if (content.children.length !== gutter.children.length) throw new Error("InteractionManager.renderSelection: gutter and content children dont match, something is wrong");
793
+ columns.push({
794
+ content,
795
+ gutter,
796
+ renderEditorActiveLine,
797
+ renderSelectedLines
798
+ });
799
+ }
800
+ return columns;
801
+ }
802
+ renderSelection = () => {
803
+ dequeueRender(this.renderSelection);
804
+ const renderState = this.getSelectionRenderState();
805
+ if (this.pre == null) return;
806
+ const { editorActiveLine, selectedLines } = renderState;
807
+ const selectedLinesChanged = !areLineRenderStatesEqual(this.renderedSelectedLinesState, selectedLines);
808
+ const editorActiveLineChanged = !areLineRenderStatesEqual(this.renderedEditorActiveLineState, editorActiveLine);
809
+ if (!selectedLinesChanged && !editorActiveLineChanged) return;
810
+ if (selectedLinesChanged) this.renderedSelectedLinesState = void 0;
811
+ if (editorActiveLineChanged) this.renderedEditorActiveLineState = void 0;
812
+ const split = this.pre.getAttribute("data-diff-type") === "split";
813
+ const selectedRowRange = !selectedLinesChanged ? void 0 : this.resolveLineRenderRange(selectedLines, split, "selected-lines");
814
+ const editorRowRange = !editorActiveLineChanged ? void 0 : this.resolveLineRenderRange(editorActiveLine, split, "editor-active-line");
815
+ const columns = this.getLineRenderColumns(selectedLinesChanged ? selectedLines : void 0, selectedRowRange, editorActiveLineChanged ? editorActiveLine : void 0, editorRowRange);
816
+ const selectedLinesComplete = selectedLines.range == null || columns.some((column) => column.renderSelectedLines);
817
+ const editorActiveLineComplete = editorActiveLine.range == null || columns.some((column) => column.renderEditorActiveLine);
818
+ if (selectedLinesChanged) for (const element of this.pre.querySelectorAll("[data-selected-line]")) element.removeAttribute("data-selected-line");
819
+ if (editorActiveLineChanged) for (const element of this.pre.querySelectorAll("[data-editor-active-line]")) element.removeAttribute("data-editor-active-line");
820
+ const selectedFirst = selectedRowRange == null ? void 0 : Math.min(selectedRowRange.start, selectedRowRange.end);
821
+ const selectedLast = selectedRowRange == null ? void 0 : Math.max(selectedRowRange.start, selectedRowRange.end);
822
+ const selectedIsSingle = selectedFirst === selectedLast;
823
+ const editorLineIndex = editorRowRange?.start;
824
+ for (const column of columns) {
825
+ const { content, gutter, renderEditorActiveLine, renderSelectedLines } = column;
826
+ const finalLineIndex = Math.max(renderSelectedLines ? selectedLast ?? -Infinity : -Infinity, renderEditorActiveLine ? editorLineIndex ?? -Infinity : -Infinity);
779
827
  const len = content.children.length;
780
- if (len !== gutter.children.length) throw new Error("InteractionManager.renderSelection: gutter and content children dont match, something is wrong");
781
828
  for (let i = 0; i < len; i++) {
782
829
  const contentElement = content.children[i];
783
830
  const gutterElement = gutter.children[i];
784
831
  if (!(contentElement instanceof HTMLElement) || !(gutterElement instanceof HTMLElement)) continue;
785
832
  const lineIndex = this.parseLineIndex(contentElement, split);
786
- if ((lineIndex ?? 0) > last) break;
787
- if (lineIndex == null || lineIndex < first) continue;
788
- let attributeValue = isSingle ? "single" : lineIndex === first ? "first" : lineIndex === last ? "last" : "";
789
- gutterElement.setAttribute("data-selected-line", attributeValue);
790
- if (numberOnly) continue;
791
- contentElement.setAttribute("data-selected-line", attributeValue);
792
- if (gutterElement.nextSibling instanceof HTMLElement && contentElement.nextSibling instanceof HTMLElement && (contentElement.nextSibling.hasAttribute("data-line-annotation") || contentElement.nextSibling.hasAttribute("data-merge-conflict-actions"))) {
793
- if (isSingle) {
794
- attributeValue = "last";
795
- contentElement.setAttribute("data-selected-line", "first");
796
- } else if (lineIndex === first) attributeValue = "";
797
- else if (lineIndex === last) contentElement.setAttribute("data-selected-line", "");
798
- contentElement.nextSibling.setAttribute("data-selected-line", attributeValue);
799
- gutterElement.nextSibling.setAttribute("data-selected-line", attributeValue);
833
+ if ((lineIndex ?? 0) > finalLineIndex) break;
834
+ if (lineIndex == null) continue;
835
+ if (renderSelectedLines && selectedFirst != null && selectedLast != null && lineIndex >= selectedFirst && lineIndex <= selectedLast) {
836
+ let attributeValue = selectedIsSingle ? "single" : lineIndex === selectedFirst ? "first" : lineIndex === selectedLast ? "last" : "";
837
+ gutterElement.setAttribute("data-selected-line", attributeValue);
838
+ if (!selectedLines.lineNumberOnly) {
839
+ contentElement.setAttribute("data-selected-line", attributeValue);
840
+ if (gutterElement.nextSibling instanceof HTMLElement && contentElement.nextSibling instanceof HTMLElement && (contentElement.nextSibling.hasAttribute("data-line-annotation") || contentElement.nextSibling.hasAttribute("data-merge-conflict-actions"))) {
841
+ if (selectedIsSingle) {
842
+ attributeValue = "last";
843
+ contentElement.setAttribute("data-selected-line", "first");
844
+ } else if (lineIndex === selectedFirst) attributeValue = "";
845
+ else if (lineIndex === selectedLast) contentElement.setAttribute("data-selected-line", "");
846
+ contentElement.nextSibling.setAttribute("data-selected-line", attributeValue);
847
+ gutterElement.nextSibling.setAttribute("data-selected-line", attributeValue);
848
+ }
849
+ }
850
+ }
851
+ if (renderEditorActiveLine && lineIndex === editorLineIndex) {
852
+ gutterElement.setAttribute("data-editor-active-line", "");
853
+ if (!editorActiveLine.lineNumberOnly) contentElement.setAttribute("data-editor-active-line", "");
800
854
  }
801
855
  }
802
856
  }
857
+ if (selectedLinesChanged && selectedLinesComplete) this.renderedSelectedLinesState = selectedLines;
858
+ if (editorActiveLineChanged && editorActiveLineComplete) this.renderedEditorActiveLineState = editorActiveLine;
803
859
  };
804
- notifySelectionCommitted() {
805
- this.options.onLineSelected?.(this.getCurrentSelectionRange() ?? null);
860
+ notifySelectionCommitted(range) {
861
+ this.options.onLineSelected?.(range);
806
862
  }
807
863
  notifySelectionChangeDelta() {
808
864
  this.options.onLineSelectionChange?.(this.getCurrentSelectionRange() ?? null);
@@ -1103,6 +1159,12 @@ function selectionPointFromAnnotationSlotName(slotName) {
1103
1159
  function hasElementFromPoint(value) {
1104
1160
  return value != null && typeof value.elementFromPoint === "function";
1105
1161
  }
1162
+ function areSelectionRangesEqual(first, second) {
1163
+ return first === second || areSelectionsEqual(first ?? void 0, second ?? void 0);
1164
+ }
1165
+ function areLineRenderStatesEqual(first, second) {
1166
+ return first?.highlightSide === second.highlightSide && first?.lineNumberOnly === second.lineNumberOnly && areSelectionRangesEqual(first?.range ?? null, second.range);
1167
+ }
1106
1168
  function getAnnotationSide(lineType, codeElement) {
1107
1169
  switch (lineType) {
1108
1170
  case "change-deletion": return "deletions";
@@ -1121,13 +1183,6 @@ function getLineTypeFromElement(element) {
1121
1183
  default: return;
1122
1184
  }
1123
1185
  }
1124
- function isGutterUtilityPath(path) {
1125
- for (const element of path) {
1126
- if (!(element instanceof HTMLElement)) continue;
1127
- if (element.hasAttribute("data-utility-button") || element.hasAttribute("data-gutter-utility-slot") || element.getAttribute("slot") === "gutter-utility-slot" || element.getAttribute("name") === "gutter-utility-slot") return true;
1128
- }
1129
- return false;
1130
- }
1131
1186
  function debugLogIfEnabled(debugLogType = "none", logIfType, ...args) {
1132
1187
  switch (debugLogType) {
1133
1188
  case "none": return;