@pierre/diffs 1.3.0-beta.6 → 1.3.0-beta.7

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 (119) hide show
  1. package/dist/components/CodeView.d.ts +4 -1
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +45 -6
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +5 -2
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts +36 -23
  9. package/dist/components/FileDiff.d.ts.map +1 -1
  10. package/dist/components/FileDiff.js +126 -58
  11. package/dist/components/FileDiff.js.map +1 -1
  12. package/dist/components/UnresolvedFile.d.ts +3 -2
  13. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  14. package/dist/components/UnresolvedFile.js +4 -2
  15. package/dist/components/UnresolvedFile.js.map +1 -1
  16. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  17. package/dist/components/VirtualizedFile.js +3 -7
  18. package/dist/components/VirtualizedFile.js.map +1 -1
  19. package/dist/components/VirtualizedFileDiff.d.ts +10 -4
  20. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.js +178 -49
  22. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  23. package/dist/editor/editor.d.ts +2 -2
  24. package/dist/editor/editor.d.ts.map +1 -1
  25. package/dist/editor/editor.js +163 -106
  26. package/dist/editor/editor.js.map +1 -1
  27. package/dist/editor/editor2.js +1 -1
  28. package/dist/editor/selection.d.ts +1 -1
  29. package/dist/editor/selection.d.ts.map +1 -1
  30. package/dist/editor/selection.js +87 -37
  31. package/dist/editor/selection.js.map +1 -1
  32. package/dist/editor/textMeasure.d.ts.map +1 -1
  33. package/dist/editor/textMeasure.js +25 -7
  34. package/dist/editor/textMeasure.js.map +1 -1
  35. package/dist/editor/tokenzier.d.ts +2 -0
  36. package/dist/editor/tokenzier.d.ts.map +1 -1
  37. package/dist/editor/tokenzier.js +11 -3
  38. package/dist/editor/tokenzier.js.map +1 -1
  39. package/dist/editor/utils.d.ts +3 -1
  40. package/dist/editor/utils.d.ts.map +1 -1
  41. package/dist/editor/utils.js +14 -1
  42. package/dist/editor/utils.js.map +1 -1
  43. package/dist/index.d.ts +5 -3
  44. package/dist/index.js +3 -1
  45. package/dist/managers/InteractionManager.d.ts.map +1 -1
  46. package/dist/managers/InteractionManager.js +0 -1
  47. package/dist/managers/InteractionManager.js.map +1 -1
  48. package/dist/react/EditorContext.js.map +1 -1
  49. package/dist/react/MultiFileDiff.d.ts +3 -4
  50. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  51. package/dist/react/MultiFileDiff.js.map +1 -1
  52. package/dist/react/index.d.ts +2 -2
  53. package/dist/react/utils/useFileDiffInstance.js +14 -15
  54. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  55. package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
  56. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  57. package/dist/renderers/DiffHunksRenderer.js +29 -16
  58. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  59. package/dist/renderers/FileRenderer.js.map +1 -1
  60. package/dist/ssr/index.d.ts +2 -2
  61. package/dist/ssr/preloadDiffs.d.ts +11 -10
  62. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  63. package/dist/ssr/preloadDiffs.js +14 -6
  64. package/dist/ssr/preloadDiffs.js.map +1 -1
  65. package/dist/types.d.ts +59 -5
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/utils/areHunkDataEqual.js +1 -1
  68. package/dist/utils/areHunkDataEqual.js.map +1 -1
  69. package/dist/utils/awaitWithTimeout.d.ts +5 -0
  70. package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
  71. package/dist/utils/awaitWithTimeout.js +15 -0
  72. package/dist/utils/awaitWithTimeout.js.map +1 -0
  73. package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
  74. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
  75. package/dist/utils/cloneFileDiffMetadata.js +16 -0
  76. package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
  77. package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
  78. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  79. package/dist/utils/computeEstimatedDiffHeights.js +8 -1
  80. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  81. package/dist/utils/createPreElement.js +0 -1
  82. package/dist/utils/createPreElement.js.map +1 -1
  83. package/dist/utils/getDiffFileInput.d.ts +14 -0
  84. package/dist/utils/getDiffFileInput.d.ts.map +1 -0
  85. package/dist/utils/getDiffFileInput.js +24 -0
  86. package/dist/utils/getDiffFileInput.js.map +1 -0
  87. package/dist/utils/getDiffHunksRendererOptions.js +1 -0
  88. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  89. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  90. package/dist/utils/getFiletypeFromFileName.js +2 -0
  91. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  92. package/dist/utils/hydratePartialDiff.d.ts +10 -0
  93. package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
  94. package/dist/utils/hydratePartialDiff.js +140 -0
  95. package/dist/utils/hydratePartialDiff.js.map +1 -0
  96. package/dist/utils/iterateOverDiff.js +3 -3
  97. package/dist/utils/iterateOverDiff.js.map +1 -1
  98. package/dist/utils/parseDiffFromFile.d.ts +1 -1
  99. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  100. package/dist/utils/parseDiffFromFile.js +26 -5
  101. package/dist/utils/parseDiffFromFile.js.map +1 -1
  102. package/dist/utils/setWrapperNodeProps.js +0 -1
  103. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  104. package/dist/utils/updateDiffHunks.d.ts +5 -1
  105. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  106. package/dist/utils/updateDiffHunks.js +26 -4
  107. package/dist/utils/updateDiffHunks.js.map +1 -1
  108. package/dist/worker/WorkerPoolManager.d.ts +7 -2
  109. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  110. package/dist/worker/WorkerPoolManager.js +78 -15
  111. package/dist/worker/WorkerPoolManager.js.map +1 -1
  112. package/dist/worker/index.d.ts +2 -2
  113. package/dist/worker/types.d.ts +7 -1
  114. package/dist/worker/types.d.ts.map +1 -1
  115. package/dist/worker/worker-portable.js +5 -3
  116. package/dist/worker/worker-portable.js.map +1 -1
  117. package/dist/worker/worker.js +5 -3
  118. package/dist/worker/worker.js.map +1 -1
  119. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  //#region src/editor/editor.css?inline
