@blankdotpage/cake 0.1.15 → 0.1.16

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 (69) hide show
  1. package/README.md +4 -0
  2. package/dist/cake/core/runtime.d.ts +32 -72
  3. package/dist/cake/core/runtime.d.ts.map +1 -1
  4. package/dist/cake/core/runtime.js +149 -85
  5. package/dist/cake/dom/dom-map.d.ts.map +1 -1
  6. package/dist/cake/dom/dom-map.js +3 -1
  7. package/dist/cake/dom/render.d.ts +3 -3
  8. package/dist/cake/dom/render.d.ts.map +1 -1
  9. package/dist/cake/dom/render.js +12 -27
  10. package/dist/cake/editor/cake-editor.d.ts +42 -5
  11. package/dist/cake/editor/cake-editor.d.ts.map +1 -1
  12. package/dist/cake/editor/cake-editor.js +228 -69
  13. package/dist/cake/editor/extension-types.d.ts +7 -0
  14. package/dist/cake/editor/extension-types.d.ts.map +1 -0
  15. package/dist/cake/editor/extension-types.js +1 -0
  16. package/dist/cake/editor/selection/selection-geometry-dom.d.ts.map +1 -1
  17. package/dist/cake/editor/selection/selection-geometry-dom.js +2 -1
  18. package/dist/cake/editor/selection/selection-layout-dom.d.ts.map +1 -1
  19. package/dist/cake/editor/selection/selection-layout-dom.js +2 -2
  20. package/dist/cake/editor/selection/selection-navigation.d.ts.map +1 -1
  21. package/dist/cake/editor/selection/selection-navigation.js +5 -1
  22. package/dist/cake/extensions/blockquote/blockquote.d.ts +2 -1
  23. package/dist/cake/extensions/blockquote/blockquote.d.ts.map +1 -1
  24. package/dist/cake/extensions/blockquote/blockquote.js +15 -12
  25. package/dist/cake/extensions/bold/bold.d.ts +2 -1
  26. package/dist/cake/extensions/bold/bold.d.ts.map +1 -1
  27. package/dist/cake/extensions/bold/bold.js +23 -18
  28. package/dist/cake/extensions/combined-emphasis/combined-emphasis.d.ts +2 -1
  29. package/dist/cake/extensions/combined-emphasis/combined-emphasis.d.ts.map +1 -1
  30. package/dist/cake/extensions/combined-emphasis/combined-emphasis.js +5 -6
  31. package/dist/cake/extensions/heading/heading.d.ts +2 -1
  32. package/dist/cake/extensions/heading/heading.d.ts.map +1 -1
  33. package/dist/cake/extensions/heading/heading.js +21 -15
  34. package/dist/cake/extensions/image/image.d.ts +2 -1
  35. package/dist/cake/extensions/image/image.d.ts.map +1 -1
  36. package/dist/cake/extensions/image/image.js +15 -12
  37. package/dist/cake/extensions/italic/italic.d.ts +2 -1
  38. package/dist/cake/extensions/italic/italic.d.ts.map +1 -1
  39. package/dist/cake/extensions/italic/italic.js +23 -18
  40. package/dist/cake/extensions/link/link-popover.d.ts +3 -15
  41. package/dist/cake/extensions/link/link-popover.d.ts.map +1 -1
  42. package/dist/cake/extensions/link/link-popover.js +30 -3
  43. package/dist/cake/extensions/link/link.d.ts +2 -1
  44. package/dist/cake/extensions/link/link.d.ts.map +1 -1
  45. package/dist/cake/extensions/link/link.js +23 -26
  46. package/dist/cake/extensions/list/list.d.ts +2 -1
  47. package/dist/cake/extensions/list/list.d.ts.map +1 -1
  48. package/dist/cake/extensions/list/list.js +13 -10
  49. package/dist/cake/extensions/scrollbar/index.d.ts +2 -1
  50. package/dist/cake/extensions/scrollbar/index.d.ts.map +1 -1
  51. package/dist/cake/extensions/scrollbar/index.js +10 -8
  52. package/dist/cake/extensions/strikethrough/strikethrough.d.ts +2 -1
  53. package/dist/cake/extensions/strikethrough/strikethrough.d.ts.map +1 -1
  54. package/dist/cake/extensions/strikethrough/strikethrough.js +23 -18
  55. package/dist/cake/extensions/types.d.ts +1 -1
  56. package/dist/cake/extensions/types.d.ts.map +1 -1
  57. package/dist/cake/extensions/underline/underline.d.ts +2 -1
  58. package/dist/cake/extensions/underline/underline.d.ts.map +1 -1
  59. package/dist/cake/extensions/underline/underline.js +40 -21
  60. package/dist/cake/index.d.ts +1 -1
  61. package/dist/cake/index.d.ts.map +1 -1
  62. package/dist/cake/react/index.d.ts.map +1 -1
  63. package/dist/cake/react/index.js +7 -49
  64. package/dist/cake/test/harness.d.ts +1 -1
  65. package/dist/cake/test/harness.d.ts.map +1 -1
  66. package/dist/cake/test/harness.js +4 -50
  67. package/dist/index.d.ts +2 -1
  68. package/dist/index.d.ts.map +1 -1
  69. package/package.json +4 -1
