edytor 0.1.0-next.36 → 0.1.0-next.40

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 (360) hide show
  1. package/README.md +6 -4
  2. package/dist/block/block.svelte.d.ts +11 -18
  3. package/dist/block/block.svelte.js +58 -45
  4. package/dist/block/block.utils.d.ts +78 -19
  5. package/dist/block/block.utils.js +4 -15
  6. package/dist/block/colors.d.ts +15 -0
  7. package/dist/block/colors.js +32 -0
  8. package/dist/block/inlineBlock.svelte.d.ts +2 -1
  9. package/dist/block/inlineBlock.svelte.js +6 -4
  10. package/dist/clipboard/createClipboardFragment.js +35 -2
  11. package/dist/clipboard/htmlFlow.d.ts +7 -5
  12. package/dist/clipboard/htmlFlow.js +34 -9
  13. package/dist/clipboard/moveText.d.ts +35 -0
  14. package/dist/clipboard/moveText.js +79 -0
  15. package/dist/clipboard/serializeClipboardFragment.js +21 -5
  16. package/dist/cloudflare/DocumentRoom.d.ts +72 -13
  17. package/dist/cloudflare/DocumentRoom.js +59 -13
  18. package/dist/cloudflare/history.d.ts +6 -6
  19. package/dist/cloudflare/history.js +4 -3
  20. package/dist/cloudflare/index.d.ts +4 -3
  21. package/dist/cloudflare/index.js +4 -3
  22. package/dist/cloudflare/locks.d.ts +2 -2
  23. package/dist/cloudflare/move.d.ts +1 -11
  24. package/dist/cloudflare/move.js +0 -5
  25. package/dist/cloudflare/room/access.js +15 -4
  26. package/dist/cloudflare/room/admission.d.ts +7 -0
  27. package/dist/cloudflare/room/admission.js +36 -7
  28. package/dist/cloudflare/room/comments.d.ts +58 -0
  29. package/dist/cloudflare/room/comments.js +293 -0
  30. package/dist/cloudflare/room/context.d.ts +40 -6
  31. package/dist/cloudflare/room/context.js +9 -4
  32. package/dist/cloudflare/room/forged.d.ts +3 -3
  33. package/dist/cloudflare/room/forged.js +6 -6
  34. package/dist/cloudflare/room/frames.d.ts +7 -0
  35. package/dist/cloudflare/room/frames.js +16 -0
  36. package/dist/cloudflare/room/history.js +8 -8
  37. package/dist/cloudflare/room/moves.js +6 -3
  38. package/dist/cloudflare/room/presence.d.ts +33 -3
  39. package/dist/cloudflare/room/presence.js +113 -23
  40. package/dist/cloudflare/room/purge.js +11 -2
  41. package/dist/cloudflare/room/replicas.js +2 -1
  42. package/dist/cloudflare/room/storage.d.ts +13 -2
  43. package/dist/cloudflare/room/storage.js +37 -8
  44. package/dist/cloudflare/room/updates.d.ts +2 -2
  45. package/dist/cloudflare/room/updates.js +6 -7
  46. package/dist/cloudflare/room/validation.js +2 -1
  47. package/dist/cloudflare/routeDocumentSocket.d.ts +20 -0
  48. package/dist/cloudflare/routeDocumentSocket.js +48 -4
  49. package/dist/collaboration/RemoteSelections.svelte +1 -1
  50. package/dist/collaboration/awarenessSelection.d.ts +4 -4
  51. package/dist/collaboration/awarenessSelection.js +2 -2
  52. package/dist/collaboration/comments/client.d.ts +96 -0
  53. package/dist/collaboration/comments/client.js +133 -0
  54. package/dist/collaboration/comments/index.d.ts +8 -0
  55. package/dist/collaboration/comments/index.js +7 -0
  56. package/dist/collaboration/comments/threads.d.ts +27 -0
  57. package/dist/collaboration/comments/threads.js +62 -0
  58. package/dist/collaboration/documentSync.d.ts +1 -1
  59. package/dist/collaboration/history/HistoryPanel.svelte +7 -13
  60. package/dist/collaboration/history/HistoryPanel.svelte.d.ts +1 -1
  61. package/dist/collaboration/history/panel.d.ts +4 -50
  62. package/dist/collaboration/history/panel.js +3 -28
  63. package/dist/collaboration/remoteSelection.d.ts +1 -1
  64. package/dist/collaboration/remoteSelection.js +3 -3
  65. package/dist/components/Block.svelte +8 -7
  66. package/dist/components/Content.svelte +3 -3
  67. package/dist/components/Content.svelte.d.ts +1 -1
  68. package/dist/components/Edytor.svelte +19 -18
  69. package/dist/components/Edytor.svelte.d.ts +6 -5
  70. package/dist/components/InlineBlock.svelte +1 -1
  71. package/dist/components/Mark.svelte +2 -2
  72. package/dist/components/SuggestionRanges.svelte +1 -1
  73. package/dist/components/Text.svelte +5 -5
  74. package/dist/crdt/admission.d.ts +1 -1
  75. package/dist/crdt/admission.js +5 -3
  76. package/dist/crdt/anchors.d.ts +3 -3
  77. package/dist/crdt/attribution/attribution.d.ts +6 -6
  78. package/dist/crdt/attribution/attribution.js +3 -3
  79. package/dist/crdt/attribution/block.d.ts +7 -7
  80. package/dist/crdt/attribution/block.js +7 -6
  81. package/dist/crdt/attribution/index.d.ts +2 -2
  82. package/dist/crdt/attribution/index.js +2 -2
  83. package/dist/crdt/data.d.ts +1 -1
  84. package/dist/crdt/data.js +5 -5
  85. package/dist/crdt/doc/anchors.js +1 -1
  86. package/dist/crdt/doc/capability.d.ts +5 -5
  87. package/dist/crdt/doc/capability.js +29 -17
  88. package/dist/crdt/doc/delete.js +12 -2
  89. package/dist/crdt/doc/events.js +3 -3
  90. package/dist/crdt/doc/funnel.js +6 -6
  91. package/dist/crdt/doc/gate.d.ts +2 -2
  92. package/dist/crdt/doc/history.js +24 -24
  93. package/dist/crdt/doc/layout.js +4 -4
  94. package/dist/crdt/doc/meta.js +8 -8
  95. package/dist/crdt/doc/moves.js +9 -9
  96. package/dist/crdt/doc/plan.d.ts +1 -1
  97. package/dist/crdt/doc/plan.js +1 -1
  98. package/dist/crdt/doc/reads.d.ts +18 -0
  99. package/dist/crdt/doc/reads.js +119 -8
  100. package/dist/crdt/doc/seed.d.ts +2 -2
  101. package/dist/crdt/doc/seed.js +10 -8
  102. package/dist/crdt/doc/split-merge.js +16 -13
  103. package/dist/crdt/doc/steps.js +18 -18
  104. package/dist/crdt/doc/table.d.ts +21 -0
  105. package/dist/crdt/doc/table.js +288 -0
  106. package/dist/crdt/doc/types.d.ts +17 -7
  107. package/dist/crdt/document.d.ts +6 -6
  108. package/dist/crdt/document.js +23 -19
  109. package/dist/crdt/edytor-doc.d.ts +49 -3
  110. package/dist/crdt/edytor-doc.js +61 -20
  111. package/dist/crdt/engine-api.d.ts +6 -0
  112. package/dist/crdt/engine.js +4 -4
  113. package/dist/crdt/flow.d.ts +16 -10
  114. package/dist/crdt/flow.js +26 -9
  115. package/dist/crdt/incarnations.d.ts +22 -9
  116. package/dist/crdt/incarnations.js +18 -4
  117. package/dist/crdt/index.d.ts +38 -9
  118. package/dist/crdt/index.js +11 -9
  119. package/dist/crdt/migration/generation.d.ts +2 -2
  120. package/dist/crdt/migration/generation.js +5 -3
  121. package/dist/crdt/migration/legacy-schema.d.ts +1 -1
  122. package/dist/crdt/migration/legacy-schema.js +5 -3
  123. package/dist/crdt/migration/migrate.d.ts +1 -12
  124. package/dist/crdt/migration/migrate.js +15 -13
  125. package/dist/crdt/nodes.d.ts +4 -4
  126. package/dist/crdt/placement/display.d.ts +8 -8
  127. package/dist/crdt/placement/display.js +21 -13
  128. package/dist/crdt/placement/model.d.ts +12 -5
  129. package/dist/crdt/placement/model.js +20 -23
  130. package/dist/crdt/placement/rank.d.ts +4 -4
  131. package/dist/crdt/placement/rank.js +8 -8
  132. package/dist/crdt/placement/resolve.js +2 -2
  133. package/dist/crdt/placement/source.d.ts +4 -4
  134. package/dist/crdt/placement/source.js +4 -4
  135. package/dist/crdt/protocol.d.ts +5 -3
  136. package/dist/crdt/protocol.js +5 -3
  137. package/dist/crdt/protocols/awareness.js +1 -1
  138. package/dist/crdt/protocols/comments.d.ts +219 -0
  139. package/dist/crdt/protocols/comments.js +283 -0
  140. package/dist/crdt/protocols/envelope.d.ts +1 -1
  141. package/dist/crdt/protocols/envelope.js +1 -1
  142. package/dist/crdt/protocols/sync.d.ts +1 -1
  143. package/dist/crdt/protocols/sync.js +8 -7
  144. package/dist/crdt/providers/container.d.ts +2 -2
  145. package/dist/crdt/providers/container.js +3 -3
  146. package/dist/crdt/providers/index.d.ts +2 -6
  147. package/dist/crdt/providers/index.js +21 -15
  148. package/dist/crdt/providers/indexeddb.js +23 -11
  149. package/dist/crdt/providers/room.d.ts +8 -2
  150. package/dist/crdt/providers/room.js +15 -8
  151. package/dist/crdt/providers/websocket.d.ts +2 -0
  152. package/dist/crdt/providers/websocket.js +67 -12
  153. package/dist/crdt/purge.d.ts +7 -1
  154. package/dist/crdt/purge.js +37 -7
  155. package/dist/crdt/rand.d.ts +3 -3
  156. package/dist/crdt/rand.js +3 -3
  157. package/dist/crdt/rangeDelete.d.ts +11 -2
  158. package/dist/crdt/rangeDelete.js +42 -2
  159. package/dist/crdt/restore.d.ts +2 -2
  160. package/dist/crdt/schema.d.ts +7 -7
  161. package/dist/crdt/schema.js +8 -8
  162. package/dist/crdt/semantics.d.ts +64 -7
  163. package/dist/crdt/semantics.js +46 -10
  164. package/dist/crdt/storage.d.ts +1 -1
  165. package/dist/crdt/storage.js +1 -1
  166. package/dist/crdt/structs.d.ts +119 -9
  167. package/dist/crdt/structs.js +109 -1
  168. package/dist/crdt/tables.d.ts +44 -0
  169. package/dist/crdt/tables.js +58 -0
  170. package/dist/crdt/text/delete-index.d.ts +5 -8
  171. package/dist/crdt/text/delete-index.js +15 -11
  172. package/dist/crdt/text/deletes.d.ts +5 -5
  173. package/dist/crdt/text/deletes.js +24 -27
  174. package/dist/crdt/text/index/anchored.js +3 -2
  175. package/dist/crdt/text/index/checks.js +2 -2
  176. package/dist/crdt/text/index/claims.d.ts +1 -1
  177. package/dist/crdt/text/index/claims.js +1 -1
  178. package/dist/crdt/text/index/fold.d.ts +2 -1
  179. package/dist/crdt/text/index/fold.js +24 -19
  180. package/dist/crdt/text/index/layout.d.ts +16 -3
  181. package/dist/crdt/text/index/layout.js +167 -3
  182. package/dist/crdt/text/index/placement.d.ts +1 -1
  183. package/dist/crdt/text/index/placement.js +45 -20
  184. package/dist/crdt/text/index/records.js +12 -7
  185. package/dist/crdt/text/index/report.js +6 -6
  186. package/dist/crdt/text/index/shared.d.ts +1 -1
  187. package/dist/crdt/text/index/shared.js +8 -3
  188. package/dist/crdt/text/index/state.d.ts +14 -4
  189. package/dist/crdt/text/index/state.js +11 -4
  190. package/dist/crdt/text/index/streams.d.ts +1 -1
  191. package/dist/crdt/text/index/streams.js +3 -3
  192. package/dist/crdt/text/items.js +2 -1
  193. package/dist/crdt/text/marks.d.ts +1 -1
  194. package/dist/crdt/text/marks.js +1 -1
  195. package/dist/crdt/text/model.d.ts +6 -5
  196. package/dist/crdt/text/model.js +22 -30
  197. package/dist/crdt/text/ranges.d.ts +2 -2
  198. package/dist/crdt/text/ranges.js +2 -2
  199. package/dist/crdt/text/rows.d.ts +1 -1
  200. package/dist/crdt/text/runs.d.ts +10 -4
  201. package/dist/crdt/text/runs.js +1 -1
  202. package/dist/crdt/vendor/yjs/API-NOTES.md +1 -1
  203. package/dist/crdt/vendor/yjs/UPSTREAM.md +105 -80
  204. package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +3 -3
  205. package/dist/crdt/vendor/yjs/dts/utils/RangeCursor.d.ts +1 -1
  206. package/dist/crdt/vendor/yjs/dts/utils/UndoManager.d.ts +6 -6
  207. package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +1 -1
  208. package/dist/crdt/vendor/yjs/src/index.js +2 -2
  209. package/dist/crdt/vendor/yjs/src/structs/Item.js +7 -7
  210. package/dist/crdt/vendor/yjs/src/utils/Doc.js +3 -3
  211. package/dist/crdt/vendor/yjs/src/utils/RangeCursor.js +5 -5
  212. package/dist/crdt/vendor/yjs/src/utils/Transaction.js +3 -3
  213. package/dist/crdt/vendor/yjs/src/utils/UndoManager.js +14 -14
  214. package/dist/crdt/vendor/yjs/src/utils/encoding.js +6 -6
  215. package/dist/crdt/vendor/yjs/src/utils/marks.js +1 -1
  216. package/dist/crdt/vendor/yjs/src/utils/renderer-helpers.js +1 -1
  217. package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +7 -7
  218. package/dist/crdt/vendor/yjs/src/ynode.js +15 -15
  219. package/dist/edytor.svelte.d.ts +13 -7
  220. package/dist/edytor.svelte.js +84 -33
  221. package/dist/events/beforeInputCommands.d.ts +0 -2
  222. package/dist/events/beforeInputCommands.js +31 -20
  223. package/dist/events/beforeInputDeleteCommands.js +13 -6
  224. package/dist/events/nativeInteractiveControl.d.ts +1 -1
  225. package/dist/events/nativeInteractiveControl.js +1 -1
  226. package/dist/events/onBeforeInput.js +4 -4
  227. package/dist/events/onDrop.d.ts +11 -0
  228. package/dist/events/onDrop.js +89 -3
  229. package/dist/events/onFocus.js +1 -1
  230. package/dist/events/onInput.d.ts +1 -1
  231. package/dist/events/onInput.js +3 -3
  232. package/dist/events/onKeyDown.js +7 -1
  233. package/dist/events/onPaste.js +1 -1
  234. package/dist/index.d.ts +3 -2
  235. package/dist/index.js +3 -1
  236. package/dist/kinds.d.ts +8 -6
  237. package/dist/kinds.js +11 -9
  238. package/dist/labels.d.ts +149 -1
  239. package/dist/labels.js +99 -2
  240. package/dist/plugins/arrowMove/arrowMove.js +1 -1
  241. package/dist/plugins/blockHandles/BlockHandleController.svelte.js +1 -1
  242. package/dist/plugins/blockHandles/BlockHandles.svelte +3 -3
  243. package/dist/plugins/blockHandles/blockHandlesPlugin.js +3 -2
  244. package/dist/plugins/blockMenu/BlockMenu.svelte +41 -4
  245. package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +25 -2
  246. package/dist/plugins/blockMenu/BlockMenuController.svelte.js +63 -2
  247. package/dist/plugins/blockMenu/blockMenuPlugin.d.ts +4 -3
  248. package/dist/plugins/blockMenu/blockMenuPlugin.js +7 -4
  249. package/dist/plugins/code/CodePlugin.svelte +1 -1
  250. package/dist/plugins/code/languages.d.ts +1 -1
  251. package/dist/plugins/code/languages.js +1 -1
  252. package/dist/plugins/columns/ColumnsPlugin.svelte +4 -4
  253. package/dist/plugins/columns/columns.css +3 -3
  254. package/dist/plugins/columns/resize.svelte.d.ts +2 -2
  255. package/dist/plugins/columns/resize.svelte.js +2 -2
  256. package/dist/plugins/columns/stacking.d.ts +1 -1
  257. package/dist/plugins/columns/stacking.js +1 -1
  258. package/dist/plugins/comments/CommentsController.svelte.d.ts +124 -0
  259. package/dist/plugins/comments/CommentsController.svelte.js +351 -0
  260. package/dist/plugins/comments/CommentsSidebar.svelte +601 -0
  261. package/dist/plugins/comments/CommentsSidebar.svelte.d.ts +16 -0
  262. package/dist/plugins/comments/commentsPlugin.d.ts +48 -0
  263. package/dist/plugins/comments/commentsPlugin.js +60 -0
  264. package/dist/plugins/equation/EquationEditor.svelte +138 -0
  265. package/dist/plugins/equation/EquationEditor.svelte.d.ts +8 -0
  266. package/dist/plugins/equation/EquationPlugin.svelte +328 -0
  267. package/dist/plugins/equation/EquationPlugin.svelte.d.ts +33 -0
  268. package/dist/plugins/equation/EquationView.svelte +34 -0
  269. package/dist/plugins/equation/EquationView.svelte.d.ts +7 -0
  270. package/dist/plugins/equation/equation.svelte.d.ts +142 -0
  271. package/dist/plugins/equation/equation.svelte.js +295 -0
  272. package/dist/plugins/find/FindHighlights.svelte +1 -1
  273. package/dist/plugins/find/findPlugin.js +1 -1
  274. package/dist/plugins/icons.js +6 -0
  275. package/dist/plugins/image/ImageEmpty.svelte +1 -1
  276. package/dist/plugins/image/ImagePlugin.svelte +1 -1
  277. package/dist/plugins/image/controls.svelte.d.ts +1 -1
  278. package/dist/plugins/image/controls.svelte.js +1 -1
  279. package/dist/plugins/index.d.ts +5 -0
  280. package/dist/plugins/index.js +5 -0
  281. package/dist/plugins/mention/MentionPlugin.svelte +10 -4
  282. package/dist/plugins/mention/MentionPlugin.svelte.d.ts +3 -0
  283. package/dist/plugins/page/PageLink.svelte +17 -5
  284. package/dist/plugins/page/PagePlugin.svelte +18 -3
  285. package/dist/plugins/page/PagePlugin.svelte.d.ts +3 -2
  286. package/dist/plugins/page/page.d.ts +7 -3
  287. package/dist/plugins/richtext/RichTextPlugin.svelte +2 -2
  288. package/dist/plugins/richtext/richTextOperations.js +1 -1
  289. package/dist/plugins/slashMenu/SlashMenuController.svelte.js +4 -1
  290. package/dist/plugins/slashMenu/slashMenuPlugin.js +1 -1
  291. package/dist/plugins/suggestions/SuggestionBars.svelte +1 -1
  292. package/dist/plugins/table/TableChrome.svelte +153 -0
  293. package/dist/plugins/table/TableChrome.svelte.d.ts +7 -0
  294. package/dist/plugins/table/TablePlugin.svelte +450 -0
  295. package/dist/plugins/table/TablePlugin.svelte.d.ts +43 -0
  296. package/dist/plugins/table/chrome.svelte.d.ts +153 -0
  297. package/dist/plugins/table/chrome.svelte.js +420 -0
  298. package/dist/plugins/table/table.css +202 -0
  299. package/dist/plugins/table/table.d.ts +94 -0
  300. package/dist/plugins/table/table.js +224 -0
  301. package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +1 -0
  302. package/dist/plugins/toolbar/ToolbarController.svelte.js +3 -0
  303. package/dist/plugins/toolbar/toolbarPlugin.js +1 -1
  304. package/dist/plugins/triggers/TriggerController.svelte.js +3 -3
  305. package/dist/plugins.d.ts +67 -7
  306. package/dist/selection/replaceSelection.d.ts +13 -13
  307. package/dist/selection/replaceSelection.js +15 -15
  308. package/dist/selection/selection.svelte.d.ts +1 -1
  309. package/dist/selection/selection.svelte.js +24 -19
  310. package/dist/selection/selection.utils.d.ts +8 -6
  311. package/dist/selection/selection.utils.js +7 -16
  312. package/dist/selection/visibility.d.ts +4 -4
  313. package/dist/selection/visibility.js +5 -5
  314. package/dist/session/attempt.d.ts +4 -4
  315. package/dist/session/attempt.js +2 -2
  316. package/dist/session/bindings.d.ts +2 -2
  317. package/dist/session/bindings.js +10 -11
  318. package/dist/session/commands.d.ts +2 -2
  319. package/dist/session/commands.js +5 -3
  320. package/dist/session/composition.svelte.d.ts +7 -7
  321. package/dist/session/composition.svelte.js +17 -21
  322. package/dist/session/editing/text.d.ts +12 -5
  323. package/dist/session/editing/text.js +17 -0
  324. package/dist/session/handles.d.ts +2 -2
  325. package/dist/session/handles.js +2 -2
  326. package/dist/session/history.d.ts +4 -4
  327. package/dist/session/history.js +1 -1
  328. package/dist/session/keymap.js +1 -1
  329. package/dist/session/moves.d.ts +1 -1
  330. package/dist/session/moves.js +7 -7
  331. package/dist/session/navigation.d.ts +4 -4
  332. package/dist/session/navigation.js +8 -8
  333. package/dist/session/ports.d.ts +45 -0
  334. package/dist/session/ports.js +1 -0
  335. package/dist/session/selection.d.ts +2 -2
  336. package/dist/session/selection.js +1 -1
  337. package/dist/surface/attributes.d.ts +3 -4
  338. package/dist/surface/attributes.js +2 -2
  339. package/dist/surface/cells.d.ts +1 -1
  340. package/dist/surface/cells.js +7 -8
  341. package/dist/surface/observer.svelte.d.ts +2 -2
  342. package/dist/surface/observer.svelte.js +10 -11
  343. package/dist/surface/overlay.d.ts +17 -5
  344. package/dist/surface/overlay.js +32 -5
  345. package/dist/surface/pin.svelte.d.ts +3 -3
  346. package/dist/surface/pin.svelte.js +2 -2
  347. package/dist/surface/popups.svelte.js +1 -1
  348. package/dist/surface/projector.svelte.d.ts +20 -5
  349. package/dist/surface/projector.svelte.js +41 -18
  350. package/dist/text/text.svelte.d.ts +4 -2
  351. package/dist/text/text.svelte.js +9 -7
  352. package/dist/text/text.utils.js +1 -1
  353. package/dist/themes/notion.css +2 -2
  354. package/dist/utils/diffText.d.ts +1 -1
  355. package/dist/utils/json.d.ts +3 -3
  356. package/dist/utils/json.js +5 -5
  357. package/dist/utils.d.ts +1 -1
  358. package/package.json +9 -11
  359. /package/dist/{events → text}/wordBoundary.d.ts +0 -0
  360. /package/dist/{events → text}/wordBoundary.js +0 -0