2
- var editor_default = "::selection {\n background-color: #0000;\n}\n\n[data-deleted-text-selection] [data-deletions] ::selection, [data-deleted-text-selection] [data-line-type=\"change-deletion\"] ::selection {\n background-color: var(--diffs-editor-selection-bg);\n}\n\n@keyframes blinking {\n 0% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n:host, [data-code], [data-content], [data-diff-type=\"split\"][data-overflow=\"wrap\"] {\n position: relative;\n}\n\n[data-code] {\n container-type: inline-size;\n}\n\n[data-content] {\n cursor: text;\n caret-color: var(--diffs-bg-caret);\n background-color: #0000;\n outline: none;\n}\n\n[data-gutter-buffer], [data-line]:not([data-selected-line]), [data-line-annotation] {\n background-color: #0000;\n}\n\n[data-line] {\n cursor: text;\n}\n\n[data-line][data-selected-line] {\n background-color: var(--diffs-editor-line-highlight-bg);\n}\n\n[data-line][data-line-type=\"change-deletion\"] {\n background-color: var(--diffs-line-bg);\n}\n\n[data-editor-overlay] {\n display: contents;\n}\n\n[data-caret], [data-selection-range], [data-match-range], [data-marker-range] {\n height: 1lh;\n line-height: var(--diffs-line-height);\n pointer-events: none;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n[data-caret] {\n background-color: var(--diffs-bg-caret-override, var(--diffs-editor-cursor-fg, light-dark(color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg)), color-mix(in lab, var(--diffs-fg) 75%, var(--diffs-bg)))));\n visibility: hidden;\n width: 2px;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n [data-caret] {\n animation: 1.2s .8s infinite blinking;\n }\n}\n\n[data-selection-range] {\n z-index: -10;\n background-color: var(--diffs-editor-selection-bg);\n}\n\n[data-selection-corner] {\n background-color: var(--diffs-bg);\n width: 100%;\n height: 100%;\n}\n\n[data-match-range] {\n z-index: -10;\n background-color: var(--diffs-editor-match-bg, var(--diffs-editor-selection-bg));\n}\n\n[data-match-range]:not([data-focus]) {\n background-color: var(--diffs-editor-match-highlight-bg, light-dark(#ff963288, #ff963266));\n}\n\n[data-rtl] {\n border-top-left-radius: 3px;\n}\n\n[data-rtr] {\n border-top-right-radius: 3px;\n}\n\n[data-rbl] {\n border-bottom-left-radius: 3px;\n}\n\n[data-rbr] {\n border-bottom-right-radius: 3px;\n}\n\n[data-marker-range] {\n z-index: 1;\n background-color: var(--diffs-marker-bg);\n mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjMiPjxwYXRoIGQ9Im0wIDIuNSBsMiAtMS41IGwxIDAgbDIgMS41IGwxIDAiIHN0cm9rZT0iI2ZmZiIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIi8+PC9zdmc+\");\n mask-position: 0 100%;\n mask-size: 6px 3px;\n mask-repeat: repeat-x;\n}\n\n[data-marker-error] {\n --diffs-marker-contrast: #fff;\n --diffs-marker-bg: var(--diffs-editor-error-fg, var(--diffs-deletion-base));\n}\n\n[data-marker-warning] {\n --diffs-marker-contrast: #000;\n --diffs-marker-bg: var(--diffs-editor-warning-fg, light-dark(var(--diffs-warning-light), var(--diffs-warning-dark)));\n}\n\n[data-marker-info] {\n --diffs-marker-contrast: #fff;\n --diffs-marker-bg: var(--diffs-editor-info-fg, var(--diffs-modified-base));\n}\n\n[data-marker-hint] {\n --diffs-marker-contrast: light-dark(#fff, #000);\n --diffs-marker-bg: var(--diffs-editor-hint-fg, var(--diffs-fg-number));\n}\n\n@media (width >= 480px) {\n [data-content] {\n caret-color: #0000;\n }\n\n [data-content]:focus ~ [data-editor-overlay] [data-caret] {\n visibility: visible;\n }\n}\n\n[data-editor-widget] {\n --diffs-widget-fg: var(--diffs-fg);\n --diffs-widget-bg: color-mix(in lab, var(--diffs-fg) 4%, var(--diffs-bg));\n --diffs-widget-border: color-mix(in lab, var(--diffs-fg) 20%, transparent);\n --diffs-widget-shadow: inset 0 0 0 1px var(--diffs-bg), 0 4px 8px #00000013,\n 0 6px 18px #00000013;\n z-index: 100;\n width: fit-content;\n max-width: calc(100% - 24px);\n font: 14px/20px var(--diffs-header-font-fallback);\n border: 1px solid var(--diffs-widget-border);\n background-color: var(--diffs-widget-bg);\n box-shadow: var(--diffs-widget-shadow);\n background-clip: padding-box;\n border-radius: 9px;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n[data-marker-popup], [data-selection-action-popover] {\n --popover-min-left: calc(var(--gutter-width, 0px) + 8px);\n --popover-available-width: calc(100cqw - var(--gutter-width, 0px) - 16px);\n max-width: min(640px, var(--popover-available-width));\n translate: clamp(var(--popover-min-left),\n var(--popover-x, var(--popover-min-left)),\n calc(100cqw - 8px - 100%))\n var(--popover-y, 0);\n}\n\n[data-marker-popup] {\n --diffs-widget-bg: var(--diffs-marker-bg);\n --diffs-widget-shadow: 0 4px 8px #00000026, 0 6px 18px #00000026;\n overflow-wrap: anywhere;\n min-width: min(180px, 100cqw - 24px);\n color: var(--diffs-marker-contrast, contrast-color(#fff, #000));\n white-space: normal;\n pointer-events: auto;\n border: 0;\n padding: 8px 12px;\n\n & [data-marker-message] {\n white-space: normal;\n overflow-wrap: anywhere;\n\n & code {\n white-space: normal;\n color: inherit;\n background-color: #0000;\n display: inline;\n }\n }\n}\n\n[data-selection-action-popover] {\n pointer-events: auto;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n width: max-content;\n padding: 4px;\n display: flex;\n}\n\n[data-search-panel] {\n z-index: 100;\n flex-direction: column;\n justify-content: right;\n width: 100%;\n height: 0;\n display: flex;\n position: sticky;\n top: 16px;\n right: 16px;\n container: search-panel / inline-size;\n\n & [data-editor-widget] {\n z-index: 100;\n flex-shrink: 0;\n align-items: stretch;\n gap: 8px;\n min-width: 260px;\n max-width: 100%;\n margin-inline: auto 16px;\n padding: 4px;\n display: flex;\n position: relative;\n }\n\n & svg {\n fill: currentColor;\n width: 12px;\n height: 12px;\n display: block;\n }\n}\n\n[data-search-grid] {\n grid-template-columns: auto auto auto;\n grid-template-areas: \"find matches nav\"\n \"replace actions .\";\n align-items: center;\n gap: 4px 6px;\n width: 100%;\n display: grid;\n}\n\n[data-input-box][data-find] {\n grid-area: find;\n}\n\n[data-search-nav] {\n grid-area: nav;\n}\n\n[data-input-box][data-replace] {\n grid-area: replace;\n}\n\n[data-replace-actions] {\n grid-area: actions;\n}\n\n[data-search-grid][data-mode=\"find\"] {\n grid-template-areas: \"find matches nav\";\n}\n\n[data-search-grid][data-mode=\"find\"] [data-replace-cell] {\n display: none;\n}\n\n@container search-panel (width < 400px) {\n [data-search-panel] [data-editor-widget] {\n padding: 10px;\n }\n\n [data-search-grid][data-mode=\"replace\"] {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"find find find\"\n \"replace replace replace\"\n \"nav matches actions\";\n }\n\n [data-search-grid][data-mode=\"find\"] {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"find find find\"\n \"nav matches matches\";\n }\n\n [data-replace-actions] {\n justify-self: end;\n }\n\n [data-search-grid] [data-input-box] {\n width: auto;\n }\n}\n\n[data-input-box] {\n align-items: center;\n width: 200px;\n display: flex;\n position: relative;\n\n & input {\n width: 100%;\n min-width: 0;\n color: var(--diffs-fg);\n background-color: var(--diffs-bg);\n border: 1px solid color-mix(in lab, var(--diffs-fg) 12%, var(--diffs-bg));\n border-radius: 6px;\n outline: none;\n flex-grow: 1;\n padding-inline: 6px;\n font-size: 13px;\n line-height: 24px;\n\n &::selection {\n background-color: color-mix(in lab, var(--diffs-fg) 8%, var(--diffs-bg));\n }\n\n &:focus-visible {\n outline: 1px solid var(--diffs-modified-base);\n }\n }\n\n &[data-find] input {\n padding-inline-end: 72px;\n }\n\n & [data-search-icon] {\n --diffs-search-icon-size: 20px;\n }\n}\n\n[data-search-toggles] {\n align-items: center;\n gap: 1px;\n display: flex;\n position: absolute;\n top: 50%;\n right: 4px;\n transform: translateY(-50%);\n}\n\n[data-matches] {\n white-space: nowrap;\n min-width: 50px;\n color: color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg));\n flex-shrink: 0;\n grid-area: matches;\n font-size: 12px;\n font-weight: 500;\n line-height: 20px;\n\n &[data-no-matches] {\n color: color-mix(in lab, var(--diffs-fg) 35%, var(--diffs-bg));\n }\n}\n\n[data-replace-actions], [data-search-nav] {\n align-items: center;\n display: flex;\n}\n\n[data-search-icon] {\n appearance: none;\n width: var(--diffs-search-icon-size, 24px);\n height: var(--diffs-search-icon-size, 24px);\n color: color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg));\n border-radius: var(--diffs-search-icon-radius, 4px);\n cursor: pointer;\n background: none;\n border: 0;\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n transition: background-color .1s ease-in-out, color .1s ease-in-out;\n display: flex;\n\n &:disabled {\n opacity: .25;\n cursor: default;\n }\n\n &:not(:disabled):hover {\n color: var(--diffs-fg);\n }\n\n &:focus-visible {\n outline: 1px solid var(--diffs-modified-base);\n }\n\n &[aria-pressed=\"true\"] {\n color: var(--diffs-modified-base);\n }\n}\n\n[data-search-close] {\n --diffs-search-icon-size: 20px;\n --diffs-search-icon-radius: 50%;\n color: var(--diffs-widget-bg);\n background-color: color-mix(in lab,\n var(--diffs-widget-fg) 50%,\n var(--diffs-bg));\n position: absolute;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n\n &:not(:disabled):hover {\n opacity: 1;\n color: var(--diffs-widget-bg);\n background-color: var(--diffs-widget-fg);\n }\n}\n";
2
+ var editor_default = "::selection {\n background-color: #0000;\n}\n\n[data-deleted-text-selection] [data-deletions] ::selection, [data-deleted-text-selection] [data-line-type=\"change-deletion\"] ::selection {\n background-color: var(--diffs-editor-selection-bg);\n}\n\n@keyframes blinking {\n 0% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n:host, [data-code], [data-content], [data-diff-type=\"split\"][data-overflow=\"wrap\"] {\n position: relative;\n}\n\n[data-code] {\n container-type: inline-size;\n}\n\n[data-content] {\n cursor: text;\n caret-color: var(--diffs-bg-caret);\n background-color: #0000;\n outline: none;\n}\n\n[data-line] {\n cursor: text;\n background-color: #0000;\n}\n\n[data-line]:after {\n content: \"\";\n z-index: -20;\n background-color: var(--diffs-line-bg);\n pointer-events: none;\n position: absolute;\n inset: 0;\n}\n\n[data-line][data-selected-line]:after {\n background-color: var(--diffs-computed-diff-line-bg, var(--diffs-bg));\n background-image: linear-gradient(var(--diffs-editor-line-highlight-bg),\n var(--diffs-editor-line-highlight-bg));\n}\n\n[data-editor-overlay] {\n display: contents;\n}\n\n[data-caret], [data-selection-range], [data-match-range], [data-marker-range] {\n height: 1lh;\n line-height: var(--diffs-line-height);\n pointer-events: none;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n[data-caret] {\n background-color: var(--diffs-bg-caret-override, var(--diffs-editor-cursor-fg, light-dark(color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg)), color-mix(in lab, var(--diffs-fg) 75%, var(--diffs-bg)))));\n visibility: hidden;\n width: 2px;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n [data-caret] {\n animation: 1.2s .8s infinite blinking;\n }\n}\n\n[data-selection-range] {\n z-index: -10;\n background-color: var(--diffs-editor-selection-bg);\n}\n\n[data-selection-corner] {\n background-color: var(--diffs-selection-corner-bg, var(--diffs-bg));\n width: 100%;\n height: 100%;\n}\n\n[data-match-range] {\n z-index: -10;\n background-color: var(--diffs-editor-match-bg, var(--diffs-editor-selection-bg));\n}\n\n[data-match-range]:not([data-focus]) {\n background-color: var(--diffs-editor-match-highlight-bg, light-dark(#ff963288, #ff963266));\n}\n\n[data-rtl] {\n border-top-left-radius: 3px;\n}\n\n[data-rtr] {\n border-top-right-radius: 3px;\n}\n\n[data-rbl] {\n border-bottom-left-radius: 3px;\n}\n\n[data-rbr] {\n border-bottom-right-radius: 3px;\n}\n\n[data-marker-range] {\n z-index: 1;\n background-color: var(--diffs-marker-bg);\n mask-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjMiPjxwYXRoIGQ9Im0wIDIuNSBsMiAtMS41IGwxIDAgbDIgMS41IGwxIDAiIHN0cm9rZT0iI2ZmZiIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIi8+PC9zdmc+\");\n mask-position: 0 100%;\n mask-size: 6px 3px;\n mask-repeat: repeat-x;\n}\n\n[data-marker-error] {\n --diffs-marker-contrast: #fff;\n --diffs-marker-bg: var(--diffs-editor-error-fg, var(--diffs-deletion-base));\n}\n\n[data-marker-warning] {\n --diffs-marker-contrast: #000;\n --diffs-marker-bg: var(--diffs-editor-warning-fg, light-dark(var(--diffs-warning-light), var(--diffs-warning-dark)));\n}\n\n[data-marker-info] {\n --diffs-marker-contrast: #fff;\n --diffs-marker-bg: var(--diffs-editor-info-fg, var(--diffs-modified-base));\n}\n\n[data-marker-hint] {\n --diffs-marker-contrast: light-dark(#fff, #000);\n --diffs-marker-bg: var(--diffs-editor-hint-fg, var(--diffs-fg-number));\n}\n\n@media (width >= 480px) {\n [data-content] {\n caret-color: #0000;\n }\n\n [data-content]:focus ~ [data-editor-overlay] [data-caret] {\n visibility: visible;\n }\n}\n\n[data-editor-widget] {\n --diffs-widget-fg: var(--diffs-fg);\n --diffs-widget-bg: color-mix(in lab, var(--diffs-fg) 4%, var(--diffs-bg));\n --diffs-widget-border: color-mix(in lab, var(--diffs-fg) 20%, transparent);\n --diffs-widget-shadow: inset 0 0 0 1px var(--diffs-bg), 0 4px 8px #00000013,\n 0 6px 18px #00000013;\n z-index: 100;\n width: fit-content;\n max-width: calc(100% - 24px);\n font: 14px/20px var(--diffs-header-font-fallback);\n border: 1px solid var(--diffs-widget-border);\n background-color: var(--diffs-widget-bg);\n box-shadow: var(--diffs-widget-shadow);\n background-clip: padding-box;\n border-radius: 9px;\n position: absolute;\n top: 0;\n left: 0;\n}\n\n[data-marker-popup], [data-selection-action-popover] {\n --popover-min-left: calc(var(--gutter-width, 0px) + 8px);\n --popover-available-width: calc(100cqw - var(--gutter-width, 0px) - 16px);\n max-width: min(640px, var(--popover-available-width));\n translate: clamp(var(--popover-min-left),\n var(--popover-x, var(--popover-min-left)),\n calc(100cqw - 8px - 100%))\n var(--popover-y, 0);\n}\n\n[data-marker-popup] {\n --diffs-widget-bg: var(--diffs-marker-bg);\n --diffs-widget-shadow: 0 4px 8px #00000026, 0 6px 18px #00000026;\n overflow-wrap: anywhere;\n min-width: min(180px, 100cqw - 24px);\n color: var(--diffs-marker-contrast, contrast-color(#fff, #000));\n white-space: normal;\n pointer-events: auto;\n border: 0;\n padding: 8px 12px;\n\n & [data-marker-message] {\n white-space: normal;\n overflow-wrap: anywhere;\n\n & code {\n white-space: normal;\n color: inherit;\n background-color: #0000;\n display: inline;\n }\n }\n}\n\n[data-selection-action-popover] {\n pointer-events: auto;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n width: max-content;\n padding: 4px;\n display: flex;\n}\n\n[data-search-panel] {\n z-index: 100;\n flex-direction: column;\n justify-content: right;\n width: 100%;\n height: 0;\n display: flex;\n position: sticky;\n top: 16px;\n right: 16px;\n container: search-panel / inline-size;\n\n & [data-editor-widget] {\n z-index: 100;\n flex-shrink: 0;\n align-items: stretch;\n gap: 8px;\n min-width: 260px;\n max-width: 100%;\n margin-inline: auto 16px;\n padding: 4px;\n display: flex;\n position: relative;\n }\n\n & svg {\n fill: currentColor;\n width: 12px;\n height: 12px;\n display: block;\n }\n}\n\n[data-search-grid] {\n grid-template-columns: auto auto auto;\n grid-template-areas: \"find matches nav\"\n \"replace actions .\";\n align-items: center;\n gap: 4px 6px;\n width: 100%;\n display: grid;\n}\n\n[data-input-box][data-find] {\n grid-area: find;\n}\n\n[data-search-nav] {\n grid-area: nav;\n}\n\n[data-input-box][data-replace] {\n grid-area: replace;\n}\n\n[data-replace-actions] {\n grid-area: actions;\n}\n\n[data-search-grid][data-mode=\"find\"] {\n grid-template-areas: \"find matches nav\";\n}\n\n[data-search-grid][data-mode=\"find\"] [data-replace-cell] {\n display: none;\n}\n\n@container search-panel (width < 400px) {\n [data-search-panel] [data-editor-widget] {\n padding: 10px;\n }\n\n [data-search-grid][data-mode=\"replace\"] {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"find find find\"\n \"replace replace replace\"\n \"nav matches actions\";\n }\n\n [data-search-grid][data-mode=\"find\"] {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"find find find\"\n \"nav matches matches\";\n }\n\n [data-replace-actions] {\n justify-self: end;\n }\n\n [data-search-grid] [data-input-box] {\n width: auto;\n }\n}\n\n[data-input-box] {\n align-items: center;\n width: 200px;\n display: flex;\n position: relative;\n\n & input {\n width: 100%;\n min-width: 0;\n color: var(--diffs-fg);\n background-color: var(--diffs-bg);\n border: 1px solid color-mix(in lab, var(--diffs-fg) 12%, var(--diffs-bg));\n border-radius: 6px;\n outline: none;\n flex-grow: 1;\n padding-inline: 6px;\n font-size: 13px;\n line-height: 24px;\n\n &::selection {\n background-color: color-mix(in lab, var(--diffs-fg) 8%, var(--diffs-bg));\n }\n\n &:focus-visible {\n outline: 1px solid var(--diffs-modified-base);\n }\n }\n\n &[data-find] input {\n padding-inline-end: 72px;\n }\n\n & [data-search-icon] {\n --diffs-search-icon-size: 20px;\n }\n}\n\n[data-search-toggles] {\n align-items: center;\n gap: 1px;\n display: flex;\n position: absolute;\n top: 50%;\n right: 4px;\n transform: translateY(-50%);\n}\n\n[data-matches] {\n white-space: nowrap;\n min-width: 50px;\n color: color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg));\n flex-shrink: 0;\n grid-area: matches;\n font-size: 12px;\n font-weight: 500;\n line-height: 20px;\n\n &[data-no-matches] {\n color: color-mix(in lab, var(--diffs-fg) 35%, var(--diffs-bg));\n }\n}\n\n[data-replace-actions], [data-search-nav] {\n align-items: center;\n display: flex;\n}\n\n[data-search-icon] {\n appearance: none;\n width: var(--diffs-search-icon-size, 24px);\n height: var(--diffs-search-icon-size, 24px);\n color: color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg));\n border-radius: var(--diffs-search-icon-radius, 4px);\n cursor: pointer;\n background: none;\n border: 0;\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n transition: background-color .1s ease-in-out, color .1s ease-in-out;\n display: flex;\n\n &:disabled {\n opacity: .25;\n cursor: default;\n }\n\n &:not(:disabled):hover {\n color: var(--diffs-fg);\n }\n\n &:focus-visible {\n outline: 1px solid var(--diffs-modified-base);\n }\n\n &[aria-pressed=\"true\"] {\n color: var(--diffs-modified-base);\n }\n}\n\n[data-search-close] {\n --diffs-search-icon-size: 20px;\n --diffs-search-icon-radius: 50%;\n color: var(--diffs-widget-bg);\n background-color: color-mix(in lab,\n var(--diffs-widget-fg) 50%,\n var(--diffs-bg));\n position: absolute;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n\n &:not(:disabled):hover {\n opacity: 1;\n color: var(--diffs-widget-bg);\n background-color: var(--diffs-widget-fg);\n }\n}\n";
3
3
  //#endregion
