@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
package/README.md CHANGED
@@ -119,3 +119,7 @@ engine.destroy();
119
119
  - `plainTextListExtension` - Ordered and unordered lists
120
120
  - `scrollbarExtension` - Custom scrollbar styling
121
121
  - `strikethroughExtension` - Strikethrough (`~~text~~`)
122
+
123
+ ## Writing extensions
124
+
125
+ See [docs/extensions.md](docs/extensions.md) for the full extension API, including examples of pure logic extensions and React-based UI extensions.
@@ -1,25 +1,8 @@
1
1
  import type { Block, Doc, Inline, Selection } from "./types";
2
- import type { ReactElement } from "react";
2
+ import type { CakeExtension } from "../editor/extension-types";
3
+ export type { CakeExtension, CakeUIComponent } from "../editor/extension-types";
3
4
  import { type CursorSourceMap } from "./mapping/cursor-source-map";
4
5
  import type { DomRenderContext } from "../dom/types";
5
- export type OverlayExtensionContext = {
6
- container: HTMLElement;
7
- insertText: (text: string) => void;
8
- replaceText: (oldText: string, newText: string) => void;
9
- getSelection: () => {
10
- start: number;
11
- end: number;
12
- } | null;
13
- executeCommand: (command: EditCommand) => boolean;
14
- contentRoot?: HTMLElement;
15
- overlayRoot?: HTMLElement;
16
- toOverlayRect?: (rect: DOMRectReadOnly) => {
17
- top: number;
18
- left: number;
19
- width: number;
20
- height: number;
21
- };
22
- };
23
6
  type BlockParseResult = {
24
7
  block: Block;
25
8
  nextPos: number;
@@ -105,57 +88,15 @@ export type ExtensionContext = {
105
88
  serializeInline: (inline: Inline) => SerializeInlineResult;
106
89
  serializeBlock: (block: Block) => SerializeBlockResult;
107
90
  };
108
- export type CakeExtension = {
109
- name: string;
110
- inlineWrapperAffinity?: InlineWrapperAffinity[];
111
- /**
112
- * Declares which inline wrapper kind a `toggle-inline` marker corresponds to.
113
- * This keeps the core runtime syntax-agnostic while still allowing extension-
114
- * specific toggle behavior at wrapper boundaries.
115
- */
116
- toggleInline?: {
117
- kind: string;
118
- markers: Array<string | {
119
- open: string;
120
- close: string;
121
- }>;
122
- };
123
- parseBlock?: (source: string, start: number, context: ExtensionContext) => ParseBlockResult;
124
- parseInline?: (source: string, start: number, end: number, context: ExtensionContext) => ParseInlineResult;
125
- serializeBlock?: (block: Block, context: ExtensionContext) => SerializeBlockResult | null;
126
- serializeInline?: (inline: Inline, context: ExtensionContext) => SerializeInlineResult | null;
127
- normalizeBlock?: (block: Block) => Block | null;
128
- normalizeInline?: (inline: Inline) => Inline | null;
129
- onEdit?: (command: EditCommand, state: RuntimeState) => EditResult | EditCommand | null;
130
- onPasteText?: (text: string, state: RuntimeState) => EditCommand | null;
131
- keybindings?: KeyBinding[];
132
- renderInline?: (inline: Inline, context: DomRenderContext) => Node | Node[] | null;
133
- renderBlock?: (block: Block, context: DomRenderContext) => Node | Node[] | null;
134
- renderOverlay?: (context: OverlayExtensionContext) => ReactElement | null;
135
- };
136
- /**
137
- * Extension config with typed custom commands.
138
- */
139
- export type ExtensionConfig<TCommand extends ExtensionCommand> = Omit<CakeExtension, "onEdit"> & {
140
- onEdit?: (command: EditCommand | TCommand, state: RuntimeState) => EditResult | EditCommand | TCommand | null;
91
+ export type DomInlineRenderer = (inline: Inline, context: DomRenderContext) => Node | Node[] | null;
92
+ export type DomBlockRenderer = (block: Block, context: DomRenderContext) => Node | Node[] | null;
93
+ export type ToggleInlineSpec = {
94
+ kind: string;
95
+ markers: Array<string | {
96
+ open: string;
97
+ close: string;
98
+ }>;
141
99
  };
142
- /**
143
- * Define an extension with typed custom commands.
144
- *
145
- * @example
146
- * type MyCommand = { type: "my-command"; value: number };
147
- * export const myExtension = defineExtension<MyCommand>({
148
- * name: "my-extension",
149
- * onEdit(command, state) {
150
- * if (command.type === "my-command") {
151
- * // command is narrowed to MyCommand here
152
- * console.log(command.value);
153
- * }
154
- * return null;
155
- * },
156
- * });
157
- */
158
- export declare function defineExtension<TCommand extends ExtensionCommand>(extension: ExtensionConfig<TCommand>): CakeExtension;
159
100
  export type RuntimeState = {
160
101
  source: string;
161
102
  selection: Selection;
@@ -164,7 +105,10 @@ export type RuntimeState = {
164
105
  runtime: Runtime;
165
106
  };
166
107
  export type Runtime = {
167
- extensions: CakeExtension[];
108
+ dom: {
109
+ inlineRenderers: DomInlineRenderer[];
110
+ blockRenderers: DomBlockRenderer[];
111
+ };
168
112
  parse(source: string): Doc;
169
113
  serialize(doc: Doc): {
170
114
  source: string;
@@ -178,6 +122,22 @@ export type Runtime = {
178
122
  serializeSelectionToHtml(state: RuntimeState, selection: Selection): string;
179
123
  applyEdit(command: EditCommand, state: RuntimeState): RuntimeState;
180
124
  };
181
- export declare function createRuntime(extensions: CakeExtension[]): Runtime;
182
- export {};
125
+ export declare function createRuntimeForTests(extensions: CakeExtension[]): Runtime;
126
+ export declare function createRuntimeFromRegistry(registry: {
127
+ toggleMarkerToSpec: Map<string, {
128
+ kind: string;
129
+ open: string;
130
+ close: string;
131
+ }>;
132
+ inclusiveAtEndByKind: Map<string, boolean>;
133
+ parseBlockFns: Array<(source: string, start: number, context: ExtensionContext) => ParseBlockResult>;
134
+ parseInlineFns: Array<(source: string, start: number, end: number, context: ExtensionContext) => ParseInlineResult>;
135
+ serializeBlockFns: Array<(block: Block, context: ExtensionContext) => SerializeBlockResult | null>;
136
+ serializeInlineFns: Array<(inline: Inline, context: ExtensionContext) => SerializeInlineResult | null>;
137
+ normalizeBlockFns: Array<(block: Block) => Block | null>;
138
+ normalizeInlineFns: Array<(inline: Inline) => Inline | null>;
139
+ onEditFns: Array<(command: EditCommand, state: RuntimeState) => EditResult | EditCommand | null>;
140
+ domInlineRenderers: DomInlineRenderer[];
141
+ domBlockRenderers: DomBlockRenderer[];
142
+ }): Runtime;
183
143
  //# sourceMappingURL=runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"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"}
@@ -17,52 +17,128 @@ export function isApplyEditCommand(command) {
17
17
  command.type === "delete-backward" ||
18
18
  command.type === "delete-forward");
19
19
  }
20
- /**
21
- * Define an extension with typed custom commands.
22
- *
23
- * @example
24
- * type MyCommand = { type: "my-command"; value: number };
25
- * export const myExtension = defineExtension<MyCommand>({
26
- * name: "my-extension",
27
- * onEdit(command, state) {
28
- * if (command.type === "my-command") {
29
- * // command is narrowed to MyCommand here
30
- * console.log(command.value);
31
- * }
32
- * return null;
33
- * },
34
- * });
35
- */
36
- export function defineExtension(extension) {
37
- return extension;
38
- }
39
20
  const defaultSelection = { start: 0, end: 0, affinity: "forward" };
40
- export function createRuntime(extensions) {
41
- const toggleMarkerToSpec = new Map();
42
- for (const extension of extensions) {
43
- const toggle = extension.toggleInline;
44
- if (!toggle) {
45
- continue;
46
- }
47
- for (const marker of toggle.markers) {
48
- const spec = typeof marker === "string"
49
- ? { kind: toggle.kind, open: marker, close: marker }
50
- : { kind: toggle.kind, open: marker.open, close: marker.close };
51
- toggleMarkerToSpec.set(spec.open, spec);
52
- }
21
+ function removeFromArray(arr, value) {
22
+ const index = arr.indexOf(value);
23
+ if (index === -1) {
24
+ return;
53
25
  }
26
+ arr.splice(index, 1);
27
+ }
28
+ export function createRuntimeForTests(extensions) {
29
+ const toggleMarkerToSpec = new Map();
54
30
  const inclusiveAtEndByKind = new Map();
55
- for (const extension of extensions) {
56
- const specs = extension.inlineWrapperAffinity;
57
- if (!specs) {
58
- continue;
59
- }
60
- for (const spec of specs) {
61
- if (!inclusiveAtEndByKind.has(spec.kind)) {
62
- inclusiveAtEndByKind.set(spec.kind, spec.inclusive);
31
+ const parseBlockFns = [];
32
+ const parseInlineFns = [];
33
+ const serializeBlockFns = [];
34
+ const serializeInlineFns = [];
35
+ const normalizeBlockFns = [];
36
+ const normalizeInlineFns = [];
37
+ const onEditFns = [];
38
+ const domInlineRenderers = [];
39
+ const domBlockRenderers = [];
40
+ const editor = {
41
+ registerInlineWrapperAffinity: (specs) => {
42
+ for (const spec of specs) {
43
+ if (!inclusiveAtEndByKind.has(spec.kind)) {
44
+ inclusiveAtEndByKind.set(spec.kind, spec.inclusive);
45
+ }
63
46
  }
64
- }
47
+ return () => {
48
+ for (const spec of specs) {
49
+ const current = inclusiveAtEndByKind.get(spec.kind);
50
+ if (current === spec.inclusive) {
51
+ inclusiveAtEndByKind.delete(spec.kind);
52
+ }
53
+ }
54
+ };
55
+ },
56
+ registerToggleInline: (toggle) => {
57
+ const added = [];
58
+ for (const marker of toggle.markers) {
59
+ const spec = typeof marker === "string"
60
+ ? { kind: toggle.kind, open: marker, close: marker }
61
+ : { kind: toggle.kind, open: marker.open, close: marker.close };
62
+ toggleMarkerToSpec.set(spec.open, spec);
63
+ added.push(spec);
64
+ }
65
+ return () => {
66
+ for (const spec of added) {
67
+ const current = toggleMarkerToSpec.get(spec.open);
68
+ if (current &&
69
+ current.kind === spec.kind &&
70
+ current.close === spec.close) {
71
+ toggleMarkerToSpec.delete(spec.open);
72
+ }
73
+ }
74
+ };
75
+ },
76
+ registerParseBlock: (fn) => {
77
+ parseBlockFns.push(fn);
78
+ return () => removeFromArray(parseBlockFns, fn);
79
+ },
80
+ registerParseInline: (fn) => {
81
+ parseInlineFns.push(fn);
82
+ return () => removeFromArray(parseInlineFns, fn);
83
+ },
84
+ registerSerializeBlock: (fn) => {
85
+ serializeBlockFns.push(fn);
86
+ return () => removeFromArray(serializeBlockFns, fn);
87
+ },
88
+ registerSerializeInline: (fn) => {
89
+ serializeInlineFns.push(fn);
90
+ return () => removeFromArray(serializeInlineFns, fn);
91
+ },
92
+ registerNormalizeBlock: (fn) => {
93
+ normalizeBlockFns.push(fn);
94
+ return () => removeFromArray(normalizeBlockFns, fn);
95
+ },
96
+ registerNormalizeInline: (fn) => {
97
+ normalizeInlineFns.push(fn);
98
+ return () => removeFromArray(normalizeInlineFns, fn);
99
+ },
100
+ registerOnEdit: (fn) => {
101
+ onEditFns.push(fn);
102
+ return () => removeFromArray(onEditFns, fn);
103
+ },
104
+ registerOnPasteText: () => {
105
+ return () => { };
106
+ },
107
+ registerKeybindings: () => {
108
+ return () => { };
109
+ },
110
+ registerInlineRenderer: (fn) => {
111
+ domInlineRenderers.push(fn);
112
+ return () => removeFromArray(domInlineRenderers, fn);
113
+ },
114
+ registerBlockRenderer: (fn) => {
115
+ domBlockRenderers.push(fn);
116
+ return () => removeFromArray(domBlockRenderers, fn);
117
+ },
118
+ registerUI: () => {
119
+ return () => { };
120
+ },
121
+ };
122
+ for (const extension of extensions) {
123
+ extension(editor);
65
124
  }
125
+ const runtime = createRuntimeFromRegistry({
126
+ toggleMarkerToSpec,
127
+ inclusiveAtEndByKind,
128
+ parseBlockFns,
129
+ parseInlineFns,
130
+ serializeBlockFns,
131
+ serializeInlineFns,
132
+ normalizeBlockFns,
133
+ normalizeInlineFns,
134
+ onEditFns,
135
+ domInlineRenderers,
136
+ domBlockRenderers,
137
+ });
138
+ return runtime;
139
+ }
140
+ export function createRuntimeFromRegistry(registry) {
141
+ const { toggleMarkerToSpec, inclusiveAtEndByKind, parseBlockFns, parseInlineFns, serializeBlockFns, serializeInlineFns, normalizeBlockFns, normalizeInlineFns, onEditFns, domInlineRenderers, domBlockRenderers, } = registry;
66
142
  const isInclusiveAtEnd = (kind) => inclusiveAtEndByKind.get(kind) ?? true;
67
143
  const context = {
68
144
  parseInline: (source, start, end) => parseInlineRange(source, start, end),
@@ -70,11 +146,8 @@ export function createRuntime(extensions) {
70
146
  serializeBlock: (block) => serializeBlock(block),
71
147
  };
72
148
  function parseBlockAt(source, start) {
73
- for (const extension of extensions) {
74
- if (!extension.parseBlock) {
75
- continue;
76
- }
77
- const result = extension.parseBlock(source, start, context);
149
+ for (const parseBlock of parseBlockFns) {
150
+ const result = parseBlock(source, start, context);
78
151
  if (result) {
79
152
  return result;
80
153
  }
@@ -86,11 +159,8 @@ export function createRuntime(extensions) {
86
159
  let pos = start;
87
160
  while (pos < end) {
88
161
  let matched = false;
89
- for (const extension of extensions) {
90
- if (!extension.parseInline) {
91
- continue;
92
- }
93
- const result = extension.parseInline(source, pos, end, context);
162
+ for (const parseInline of parseInlineFns) {
163
+ const result = parseInline(source, pos, end, context);
94
164
  if (result) {
95
165
  inlines.push(result.inline);
96
166
  pos = result.nextPos;
@@ -138,11 +208,8 @@ export function createRuntime(extensions) {
138
208
  return builder.build();
139
209
  }
140
210
  function serializeBlock(block) {
141
- for (const extension of extensions) {
142
- if (!extension.serializeBlock) {
143
- continue;
144
- }
145
- const result = extension.serializeBlock(block, context);
211
+ for (const serializeBlockFn of serializeBlockFns) {
212
+ const result = serializeBlockFn(block, context);
146
213
  if (result) {
147
214
  return result;
148
215
  }
@@ -156,11 +223,8 @@ export function createRuntime(extensions) {
156
223
  return { source: "", map: new CursorSourceBuilder().build().map };
157
224
  }
158
225
  function serializeInline(inline) {
159
- for (const extension of extensions) {
160
- if (!extension.serializeInline) {
161
- continue;
162
- }
163
- const result = extension.serializeInline(inline, context);
226
+ for (const serializeInlineFn of serializeInlineFns) {
227
+ const result = serializeInlineFn(inline, context);
164
228
  if (result) {
165
229
  return result;
166
230
  }
@@ -185,14 +249,12 @@ export function createRuntime(extensions) {
185
249
  }
186
250
  function normalizeBlock(block) {
187
251
  let next = block;
188
- for (const extension of extensions) {
189
- if (extension.normalizeBlock) {
190
- const result = extension.normalizeBlock(next);
191
- if (result === null) {
192
- return null;
193
- }
194
- next = result;
252
+ for (const normalizeBlockFn of normalizeBlockFns) {
253
+ const result = normalizeBlockFn(next);
254
+ if (result === null) {
255
+ return null;
195
256
  }
257
+ next = result;
196
258
  }
197
259
  if (next.type === "paragraph") {
198
260
  return {
@@ -214,11 +276,8 @@ export function createRuntime(extensions) {
214
276
  }
215
277
  function applyInlineNormalizers(inline) {
216
278
  let next = inline;
217
- for (const extension of extensions) {
218
- if (!extension.normalizeInline) {
219
- continue;
220
- }
221
- const result = extension.normalizeInline(next);
279
+ for (const normalizeInlineFn of normalizeInlineFns) {
280
+ const result = normalizeInlineFn(next);
222
281
  if (result === null) {
223
282
  return null;
224
283
  }
@@ -275,11 +334,8 @@ export function createRuntime(extensions) {
275
334
  // If an extension delegates in a loop, this will loop as well.
276
335
  while (true) {
277
336
  let delegated = false;
278
- for (const extension of extensions) {
279
- if (!extension.onEdit) {
280
- continue;
281
- }
282
- const result = extension.onEdit(command, state);
337
+ for (const onEdit of onEditFns) {
338
+ const result = onEdit(command, state);
283
339
  if (!result) {
284
340
  continue;
285
341
  }
@@ -474,8 +530,7 @@ export function createRuntime(extensions) {
474
530
  endLoc.offsetInLine === 0 &&
475
531
  endLoc.lineIndex > 0) {
476
532
  const prevLine = lines[endLoc.lineIndex - 1];
477
- if (prevLine &&
478
- !pathsEqual(prevLine.parentPath, endLine.parentPath)) {
533
+ if (prevLine && !pathsEqual(prevLine.parentPath, endLine.parentPath)) {
479
534
  const prevBlock = getBlockAtPath(doc.blocks, prevLine.path);
480
535
  const currentBlock = getBlockAtPath(doc.blocks, endLine.path);
481
536
  if (prevBlock &&
@@ -1259,7 +1314,7 @@ export function createRuntime(extensions) {
1259
1314
  if (!markerSpec) {
1260
1315
  return state;
1261
1316
  }
1262
- const { kind: markerKind, open: openMarker, close: closeMarker } = markerSpec;
1317
+ const { kind: markerKind, open: openMarker, close: closeMarker, } = markerSpec;
1263
1318
  const openLen = openMarker.length;
1264
1319
  const closeLen = closeMarker.length;
1265
1320
  if (selection.start === selection.end) {
@@ -1401,7 +1456,9 @@ export function createRuntime(extensions) {
1401
1456
  continue;
1402
1457
  }
1403
1458
  const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
1404
- const endInLine = lineIndex === endLoc.lineIndex ? endLoc.offsetInLine : line.cursorLength;
1459
+ const endInLine = lineIndex === endLoc.lineIndex
1460
+ ? endLoc.offsetInLine
1461
+ : line.cursorLength;
1405
1462
  if (startInLine === endInLine) {
1406
1463
  continue;
1407
1464
  }
@@ -1590,7 +1647,9 @@ export function createRuntime(extensions) {
1590
1647
  }
1591
1648
  };
1592
1649
  const openList = (type, indent) => {
1593
- if (activeList && activeList.type === type && activeList.indent === indent) {
1650
+ if (activeList &&
1651
+ activeList.type === type &&
1652
+ activeList.indent === indent) {
1594
1653
  return;
1595
1654
  }
1596
1655
  closeList();
@@ -1608,7 +1667,9 @@ export function createRuntime(extensions) {
1608
1667
  }
1609
1668
  const runs = paragraphToRuns(block);
1610
1669
  const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
1611
- const endInLine = lineIndex === endLoc.lineIndex ? endLoc.offsetInLine : line.cursorLength;
1670
+ const endInLine = lineIndex === endLoc.lineIndex
1671
+ ? endLoc.offsetInLine
1672
+ : line.cursorLength;
1612
1673
  const selectedRuns = sliceRuns(runs, startInLine, endInLine).selected;
1613
1674
  // Check if this line is inside a block-wrapper (heading or list)
1614
1675
  let wrapperKind = null;
@@ -1671,7 +1732,10 @@ export function createRuntime(extensions) {
1671
1732
  return `<div>${html}</div>`;
1672
1733
  }
1673
1734
  const runtime = {
1674
- extensions,
1735
+ dom: {
1736
+ inlineRenderers: domInlineRenderers,
1737
+ blockRenderers: domBlockRenderers,
1738
+ },
1675
1739
  parse,
1676
1740
  serialize,
1677
1741
  createState,
@@ -1 +1 @@
1
- {"version":3,"file":"dom-map.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/dom-map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvE,WAAW,CACT,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACxD,CAAC;AASF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAqBtE;AAqDD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CA2GpD"}
1
+ {"version":3,"file":"dom-map.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/dom-map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvE,WAAW,CACT,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACxD,CAAC;AASF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAqBtE;AAqDD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CA+GpD"}
@@ -85,7 +85,9 @@ export function createDomMap(runs) {
85
85
  const run = runs[runIndex];
86
86
  const previous = runIndex > 0 ? runs[runIndex - 1] : null;
87
87
  const next = nextIndex < runs.length ? runs[nextIndex] : null;
88
- if (cursorOffset === run.cursorStart && previous && affinity === "backward") {
88
+ if (cursorOffset === run.cursorStart &&
89
+ previous &&
90
+ affinity === "backward") {
89
91
  return {
90
92
  node: previous.node,
91
93
  offset: previous.boundaryOffsets[previous.boundaryOffsets.length - 1],
@@ -1,5 +1,5 @@
1
1
  import type { Doc, Inline } from "../core/types";
2
- import type { CakeExtension } from "../core/runtime";
2
+ import type { Runtime } from "../core/runtime";
3
3
  import { createDomMap } from "./dom-map";
4
4
  export type RenderResult = {
5
5
  root: HTMLElement;
@@ -9,7 +9,7 @@ export type RenderContentResult = {
9
9
  content: Node[];
10
10
  map: ReturnType<typeof createDomMap>;
11
11
  };
12
- export declare function renderDocContent(doc: Doc, extensions: CakeExtension[], root?: HTMLElement): RenderContentResult;
13
- export declare function renderDoc(doc: Doc, extensions: CakeExtension[]): RenderResult;
12
+ export declare function renderDocContent(doc: Doc, dom: Runtime["dom"], root?: HTMLElement): RenderContentResult;
13
+ export declare function renderDoc(doc: Doc, dom: Runtime["dom"]): RenderResult;
14
14
  export declare function mergeInlineForRender(inlines: Inline[]): Inline[];
15
15
  //# sourceMappingURL=render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,GAAG,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EACL,YAAY,EAGb,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AASF,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,aAAa,EAAE,EAC3B,IAAI,CAAC,EAAE,WAAW,GACjB,mBAAmB,CAmXrB;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,aAAa,EAAE,GAC1B,YAAY,CAkJd;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiChE"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/cake/dom/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,GAAG,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,YAAY,EAGb,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACtC,CAAC;AASF,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,IAAI,CAAC,EAAE,WAAW,GACjB,mBAAmB,CA4WrB;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,CA0IrE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiChE"}
@@ -5,7 +5,7 @@ function normalizeNodes(result) {
5
5
  }
6
6
  return Array.isArray(result) ? result : [result];
7
7
  }
8
- export function renderDocContent(doc, extensions, root) {
8
+ export function renderDocContent(doc, dom, root) {
9
9
  const runs = [];
10
10
  let cursorOffset = 0;
11
11
  let lineIndex = 0;
@@ -79,12 +79,8 @@ export function renderDocContent(doc, extensions, root) {
79
79
  return "unknown";
80
80
  }
81
81
  function reconcileInline(inline, existing) {
82
- for (const extension of extensions) {
83
- const render = extension.renderInline;
84
- if (!render) {
85
- continue;
86
- }
87
- const result = render(inline, context);
82
+ for (const renderInline of dom.inlineRenderers) {
83
+ const result = renderInline(inline, context);
88
84
  if (result) {
89
85
  return normalizeNodes(result);
90
86
  }
@@ -157,7 +153,8 @@ export function renderDocContent(doc, extensions, root) {
157
153
  const newChildren = [];
158
154
  mergedInlines.forEach((inline, i) => {
159
155
  const existingChild = existingChildren[i] ?? null;
160
- const canReuse = existingChild && getInlineElementKey(existingChild) === getInlineKey(inline);
156
+ const canReuse = existingChild &&
157
+ getInlineElementKey(existingChild) === getInlineKey(inline);
161
158
  const nodes = reconcileInline(inline, canReuse ? existingChild : null);
162
159
  newChildren.push(...nodes);
163
160
  });
@@ -171,12 +168,8 @@ export function renderDocContent(doc, extensions, root) {
171
168
  return reconcileInline(inline, null);
172
169
  }
173
170
  function reconcileBlock(block, existing) {
174
- for (const extension of extensions) {
175
- const render = extension.renderBlock;
176
- if (!render) {
177
- continue;
178
- }
179
- const result = render(block, context);
171
+ for (const renderBlock of dom.blockRenderers) {
172
+ const result = renderBlock(block, context);
180
173
  if (result) {
181
174
  return normalizeNodes(result);
182
175
  }
@@ -311,7 +304,7 @@ export function renderDocContent(doc, extensions, root) {
311
304
  });
312
305
  return { content: contentNodes, map: createDomMap(runs) };
313
306
  }
314
- export function renderDoc(doc, extensions) {
307
+ export function renderDoc(doc, dom) {
315
308
  const root = document.createElement("div");
316
309
  root.className = "cake-content";
317
310
  root.setAttribute("contenteditable", "true");
@@ -335,12 +328,8 @@ export function renderDoc(doc, extensions) {
335
328
  },
336
329
  };
337
330
  function renderInline(inline) {
338
- for (const extension of extensions) {
339
- const render = extension.renderInline;
340
- if (!render) {
341
- continue;
342
- }
343
- const result = render(inline, context);
331
+ for (const renderInline of dom.inlineRenderers) {
332
+ const result = renderInline(inline, context);
344
333
  if (result) {
345
334
  return normalizeNodes(result);
346
335
  }
@@ -374,12 +363,8 @@ export function renderDoc(doc, extensions) {
374
363
  return [];
375
364
  }
376
365
  function renderBlock(block) {
377
- for (const extension of extensions) {
378
- const render = extension.renderBlock;
379
- if (!render) {
380
- continue;
381
- }
382
- const result = render(block, context);
366
+ for (const renderBlock of dom.blockRenderers) {
367
+ const result = renderBlock(block, context);
383
368
  if (result) {
384
369
  return normalizeNodes(result);
385
370
  }