package/README.md CHANGED
@@ -10,20 +10,22 @@
10
10
  <p>
11
11
  <a href="https://edytor.dev/docs">Documentation</a> •
12
12
  <a href="#quick-start">Quick start</a> •
13
- <a href="https://edytor.dev/docs/reference/migration">Migrating from 0.0.11</a>
13
+ <a href="https://edytor.dev/docs/reference/migration">Changelog</a>
14
14
  </p>
15
15
  </div>
16
16
 
17
17
  Edytor aims to be for Svelte what Slate.js is for React: a heavily customizable editor with an API to build any kind of collaborative rich text editor.
18
18
 
19
- > **Work in progress.** Edytor is a pre-release (`0.1.0-next.36`, `edytor@next` on npm) and not ready for production; the API changes between releases without a compatibility layer. The untagged `edytor@0.0.11` on npm predates the current API. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
19
+ > **Work in progress.** Edytor is a pre-release (`0.1.0-next.40`, `edytor@next` on npm) and not ready for production; the API changes between releases without a compatibility layer. The untagged `edytor@0.0.11` on npm predates the current API. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
20
20
 
21
21
  ## Features
22
22
 
23
23
  - **Notion-style editing out of the box.** `<Edytor />` alone is a rich text editor with images and block handles: headings, toggle headings, lists, to-dos, toggles, callouts, quotes, dividers, ten marks and Notion's hotkeys. Add the Notion theme, a block menu (block colours; drag one block, or every block the selection covers), a slash menu, a selection toolbar, markdown shortcuts (`markdownShortcutsPlugin`) and code blocks.