4
4
  export { editor_default as default };
5
5
 
@@ -152,7 +152,7 @@ declare function getDocumentFullSelection(textDocument: TextDocument<unknown>):
152
152
  /**
153
153
  * Get the boundary selection of the document.
154
154
  */
155
- declare function getDocumentBoundarySelection(textDocument: TextDocument<unknown>, atEnd: boolean): EditorSelection;
155
+ declare function getDocumentBoundarySelection(textDocument: TextDocument<unknown>, atEnd: boolean, trimmedEndNewLine?: boolean): EditorSelection;
156
156
  /**
157
157
  * Get the clipboard text of the selections for the given text document. Used by
158
158
  * both copy and cut so the two stay in sync. Overlapping regions (e.g. several
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","names":[],"sources":["../../src/editor/selection.ts"],"mappings":";;;;cAYa,iBAAA;AAAA,cACA,aAAA;AAAA,cACA,gBAAA;AAAA,KAED,kBAAA,UACD,iBAAA,UACA,aAAA,UACA,gBAAA;AAAA,UAEM,eAAA,SAAwB,KAAK;EAC5C,SAAA,EAAW,kBAAA;AAAA;AATb;;;AAAA,iBAegB,gBAAA,CACd,KAAA,EAAO,WAAA,EACP,SAAA,GAAW,kBAAA,GACV,eAAA;AAlBuB;AAC1B;;AAD0B,iBAkCV,kBAAA,CACd,YAAA,EAAc,YAAA,WACd,SAAA,EAAW,eAAA,EACX,OAAA,UACA,OAAA,aACE,KAAA,EAAO,QAAA,IAAY,aAAA,EAAe,eAAA;;AAtCT;AAE7B;iBAqGgB,aAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,EAAY,eAAA,IACZ,QAAA,qEACC,eAAA;;;;iBAoEa,iBAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,EAAY,eAAA,IACZ,QAAA,qEACC,eAAA;;;;iBAwBa,2BAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,IAAA,EAAM,gBAAA,EACN,eAAA,GAAkB,kBAAA,CAAmB,WAAA,KACrC,OAAA,WACA,YAAA;EAEA,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;AA7MX;;;AAAA,iBAwYgB,4BAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,KAAA,YACA,eAAA,GAAkB,kBAAA,CAAmB,WAAA,KACrC,YAAA;EAEA,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;AAAA,KAiLC,YAAA;AAhkBmB;AAM/B;;;AAN+B,iBA2lBf,+BAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,IAAA,UACA,YAAA,GAAe,YAAA;;;;;iBAuBD,0BAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAErC,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;;;AAnnBO;AAgBlB;;iBAwuBgB,sCAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAErC,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;;;;;iBAsBK,uCAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,gBAAA,IAAoB,IAAA,UAAc,SAAA,qBAClC,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAErC,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;;;;;iBA8CK,mCAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAErC,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;;;;;iBAyBK,2BAAA,CACd,YAAA,EAAc,YAAA,WACd,SAAA,EAAW,eAAA,EACX,OAAA,aACE,KAAA,EAAO,QAAA,EAAU,GAAA,EAAK,QAAA;;;;iBAiEV,gCAAA,cACd,YAAA,EAAc,YAAA,CAAa,WAAA,GAC3B,UAAA,EAAY,eAAA,IACZ,OAAA,WACA,eAAA,GAAkB,kBAAA,CAAmB,WAAA,KACrC,OAAA;EAEA,cAAA,EAAgB,eAAA;EAChB,MAAA,GAAS,kBAAA;AAAA;;;AA31BO;iBAo4BF,oBAAA,CACd,SAAA,EAAW,eAAA,GAAkB,KAAK;;;;iBAWpB,gBAAA,CAAiB,SAAA,EAAW,eAAA,GAAkB,QAAQ;;;;iBAQtD,cAAA,CAAe,QAAgB;;;;iBAW/B,mBAAA,CACd,CAAA,EAAG,eAAA,GAAkB,KAAA,EACrB,CAAA,EAAG,eAAA,GAAkB,KAAA;;;AA71BL;iBAw3BF,eAAA,CAAgB,CAAA,EAAG,QAAA,EAAU,CAAA,EAAG,QAAQ;;;;iBAUxC,wCAAA,CACd,YAAA,EAAc,YAAA,WACd,YAAA,UACA,WAAA,WACC,eAAe;;;;;;;;;;iBAmDF,yBAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,WAAqB,eAAA,IACrB,gBAAA,EAAkB,aAAA,6BAClB,KAAA,WAAgB,gBAAA,KACf,eAAA;;;;iBAoBa,mBAAA,CACd,eAAA,EAAiB,eAAA,EACjB,cAAA,EAAgB,eAAA,GACf,eAAA;;;;;iBAqCa,eAAA,CACd,QAAA,EAAU,eAAA,EACV,MAAA,EAAQ,eAAA,GACP,eAAA;;;;iBA4Ca,gBAAA,CACd,UAAA,EAAY,eAAA,IACZ,MAAA,EAAQ,eAAA,GACP,eAAA;;;;iBAUa,0BAAA,CACd,UAAA,EAAY,eAAA,KACX,eAAe;AA51BlB;;;AAAA,iBAy4BgB,YAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,EAAY,eAAA,KACX,eAAA;;;;iBAkDa,wBAAA,CACd,YAAA,EAAc,YAAA,YACb,eAAe;;;;iBAaF,4BAAA,CACd,YAAA,EAAc,YAAA,WACd,KAAA,YACC,eAAe;;;;;;;;iBAyDF,gBAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,EAAY,eAAe;AAAA,iBA2Ib,mBAAA,CACd,YAAA,EAAc,YAAA,WACd,UAAA,EAAY,eAAA;EAEZ,IAAA;EACA,KAAA,EAAO,gBAAA;EACP,oBAAA;AAAA;;;;iBA4Bc,kBAAA,CACd,WAAA,EAAa,WAAA,EACb,SAAA,YACE,IAAI;AAlgCR;;;AAAA,iBAikCgB,8BAAA,CACd,YAAA,EAAc,YAAA,WACd,SAAA,EAAW,eAAA,GACV,eAAA"}
1
+ {"version":3,"file":"selection.d.ts","names":[],"sources":["../../src/editor/selection.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { endsWithLineBreak } from "./utils.js";
1
+ import { createSegmenter, endsWithLineBreak, getGraphemeSegmenter } from "./utils.js";
2
2
  import { applyDocumentChangeToLineAnnotations } from "./lineAnnotations.js";
3
3
  //#region src/editor/selection.ts
4
4
  const DirectionBackward = -1;
@@ -81,12 +81,13 @@ function mapCursorMove(textDocument, selections, shortcut) {
81
81
  return selections.map((selection) => {
82
82
  let { line, character } = shortcut === "up" || shortcut === "left" ? selection.start : selection.end;
83
83
  if (shortcut === "textStart" || shortcut === "start" || shortcut === "end") {
84
+ const caret = getCaretPosition(selection);
85
+ line = caret.line;
86
+ character = caret.character;
84
87
  if (shortcut === "textStart") {
85
88
  const indent = getLeadingSpaces(textDocument.getLineText(line));
86
89
  character = character === indent ? 0 : indent;
87
90
  } else character = shortcut === "start" ? 0 : textDocument.getLineLength(line);
88
- if (selection.direction === -1) line = selection.start.line;
89
- else line = selection.end.line;
90
91
  } else if (shortcut === "up") line = Math.max(0, line - 1);
91
92
  else if (shortcut === "down") line = Math.min(Math.max(lineCount - 1, 0), line + 1);
92
93
  else if (isCollapsedSelection(selection)) {
@@ -738,30 +739,39 @@ function extendSelections(selections, target) {
738
739
  */
