edytor 4.0.0 → 6.0.0

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 (193) hide show
  1. package/README.md +2 -2
  2. package/dist/block/block.svelte.js +6 -21
  3. package/dist/block/inlineBlock.svelte.js +4 -6
  4. package/dist/clipboard/moveText.js +6 -8
  5. package/dist/cloudflare/DocumentRoom.d.ts +10 -3
  6. package/dist/cloudflare/index.d.ts +1 -1
  7. package/dist/cloudflare/room/access.d.ts +8 -3
  8. package/dist/cloudflare/room/access.js +44 -20
  9. package/dist/cloudflare/room/admission.js +28 -5
  10. package/dist/cloudflare/room/comments.js +28 -1
  11. package/dist/cloudflare/room/context.d.ts +106 -109
  12. package/dist/cloudflare/room/context.js +10 -3
  13. package/dist/cloudflare/room/forged.d.ts +14 -0
  14. package/dist/cloudflare/room/forged.js +30 -2
  15. package/dist/cloudflare/room/frames.d.ts +4 -0
  16. package/dist/cloudflare/room/frames.js +5 -1
  17. package/dist/cloudflare/room/purge.js +2 -1
  18. package/dist/cloudflare/room/replicas.d.ts +4 -2
  19. package/dist/cloudflare/room/replicas.js +8 -3
  20. package/dist/cloudflare/room/suggest.d.ts +7 -0
  21. package/dist/cloudflare/room/suggest.js +143 -0
  22. package/dist/cloudflare/routeDocumentSocket.d.ts +10 -1
  23. package/dist/cloudflare/routeDocumentSocket.js +5 -3
  24. package/dist/components/Content.svelte +9 -1
  25. package/dist/crdt/anchors.js +3 -2
  26. package/dist/crdt/attribution/attribution.d.ts +3 -0
  27. package/dist/crdt/attribution/attribution.js +3 -3
  28. package/dist/crdt/doc/funnel.d.ts +1 -1
  29. package/dist/crdt/doc/funnel.js +5 -2
  30. package/dist/crdt/doc/gate.d.ts +1 -1
  31. package/dist/crdt/doc/history.d.ts +6 -0
  32. package/dist/crdt/doc/history.js +79 -59
  33. package/dist/crdt/doc/ops.d.ts +81 -0
  34. package/dist/crdt/doc/ops.js +1898 -0
  35. package/dist/crdt/doc/reads.d.ts +2 -2
  36. package/dist/crdt/doc/reads.js +18 -28
  37. package/dist/crdt/doc/suggest.d.ts +167 -0
  38. package/dist/crdt/doc/suggest.js +579 -0
  39. package/dist/crdt/document.d.ts +10 -1
  40. package/dist/crdt/document.js +19 -11
  41. package/dist/crdt/edytor-doc.d.ts +294 -272
  42. package/dist/crdt/edytor-doc.js +123 -108
  43. package/dist/crdt/engine-api.d.ts +8 -2
  44. package/dist/crdt/engine.d.ts +2 -1
  45. package/dist/crdt/engine.js +3 -1
  46. package/dist/crdt/flow.d.ts +5 -47
  47. package/dist/crdt/flow.js +3 -269
  48. package/dist/crdt/index.d.ts +102 -108
  49. package/dist/crdt/index.js +3 -0
  50. package/dist/crdt/operations.d.ts +13 -4
  51. package/dist/crdt/parts.d.ts +43 -0
  52. package/dist/crdt/parts.js +44 -0
  53. package/dist/crdt/placement/display.d.ts +1 -1
  54. package/dist/crdt/placement/display.js +3 -3
  55. package/dist/crdt/placement/keys.d.ts +5 -0
  56. package/dist/crdt/placement/keys.js +5 -0
  57. package/dist/crdt/placement/resolve.d.ts +1 -1
  58. package/dist/crdt/placement/resolve.js +2 -1
  59. package/dist/crdt/protocol.d.ts +1 -1
  60. package/dist/crdt/protocol.js +1 -1
  61. package/dist/crdt/protocols/auth.d.ts +11 -1
  62. package/dist/crdt/protocols/auth.js +17 -1
  63. package/dist/crdt/protocols/awareness.js +46 -81
  64. package/dist/crdt/protocols/comments.d.ts +16 -1
  65. package/dist/crdt/protocols/comments.js +9 -1
  66. package/dist/crdt/providers/index.d.ts +12 -22
  67. package/dist/crdt/providers/index.js +3 -1
  68. package/dist/crdt/providers/indexeddb.d.ts +6 -10
  69. package/dist/crdt/providers/indexeddb.js +10 -16
  70. package/dist/crdt/providers/room.d.ts +11 -0
  71. package/dist/crdt/providers/room.js +26 -12
  72. package/dist/crdt/providers/websocket.d.ts +8 -12
  73. package/dist/crdt/providers/websocket.js +17 -19
  74. package/dist/crdt/purge.d.ts +7 -1
  75. package/dist/crdt/purge.js +32 -2
  76. package/dist/crdt/rangeDelete.d.ts +2 -47
  77. package/dist/crdt/rangeDelete.js +1 -169
  78. package/dist/crdt/restore.d.ts +2 -1
  79. package/dist/crdt/restore.js +9 -0
  80. package/dist/crdt/schema.d.ts +9 -1
  81. package/dist/crdt/schema.js +13 -3
  82. package/dist/crdt/structs.d.ts +2 -0
  83. package/dist/crdt/structs.js +2 -0
  84. package/dist/crdt/text/index/build.d.ts +125 -0
  85. package/dist/crdt/text/index/build.js +2895 -0
  86. package/dist/crdt/text/index/shared.d.ts +2 -6
  87. package/dist/crdt/text/index/shared.js +19 -19
  88. package/dist/crdt/text/model.d.ts +10 -0
  89. package/dist/crdt/text/model.js +10 -4
  90. package/dist/crdt/text/runs.d.ts +43 -42
  91. package/dist/crdt/text/runs.js +2 -165
  92. package/dist/crdt/vendor/yjs/UPSTREAM.md +83 -0
  93. package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
  94. package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +6 -3
  95. package/dist/crdt/vendor/yjs/dts/ynode.d.ts +13 -2
  96. package/dist/crdt/vendor/yjs/src/index.js +1 -1
  97. package/dist/crdt/vendor/yjs/src/structs/Item.js +44 -5
  98. package/dist/crdt/vendor/yjs/src/ynode.js +29 -7
  99. package/dist/edytor.svelte.d.ts +1 -1
  100. package/dist/edytor.svelte.js +100 -75
  101. package/dist/events/beforeInputCommands.d.ts +2 -2
  102. package/dist/events/domTextOffset.d.ts +2 -0
  103. package/dist/events/domTextOffset.js +8 -0
  104. package/dist/events/nativeInteractiveControl.d.ts +11 -1
  105. package/dist/events/nativeInteractiveControl.js +41 -1
  106. package/dist/events/onBeforeInput.js +3 -3
  107. package/dist/events/onFocus.js +9 -11
  108. package/dist/export/forms.d.ts +75 -75
  109. package/dist/index.d.ts +4 -2
  110. package/dist/index.js +1 -1
  111. package/dist/labels.d.ts +8 -0
  112. package/dist/labels.js +6 -1
  113. package/dist/plugins/comments/CommentsController.svelte.d.ts +5 -1
  114. package/dist/plugins/comments/CommentsController.svelte.js +14 -4
  115. package/dist/plugins/find/search.js +2 -2
  116. package/dist/plugins/index.d.ts +1 -0
  117. package/dist/plugins/index.js +1 -0
  118. package/dist/plugins/richtext/RichTextPlugin.svelte +63 -61
  119. package/dist/plugins/richtext/richTextOperations.js +26 -32
  120. package/dist/plugins/suggestions/SuggestionBars.svelte +40 -23
  121. package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +3 -1
  122. package/dist/plugins/suggestions/SuggestionRuns.svelte +77 -0
  123. package/dist/plugins/suggestions/SuggestionRuns.svelte.d.ts +9 -0
  124. package/dist/plugins/suggestions/shared.svelte.d.ts +58 -0
  125. package/dist/plugins/suggestions/shared.svelte.js +421 -0
  126. package/dist/plugins/suggestions/suggestionsPlugin.d.ts +15 -4
  127. package/dist/selection/domSelection.d.ts +2 -0
  128. package/dist/selection/domSelection.js +6 -2
  129. package/dist/selection/pointer.svelte.js +75 -48
  130. package/dist/selection/replaceSelection.js +2 -6
  131. package/dist/selection/selection.svelte.d.ts +3 -3
  132. package/dist/selection/selection.svelte.js +39 -32
  133. package/dist/selection/selection.utils.d.ts +14 -0
  134. package/dist/selection/selection.utils.js +33 -11
  135. package/dist/session/commands.js +21 -11
  136. package/dist/session/composition.svelte.d.ts +5 -3
  137. package/dist/session/composition.svelte.js +21 -17
  138. package/dist/session/handles.d.ts +4 -17
  139. package/dist/session/handles.js +14 -44
  140. package/dist/session/navigation.js +6 -9
  141. package/dist/session/selection.d.ts +11 -5
  142. package/dist/session/selection.js +14 -48
  143. package/dist/session/suggestions.svelte.d.ts +38 -9
  144. package/dist/session/suggestions.svelte.js +37 -18
  145. package/dist/session/virtual.d.ts +1 -1
  146. package/dist/surface/attributes.d.ts +5 -0
  147. package/dist/surface/attributes.js +2 -2
  148. package/dist/surface/cells.d.ts +2 -26
  149. package/dist/surface/cells.js +2 -33
  150. package/dist/surface/observer.svelte.d.ts +6 -1
  151. package/dist/surface/observer.svelte.js +143 -111
  152. package/dist/surface/pin.svelte.d.ts +9 -9
  153. package/dist/surface/pin.svelte.js +15 -22
  154. package/dist/surface/projector.svelte.js +10 -16
  155. package/dist/text/text.svelte.js +14 -19
  156. package/dist/themes/notion.css +29 -0
  157. package/dist/utils.d.ts +5 -0
  158. package/dist/utils.js +7 -0
  159. package/package.json +3 -1
  160. package/dist/crdt/doc/capability.d.ts +0 -56
  161. package/dist/crdt/doc/capability.js +0 -211
  162. package/dist/crdt/doc/content.d.ts +0 -16
  163. package/dist/crdt/doc/content.js +0 -77
  164. package/dist/crdt/doc/delete.d.ts +0 -15
  165. package/dist/crdt/doc/delete.js +0 -84
  166. package/dist/crdt/doc/layout.d.ts +0 -9
  167. package/dist/crdt/doc/layout.js +0 -178
  168. package/dist/crdt/doc/meta.d.ts +0 -19
  169. package/dist/crdt/doc/meta.js +0 -199
  170. package/dist/crdt/doc/moves.d.ts +0 -21
  171. package/dist/crdt/doc/moves.js +0 -274
  172. package/dist/crdt/doc/split-merge.d.ts +0 -10
  173. package/dist/crdt/doc/split-merge.js +0 -179
  174. package/dist/crdt/doc/steps.d.ts +0 -65
  175. package/dist/crdt/doc/steps.js +0 -311
  176. package/dist/crdt/text/index/cache.d.ts +0 -16
  177. package/dist/crdt/text/index/cache.js +0 -175
  178. package/dist/crdt/text/index/claims.d.ts +0 -18
  179. package/dist/crdt/text/index/claims.js +0 -225
  180. package/dist/crdt/text/index/fold.d.ts +0 -21
  181. package/dist/crdt/text/index/fold.js +0 -656
  182. package/dist/crdt/text/index/layout.d.ts +0 -24
  183. package/dist/crdt/text/index/layout.js +0 -271
  184. package/dist/crdt/text/index/placement.d.ts +0 -47
  185. package/dist/crdt/text/index/placement.js +0 -741
  186. package/dist/crdt/text/index/records.d.ts +0 -13
  187. package/dist/crdt/text/index/records.js +0 -139
  188. package/dist/crdt/text/index/report.d.ts +0 -18
  189. package/dist/crdt/text/index/report.js +0 -337
  190. package/dist/crdt/text/index/state.d.ts +0 -197
  191. package/dist/crdt/text/index/state.js +0 -116
  192. package/dist/crdt/text/index/streams.d.ts +0 -25
  193. package/dist/crdt/text/index/streams.js +0 -248