24
24
  - **Pages and a table of contents, opt-in.** `createPagePlugin` links a block to another document (a page per room, opened and named by your app), and `tocPlugin` lists the headings live ([Page](https://edytor.dev/docs/plugins/page), [Table of contents](https://edytor.dev/docs/plugins/table-of-contents)).
25
25
  - **Columns, opt-in.** List `columnsPlugin` for Notion's multi-column layouts: drag a block to the edge of another to put them side by side, or pick "2 columns" to "5 columns"; drag the gap to resize. Layouts converge across collaborators and the room ([Columns](https://edytor.dev/docs/plugins/columns)).
26
+ - **Tables, opt-in.** List `tablePlugin` for Notion's simple table: cells of text, <kbd>Tab</kbd> between them, rows and columns added, moved and deleted from the table's edges and grips, resizable columns, header row and column, HTML tables pasted and copied. Concurrent row and column edits converge on every replica ([Table](https://edytor.dev/docs/plugins/table)).
26
27
  - **Mentions, page links and your own triggers.** `createMentionPlugin` (`@` people) and `createPageLinkPlugin` (`[[` pages) take your app's search; a plugin's `inputRules` (`:smile:` → 😄) and `triggers` (a menu on a typed character) declare the rest ([Input rules and triggers](https://edytor.dev/docs/plugins/input-rules)).
28
+ - **Comments, opt-in.** `createCommentsPlugin` adds Notion's comment threads: select text, press Comment, and the thread shows in a sidebar beside it with replies, Resolve and Re-open. The room keeps the threads beside the document and sends each change live; the anchor follows the text through edits and is not copied ([Comments](https://edytor.dev/docs/plugins/comments)).
27
29
  - **Your markup.** Blocks, marks and inline atoms render through your Svelte snippets; the slash menu, toolbar, block menu and handles take a snippet and keep their behavior.
28
30
  - **Your language.** Every word the chrome shows or says, slash keywords included, comes from a labels dictionary each plugin takes; English by default ([Localization](https://edytor.dev/docs/customization/localization)).
29
31
  - **Synced properties.** `block.data`, `atom.data` and `edytor.data` read and write like plain objects (`bind:value={block.data.title}`); each property and each array item syncs on its own, so concurrent edits of different properties, or of different items of one array, merge.
@@ -102,11 +104,11 @@ The [documentation site](https://edytor.dev/docs) is the single source for the A
102
104
  - [Editor](https://edytor.dev/docs/editor/edytor-component): the component, commands, selection, history, clipboard, readonly
103
105
  - [Plugins](https://edytor.dev/docs/plugins) and [customization](https://edytor.dev/docs/customization/blocks): bundled plugins, custom blocks and marks, [hotkeys and editing behavior](https://edytor.dev/docs/customization/hotkeys)
104
106
  - [Collaboration](https://edytor.dev/docs/collaboration) and [server](https://edytor.dev/docs/server/quick-start): documents, providers, presence, the Durable Object room and its protocol
105
- - [Reference](https://edytor.dev/docs/reference/document-api): the document API, [troubleshooting](https://edytor.dev/docs/reference/troubleshooting), [migration from 0.0.11](https://edytor.dev/docs/reference/migration), limitations, [platform support](https://edytor.dev/docs/reference/platform-support)
107
+ - [Reference](https://edytor.dev/docs/reference/document-api): the document API, [troubleshooting](https://edytor.dev/docs/reference/troubleshooting), the [changelog](https://edytor.dev/docs/reference/migration) (with [migration from 0.0.11](https://edytor.dev/docs/reference/migration#upgrading-from-0011)), [importing v13 documents](https://edytor.dev/docs/reference/v13-import), limitations, [platform support](https://edytor.dev/docs/reference/platform-support)
106
108
 
107
109
  ## Contributing
108
110
 
109
- `CONTRIBUTING.md` lists the test lanes, what CI runs, and the pull request checklist; `AGENTS.md` describes the architecture (one owner per fact) and where to fix what. The docs live in `site/content/docs`; a change to public behavior updates them in the same commit.
111
+ `CONTRIBUTING.md` lists the test lanes, what CI runs, and the pull request checklist; `AGENTS.md` describes the architecture (one owner per fact) and where to fix what, and `docs/agents/` holds the rules of each area. The docs live in `site/content/docs`; a change to public behavior updates them in the same commit.
110
112
 
111
113
  ```bash
112
114
  pnpm install
@@ -1,18 +1,22 @@
1
1
  import { Text } from '../text/text.svelte.js';
2
- import { Edytor } from '../edytor.svelte.js';
2
+ import type { Edytor } from '../edytor.svelte.js';
3
3
  import type { JSONBlock, JSONText, JSONInlineBlock } from '../utils/json.js';
4
4
  import { type BlockOperations } from './block.utils.js';
5
5
  import type { BlockDefinition } from '../plugins.js';
6
6
  import { InlineBlock } from './inlineBlock.svelte.js';
7
7
  import type { DocBlock } from '../crdt/index.js';
8
- /**
9
- * An id-only block handle (§2.4 "Handles", R4): every getter reads the
10
- * document index (transaction-aware), every mutator issues a command. The
11
- * view keeps one per id (`edytor.idToBlock`); `node` is the element the core
12
- * renders for it (O45).
13
- */
14
8
  /** Mark an element inside a block's markup as non-editable chrome (`block.void`, a preview's too). */
15
9
  export declare const voidChrome: (node: HTMLElement) => void;
10
+ /**
11
+ * An id-only block handle: every getter reads the document index
12
+ * (transaction-aware), every mutator issues a command. The view keeps one per
13
+ * id (`edytor.idToBlock`); `node` is the element the core renders for it.
14
+ *
15
+ * A reactive reader (a template, a `$derived`, an `$effect`) of a getter
16
+ * depends on the cells the answer comes from (this block's, its parent's,
17
+ * the root's list), so it re-runs when a commit changes them, as `data`
18
+ * does; a read anywhere else is a plain read of the document.
19
+ */
16
20
  export declare class Block {
17
21
  #private;
18
22
  readonly: boolean;
@@ -60,13 +64,6 @@ export declare class Block {
60
64
  get path(): number[];
61
65
  /** The block is visible in the document (a dead handle answers false). */
62
66
  get isInTree(): boolean;
63
- /**
64
- * @deprecated `edytor.suggestions` with `{ end: block.id }`. The content of
65
- * this block's latest `end` suggestion, as parts (a text's runs, or an
66
- * atom); setting it replaces this block's `end` suggestions, `null` drops them.
67
- */
68
- get suggestions(): (JSONText[] | JSONInlineBlock)[] | null;
69
- set suggestions(value: (JSONText[] | JSONInlineBlock)[] | null);
70
67
  get nextBlock(): Block | null;
71
68
  get previousBlock(): Block | null;
72
69
  get closestPreviousBlock(): Block | null;
@@ -173,10 +170,6 @@ export declare class Block {
173
170
  }) => Text | null | undefined;
174
171
  normalizeContent: () => void;
175
172
  normalizeChildren: () => void;
176
- /** @deprecated `edytor.suggestions.add({ end: block.id }, …)`. */
177
- suggestText: (payload: BlockOperations["suggestText"]) => void;
178
- /** @deprecated `suggestion.accept()`. */
179
- acceptSuggestedText: () => void;
180
173
  deleteContentAtRange: (payload: {
181
174
  start: [number, number];
182
175
  end: [number, number];
@@ -1,22 +1,25 @@
1
1
  import { Text } from '../text/text.svelte.js';
2
- import { Edytor } from '../edytor.svelte.js';
3
- import { batch, removeInlineBlock, addChildBlock, insertBlockAfter, insertBlockBefore, mergeBlockBackward, mergeBlockForward, nestBlock, removeBlock, setBlock, splitBlock, prepareSplit, duplicateBlock, prepareDuplicate, prepareSet, prepareMove, prepareMoves, prepareInsertAfter, prepareInsertBefore, prepareRemove, prepareMergeBackward, prepareMergeForward, prepareUnNest, prepareNest, prepareRemoveInline, preparePatch, patchData, prepareDeleteRange, addChildBlocks, pushContentIntoBlock, unNestBlock, moveBlock, moveBlocks, normalizeContent, addInlineBlock, textAfterAtom, blockOf, acceptSuggestedText, suggestText, deleteContentAtRange, normalizeChildren } from './block.utils.js';
2
+ import { batch, removeInlineBlock, addChildBlock, insertBlockAfter, insertBlockBefore, mergeBlockBackward, mergeBlockForward, nestBlock, removeBlock, setBlock, splitBlock, prepareSplit, duplicateBlock, prepareDuplicate, prepareSet, prepareMove, prepareMoves, prepareInsertAfter, prepareInsertBefore, prepareRemove, prepareMergeBackward, prepareMergeForward, prepareUnNest, prepareNest, prepareRemoveInline, preparePatch, patchData, prepareDeleteRange, addChildBlocks, pushContentIntoBlock, unNestBlock, moveBlock, moveBlocks, normalizeContent, addInlineBlock, textAfterAtom, blockOf, deleteContentAtRange, normalizeChildren } from './block.utils.js';
4
3
  import { jsonBlockToSpec, jsonContentToItems } from '../utils/json.js';
5
4
  import { InlineBlock } from './inlineBlock.svelte.js';
6
5
  import { revealed } from '../selection/replaceSelection.js';
7
6
  import { propsProxy } from '../session/props.js';
8
- /**
9
- * An id-only block handle (§2.4 "Handles", R4): every getter reads the
10
- * document index (transaction-aware), every mutator issues a command. The
11
- * view keeps one per id (`edytor.idToBlock`); `node` is the element the core
12
- * renders for it (O45).
13
- */
14
7
  /** Mark an element inside a block's markup as non-editable chrome (`block.void`, a preview's too). */
15
8
  export const voidChrome = (node) => {
16
9
  node.setAttribute('data-edytor-void', `true`);
17
10
  node.style.userSelect = 'none';
18
11
  node.setAttribute('contenteditable', 'false');
19
12
  };
13
+ /**
14
+ * An id-only block handle: every getter reads the document index
15
+ * (transaction-aware), every mutator issues a command. The view keeps one per
16
+ * id (`edytor.idToBlock`); `node` is the element the core renders for it.
17
+ *
18
+ * A reactive reader (a template, a `$derived`, an `$effect`) of a getter
19
+ * depends on the cells the answer comes from (this block's, its parent's,
20
+ * the root's list), so it re-runs when a commit changes them, as `data`
21
+ * does; a read anywhere else is a plain read of the document.
22
+ */
20
23
  export class Block {
21
24
  readonly = false;
22
25
  edytor;
@@ -29,21 +32,43 @@ export class Block {
29
32
  get isRoot() {
30
33
  return this.id === 'root';
31
34
  }
35
+ /**
36
+ * Under a reactive reader, depend on block `id`'s cell (the root: its
37
+ * child list): the commit that patches it re-runs the reader. A cell
38
+ * that goes away (the block died) re-runs it too.
39
+ */
40
+ #track(id = this.id) {
41
+ if (!$effect.tracking())
42
+ return;
43
+ const cells = this.edytor.cells;
44
+ if (id === 'root')
45
+ void cells?.rootIds;
46
+ else
47
+ cells?.get(id);
48
+ }
32
49
  /** The typed document node — `null` for the root. */
33
50
  get model() {
34
51
  return this.isRoot ? null : this.edytor.facade.block(this.id);
35
52
  }
36
53
  /** The display parent (the root for a top-level block); none for the root or a dead block. */
37
54
  get parent() {
38
- const at = this.isRoot ? null : this.edytor.facade.positionOf(this.id);
55
+ if (this.isRoot)
56
+ return undefined;
57
+ this.#track();
58
+ const at = this.edytor.facade.positionOf(this.id);
59
+ // The parent's child list names this block: a move patches it.
60
+ if (at)
61
+ this.#track(at.parent ?? 'root');
39
62
  return at ? this.edytor.idToBlock.block(at.parent ?? 'root') : undefined;
40
63
  }
41
64
  get children() {
65
+ this.#track();
42
66
  const { facade, idToBlock } = this.edytor;
43
67
  return facade.childrenIds(this.isRoot ? null : this.id).map(idToBlock.block);
44
68
  }
45
69
  /** Text segments and inline atoms, alternating, starting and ending with a text. */
46
70
  get content() {
71
+ this.#track();
47
72
  const handles = this.edytor.idToBlock;
48
73
  let ordinal = 0;
49
74
  return handles
@@ -53,7 +78,10 @@ export class Block {
53
78
  : handles.atom(this.id, part.item.id));
54
79
  }
55
80
  get type() {
56
- return this.isRoot ? 'root' : (this.edytor.facade.blockTypeOf(this.id) ?? '');
81
+ if (this.isRoot)
82
+ return 'root';
83
+ this.#track();
84
+ return this.edytor.facade.blockTypeOf(this.id) ?? '';
57
85
  }
58
86
  /** Retype the block — the `setBlock` command (readonly, hooks, `dispatcher.last`). */
59
87
  set type(value) {
@@ -139,7 +167,13 @@ export class Block {
139
167
  return undefined;
140
168
  }
141
169
  get index() {
142
- return (!this.isRoot && this.edytor.facade.positionOf(this.id)?.index) || 0;
170
+ if (this.isRoot)
171
+ return 0;
172
+ const at = this.edytor.facade.positionOf(this.id);
173
+ this.#track();
174
+ if (at)
175
+ this.#track(at.parent ?? 'root');
176
+ return at?.index || 0;
143
177
  }
144
178
  get depth() {
145
179
  return this.parent ? this.parent.depth + 1 : 0;
@@ -155,33 +189,10 @@ export class Block {
155
189
  }
156
190
  /** The block is visible in the document (a dead handle answers false). */
157
191
  get isInTree() {
158
- return this.isRoot || this.edytor.facade.isVisibleBlock(this.id);
159
- }
160
- /**
161
- * @deprecated `edytor.suggestions` with `{ end: block.id }`. The content of
162
- * this block's latest `end` suggestion, as parts (a text's runs, or an
163
- * atom); setting it replaces this block's `end` suggestions, `null` drops them.
164
- */
165
- get suggestions() {
166
- const content = this.edytor.suggestions?.at(this.id).end.at(-1)?.content[0]?.content;
167
- if (!content?.length)
168
- return null;
169
- const parts = [];
170
- for (const part of content)
171
- if ('type' in part)
172
- parts.push(part);
173
- else if (Array.isArray(parts.at(-1)))
174
- parts.at(-1).push(part);
175
- else
176
- parts.push([part]);
177
- return parts;
178
- }
179
- set suggestions(value) {
180
- const { suggestions } = this.edytor;
181
- for (const suggestion of suggestions.at(this.id).end)
182
- suggestion.discard();
183
- if (value)
184
- suggestions.add({ end: this.id }, [{ type: this.type, content: value.flat() }]);
192
+ if (this.isRoot)
193
+ return true;
194
+ this.#track();
195
+ return this.edytor.facade.isVisibleBlock(this.id);
185
196
  }
186
197
  get nextBlock() {
187
198
  return this.parent ? this.parent.children[this.index + 1] : null;
@@ -211,6 +222,9 @@ export class Block {
211
222
  }
212
223
  /** This block's JSON — the document's one serializer (`facade.blockJSON`). */
213
224
  get value() {
225
+ // Its subtree's: every commit re-runs a reactive reader.
226
+ if ($effect.tracking())
227
+ void this.edytor.valueRevision;
214
228
  if (!this.isRoot)
215
229
  return this.edytor.facade.blockJSON(this.id);
216
230
  const { data = {}, children } = this.edytor.facade.toJSON();
@@ -310,10 +324,6 @@ export class Block {
310
324
  };
311
325
  normalizeContent = batch('normalizeContent', normalizeContent);
312
326
  normalizeChildren = batch('normalizeChildren', normalizeChildren);
313
- /** @deprecated `edytor.suggestions.add({ end: block.id }, …)`. */
314
- suggestText = (payload) => suggestText.call(this, payload);
315
- /** @deprecated `suggestion.accept()`. */
316
- acceptSuggestedText = () => acceptSuggestedText.call(this);
317
327
  deleteContentAtRange = batch('deleteContentAtRange', deleteContentAtRange, prepareDeleteRange);
318
328
  /** Mark an element inside the block's markup as non-editable chrome (a header, a caption bar). */
319
329
  void = voidChrome;
@@ -342,7 +352,7 @@ export class Block {
342
352
  }
343
353
  return hit;
344
354
  };
345
- // ── JSON insertion (K5: specs are data; `new Block({block})` is gone) ──
355
+ // ── JSON insertion (specs are data; `new Block({block})` is gone) ──
346
356
  /**
347
357
  * Insert children at `index`: a JSON spec is created (its id kept, minted
348
358
  * when missing); a block handle moves there with its identity.
@@ -385,9 +395,9 @@ export class Block {
385
395
  /** The declared view state (`open` on a `details`) the block's last element held. */
386
396
  #viewState = [];
387
397
  /**
388
- * Register the element the core rendered for this block (O45) and run the
398
+ * Register the element the core rendered for this block and run the
389
399
  * attach hooks. A re-rendered block (moved, re-parented) keeps its declared
390
- * view state (R11): an open toggle stays open.
400
+ * view state: an open toggle stays open.
391
401
  * @internal
392
402
  */
393
403
  attach = (node) => {
@@ -398,6 +408,8 @@ export class Block {
398
408
  node.setAttribute(name, value);
399
409
  this.node = node;
400
410
  const release = this.edytor.surface.register(node, 'block', this.id);
411
+ // A block laid out again with no commit moves the chrome beside it (the overlay measures).
412
+ const unobserve = this.edytor.overlay.observe(node);
401
413
  const onDestroy = this.edytor.plugins.flatMap((plugin) => {
402
414
  const action = plugin.onBlockAttached?.({ node, block: this });
403
415
  return typeof action === 'function' ? [action] : [];
@@ -408,6 +420,7 @@ export class Block {
408
420
  if (this.node === node)
409
421
  this.node = undefined;
410
422
  release();
423
+ unobserve();
411
424
  onDestroy.forEach((destroy) => destroy());
412
425
  }
413
426
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * View-side command adapter for block operations (U2 delegation contract).
2
+ * View-side command adapter for block operations: each delegates to one document operation.
3
3
  *
4
4
  * These functions are the `BlockOperations` layer bound onto `Block` via
5
5
  * `batch()`, which dispatches each call as a command (admission, plugin
@@ -8,8 +8,8 @@
8
8
  * sibling lookup for `nestBlock`), the plan of an operation
9
9
  * that is one document op (`prepare*`) and its normalization requests.
10
10
  *
11
- * OPERATIONS READ AND WRITE ONLY THE DOCUMENT (R3): `Block`/`Text` are id-only
12
- * handles whose getters read the index (R4), so what a caller needs after the
11
+ * OPERATIONS READ AND WRITE ONLY THE DOCUMENT: `Block`/`Text` are id-only
12
+ * handles whose getters read the index, so what a caller needs after the
13
13
  * write (the new block, the text after an inserted atom, the caret a range op
14
14
  * decided) is the op's document result as a handle (`batch`'s `resolve`) —
15
15
  * inside an outer transaction too.
@@ -19,13 +19,13 @@
19
19
  * as "refused" — no view-side re-checks of the rules the document already
20
20
  * enforces (island sealing, void/island destinations, own-subtree moves,
21
21
  * merges across island boundaries; see `edytor-doc.ts` `canPlace` and
22
- * `canMerge`, R5). Removing a view-side semantic guard must never
22
+ * `canMerge`). Removing a view-side semantic guard must never
23
23
  * change document behavior — if a rule matters here it belongs in the
24
24
  * facade, not in this file.
25
25
  *
26
26
  * Content preparation produces `BlockSpec`/`ContentItem` DIRECTLY from
27
27
  * JSON (`jsonBlockToSpec`/`jsonContentToItems` in `utils/json.ts`): specs are
28
- * data (K5: `new Block({block})` is gone). The live-content invariant
28
+ * data (`new Block({block})` is gone). The live-content invariant
29
29
  * (text-first/text-last, no adjacent same-kind parts) is derived by the
30
30
  * document's projection on read, so stored content needs no
31
31
  * pre-normalization.
@@ -36,7 +36,7 @@ import type { Flow, FlowTarget } from '../crdt/flow.js';
36
36
  import type { Plan, Prepared } from '../crdt/edytor-doc.js';
37
37
  import type { DataPatch } from '../crdt/data.js';
38
38
  import type { ResolvedAt } from '../session/suggestions.svelte.js';
39
- import { type JSONBlock, type JSONInlineBlock, type JSONText } from '../utils/json.js';
39
+ import { type JSONBlock, type JSONInlineBlock } from '../utils/json.js';
40
40
  import { InlineBlock } from './inlineBlock.svelte.js';
41
41
  /** A move beside `target`, to its `side` (`prepare.placeBeside`, `layout.place-beside`). */
42
42
  export type BlockBeside = {
@@ -108,12 +108,6 @@ export type BlockOperations = {
108
108
  };
109
109
  normalizeContent: {};
110
110
  normalizeChildren: {};
111
- /** @deprecated `edytor.suggestions.add({ end: block.id }, …)`. */
112
- suggestText: {
113
- value: (JSONText | JSONInlineBlock)[] | string | null;
114
- };
115
- /** @deprecated `suggestion.accept()`; the command hooks see is `acceptSuggestion`. */
116
- acceptSuggestedText: {};
117
111
  /** A suggestion placed in the document (`edytor.suggestions`, `suggestion.accept()`). */
118
112
  acceptSuggestion: {
119
113
  suggestion: {
@@ -135,6 +129,19 @@ export type BlockOperations = {
135
129
  }[];
136
130
  replacement: string;
137
131
  };
132
+ /**
133
+ * A comment thread's anchor (`plugins/comments`): its `comment:<thread>`
134
+ * mark over each run of the text it was made on, one plan, one undo step
135
+ * (its steps: a `formatRange` per run).
136
+ */
137
+ addComment: {
138
+ thread: string;
139
+ runs: {
140
+ block: string;
141
+ offset: number;
142
+ length: number;
143
+ }[];
144
+ };
138
145
  deleteContentAtRange: {
139
146
  start: [number, number];
140
147
  end: [number, number];
@@ -146,6 +153,30 @@ export type BlockOperations = {
146
153
  flow: Flow;
147
154
  target: FlowTarget;
148
155
  };
156
+ /**
157
+ * A text range dragged inside the editor and dropped at `to` (block
158
+ * offsets): its content placed at `to`, then the range deleted — or,
159
+ * with `copy` (Alt), only placed. Both are prepared before any write:
160
+ * hooks see the placement's planned steps and the deletion's, and a
161
+ * veto or a refusal of either writes nothing.
162
+ */
163
+ moveText: {
164
+ from: {
165
+ start: {
166
+ block: string;
167
+ offset: number;
168
+ };
169
+ end: {
170
+ block: string;
171
+ offset: number;
172
+ };
173
+ };
174
+ to: {
175
+ block: string;
176
+ offset: number;
177
+ };
178
+ copy: boolean;
179
+ };
149
180
  deleteBlocks: {
150
181
  blocks: Block[];
151
182
  };
@@ -157,6 +188,38 @@ export type BlockOperations = {
157
188
  };
158
189
  /** A divider at the caret: its steps are the conversion, insertion or split it plans. */
159
190
  insertDivider: {};
191
+ /** A table's row at `index`, one empty cell per column (`table.insert-row`). */
192
+ insertTableRow: {
193
+ index: number;
194
+ };
195
+ /** A table's rows, with their cells (`table.delete-row`). */
196
+ deleteTableRows: {
197
+ rows: Block[];
198
+ };
199
+ /** A table's column at `index`, an empty cell in every row (`table.insert-column`). */
200
+ insertTableColumn: {
201
+ index: number;
202
+ width?: number;
203
+ };
204
+ /** A table's column, by id or position, with its cells (`table.delete-column`). */
205
+ deleteTableColumn: {
206
+ column: string | number;
207
+ };
208
+ /** A table's column moved to position `to` (`table.move-column`). */
209
+ moveTableColumn: {
210
+ column: string | number;
211
+ to: number;
212
+ };
213
+ /** A table's rows moved to position `to` among its rows (`table.move-row`). */
214
+ moveTableRows: {
215
+ rows: Block[];
216
+ to: number;
217
+ };
218
+ /** The cell a row shows none of in `column`, created (`table.pad`). */
219
+ fillTableCell: {
220
+ row: string;
221
+ column: string | number;
222
+ };
160
223
  };
161
224
  /**
162
225
  * Bind an operation onto its wrapper: every call is dispatched as a command
@@ -223,7 +286,7 @@ export declare function prepareMove(this: Block, { path }: BlockOperations['move
223
286
  export declare function moveBlock(this: Block, payload: BlockOperations['moveBlock'], plan?: Prepared): Block | null;
224
287
  /**
225
288
  * Grouped move — the operation-layer counterpart of `moveBlock` for
226
- * drags/multi-moves (D5). `path` is the same view-tree address shape:
289
+ * drags/multi-moves. `path` is the same view-tree address shape:
227
290
  * the prefix resolves the destination PARENT block, the last element is
228
291
  * the FINAL index — already discounted for the moved members by the
229
292
  * caller (the `facade.moveBlocks` contract, which counts the
@@ -260,20 +323,16 @@ export declare function patchData(this: Block, payload: BlockOperations['patchDa
260
323
  * ({@link textAfterAtom}), where the caret's pending marks follow.
261
324
  */
262
325
  export declare function addInlineBlock(this: Block, { index, block, text }: BlockOperations['addInlineBlock']): string;
263
- /** The text after atom `atom` of this block; the caret's pending marks follow it there (L4). */
326
+ /** The text after atom `atom` of this block; the caret's pending marks follow it there. */
264
327
  export declare function textAfterAtom(this: Block, atom: string | undefined): Text | null | undefined;
265
328
  /**
266
329
  * Normalization runs at the end of the command's transaction
267
330
  * (`Dispatcher.drain`): a normalizer reads handles over the index; when a
268
331
  * plugin hook answers work, the work runs in the same transaction and the
269
- * block is requested again (bounded by the dispatcher's pass limit, D25).
332
+ * block is requested again (bounded by the dispatcher's pass limit).
270
333
  */
271
334
  export declare function normalizeContent(this: Block): void;
272
335
  export declare function normalizeChildren(this: Block): void;
273
- /** @deprecated A thin wrapper over an `{ end: block.id }` suggestion (`edytor.suggestions`). */
274
- export declare function suggestText(this: Block, { value }: BlockOperations['suggestText']): void;
275
- /** @deprecated Accepts this block's latest `{ end }` suggestion (`suggestion.accept()`). */
276
- export declare function acceptSuggestedText(this: Block): void;
277
336
  export declare function prepareDeleteRange(this: Block, { start: [startIndex, startOffset], end: [endIndex, endOffset] }: {
278
337
  start: number[];
279
338
  end: number[];
@@ -96,7 +96,7 @@ export function duplicateBlock(_ = {}, plan = prepareDuplicate.call(this)) {
96
96
  export function prepareSplit({ index, text }) {
97
97
  if (!text || !this.parent || !this.model)
98
98
  return REFUSED;
99
- // G5: the sibling takes its parent's default child type and no data — a
99
+ // The sibling takes its parent's default child type and no data — a
100
100
  // list-like kind (`continues`) keeps its own, with its first preset's data.
101
101
  const { continues, presets } = this.definition;
102
102
  const tail = continues
@@ -183,7 +183,7 @@ export function moveBlock(payload, plan = prepareMove.call(this, payload)) {
183
183
  }
184
184
  /**
185
185
  * Grouped move — the operation-layer counterpart of `moveBlock` for
186
- * drags/multi-moves (D5). `path` is the same view-tree address shape:
186
+ * drags/multi-moves. `path` is the same view-tree address shape:
187
187
  * the prefix resolves the destination PARENT block, the last element is
188
188
  * the FINAL index — already discounted for the moved members by the
189
189
  * caller (the `facade.moveBlocks` contract, which counts the
@@ -298,7 +298,7 @@ export function addInlineBlock({ index, block, text }) {
298
298
  this.normalizeContent();
299
299
  return atom.id;
300
300
  }
301
- /** The text after atom `atom` of this block; the caret's pending marks follow it there (L4). */
301
+ /** The text after atom `atom` of this block; the caret's pending marks follow it there. */
302
302
  export function textAfterAtom(atom) {
303
303
  if (atom === undefined)
304
304
  return undefined;
@@ -317,7 +317,7 @@ export function textAfterAtom(atom) {
317
317
  * Normalization runs at the end of the command's transaction
318
318
  * (`Dispatcher.drain`): a normalizer reads handles over the index; when a
319
319
  * plugin hook answers work, the work runs in the same transaction and the
320
- * block is requested again (bounded by the dispatcher's pass limit, D25).
320
+ * block is requested again (bounded by the dispatcher's pass limit).
321
321
  */
322
322
  export function normalizeContent() {
323
323
  if (this.edytor.dispatcher.defer(this, normalizeContent))
@@ -341,17 +341,6 @@ export function normalizeChildren() {
341
341
  this.normalizeChildren();
342
342
  }
343
343
  }
344
- /** @deprecated A thin wrapper over an `{ end: block.id }` suggestion (`edytor.suggestions`). */
345
- export function suggestText({ value }) {
346
- this.suggestions =
347
- typeof value === 'string'
348
- ? [[{ text: value }]]
349
- : (value?.map((part) => ('type' in part ? part : [part])) ?? null);
350
- }
351
- /** @deprecated Accepts this block's latest `{ end }` suggestion (`suggestion.accept()`). */
352
- export function acceptSuggestedText() {
353
- this.edytor.suggestions.at(this.id).end.at(-1)?.accept();
354
- }
355
344
  export function prepareDeleteRange({ start: [startIndex, startOffset], end: [endIndex, endOffset] }) {
356
345
  const parts = this.edytor.idToBlock.parts(this.id);
357
346
  const [startPart, endPart] = [parts.at(startIndex), parts.at(endIndex)];
@@ -45,3 +45,18 @@ export declare const colorable: (block: Block) => boolean;
45
45
  * that block as it was. Answers whether any block changed.
46
46
  */
47
47
  export declare const setBlockColor: (edytor: Edytor, blocks: Iterable<Block>, field: BlockColorField, value: string | null) => boolean;
48
+ /**
49
+ * A block's colours as the classes Notion's HTML export writes
50
+ * (`block-color-red`, `block-color-red_background`), space-separated; empty
51
+ * when it holds none. The copy's `text/html` names them so.
52
+ */
53
+ export declare const colorClasses: (data: Readonly<Record<string, unknown>> | undefined) => string;
54
+ /**
55
+ * The palette colours `element`'s classes name as Notion's HTML export does
56
+ * (its `teal` read as green): what a paste keeps. A class naming no palette
57
+ * colour adds nothing.
58
+ */
59
+ export declare const colorsOfClasses: (element: Element) => {
60
+ color?: string;
61
+ background?: string;
62
+ };
@@ -72,3 +72,35 @@ export const setBlockColor = (edytor, blocks, field, value) => {
72
72
  });
73
73
  return applied.some(Boolean);
74
74
  };
75
+ /** The class Notion's HTML export gives a block's colour: `block-color-<name>`, `block-color-<name>_background`. */
76
+ const CLASS = /^block-color-([a-z]+)(_background)?$/;
77
+ /** Notion's export names the palette's green `teal`. */
78
+ const EXPORTED = { teal: 'green' };
79
+ /**
80
+ * A block's colours as the classes Notion's HTML export writes
81
+ * (`block-color-red`, `block-color-red_background`), space-separated; empty
82
+ * when it holds none. The copy's `text/html` names them so.
83
+ */
84
+ export const colorClasses = (data) => {
85
+ const color = colorName(data?.color);
86
+ const background = colorName(data?.background);
87
+ return [color && `block-color-${color}`, background && `block-color-${background}_background`]
88
+ .filter(Boolean)
89
+ .join(' ');
90
+ };
91
+ /**
92
+ * The palette colours `element`'s classes name as Notion's HTML export does
93
+ * (its `teal` read as green): what a paste keeps. A class naming no palette
94
+ * colour adds nothing.
95
+ */
96
+ export const colorsOfClasses = (element) => {
97
+ const found = {};
98
+ for (const name of element.classList) {
99
+ const [, raw, background] = CLASS.exec(name) ?? [];
100
+ const color = raw && (EXPORTED[raw] ?? raw);
101
+ if (!color || !BLOCK_COLORS.includes(color))
102
+ continue;
103
+ found[background ? 'background' : 'color'] = color;
104
+ }
105
+ return found;
106
+ };
@@ -5,7 +5,8 @@ import type { Block } from './block.svelte.js';
5
5
  /**
6
6
  * An id-only inline-atom handle: atom `id`, shown in
7
7
  * block `blockId`. Getters read the document index; `node` is the element
8
- * that renders it (a Surface fact).
8
+ * that renders it (a Surface fact). A reactive reader of a getter depends on
9
+ * the block's cell, so it re-runs when a commit changes the block's content.
9
10
  */
10
11
  export declare class InlineBlock {
11
12
  #private;
@@ -1,11 +1,11 @@
1
- import { clearDomSelection } from '../selection/domSelection.js';
2
1
  import { propsProxy } from '../session/props.js';
3
2
  const INLINE_EDGE_CARET_THRESHOLD_PX = 4;
4
3
  const isTextPart = (part) => part !== undefined && !(part instanceof InlineBlock);
5
4
  /**
6
5
  * An id-only inline-atom handle: atom `id`, shown in
7
6
  * block `blockId`. Getters read the document index; `node` is the element
8
- * that renders it (a Surface fact).
7
+ * that renders it (a Surface fact). A reactive reader of a getter depends on
8
+ * the block's cell, so it re-runs when a commit changes the block's content.
9
9
  */
10
10
  export class InlineBlock {
11
11
  _def = 'inline';
@@ -25,6 +25,8 @@ export class InlineBlock {
25
25
  return this.edytor.idToBlock.block(this.blockId);
26
26
  }
27
27
  get #item() {
28
+ if ($effect.tracking())
29
+ this.edytor.cells?.get(this.blockId);
28
30
  const parts = this.edytor.idToBlock.parts(this.blockId);
29
31
  const part = parts.find((part) => part.kind === 'inline' && part.item.id === this.id);
30
32
  return part?.kind === 'inline' ? part.item : undefined;
@@ -88,10 +90,10 @@ export class InlineBlock {
88
90
  if (event.clientX >= rect.right - INLINE_EDGE_CARET_THRESHOLD_PX && isTextPart(after))
89
91
  return selection.setAtTextOffset(after, 0);
90
92
  selection.selectInlineBlock(this);
91
- clearDomSelection(this.edytor.node);
93
+ this.edytor.ports.surface.clear();
92
94
  // The atom took the press: the caret the browser still leaves for it
93
95
  // (Chromium parks one at the host's start before the release) is its own.
94
- this.edytor.projector.parked();
96
+ this.edytor.ports.surface.parked();
95
97
  };
96
98
  node.addEventListener('pointerdown', selectInlineBlock);
97
99
  return {