@@ -1,4 +1,4 @@
1
- import { createRuntime, isApplyEditCommand, } from "../core/runtime";
1
+ import { isApplyEditCommand, createRuntimeFromRegistry, } from "../core/runtime";
2
2
  import { renderDocContent } from "../dom/render";
3
3
  import { applyDomSelection, readDomSelection } from "../dom/dom-selection";
4
4
  import { bundledExtensions } from "../extensions";
@@ -14,6 +14,13 @@ const defaultSelection = { start: 0, end: 0, affinity: "forward" };
14
14
  const COMPOSITION_COMMIT_CLEAR_DELAY_MS = 50;
15
15
  const HISTORY_GROUPING_INTERVAL_MS = 500;
16
16
  const MAX_UNDO_STACK_SIZE = 100;
17
+ function removeFromArray(arr, value) {
18
+ const index = arr.indexOf(value);
19
+ if (index === -1) {
20
+ return;
21
+ }
22
+ arr.splice(index, 1);
23
+ }
17
24
  export class CakeEditor {
18
25
  get state() {
19
26
  return this._state;
@@ -41,10 +48,24 @@ export class CakeEditor {
41
48
  // Detect if this is a touch-primary device (mobile/tablet)
42
49
  // We check for touch support AND coarse pointer to exclude laptops with touchscreens
43
50
  isTouchDevice() {
44
- return ("ontouchstart" in window &&
45
- window.matchMedia("(pointer: coarse)").matches);
51
+ return ("ontouchstart" in window && window.matchMedia("(pointer: coarse)").matches);
46
52
  }
47
53
  constructor(options) {
54
+ this.toggleMarkerToSpec = new Map();
55
+ this.inclusiveAtEndByKind = new Map();
56
+ this.parseBlockFns = [];
57
+ this.parseInlineFns = [];
58
+ this.serializeBlockFns = [];
59
+ this.serializeInlineFns = [];
60
+ this.normalizeBlockFns = [];
61
+ this.normalizeInlineFns = [];
62
+ this.onEditFns = [];
63
+ this.keybindings = [];
64
+ this.onPasteTextHandlers = [];
65
+ this.domInlineRenderers = [];
66
+ this.domBlockRenderers = [];
67
+ this.uiComponents = [];
68
+ this.extensionDisposers = [];
48
69
  this.contentRoot = null;
49
70
  this.domMap = null;
50
71
  this.isApplyingSelection = false;
@@ -67,6 +88,8 @@ export class CakeEditor {
67
88
  this.scrollCaretIntoViewId = null;
68
89
  this.selectionRectElements = [];
69
90
  this.lastSelectionRects = null;
91
+ this.changeSubscribers = [];
92
+ this.selectionChangeSubscribers = [];
70
93
  this.extensionsRoot = null;
71
94
  this.placeholderRoot = null;
72
95
  this.resizeObserver = null;
@@ -120,18 +143,129 @@ export class CakeEditor {
120
143
  this.lastTouchTime = 0;
121
144
  this.container = options.container;
122
145
  this.contentRoot = options.contentRoot ?? null;
123
- this.extensions = options.extensions ?? bundledExtensions;
124
- this.runtime = createRuntime(this.extensions);
125
- this.state = this.runtime.createState(options.value, options.selection ?? defaultSelection);
126
- this.onChange = options.onChange;
127
- this.onSelectionChange = options.onSelectionChange;
146
+ this.onChangeOption = options.onChange;
147
+ this.onSelectionChangeOption = options.onSelectionChange;
128
148
  this.readOnly = options.readOnly ?? false;
129
149
  this.spellCheckEnabled = options.spellCheckEnabled ?? true;
150
+ this.runtime = createRuntimeFromRegistry({
151
+ toggleMarkerToSpec: this.toggleMarkerToSpec,
152
+ inclusiveAtEndByKind: this.inclusiveAtEndByKind,
153
+ parseBlockFns: this.parseBlockFns,
154
+ parseInlineFns: this.parseInlineFns,
155
+ serializeBlockFns: this.serializeBlockFns,
156
+ serializeInlineFns: this.serializeInlineFns,
157
+ normalizeBlockFns: this.normalizeBlockFns,
158
+ normalizeInlineFns: this.normalizeInlineFns,
159
+ onEditFns: this.onEditFns,
160
+ domInlineRenderers: this.domInlineRenderers,
161
+ domBlockRenderers: this.domBlockRenderers,
162
+ });
163
+ this.installExtensions(options.extensions ?? bundledExtensions);
164
+ this.state = this.runtime.createState(options.value, options.selection ?? defaultSelection);
130
165
  this.render();
131
166
  this.attachListeners();
132
167
  }
168
+ installExtensions(extensions) {
169
+ for (const extension of extensions) {
170
+ const dispose = extension(this);
171
+ if (dispose) {
172
+ this.extensionDisposers.push(dispose);
173
+ }
174
+ }
175
+ }
176
+ registerInlineWrapperAffinity(specs) {
177
+ for (const spec of specs) {
178
+ if (!this.inclusiveAtEndByKind.has(spec.kind)) {
179
+ this.inclusiveAtEndByKind.set(spec.kind, spec.inclusive);
180
+ }
181
+ }
182
+ return () => {
183
+ for (const spec of specs) {
184
+ const current = this.inclusiveAtEndByKind.get(spec.kind);
185
+ if (current === spec.inclusive) {
186
+ this.inclusiveAtEndByKind.delete(spec.kind);
187
+ }
188
+ }
189
+ };
190
+ }
191
+ registerToggleInline(toggle) {
192
+ const added = [];
193
+ for (const marker of toggle.markers) {
194
+ const spec = typeof marker === "string"
195
+ ? { kind: toggle.kind, open: marker, close: marker }
196
+ : { kind: toggle.kind, open: marker.open, close: marker.close };
197
+ this.toggleMarkerToSpec.set(spec.open, spec);
198
+ added.push(spec);
199
+ }
200
+ return () => {
201
+ for (const spec of added) {
202
+ const current = this.toggleMarkerToSpec.get(spec.open);
203
+ if (current &&
204
+ current.kind === spec.kind &&
205
+ current.close === spec.close) {
206
+ this.toggleMarkerToSpec.delete(spec.open);
207
+ }
208
+ }
209
+ };
210
+ }
211
+ registerParseBlock(fn) {
212
+ this.parseBlockFns.push(fn);
213
+ return () => removeFromArray(this.parseBlockFns, fn);
214
+ }
215
+ registerParseInline(fn) {
216
+ this.parseInlineFns.push(fn);
217
+ return () => removeFromArray(this.parseInlineFns, fn);
218
+ }
219
+ registerSerializeBlock(fn) {
220
+ this.serializeBlockFns.push(fn);
221
+ return () => removeFromArray(this.serializeBlockFns, fn);
222
+ }
223
+ registerSerializeInline(fn) {
224
+ this.serializeInlineFns.push(fn);
225
+ return () => removeFromArray(this.serializeInlineFns, fn);
226
+ }
227
+ registerNormalizeBlock(fn) {
228
+ this.normalizeBlockFns.push(fn);
229
+ return () => removeFromArray(this.normalizeBlockFns, fn);
230
+ }
231
+ registerNormalizeInline(fn) {
232
+ this.normalizeInlineFns.push(fn);
233
+ return () => removeFromArray(this.normalizeInlineFns, fn);
234
+ }
235
+ registerOnEdit(fn) {
236
+ this.onEditFns.push(fn);
237
+ return () => removeFromArray(this.onEditFns, fn);
238
+ }
239
+ registerOnPasteText(fn) {
240
+ this.onPasteTextHandlers.push(fn);
241
+ return () => removeFromArray(this.onPasteTextHandlers, fn);
242
+ }
243
+ registerKeybindings(bindings) {
244
+ this.keybindings.push(...bindings);
245
+ return () => {
246
+ for (const binding of bindings) {
247
+ removeFromArray(this.keybindings, binding);
248
+ }
249
+ };
250
+ }
251
+ registerInlineRenderer(fn) {
252
+ this.domInlineRenderers.push(fn);
253
+ return () => removeFromArray(this.domInlineRenderers, fn);
254
+ }
255
+ registerBlockRenderer(fn) {
256
+ this.domBlockRenderers.push(fn);
257
+ return () => removeFromArray(this.domBlockRenderers, fn);
258
+ }
259
+ registerUI(component) {
260
+ this.uiComponents.push(component);
261
+ return () => removeFromArray(this.uiComponents, component);
262
+ }
133
263
  destroy() {
134
264
  this.detachListeners();
265
+ this.extensionDisposers
266
+ .splice(0)
267
+ .reverse()
268
+ .forEach((dispose) => dispose());
135
269
  this.clearCaretBlinkTimer();
136
270
  if (this.overlayUpdateId !== null) {
137
271
  window.cancelAnimationFrame(this.overlayUpdateId);
@@ -174,6 +308,27 @@ export class CakeEditor {
174
308
  getOverlayRoot() {
175
309
  return this.ensureExtensionsRoot();
176
310
  }
311
+ getUIComponents() {
312
+ return this.uiComponents.slice();
313
+ }
314
+ onChange(callback) {
315
+ this.changeSubscribers.push(callback);
316
+ return () => {
317
+ const index = this.changeSubscribers.indexOf(callback);
318
+ if (index !== -1) {
319
+ this.changeSubscribers.splice(index, 1);
320
+ }
321
+ };
322
+ }
323
+ onSelectionChange(callback) {
324
+ this.selectionChangeSubscribers.push(callback);
325
+ return () => {
326
+ const index = this.selectionChangeSubscribers.indexOf(callback);
327
+ if (index !== -1) {
328
+ this.selectionChangeSubscribers.splice(index, 1);
329
+ }
330
+ };
331
+ }
177
332
  // Placeholder text is provided by the caller via the container's
178
333
  // `data-placeholder` attribute (set by the React wrapper).
179
334
  // The engine owns the placeholder element so it survives internal renders.
@@ -206,7 +361,7 @@ export class CakeEditor {
206
361
  this.recordHistory("replace");
207
362
  this.state = this.runtime.createState(nextSource, this.state.selection);
208
363
  this.render();
209
- this.onChange?.(this.state.source, this.state.selection);
364
+ this.notifyChange();
210
365
  this.scheduleOverlayUpdate();
211
366
  this.scheduleScrollCaretIntoView();
212
367
  }
@@ -270,7 +425,7 @@ export class CakeEditor {
270
425
  this.history.lastKind = null;
271
426
  this.state = this.runtime.createState(entry.source, entry.selection);
272
427
  this.render();
273
- this.onChange?.(this.state.source, this.state.selection);
428
+ this.notifyChange();
274
429
  }
275
430
  redo() {
276
431
  const entry = this.history.redoStack.pop();
@@ -284,7 +439,7 @@ export class CakeEditor {
284
439
  this.history.lastKind = null;
285
440
  this.state = this.runtime.createState(entry.source, entry.selection);
286
441
  this.render();
287
- this.onChange?.(this.state.source, this.state.selection);
442
+ this.notifyChange();
288
443
  }
289
444
  canUndo() {
290
445
  return this.history.undoStack.length > 0;
@@ -306,7 +461,7 @@ export class CakeEditor {
306
461
  // overlay is updated immediately rather than waiting for the next animation
307
462
  // frame (which can vary across engines in test and headless environments).
308
463
  this.flushOverlayUpdate();
309
- this.onChange?.(this.state.source, this.state.selection);
464
+ this.notifyChange();
310
465
  this.scheduleScrollCaretIntoView();
311
466
  if (shouldOpenLinkPopover) {
312
467
  // The popover is rendered via React overlays, and its event listeners are
@@ -447,7 +602,7 @@ export class CakeEditor {
447
602
  if (perfEnabled) {
448
603
  renderStart = performance.now();
449
604
  }
450
- const { content, map } = renderDocContent(this.state.doc, this.extensions, this.contentRoot);
605
+ const { content, map } = renderDocContent(this.state.doc, this.runtime.dom, this.contentRoot);
451
606
  const existingChildren = Array.from(this.contentRoot.childNodes);
452
607
  const isManagedChild = (node) => node instanceof Element &&
453
608
  (node.hasAttribute("data-line-index") ||
@@ -622,7 +777,7 @@ export class CakeEditor {
622
777
  this.state = this.runtime.updateSelection(this.state, adjustedSelection, {
623
778
  kind: "dom",
624
779
  });
625
- this.onSelectionChange?.(this.state.selection);
780
+ this.notifySelectionChange();
626
781
  this.scheduleOverlayUpdate();
627
782
  this.scheduleScrollCaretIntoView();
628
783
  // If we adjusted selection, apply it to DOM
@@ -646,7 +801,7 @@ export class CakeEditor {
646
801
  this.state = this.runtime.updateSelection(this.state, selection, {
647
802
  kind: "dom",
648
803
  });
649
- this.onSelectionChange?.(this.state.selection);
804
+ this.notifySelectionChange();
650
805
  this.lastAppliedSelection = this.state.selection;
651
806
  this.scheduleOverlayUpdate();
652
807
  this.scheduleScrollCaretIntoView();
@@ -752,7 +907,7 @@ export class CakeEditor {
752
907
  event.preventDefault();
753
908
  this.state = this.runtime.updateSelection(this.state, atomicBlockSelection, { kind: "dom" });
754
909
  this.applySelection(this.state.selection);
755
- this.onSelectionChange?.(this.state.selection);
910
+ this.notifySelectionChange();
756
911
  this.scheduleOverlayUpdate();
757
912
  this.selectedAtomicLineIndex = atomicResult.lineIndex;
758
913
  this.suppressSelectionChange = false;
@@ -775,7 +930,7 @@ export class CakeEditor {
775
930
  kind: "dom",
776
931
  });
777
932
  this.applySelection(this.state.selection);
778
- this.onSelectionChange?.(this.state.selection);
933
+ this.notifySelectionChange();
779
934
  this.scheduleOverlayUpdate();
780
935
  setTimeout(() => {
781
936
  this.suppressSelectionChange = false;
@@ -802,7 +957,7 @@ export class CakeEditor {
802
957
  kind: "dom",
803
958
  });
804
959
  this.applySelection(this.state.selection);
805
- this.onSelectionChange?.(this.state.selection);
960
+ this.notifySelectionChange();
806
961
  this.scheduleOverlayUpdate();
807
962
  setTimeout(() => {
808
963
  this.suppressSelectionChange = false;
@@ -845,7 +1000,7 @@ export class CakeEditor {
845
1000
  kind: "dom",
846
1001
  });
847
1002
  this.applySelection(this.state.selection);
848
- this.onSelectionChange?.(this.state.selection);
1003
+ this.notifySelectionChange();
849
1004
  this.suppressSelectionChange = false;
850
1005
  return;
851
1006
  }
@@ -869,7 +1024,7 @@ export class CakeEditor {
869
1024
  kind: "dom",
870
1025
  });
871
1026
  this.applySelection(this.state.selection);
872
- this.onSelectionChange?.(this.state.selection);
1027
+ this.notifySelectionChange();
873
1028
  this.suppressSelectionChange = false;
874
1029
  }
875
1030
  }
@@ -1109,34 +1264,28 @@ export class CakeEditor {
1109
1264
  }
1110
1265
  resolveExtensionKeybinding(event) {
1111
1266
  const eventKey = event.key.length === 1 ? event.key.toLowerCase() : event.key;
1112
- for (const extension of this.extensions) {
1113
- const bindings = extension.keybindings;
1114
- if (!bindings) {
1267
+ for (const binding of this.keybindings) {
1268
+ const bindingKey = binding.key.length === 1 ? binding.key.toLowerCase() : binding.key;
1269
+ if (bindingKey !== eventKey) {
1115
1270
  continue;
1116
1271
  }
1117
- for (const binding of bindings) {
1118
- const bindingKey = binding.key.length === 1 ? binding.key.toLowerCase() : binding.key;
1119
- if (bindingKey !== eventKey) {
1120
- continue;
1121
- }
1122
- if (binding.meta !== undefined && binding.meta !== event.metaKey) {
1123
- continue;
1124
- }
1125
- if (binding.ctrl !== undefined && binding.ctrl !== event.ctrlKey) {
1126
- continue;
1127
- }
1128
- if (binding.alt !== undefined && binding.alt !== event.altKey) {
1129
- continue;
1130
- }
1131
- if (binding.shift !== undefined && binding.shift !== event.shiftKey) {
1132
- continue;
1133
- }
1134
- const command = typeof binding.command === "function"
1135
- ? binding.command(this.state)
1136
- : binding.command;
1137
- if (command) {
1138
- return command;
1139
- }
1272
+ if (binding.meta !== undefined && binding.meta !== event.metaKey) {
1273
+ continue;
1274
+ }
1275
+ if (binding.ctrl !== undefined && binding.ctrl !== event.ctrlKey) {
1276
+ continue;
1277
+ }
1278
+ if (binding.alt !== undefined && binding.alt !== event.altKey) {
1279
+ continue;
1280
+ }
1281
+ if (binding.shift !== undefined && binding.shift !== event.shiftKey) {
1282
+ continue;
1283
+ }
1284
+ const command = typeof binding.command === "function"
1285
+ ? binding.command(this.state)
1286
+ : binding.command;
1287
+ if (command) {
1288
+ return command;
1140
1289
  }
1141
1290
  }
1142
1291
  return null;
@@ -1194,11 +1343,7 @@ export class CakeEditor {
1194
1343
  if (!text) {
1195
1344
  return;
1196
1345
  }
1197
- for (const extension of this.extensions) {
1198
- const handler = extension.onPasteText;
1199
- if (!handler) {
1200
- continue;
1201
- }
1346
+ for (const handler of this.onPasteTextHandlers) {
1202
1347
  const command = handler(text, this.state);
1203
1348
  if (!command) {
1204
1349
  continue;
@@ -1485,7 +1630,7 @@ export class CakeEditor {
1485
1630
  this.selectedAtomicLineIndex = null;
1486
1631
  this.state = nextState;
1487
1632
  this.render();
1488
- this.onChange?.(this.state.source, this.state.selection);
1633
+ this.notifyChange();
1489
1634
  if (this.state.selection.start === this.state.selection.end) {
1490
1635
  this.flushOverlayUpdate();
1491
1636
  }
@@ -1536,7 +1681,7 @@ export class CakeEditor {
1536
1681
  affinity: "forward",
1537
1682
  });
1538
1683
  this.render();
1539
- this.onChange?.(this.state.source, this.state.selection);
1684
+ this.notifyChange();
1540
1685
  this.flushOverlayUpdate();
1541
1686
  this.scheduleScrollCaretIntoView();
1542
1687
  this.selectedAtomicLineIndex = null;
@@ -1597,7 +1742,7 @@ export class CakeEditor {
1597
1742
  selection: { start: cursorPos, end: cursorPos, affinity: "forward" },
1598
1743
  };
1599
1744
  this.render();
1600
- this.onChange?.(this.state.source, this.state.selection);
1745
+ this.notifyChange();
1601
1746
  this.flushOverlayUpdate();
1602
1747
  this.scheduleScrollCaretIntoView();
1603
1748
  return true;
@@ -1629,7 +1774,7 @@ export class CakeEditor {
1629
1774
  if (!this.isComposing) {
1630
1775
  this.applySelection(this.state.selection);
1631
1776
  }
1632
- this.onSelectionChange?.(this.state.selection);
1777
+ this.notifySelectionChange();
1633
1778
  if (this.state.selection.start === this.state.selection.end) {
1634
1779
  this.flushOverlayUpdate();
1635
1780
  }
@@ -1685,7 +1830,8 @@ export class CakeEditor {
1685
1830
  affinity: "backward",
1686
1831
  });
1687
1832
  // If backward affinity puts us on a different row, just change affinity
1688
- if (prevBoundaries.rowEnd !== rowEnd || prevBoundaries.rowStart !== rowStart) {
1833
+ if (prevBoundaries.rowEnd !== rowEnd ||
1834
+ prevBoundaries.rowStart !== rowStart) {
1689
1835
  return { start: currentPos, end: currentPos, affinity: "backward" };
1690
1836
  }
1691
1837
  }
@@ -1702,7 +1848,8 @@ export class CakeEditor {
1702
1848
  affinity: "forward",
1703
1849
  });
1704
1850
  // If forward affinity puts us on a different row, just change affinity
1705
- if (nextBoundaries.rowEnd !== rowEnd || nextBoundaries.rowStart !== rowStart) {
1851
+ if (nextBoundaries.rowEnd !== rowEnd ||
1852
+ nextBoundaries.rowStart !== rowStart) {
1706
1853
  return { start: currentPos, end: currentPos, affinity: "forward" };
1707
1854
  }
1708
1855
  }
@@ -2078,7 +2225,7 @@ export class CakeEditor {
2078
2225
  const nextState = this.runtime.applyEdit({ type: "indent" }, this.state);
2079
2226
  this.state = nextState;
2080
2227
  this.render();
2081
- this.onChange?.(this.state.source, this.state.selection);
2228
+ this.notifyChange();
2082
2229
  this.scheduleOverlayUpdate();
2083
2230
  return;
2084
2231
  }
@@ -2133,7 +2280,7 @@ export class CakeEditor {
2133
2280
  };
2134
2281
  this.state = this.runtime.createState(newSource, newSelection);
2135
2282
  this.render();
2136
- this.onChange?.(this.state.source, this.state.selection);
2283
+ this.notifyChange();
2137
2284
  this.scheduleOverlayUpdate();
2138
2285
  }
2139
2286
  handleOutdent() {
@@ -2155,7 +2302,7 @@ export class CakeEditor {
2155
2302
  if (nextState.source !== this.state.source) {
2156
2303
  this.state = nextState;
2157
2304
  this.render();
2158
- this.onChange?.(this.state.source, this.state.selection);
2305
+ this.notifyChange();
2159
2306
  this.scheduleOverlayUpdate();
2160
2307
  }
2161
2308
  return;
@@ -2208,7 +2355,7 @@ export class CakeEditor {
2208
2355
  };
2209
2356
  this.state = this.runtime.createState(newSource, newSelection);
2210
2357
  this.render();
2211
- this.onChange?.(this.state.source, this.state.selection);
2358
+ this.notifyChange();
2212
2359
  this.scheduleOverlayUpdate();
2213
2360
  }
2214
2361
  readDomText() {
@@ -2265,7 +2412,7 @@ export class CakeEditor {
2265
2412
  // History was already recorded above
2266
2413
  this.state = this.runtime.createState(domText, selection);
2267
2414
  this.render();
2268
- this.onChange?.(this.state.source, this.state.selection);
2415
+ this.notifyChange();
2269
2416
  return true;
2270
2417
  }
2271
2418
  // Map cursor positions to source positions.
@@ -2309,7 +2456,7 @@ export class CakeEditor {
2309
2456
  };
2310
2457
  this.state = { ...newState, selection: newSelection };
2311
2458
  this.render();
2312
- this.onChange?.(this.state.source, this.state.selection);
2459
+ this.notifyChange();
2313
2460
  return true;
2314
2461
  }
2315
2462
  resolveCollapsedReconcileAffinity(cursorOffset) {
@@ -2357,6 +2504,18 @@ export class CakeEditor {
2357
2504
  this.suppressSelectionChangeResetId = null;
2358
2505
  });
2359
2506
  }
2507
+ notifyChange() {
2508
+ this.onChangeOption?.(this.state.source, this.state.selection);
2509
+ for (const callback of this.changeSubscribers) {
2510
+ callback(this.state.source, this.state.selection);
2511
+ }
2512
+ }
2513
+ notifySelectionChange() {
2514
+ this.onSelectionChangeOption?.(this.state.selection);
2515
+ for (const callback of this.selectionChangeSubscribers) {
2516
+ callback(this.state.selection);
2517
+ }
2518
+ }
2360
2519
  markCompositionCommit() {
2361
2520
  this.compositionCommit = true;
2362
2521
  if (this.compositionCommitTimeoutId !== null) {
@@ -2750,7 +2909,7 @@ export class CakeEditor {
2750
2909
  this.suppressSelectionChange = true;
2751
2910
  this.state = { ...this.state, selection: atomicSelection };
2752
2911
  this.applySelection(atomicSelection);
2753
- this.onSelectionChange?.(atomicSelection);
2912
+ this.notifySelectionChange();
2754
2913
  this.flushOverlayUpdate();
2755
2914
  this.selectedAtomicLineIndex = lineIndex;
2756
2915
  this.dragState = {
@@ -2803,7 +2962,7 @@ export class CakeEditor {
2803
2962
  kind: "dom",
2804
2963
  });
2805
2964
  this.applySelection(this.state.selection);
2806
- this.onSelectionChange?.(this.state.selection);
2965
+ this.notifySelectionChange();
2807
2966
  this.scheduleOverlayUpdate();
2808
2967
  return;
2809
2968
  }
@@ -2821,7 +2980,7 @@ export class CakeEditor {
2821
2980
  kind: "dom",
2822
2981
  });
2823
2982
  this.applySelection(this.state.selection);
2824
- this.onSelectionChange?.(this.state.selection);
2983
+ this.notifySelectionChange();
2825
2984
  this.scheduleOverlayUpdate();
2826
2985
  return;
2827
2986
  }
@@ -3228,7 +3387,7 @@ export class CakeEditor {
3228
3387
  affinity: "forward",
3229
3388
  });
3230
3389
  this.render();
3231
- this.onChange?.(this.state.source, this.state.selection);
3390
+ this.notifyChange();
3232
3391
  }
3233
3392
  handleDragStart(event) {
3234
3393
  if (this.readOnly) {
@@ -3385,7 +3544,7 @@ export class CakeEditor {
3385
3544
  const afterInsert = this.runtime.applyEdit({ type: "insert", text: dragState.sourceText }, insertState);
3386
3545
  this.state = afterInsert;
3387
3546
  this.render();
3388
- this.onChange?.(this.state.source, this.state.selection);
3547
+ this.notifyChange();
3389
3548
  return;
3390
3549
  }
3391
3550
  // External drop - insert the text
@@ -3402,7 +3561,7 @@ export class CakeEditor {
3402
3561
  const afterInsert = this.runtime.applyEdit({ type: "insert", text }, insertState);
3403
3562
  this.state = afterInsert;
3404
3563
  this.render();
3405
- this.onChange?.(this.state.source, this.state.selection);
3564
+ this.notifyChange();
3406
3565
  }
3407
3566
  handleDragEnd() {
3408
3567
  this.textDragState = null;
@@ -0,0 +1,7 @@
1
+ import type { ComponentType } from "react";
2
+ import type { CakeEditor } from "./cake-editor";
3
+ export type CakeExtension = (editor: CakeEditor) => void | (() => void);
4
+ export type CakeUIComponent = ComponentType<{
5
+ editor: CakeEditor;
6
+ }>;
7
+ //# sourceMappingURL=extension-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-types.d.ts","sourceRoot":"","sources":["../../../src/cake/editor/extension-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;AAExE,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"selection-geometry-dom.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-geometry-dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAUxE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACtB,GAAG,iBAAiB,CAoHpB;AAMD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CACnC,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAwN9C"}
1
+ {"version":3,"file":"selection-geometry-dom.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-geometry-dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAUxE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACtB,GAAG,iBAAiB,CAoHpB;AAMD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CACnC,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAqO9C"}
@@ -160,7 +160,8 @@ export function getCaretRect(params) {
160
160
  let bestRect = backRects[backRects.length - 1];
161
161
  for (let i = 0; i < backRects.length; i += 1) {
162
162
  const rect = backRects[i];
163
- if (rect.width > 0 && (bestRect.width === 0 || rect.top < bestRect.top)) {
163
+ if (rect.width > 0 &&
164
+ (bestRect.width === 0 || rect.top < bestRect.top)) {
164
165
  bestRect = rect;
165
166
  }
166
167
  }
@@ -1 +1 @@
1
- {"version":3,"file":"selection-layout-dom.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-layout-dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,UAAU,EAEV,QAAQ,EAET,MAAM,oBAAoB,CAAC;AAG5B,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GAAG,UAAU,CAOb;AAqBD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CA2B9D;AA+UD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,cAAc,GAAG,IAAI,CA+CxB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;CACxB,GAAG,WAAW,GAAG,IAAI,CAUrB;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,GAAG,IAAI,CAwCrB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,GAChB,WAAW,GAAG,IAAI,CAEpB;AAMD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,GACnB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAiBhC;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAiC7D;AAED,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,aAAa,GAAG,IAAI,CAkXvB"}
1
+ {"version":3,"file":"selection-layout-dom.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-layout-dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,UAAU,EAEV,QAAQ,EAET,MAAM,oBAAoB,CAAC;AAG5B,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GAAG,UAAU,CAOb;AAqBD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CA2B9D;AAkVD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,cAAc,GAAG,IAAI,CA+CxB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;CACxB,GAAG,WAAW,GAAG,IAAI,CAUrB;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,GAAG,IAAI,CA8CrB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,GAChB,WAAW,GAAG,IAAI,CAEpB;AAMD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,GACnB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAiBhC;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAiC7D;AAED,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,GAAG,aAAa,GAAG,IAAI,CA0XvB"}
@@ -83,7 +83,7 @@ function createDomPositionResolver(lineElement) {
83
83
  let low = 0;
84
84
  let high = cumulativeEnds.length - 1;
85
85
  while (low < high) {
86
- const mid = low + high >>> 1;
86
+ const mid = (low + high) >>> 1;
87
87
  if ((cumulativeEnds[mid] ?? 0) < clamped) {
88
88
  low = mid + 1;
89
89
  }
@@ -668,7 +668,7 @@ export function hitTestFromLayout(params) {
668
668
  return best.left - containerRect.left + scroll.left;
669
669
  };
670
670
  const caretX = (cursorOffsetInLine) => {
671
- return measureCaretXOnRow(cursorOffsetInLine) ?? approximateX(cursorOffsetInLine);
671
+ return (measureCaretXOnRow(cursorOffsetInLine) ?? approximateX(cursorOffsetInLine));
672
672
  };
673
673
  // Check if the click is outside the row's horizontal bounds (i.e. in container padding).
674
674
  // If so, snap directly to the row edge rather than searching for a character.
@@ -1 +1 @@
1
- {"version":3,"file":"selection-navigation.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAa,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG3E,KAAK,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvC,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAsIF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,CAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,KACN;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7E,GAAG,wBAAwB,GAAG,IAAI,CA+JlC"}
1
+ {"version":3,"file":"selection-navigation.d.ts","sourceRoot":"","sources":["../../../../src/cake/editor/selection/selection-navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAa,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG3E,KAAK,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvC,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAsIF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,CAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,KACN;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7E,GAAG,wBAAwB,GAAG,IAAI,CAmKlC"}
@@ -211,7 +211,11 @@ export function moveSelectionVertically(params) {
211
211
  end: hit.cursorOffset,
212
212
  affinity: normalizedAffinity,
213
213
  }
214
- : { start: anchor, end: hit.cursorOffset, affinity: normalizedAffinity };
214
+ : {
215
+ start: anchor,
216
+ end: hit.cursorOffset,
217
+ affinity: normalizedAffinity,
218
+ };
215
219
  return { selection: nextSelection, goalX };
216
220
  }
217
221
  }
@@ -1,2 +1,3 @@
1
- export declare const blockquoteExtension: import("../../..").CakeExtension;
1
+ import { type CakeExtension } from "../../core/runtime";
2
+ export declare const blockquoteExtension: CakeExtension;
2
3
  //# sourceMappingURL=blockquote.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"blockquote.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/blockquote/blockquote.ts"],"names":[],"mappings":"AAsIA,eAAO,MAAM,mBAAmB,kCA8F9B,CAAC"}
1
+ {"version":3,"file":"blockquote.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/blockquote/blockquote.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AAgI5B,eAAO,MAAM,mBAAmB,EAAE,aAkHjC,CAAC"}