package/dist/crdt/flow.js CHANGED
@@ -1,9 +1,5 @@
1
- import { ref } from './doc/plan.js';
2
- import { id as freshId } from '../utils.js';
3
- import { sanitizeSpec } from '../utils/json.js';
4
- import { collides } from './placement/model.js';
5
- import { TYPE } from './schema.js';
6
- const lengthOf = (l) => (l.content ?? []).reduce((n, i) => n + (i.kind === 'text' ? i.text.length : 1), 0);
1
+ /** The units of a line's content (an atom counts 1). */
2
+ export const lengthOf = (l) => (l.content ?? []).reduce((n, i) => n + (i.kind === 'text' ? i.text.length : 1), 0);
7
3
  /**
8
4
  * Where the caret ends a placed block: its own content's end when it shows a
9
5
  * line (renders its content, no void; a toggle's header, never its body),
@@ -14,7 +10,7 @@ const lengthOf = (l) => (l.content ?? []).reduce((n, i) => n + (i.kind === 'text
14
10
  export const placedEnd = (roleOf) => {
15
11
  const endOf = (s) => {
16
12
  const role = roleOf(s.type);
17
- if (role.rendersContent && !role.void)
13
+ if (role.rendersContent && !role.childless)
18
14
  return { block: s.id, offset: lengthOf(s) };
19
15
  for (const kid of [...(s.children ?? [])].reverse()) {
20
16
  const at = endOf(kid);
@@ -25,265 +21,3 @@ export const placedEnd = (roleOf) => {
25
21
  };
26
22
  return endOf;
27
23
  };
28
- /** `insertFlow`, prepared. */
29
- export const flowOps = (c) => {
30
- /** A kind's roles, as placement reads them. */
31
- const roleOf = (kind) => ({
32
- void: c.roles.childless(kind),
33
- island: c.roles.island(kind),
34
- rendersContent: c.roles.rendersContent(kind),
35
- layout: c.roles.layout(kind)
36
- });
37
- /** What a kind is in a table: the table, its row or its cell. */
38
- const tableKind = (kind) => c.roles.table(kind) !== undefined
39
- ? 'table'
40
- : c.isRowKind(kind)
41
- ? 'row'
42
- : c.isCellKind(kind)
43
- ? 'cell'
44
- : undefined;
45
- return {
46
- insertFlow: (target, flow, view = {}) => {
47
- // Ingress: a run carries a placeholder kind through the spec sanitizer.
48
- let lines = flow.lines
49
- .map((l) => sanitizeSpec({ ...l, type: l.type ?? '' }))
50
- .map((s) => ({ ...s, type: s.type || undefined }));
51
- if (lines.length === 0)
52
- return c.plan([], []);
53
- // A cell outside a row is its text, a row outside a table its cells (`table.paste`).
54
- const unbare = (l, holder) => {
55
- const kind = l.type ? tableKind(l.type) : undefined;
56
- const kids = (next) => (l.children ?? []).flatMap((kid) => unbare(kid, next));
57
- if (kind === 'cell' && holder !== 'row')
58
- return [{ id: l.id, content: l.content }, ...kids(null)];
59
- if (kind === 'row' && holder !== 'table')
60
- return kids(null);
61
- if (!l.children)
62
- return [l];
63
- return [{ ...l, children: kids(kind === 'cell' ? null : (kind ?? null)) }];
64
- };
65
- lines = lines.flatMap((l) => unbare(l, null));
66
- /** A line's kind under `parent`: the list's item for its flat item kind, then `fitted`. */
67
- const fit = (parent, kind) => c.fitted(parent, parent !== null && kind !== undefined && kind === view.itemKind?.(parent)
68
- ? c.defaultChild(parent)
69
- : kind);
70
- const specs = (parent, of = lines) => of.map((l) => ({ ...l, type: fit(parent, l.type) ?? c.defaultChild(parent) }));
71
- const last = () => lines.at(-1);
72
- /** `l` and its nested lines as runs, each line that shows its own content one run. */
73
- const plain = (l) => [
74
- ...(!l.type || roleOf(l.type).rendersContent ? [{ id: l.id, content: l.content }] : []),
75
- ...(l.children ?? []).flatMap(plain)
76
- ];
77
- const endOf = placedEnd(roleOf);
78
- /**
79
- * A layout line, here or nested, as its items' lines in reading order, and
80
- * any other child it holds (`flow.layout`): no layout lands in an item.
81
- */
82
- const unwrap = (l) => {
83
- const item = l.type ? roleOf(l.type).layout : undefined;
84
- if (item === undefined)
85
- return [l.children ? { ...l, children: l.children.flatMap(unwrap) } : l];
86
- return (l.children ?? []).flatMap((kid) => kid.type === item ? (kid.children ?? []).flatMap(unwrap) : unwrap(kid));
87
- };
88
- const intoItem = (parent) => {
89
- if (parent !== null && c.insideItem(parent))
90
- lines = lines.flatMap(unwrap);
91
- };
92
- /** Whole blocks at a slot, after `pre`; the caret ends the last one's shown content. */
93
- const atSlot = (dest, pre) => {
94
- const placed = specs(dest.parent);
95
- const p = c.insertBlocks(dest, placed);
96
- const at = endOf(placed.at(-1)) ?? { block: last().id, offset: lengthOf(last()) };
97
- // The lines are placed while the replaced blocks still show (each step reads the
98
- // display as it stands), then those go.
99
- return 'writes' in p ? { ...c.plan(p.ids, [...p.writes, ...pre]), at } : p;
100
- };
101
- if ('replace' in target || 'slot' in target) {
102
- let slot;
103
- let pre = [];
104
- if ('slot' in target)
105
- slot = target.slot;
106
- else {
107
- // The lines fill the first block's slot: its parent is never emptied
108
- // by the delete, so a column keeps its layout (`layout.flow-slot`).
109
- const at = c.view().order.at;
110
- const first = target.replace
111
- .filter((id) => at.has(id))
112
- .sort((a, b) => at.get(a) - at.get(b))[0];
113
- const del = c.deleteBlocks(target.replace, false, first === undefined ? undefined : c.positionOf(first)?.parent);
114
- if (!('writes' in del))
115
- return del;
116
- if (first === undefined)
117
- return c.REFUSED;
118
- slot = c.positionOf(first);
119
- pre = [...del.writes];
120
- }
121
- intoItem(slot.parent);
122
- if (lines.length === 0)
123
- return c.plan([], []);
124
- // In a code block (selected lines, a slot), the lines are plain lines too (`flow.lines`).
125
- if (slot.parent !== null && c.isLines(slot.parent)) {
126
- const shown = lines.flatMap(plain);
127
- lines = shown.length ? shown : [{ id: lines[0].id, content: [] }];
128
- }
129
- return atSlot(slot, pre);
130
- }
131
- const B = ref(target.block);
132
- if (!c.contentTarget(B) || !c.rendersContent(B))
133
- return c.REFUSED;
134
- const len = c.displayLength(B);
135
- const o = Math.max(0, Math.min(target.offset, len));
136
- const { parent, index } = c.positionOf(B);
137
- intoItem(B);
138
- const empty = len === 0 && c.childrenIds(B).length === 0;
139
- // A line of a lines island (a code line) takes plain lines: every line the flow
140
- // shows, nested ones included, in order; no block lands in the island (`flow.lines`).
141
- const inLines = parent !== null && c.isLines(parent);
142
- if (inLines)
143
- lines = lines.flatMap(plain);
144
- // A table's cell is never split: the lines it shows join its text (`table.paste`).
145
- const cell = c.isTableCell(B);
146
- if (cell)
147
- lines = lines.flatMap(plain);
148
- // A line that joins no text under `under` (`flow.apart`): its kind renders
149
- // none of its own (a list, a code block), or is a void or an island.
150
- const apart = (l, under) => {
151
- const kind = l.type && fit(under, l.type);
152
- const role = kind ? roleOf(kind) : undefined;
153
- return !!role && (!role.rendersContent || role.void || role.island);
154
- };
155
- // At the end of a container's header whose body shows, what follows the caret
156
- // leads its children and the body stays, as Enter opens a first child
157
- // (`flow.header`), unless the first line stands apart and replaces an empty
158
- // one (`flow.apart`); elsewhere it follows `B` among its siblings.
159
- const header = view.header?.(B);
160
- // A closed header shows no children: a line it takes brings none into its hidden
161
- // body; they follow it, shown (`flow.header`).
162
- const shut = header === 'closed';
163
- const inside = o === len && !inLines && !flow.whole && header === true && !(empty && apart(lines[0], B));
164
- const home = inside ? B : parent;
165
- if (lines.length === 0)
166
- return { ...c.plan([B], []), at: { block: B, offset: o } };
167
- if (flow.whole && !inLines && !cell)
168
- return atSlot({ parent, index: index + 1 }, empty ? [c.remove(B, [])] : []);
169
- // A void is never split: its caption takes the lines as one run; nor is a cell.
170
- const br = { kind: 'text', text: '\n' };
171
- if (c.isVoid(B) || cell) {
172
- const content = lines.flatMap((l, i) => [...(i ? [br] : []), ...(l.content ?? [])]);
173
- lines = [{ id: lines[0].id, content }];
174
- }
175
- // So a first line it joins leaves its nested lines as lines of the flow after it.
176
- if (shut && lines[0].children?.length && !apart(lines[0], home))
177
- lines = [{ ...lines[0], children: undefined }, ...lines[0].children, ...lines.slice(1)];
178
- const first = lines[0];
179
- const [joinsHead, joinsTail] = [
180
- !apart(first, home),
181
- lines.length > 1 && !apart(last(), home)
182
- ];
183
- const all = specs(home);
184
- const placed = all.slice(joinsHead ? 1 : 0, joinsTail ? -1 : undefined);
185
- const ids = placed.map((s) => s.id);
186
- if (collides(c.doc, [
187
- ...(joinsHead ? (first.children ?? []) : []),
188
- ...all.slice(joinsHead ? 1 : 0)
189
- ]))
190
- return c.REFUSED;
191
- const writes = [];
192
- /** A joined line's children lead the block it joins; `moved` follow them. */
193
- const kids = (to, l, moved = []) => {
194
- const k = l?.children?.length ?? 0;
195
- if (k)
196
- writes.push({ op: 'insertBlocks', parent: to, index: 0, specs: l.children });
197
- if (moved.length)
198
- writes.push({ op: 'moveBlocks', ids: moved, parent: to, index: k });
199
- };
200
- /**
201
- * `l` joins `B` at `at`: its content, its kind when `B` shows no text (a header
202
- * keeps its own, as Enter does), its children first.
203
- */
204
- const join = (l, at) => {
205
- const end = c.writeContent(writes, B, at, l.content);
206
- const kind = l.type && fit(parent, l.type);
207
- if (len === 0 && !header && kind && kind === l.type)
208
- writes.push(...c.attr(B, TYPE, kind), ...(c.dataSteps(B, c.replaceData(l.data ?? {})) ?? []));
209
- if (!shut)
210
- kids(B, l);
211
- return end;
212
- };
213
- /** The placed lines at `at` under `home` (`split`: the tail of the split they come with). */
214
- const place = (at, split) => {
215
- if (placed.length)
216
- writes.push({
217
- op: 'insertBlocks',
218
- parent: home,
219
- index: at,
220
- specs: placed,
221
- ...(split !== undefined && { split })
222
- });
223
- };
224
- // Under a header, the first line's children, the placed lines and the rest, in order.
225
- const k = joinsHead ? (first.children?.length ?? 0) : 0;
226
- const slot = inside ? k : index + 1;
227
- // Where the placed lines end the caret: after their last shown line (`flow.apart`).
228
- const end = placed.length ? endOf(placed.at(-1)) : undefined;
229
- // Nothing before the position and the first line stands apart: the lines go before `B`,
230
- // which keeps its text and takes a joining last line, or goes when empty and not needed.
231
- if (!joinsHead && o === 0 && !inside) {
232
- place(index);
233
- if (joinsTail) {
234
- const at = join(last(), 0);
235
- // A closed header's taken line's nested lines follow it, the caret ending them.
236
- const after = shut ? specs(parent, last().children ?? []) : [];
237
- if (after.length) {
238
- const slot = index + placed.length + 1;
239
- writes.push({ op: 'insertBlocks', parent, index: slot, specs: after });
240
- }
241
- const caret = after.length ? endOf(after.at(-1)) : undefined;
242
- const touched = [...ids, B, ...after.map((s) => s.id)];
243
- return { ...c.plan(touched, writes), at: caret ?? { block: B, offset: at } };
244
- }
245
- if (empty && end)
246
- return { ...c.plan(ids, [...writes, c.remove(B, [])]), at: end };
247
- return { ...c.plan([...ids, B], writes), at: end ?? { block: B, offset: 0 } };
248
- }
249
- const head = joinsHead ? join(first, o) : o;
250
- if (lines.length === 1 && joinsHead)
251
- return { ...c.plan([B], writes), at: { block: B, offset: head } };
252
- const moved = inside ? [] : c.childrenIds(B).filter((id) => !view.hidden?.(id));
253
- // Nothing after the position to keep, and the caret has a line: no split.
254
- if (!joinsTail && o === len && moved.length === 0 && end) {
255
- place(slot);
256
- return { ...c.plan([B, ...ids], writes), at: end };
257
- }
258
- // The rest of `B` stays in a shown line: the last line's block when it joins, else
259
- // a line of `B`'s kind, as Enter makes; one made only for the caret (after a
260
- // divider at the end) or under a header is a fresh line of its parent's default kind.
261
- const T = joinsTail ? last().id : freshId('b');
262
- const lastType = joinsTail && last().type && fit(home, last().type);
263
- const bare = !joinsTail && o === len && moved.length === 0;
264
- const tail = lastType
265
- ? { type: lastType, data: last().data }
266
- : bare || inside
267
- ? { type: c.defaultChild(home), data: {} }
268
- : { type: c.kindToCopy(B), data: c.blockDataOf(B) };
269
- // After `B` (under a header: after the first line's children); the placed lines go before it.
270
- const length = len - o;
271
- writes.push({
272
- op: 'splitBlock',
273
- id: B,
274
- offset: head,
275
- length,
276
- newId: T,
277
- tail,
278
- parent: home,
279
- index: slot
280
- });
281
- kids(T, joinsTail ? last() : undefined, moved);
282
- place(slot, T);
283
- const at = joinsTail
284
- ? { block: T, offset: c.writeContent(writes, T, 0, last().content) }
285
- : (end ?? { block: T, offset: 0 });
286
- return { ...c.plan([B, ...ids, T], writes), at };
287
- }
288
- };
289
- };