739
740
  function mergeOverlappingSelections(selections) {
740
741
  if (selections.length <= 1) return selections;
741
- const selected = /* @__PURE__ */ new Set();
742
- const accepted = [];
743
- for (let i = selections.length - 1; i >= 0; i--) {
744
- const selection = selections[i];
745
- if (selection === void 0) continue;
746
- let left = 0;
747
- let right = accepted.length;
748
- while (left < right) {
749
- const mid = Math.floor((left + right) / 2);
750
- const candidate = accepted[mid]?.selection;
751
- if (candidate === void 0) break;
752
- if (comparePosition(candidate.start, selection.start) < 0) left = mid + 1;
753
- else right = mid;
742
+ const ordered = selections.map((selection, index) => ({
743
+ index,
744
+ selection
745
+ })).sort((a, b) => {
746
+ const startOrder = comparePosition(a.selection.start, b.selection.start);
747
+ if (startOrder !== 0) return startOrder;
748
+ const endOrder = comparePosition(a.selection.end, b.selection.end);
749
+ return endOrder !== 0 ? endOrder : a.index - b.index;
750
+ });
751
+ const merged = [];
752
+ let current = ordered[0];
753
+ for (const entry of ordered.slice(1)) {
754
+ if (selectionIntersects(current.selection, entry.selection)) {
755
+ const latest = entry.index > current.index ? entry : current;
756
+ const start = comparePosition(entry.selection.start, current.selection.start) < 0 ? entry.selection.start : current.selection.start;
757
+ const end = comparePosition(entry.selection.end, current.selection.end) > 0 ? entry.selection.end : current.selection.end;
758
+ let direction = latest.selection.direction;
759
+ if (direction === 0 && comparePosition(start, end) !== 0) direction = comparePosition(latest.selection.start, start) === 0 ? -1 : 1;
760
+ current = {
761
+ index: latest.index,
762
+ selection: {
763
+ direction,
764
+ end,
765
+ start
766
+ }
767
+ };
768
+ continue;
754
769
  }
755
- const previous = accepted[left - 1]?.selection;
756
- const next = accepted[left]?.selection;
757
- if (previous !== void 0 && selectionIntersects(previous, selection) || next !== void 0 && selectionIntersects(next, selection)) continue;
758
- accepted.splice(left, 0, {
759
- index: i,
760
- selection
761
- });
762
- selected.add(i);
770
+ merged.push(current);
771
+ current = entry;
763
772
  }
764
- return selections.filter((_, index) => selected.has(index));
773
+ merged.push(current);
774
+ return merged.sort((a, b) => a.index - b.index).map(({ selection }) => selection);
765
775
  }
766
776
  /**
767
777
  * Finds the next matching word and updates the selections.
@@ -801,11 +811,16 @@ function getDocumentFullSelection(textDocument) {
801
811
  /**
802
812
  * Get the boundary selection of the document.
803
813
  */
804
- function getDocumentBoundarySelection(textDocument, atEnd) {
805
- const line = atEnd ? textDocument.lineCount - 1 : 0;
814
+ function getDocumentBoundarySelection(textDocument, atEnd, trimmedEndNewLine) {
815
+ let line = 0;
816
+ if (atEnd) {
817
+ const lastLine = textDocument.lineCount - 1;
818
+ line = trimmedEndNewLine === true && lastLine > 0 && textDocument.getLineLength(lastLine) === 0 ? lastLine - 1 : lastLine;
819
+ }
820
+ const character = atEnd ? textDocument.getLineLength(line) : 0;
806
821
  const start = {
807
822
  line,
808
- character: atEnd ? textDocument.getLineLength(line) : 0
823
+ character
809
824
  };
810
825
  return {
811
826
  start,
@@ -1021,11 +1036,24 @@ function expandCollapsedSelectionToWord(textDocument, selection) {
1021
1036
  };
1022
1037
  }
1023
1038
  function expandCollapsedLineWord(lineText, character) {
1024
- const segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
1025
- for (const seg of segmenter.segment(lineText)) {
1026
- if (seg.isWordLike !== true) continue;
1027
- const lo = seg.index;
1028
- const hi = lo + seg.segment.length;
1039
+ const segmenter = createSegmenter({ granularity: "word" });
1040
+ if (segmenter !== void 0) {
1041
+ for (const seg of segmenter.segment(lineText)) {
1042
+ if (seg.isWordLike !== true) continue;
1043
+ const lo = seg.index;
1044
+ const hi = lo + seg.segment.length;
1045
+ if (character >= lo && character <= hi) return {
1046
+ start: lo,
1047
+ end: hi
1048
+ };
1049
+ }
1050
+ return;
1051
+ }
1052
+ const wordRe = /[\p{Alphabetic}\p{Number}_]+/gu;
1053
+ let match;
1054
+ while ((match = wordRe.exec(lineText)) !== null) {
1055
+ const lo = match.index;
1056
+ const hi = lo + match[0].length;
1029
1057
  if (character >= lo && character <= hi) return {
1030
1058
  start: lo,
1031
1059
  end: hi
@@ -1078,10 +1106,18 @@ function findClusterBreak(text, pos, forward, graphemeStarts) {
1078
1106
  }
1079
1107
  return 0;
1080
1108
  }
1081
- const graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1082
1109
  function getLineGraphemeStarts(lineText) {
1083
1110
  const graphemeStarts = [0];
1084
- for (const segment of graphemeSegmenter.segment(lineText)) if (segment.index > 0) graphemeStarts.push(segment.index);
1111
+ const segmenter = getGraphemeSegmenter();
1112
+ if (segmenter !== void 0) {
1113
+ for (const segment of segmenter.segment(lineText)) if (segment.index > 0) graphemeStarts.push(segment.index);
1114
+ return graphemeStarts;
1115
+ }
1116
+ let index = 0;
1117
+ for (const codePoint of lineText) {
1118
+ if (index > 0) graphemeStarts.push(index);
1119
+ index += codePoint.length;
1120
+ }
1085
1121
  return graphemeStarts;
1086
1122
  }
1087
1123
  function stepCharacterByGrapheme(textDocument, line, character, forward) {
@@ -1093,7 +1129,12 @@ function stepCharacterByGrapheme(textDocument, line, character, forward) {
1093
1129
  character: 0
1094
1130
  });
1095
1131
  const suffix = textDocument.getTextSlice(lineStart + character, lineStart + lineLength);
1096
- for (const segment of graphemeSegmenter.segment(suffix)) return character + segment.segment.length;
1132
+ const segmenter = getGraphemeSegmenter();
1133
+ if (segmenter !== void 0) {
1134
+ for (const segment of segmenter.segment(suffix)) return character + segment.segment.length;
1135
+ return lineLength;
1136
+ }
1137
+ for (const codePoint of suffix) return character + codePoint.length;
1097
1138
  return lineLength;
1098
1139
  }
1099
1140
  if (character <= 0) return 0;
@@ -1103,7 +1144,16 @@ function stepCharacterByGrapheme(textDocument, line, character, forward) {
1103
1144
  });
1104
1145
  const prefix = textDocument.getTextSlice(lineStart, lineStart + character);
1105
1146
  let prevStart = 0;
1106
- for (const segment of graphemeSegmenter.segment(prefix)) prevStart = segment.index;
1147
+ const segmenter = getGraphemeSegmenter();
1148
+ if (segmenter !== void 0) {
1149
+ for (const segment of segmenter.segment(prefix)) prevStart = segment.index;
1150
+ return prevStart;
1151
+ }
1152
+ let index = 0;
1153
+ for (const codePoint of prefix) {
1154
+ prevStart = index;
1155
+ index += codePoint.length;
1156
+ }
1107
1157
  return prevStart;
1108
1158
  }
1109
1159
  function getSelectionAnchorAndFocusOffsets(textDocument, selection) {