edytor 0.1.0-next.34 → 0.1.0-next.38

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 (359) hide show
  1. package/README.md +9 -4
  2. package/dist/block/block.svelte.d.ts +20 -10
  3. package/dist/block/block.svelte.js +68 -12
  4. package/dist/block/block.utils.d.ts +69 -0
  5. package/dist/block/colors.d.ts +62 -0
  6. package/dist/block/colors.js +106 -0
  7. package/dist/block/inlineBlock.svelte.d.ts +2 -1
  8. package/dist/block/inlineBlock.svelte.js +6 -4
  9. package/dist/clipboard/createClipboardFragment.js +34 -1
  10. package/dist/clipboard/htmlFlow.d.ts +5 -3
  11. package/dist/clipboard/htmlFlow.js +32 -7
  12. package/dist/clipboard/moveText.d.ts +35 -0
  13. package/dist/clipboard/moveText.js +79 -0
  14. package/dist/clipboard/serializeClipboardFragment.js +20 -4
  15. package/dist/cloudflare/DocumentRoom.d.ts +79 -512
  16. package/dist/cloudflare/DocumentRoom.js +158 -3725
  17. package/dist/cloudflare/index.d.ts +3 -2
  18. package/dist/cloudflare/index.js +3 -2
  19. package/dist/cloudflare/room/access.d.ts +31 -0
  20. package/dist/cloudflare/room/access.js +237 -0
  21. package/dist/cloudflare/room/admission.d.ts +124 -0
  22. package/dist/cloudflare/room/admission.js +588 -0
  23. package/dist/cloudflare/room/comments.d.ts +58 -0
  24. package/dist/cloudflare/room/comments.js +293 -0
  25. package/dist/cloudflare/room/context.d.ts +827 -0
  26. package/dist/cloudflare/room/context.js +298 -0
  27. package/dist/cloudflare/room/forged.d.ts +50 -0
  28. package/dist/cloudflare/room/forged.js +250 -0
  29. package/dist/cloudflare/room/frames.d.ts +31 -0
  30. package/dist/cloudflare/room/frames.js +53 -0
  31. package/dist/cloudflare/room/history.d.ts +100 -0
  32. package/dist/cloudflare/room/history.js +500 -0
  33. package/dist/cloudflare/room/moves.d.ts +60 -0
  34. package/dist/cloudflare/room/moves.js +422 -0
  35. package/dist/cloudflare/room/presence.d.ts +94 -0
  36. package/dist/cloudflare/room/presence.js +292 -0
  37. package/dist/cloudflare/room/purge.d.ts +16 -0
  38. package/dist/cloudflare/room/purge.js +123 -0
  39. package/dist/cloudflare/room/replicas.d.ts +51 -0
  40. package/dist/cloudflare/room/replicas.js +146 -0
  41. package/dist/cloudflare/room/scheduler.d.ts +39 -0
  42. package/dist/cloudflare/room/scheduler.js +122 -0
  43. package/dist/cloudflare/room/storage.d.ts +164 -0
  44. package/dist/cloudflare/room/storage.js +787 -0
  45. package/dist/cloudflare/room/updates.d.ts +89 -0
  46. package/dist/cloudflare/room/updates.js +327 -0
  47. package/dist/cloudflare/room/validation.d.ts +61 -0
  48. package/dist/cloudflare/room/validation.js +228 -0
  49. package/dist/cloudflare/routeDocumentSocket.d.ts +20 -0
  50. package/dist/cloudflare/routeDocumentSocket.js +46 -1
  51. package/dist/collaboration/comments/client.d.ts +96 -0
  52. package/dist/collaboration/comments/client.js +133 -0
  53. package/dist/collaboration/comments/index.d.ts +8 -0
  54. package/dist/collaboration/comments/index.js +7 -0
  55. package/dist/collaboration/comments/threads.d.ts +27 -0
  56. package/dist/collaboration/comments/threads.js +62 -0
  57. package/dist/collaboration/history/HistoryPanel.svelte +525 -0
  58. package/dist/collaboration/history/HistoryPanel.svelte.d.ts +7 -0
  59. package/dist/collaboration/history/VersionHighlights.svelte +103 -0
  60. package/dist/collaboration/history/VersionHighlights.svelte.d.ts +9 -0
  61. package/dist/collaboration/history/client.d.ts +75 -0
  62. package/dist/collaboration/history/client.js +50 -0
  63. package/dist/collaboration/history/diff.d.ts +42 -0
  64. package/dist/collaboration/history/diff.js +99 -0
  65. package/dist/collaboration/history/index.d.ts +9 -0
  66. package/dist/collaboration/history/index.js +9 -0
  67. package/dist/collaboration/history/panel.d.ts +43 -0
  68. package/dist/collaboration/history/panel.js +3 -0
  69. package/dist/collaboration/history/versionHighlights.d.ts +9 -0
  70. package/dist/collaboration/history/versionHighlights.js +17 -0
  71. package/dist/components/Block.svelte +65 -1
  72. package/dist/components/Edytor.svelte +22 -4
  73. package/dist/components/Edytor.svelte.d.ts +13 -1
  74. package/dist/components/Suggestion.svelte +1 -1
  75. package/dist/crdt/admission.js +4 -2
  76. package/dist/crdt/attribution/block.js +4 -3
  77. package/dist/crdt/doc/anchors.d.ts +17 -0
  78. package/dist/crdt/doc/anchors.js +83 -0
  79. package/dist/crdt/doc/capability.d.ts +56 -0
  80. package/dist/crdt/doc/capability.js +211 -0
  81. package/dist/crdt/doc/content.d.ts +12 -0
  82. package/dist/crdt/doc/content.js +75 -0
  83. package/dist/crdt/doc/delete.d.ts +14 -0
  84. package/dist/crdt/doc/delete.js +101 -0
  85. package/dist/crdt/doc/events.d.ts +9 -0
  86. package/dist/crdt/doc/events.js +63 -0
  87. package/dist/crdt/doc/funnel.d.ts +50 -0
  88. package/dist/crdt/doc/funnel.js +227 -0
  89. package/dist/crdt/doc/gate.d.ts +106 -0
  90. package/dist/crdt/doc/gate.js +118 -0
  91. package/dist/crdt/doc/history.d.ts +27 -0
  92. package/dist/crdt/doc/history.js +207 -0
  93. package/dist/crdt/doc/layout.d.ts +10 -0
  94. package/dist/crdt/doc/layout.js +190 -0
  95. package/dist/crdt/doc/meta.d.ts +19 -0
  96. package/dist/crdt/doc/meta.js +215 -0
  97. package/dist/crdt/doc/moves.d.ts +21 -0
  98. package/dist/crdt/doc/moves.js +254 -0
  99. package/dist/crdt/doc/plan.d.ts +28 -0
  100. package/dist/crdt/doc/plan.js +77 -0
  101. package/dist/crdt/doc/reads.d.ts +79 -0
  102. package/dist/crdt/doc/reads.js +351 -0
  103. package/dist/crdt/doc/seed.d.ts +38 -0
  104. package/dist/crdt/doc/seed.js +109 -0
  105. package/dist/crdt/doc/split-merge.d.ts +12 -0
  106. package/dist/crdt/doc/split-merge.js +183 -0
  107. package/dist/crdt/doc/steps.d.ts +57 -0
  108. package/dist/crdt/doc/steps.js +370 -0
  109. package/dist/crdt/doc/table.d.ts +21 -0
  110. package/dist/crdt/doc/table.js +288 -0
  111. package/dist/crdt/doc/types.d.ts +312 -0
  112. package/dist/crdt/doc/types.js +1 -0
  113. package/dist/crdt/document.js +15 -11
  114. package/dist/crdt/edytor-doc.d.ts +67 -506
  115. package/dist/crdt/edytor-doc.js +116 -2461
  116. package/dist/crdt/engine-api.d.ts +6 -0
  117. package/dist/crdt/flow.d.ts +6 -0
  118. package/dist/crdt/flow.js +20 -3
  119. package/dist/crdt/incarnations.d.ts +16 -3
  120. package/dist/crdt/incarnations.js +17 -3
  121. package/dist/crdt/index.d.ts +39 -13
  122. package/dist/crdt/index.js +5 -3
  123. package/dist/crdt/migration/generation.js +5 -3
  124. package/dist/crdt/migration/legacy-schema.js +5 -3
  125. package/dist/crdt/migration/migrate.js +6 -4
  126. package/dist/crdt/placement/display.d.ts +106 -0
  127. package/dist/crdt/placement/display.js +347 -0
  128. package/dist/crdt/placement/model.d.ts +15 -169
  129. package/dist/crdt/placement/model.js +12 -566
  130. package/dist/crdt/placement/resolve.d.ts +38 -0
  131. package/dist/crdt/placement/resolve.js +169 -0
  132. package/dist/crdt/placement/source.d.ts +43 -0
  133. package/dist/crdt/placement/source.js +66 -0
  134. package/dist/crdt/protocol.d.ts +5 -3
  135. package/dist/crdt/protocol.js +5 -3
  136. package/dist/crdt/protocols/comments.d.ts +219 -0
  137. package/dist/crdt/protocols/comments.js +283 -0
  138. package/dist/crdt/protocols/sync.js +5 -4
  139. package/dist/crdt/providers/index.d.ts +1 -0
  140. package/dist/crdt/providers/index.js +3 -1
  141. package/dist/crdt/providers/indexeddb.js +15 -3
  142. package/dist/crdt/providers/room.d.ts +6 -0
  143. package/dist/crdt/providers/room.js +8 -1
  144. package/dist/crdt/providers/websocket.d.ts +2 -0
  145. package/dist/crdt/providers/websocket.js +58 -3
  146. package/dist/crdt/purge.d.ts +6 -0
  147. package/dist/crdt/purge.js +34 -4
  148. package/dist/crdt/rangeDelete.d.ts +9 -0
  149. package/dist/crdt/rangeDelete.js +40 -0
  150. package/dist/crdt/semantics.d.ts +96 -6
  151. package/dist/crdt/semantics.js +64 -9
  152. package/dist/crdt/structs.d.ts +118 -8
  153. package/dist/crdt/structs.js +108 -0
  154. package/dist/crdt/tables.d.ts +44 -0
  155. package/dist/crdt/tables.js +58 -0
  156. package/dist/crdt/text/delete-index.d.ts +142 -0
  157. package/dist/crdt/text/delete-index.js +372 -0
  158. package/dist/crdt/text/deletes.d.ts +49 -0
  159. package/dist/crdt/text/deletes.js +18 -398
  160. package/dist/crdt/text/index/anchored.d.ts +17 -0
  161. package/dist/crdt/text/index/anchored.js +197 -0
  162. package/dist/crdt/text/index/cache.d.ts +16 -0
  163. package/dist/crdt/text/index/cache.js +171 -0
  164. package/dist/crdt/text/index/checks.d.ts +15 -0
  165. package/dist/crdt/text/index/checks.js +156 -0
  166. package/dist/crdt/text/index/claims.d.ts +18 -0
  167. package/dist/crdt/text/index/claims.js +213 -0
  168. package/dist/crdt/text/index/fold.d.ts +23 -0
  169. package/dist/crdt/text/index/fold.js +501 -0
  170. package/dist/crdt/text/index/layout.d.ts +34 -0
  171. package/dist/crdt/text/index/layout.js +288 -0
  172. package/dist/crdt/text/index/placement.d.ts +39 -0
  173. package/dist/crdt/text/index/placement.js +475 -0
  174. package/dist/crdt/text/index/records.d.ts +13 -0
  175. package/dist/crdt/text/index/records.js +145 -0
  176. package/dist/crdt/text/index/report.d.ts +18 -0
  177. package/dist/crdt/text/index/report.js +338 -0
  178. package/dist/crdt/text/index/shared.d.ts +64 -0
  179. package/dist/crdt/text/index/shared.js +107 -0
  180. package/dist/crdt/text/index/state.d.ts +223 -0
  181. package/dist/crdt/text/index/state.js +120 -0
  182. package/dist/crdt/text/index/streams.d.ts +20 -0
  183. package/dist/crdt/text/index/streams.js +197 -0
  184. package/dist/crdt/text/items.d.ts +8 -0
  185. package/dist/crdt/text/items.js +3 -0
  186. package/dist/crdt/text/model.d.ts +9 -54
  187. package/dist/crdt/text/model.js +18 -246
  188. package/dist/crdt/text/ranges.d.ts +20 -0
  189. package/dist/crdt/text/ranges.js +82 -0
  190. package/dist/crdt/text/runs.d.ts +16 -16
  191. package/dist/crdt/text/runs.js +39 -2486
  192. package/dist/crdt/text/streams.d.ts +45 -0
  193. package/dist/crdt/text/streams.js +138 -0
  194. package/dist/crdt/vendor/yjs/UPSTREAM.md +38 -13
  195. package/dist/edytor.svelte.d.ts +18 -5
  196. package/dist/edytor.svelte.js +51 -16
  197. package/dist/events/beforeInputCommands.d.ts +0 -2
  198. package/dist/events/beforeInputCommands.js +26 -15
  199. package/dist/events/beforeInputDeleteCommands.js +8 -1
  200. package/dist/events/onDrop.d.ts +11 -0
  201. package/dist/events/onDrop.js +89 -3
  202. package/dist/events/onKeyDown.js +6 -0
  203. package/dist/index.d.ts +7 -2
  204. package/dist/index.js +8 -1
  205. package/dist/kinds.d.ts +9 -0
  206. package/dist/kinds.js +11 -2
  207. package/dist/labels.d.ts +488 -0
  208. package/dist/labels.js +431 -0
  209. package/dist/plugins/blockHandles/BlockHandle.svelte +4 -7
  210. package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +4 -0
  211. package/dist/plugins/blockHandles/BlockHandleController.svelte.js +5 -0
  212. package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +3 -0
  213. package/dist/plugins/blockHandles/blockHandlesPlugin.js +5 -2
  214. package/dist/plugins/blockMenu/BlockMenu.svelte +129 -25
  215. package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +69 -12
  216. package/dist/plugins/blockMenu/BlockMenuController.svelte.js +155 -21
  217. package/dist/plugins/blockMenu/blockMenuPlugin.d.ts +4 -3
  218. package/dist/plugins/blockMenu/blockMenuPlugin.js +7 -4
  219. package/dist/plugins/code/CodeHeader.svelte +11 -8
  220. package/dist/plugins/code/CodePlugin.svelte +8 -3
  221. package/dist/plugins/code/languages.d.ts +16 -2
  222. package/dist/plugins/code/languages.js +5 -1
  223. package/dist/plugins/columns/ColumnResize.svelte +1 -1
  224. package/dist/plugins/columns/ColumnsPlugin.svelte +30 -9
  225. package/dist/plugins/columns/ColumnsPlugin.svelte.d.ts +8 -0
  226. package/dist/plugins/columns/resize.svelte.d.ts +6 -1
  227. package/dist/plugins/columns/resize.svelte.js +6 -1
  228. package/dist/plugins/comments/CommentsController.svelte.d.ts +124 -0
  229. package/dist/plugins/comments/CommentsController.svelte.js +351 -0
  230. package/dist/plugins/comments/CommentsSidebar.svelte +601 -0
  231. package/dist/plugins/comments/CommentsSidebar.svelte.d.ts +16 -0
  232. package/dist/plugins/comments/commentsPlugin.d.ts +48 -0
  233. package/dist/plugins/comments/commentsPlugin.js +60 -0
  234. package/dist/plugins/equation/EquationEditor.svelte +138 -0
  235. package/dist/plugins/equation/EquationEditor.svelte.d.ts +8 -0
  236. package/dist/plugins/equation/EquationPlugin.svelte +328 -0
  237. package/dist/plugins/equation/EquationPlugin.svelte.d.ts +33 -0
  238. package/dist/plugins/equation/EquationView.svelte +34 -0
  239. package/dist/plugins/equation/EquationView.svelte.d.ts +7 -0
  240. package/dist/plugins/equation/equation.svelte.d.ts +142 -0
  241. package/dist/plugins/equation/equation.svelte.js +295 -0
  242. package/dist/plugins/find/FindBar.svelte +17 -16
  243. package/dist/plugins/find/FindController.svelte.d.ts +6 -1
  244. package/dist/plugins/find/FindController.svelte.js +6 -1
  245. package/dist/plugins/find/findPlugin.d.ts +3 -0
  246. package/dist/plugins/find/findPlugin.js +2 -1
  247. package/dist/plugins/icons.js +13 -0
  248. package/dist/plugins/image/ImageChrome.svelte +11 -10
  249. package/dist/plugins/image/ImageEmpty.svelte +19 -16
  250. package/dist/plugins/image/ImagePlugin.svelte +21 -4
  251. package/dist/plugins/image/ImagePlugin.svelte.d.ts +8 -0
  252. package/dist/plugins/image/controls.svelte.d.ts +6 -1
  253. package/dist/plugins/image/controls.svelte.js +6 -1
  254. package/dist/plugins/image/image.d.ts +5 -0
  255. package/dist/plugins/image/image.js +3 -0
  256. package/dist/plugins/index.d.ts +12 -2
  257. package/dist/plugins/index.js +10 -1
  258. package/dist/plugins/markdownShortcuts.js +99 -67
  259. package/dist/plugins/media/AudioPlugin.svelte +11 -5
  260. package/dist/plugins/media/BookmarkPlugin.svelte +26 -14
  261. package/dist/plugins/media/BookmarkPlugin.svelte.d.ts +5 -0
  262. package/dist/plugins/media/EmbedPlugin.svelte +25 -12
  263. package/dist/plugins/media/EmbedPlugin.svelte.d.ts +5 -0
  264. package/dist/plugins/media/FilePlugin.svelte +15 -8
  265. package/dist/plugins/media/MediaEmpty.svelte +14 -13
  266. package/dist/plugins/media/MediaEmpty.svelte.d.ts +3 -8
  267. package/dist/plugins/media/UrlPasteMenu.svelte +1 -1
  268. package/dist/plugins/media/VideoPlugin.svelte +11 -5
  269. package/dist/plugins/media/media.d.ts +12 -2
  270. package/dist/plugins/media/media.js +12 -13
  271. package/dist/plugins/media/urlPaste.svelte.d.ts +7 -2
  272. package/dist/plugins/media/urlPaste.svelte.js +9 -5
  273. package/dist/plugins/mention/MentionPlugin.svelte +169 -31
  274. package/dist/plugins/mention/MentionPlugin.svelte.d.ts +35 -2
  275. package/dist/plugins/page/PageLink.svelte +129 -0
  276. package/dist/plugins/page/PageLink.svelte.d.ts +11 -0
  277. package/dist/plugins/page/PagePlugin.svelte +127 -0
  278. package/dist/plugins/page/PagePlugin.svelte.d.ts +44 -0
  279. package/dist/plugins/page/page.d.ts +58 -0
  280. package/dist/plugins/page/page.js +42 -0
  281. package/dist/plugins/pageLink/PageLinkPlugin.svelte +169 -0
  282. package/dist/plugins/pageLink/PageLinkPlugin.svelte.d.ts +58 -0
  283. package/dist/plugins/richtext/RichTextPlugin.svelte +155 -63
  284. package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +23 -2
  285. package/dist/plugins/richtext/TodoCheckbox.svelte +35 -0
  286. package/dist/plugins/richtext/TodoCheckbox.svelte.d.ts +11 -0
  287. package/dist/plugins/richtext/labels.d.ts +5 -0
  288. package/dist/plugins/richtext/labels.js +3 -0
  289. package/dist/plugins/richtext/richTextOperations.d.ts +6 -1
  290. package/dist/plugins/richtext/richTextOperations.js +5 -0
  291. package/dist/plugins/slashMenu/SlashMenu.svelte +11 -7
  292. package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +25 -29
  293. package/dist/plugins/slashMenu/SlashMenuController.svelte.js +51 -146
  294. package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +3 -0
  295. package/dist/plugins/slashMenu/slashMenuPlugin.js +7 -25
  296. package/dist/plugins/suggestions/SuggestionBars.svelte +13 -6
  297. package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +2 -0
  298. package/dist/plugins/suggestions/suggestionsPlugin.d.ts +3 -0
  299. package/dist/plugins/suggestions/suggestionsPlugin.js +3 -1
  300. package/dist/plugins/table/TableChrome.svelte +153 -0
  301. package/dist/plugins/table/TableChrome.svelte.d.ts +7 -0
  302. package/dist/plugins/table/TablePlugin.svelte +450 -0
  303. package/dist/plugins/table/TablePlugin.svelte.d.ts +43 -0
  304. package/dist/plugins/table/chrome.svelte.d.ts +153 -0
  305. package/dist/plugins/table/chrome.svelte.js +420 -0
  306. package/dist/plugins/table/table.css +202 -0
  307. package/dist/plugins/table/table.d.ts +94 -0
  308. package/dist/plugins/table/table.js +224 -0
  309. package/dist/plugins/toc/TableOfContents.svelte +83 -0
  310. package/dist/plugins/toc/TableOfContents.svelte.d.ts +7 -0
  311. package/dist/plugins/toc/TocPlugin.svelte +71 -0
  312. package/dist/plugins/toc/TocPlugin.svelte.d.ts +32 -0
  313. package/dist/plugins/toc/toc.d.ts +29 -0
  314. package/dist/plugins/toc/toc.js +10 -0
  315. package/dist/plugins/toolbar/LinkCard.svelte +8 -7
  316. package/dist/plugins/toolbar/Toolbar.svelte +21 -18
  317. package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +10 -2
  318. package/dist/plugins/toolbar/ToolbarController.svelte.js +12 -2
  319. package/dist/plugins/toolbar/toolbarPlugin.d.ts +3 -0
  320. package/dist/plugins/toolbar/toolbarPlugin.js +2 -1
  321. package/dist/plugins/triggers/TriggerController.svelte.d.ts +131 -0
  322. package/dist/plugins/triggers/TriggerController.svelte.js +333 -0
  323. package/dist/plugins/triggers/TriggerMenu.svelte +144 -0
  324. package/dist/plugins/triggers/TriggerMenu.svelte.d.ts +7 -0
  325. package/dist/plugins/triggers/place.d.ts +15 -0
  326. package/dist/plugins/triggers/place.js +37 -0
  327. package/dist/plugins/triggers/triggers.d.ts +12 -0
  328. package/dist/plugins/triggers/triggers.js +87 -0
  329. package/dist/plugins.d.ts +188 -4
  330. package/dist/selection/selection.svelte.d.ts +22 -0
  331. package/dist/selection/selection.svelte.js +29 -2
  332. package/dist/selection/selection.utils.d.ts +7 -5
  333. package/dist/selection/selection.utils.js +5 -14
  334. package/dist/session/announcer.svelte.d.ts +2 -1
  335. package/dist/session/announcer.svelte.js +15 -9
  336. package/dist/session/attempt.js +1 -1
  337. package/dist/session/bindings.js +2 -3
  338. package/dist/session/commands.d.ts +8 -2
  339. package/dist/session/commands.js +45 -7
  340. package/dist/session/composition.svelte.js +5 -9
  341. package/dist/session/editing/text.d.ts +7 -0
  342. package/dist/session/editing/text.js +17 -0
  343. package/dist/session/inputRules.d.ts +20 -0
  344. package/dist/session/inputRules.js +128 -0
  345. package/dist/session/navigation.js +1 -1
  346. package/dist/session/ports.d.ts +45 -0
  347. package/dist/session/ports.js +1 -0
  348. package/dist/surface/attributes.js +4 -0
  349. package/dist/surface/overlay.d.ts +15 -3
  350. package/dist/surface/overlay.js +30 -3
  351. package/dist/surface/projector.svelte.d.ts +15 -0
  352. package/dist/surface/projector.svelte.js +32 -2
  353. package/dist/text/text.svelte.d.ts +4 -2
  354. package/dist/text/text.svelte.js +9 -7
  355. package/dist/themes/notion.css +130 -14
  356. package/dist/utils.d.ts +1 -1
  357. package/package.json +12 -12
  358. /package/dist/{events → text}/wordBoundary.d.ts +0 -0
  359. /package/dist/{events → text}/wordBoundary.js +0 -0
package/README.md CHANGED
@@ -10,19 +10,24 @@
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.34`, `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.38`, `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
- - **Notion-style editing out of the box.** `<Edytor />` alone is a rich text editor with images and block handles: headings, lists, to-dos, toggles, callouts, quotes, dividers, ten marks and Notion's hotkeys. Add the Notion theme, a block menu (drag one block, or every block the selection covers), a slash menu, a selection toolbar, markdown shortcuts (`markdownShortcutsPlugin`) and code blocks.
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
+ - **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)).
24
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)).
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)).
25
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.
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)).
26
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.
27
32
  - **AI suggestions.** `edytor.suggestions.add(position, content)` proposes text, paragraphs, lists, to-dos or images after, before or inside a block, at the end of its text, or in place of the selection; it streams in, shows only on your screen, and becomes one undo step when accepted ([Suggestions](https://edytor.dev/docs/editor/suggestions)).
28
33
  - **Plugins that can veto anything.** Every command is prepared before it writes; plugins see the command and each planned step and can refuse or replace it.
@@ -99,7 +104,7 @@ The [documentation site](https://edytor.dev/docs) is the single source for the A
99
104
  - [Editor](https://edytor.dev/docs/editor/edytor-component): the component, commands, selection, history, clipboard, readonly
100
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)
101
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
102
- - [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)
103
108
 
104
109
  ## Contributing
105
110
 
@@ -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;
@@ -160,10 +164,16 @@ export declare class Block {
160
164
  ops: import("../crdt/index.js").DataPatch[];
161
165
  atom?: string;
162
166
  }) => void;
163
- addInlineBlock: (payload: {
164
- index: number;
167
+ /**
168
+ * Insert an inline atom: at `offset` of the block's content (block
169
+ * offsets, an inline atom counting 1; a caret's), or at `index` of the
170
+ * text segment `text`. One `addInlineBlock` operation (its payload names
171
+ * the segment). Answers the text segment right after the atom, where a
172
+ * caret goes (`null` when it was not written, `undefined` when refused).
173
+ */
174
+ addInlineBlock: (payload: BlockOperations["addInlineBlock"] | {
175
+ offset: number;
165
176
  block: JSONInlineBlock;
166
- text: Text;
167
177
  }) => Text | null | undefined;
168
178
  normalizeContent: () => void;
169
179
  normalizeChildren: () => void;
@@ -1,22 +1,25 @@
1
1
  import { Text } from '../text/text.svelte.js';
2
- import { Edytor } from '../edytor.svelte.js';
3
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, acceptSuggestedText, suggestText, 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,7 +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);
192
+ if (this.isRoot)
193
+ return true;
194
+ this.#track();
195
+ return this.edytor.facade.isVisibleBlock(this.id);
159
196
  }
160
197
  /**
161
198
  * @deprecated `edytor.suggestions` with `{ end: block.id }`. The content of
@@ -211,6 +248,9 @@ export class Block {
211
248
  }
212
249
  /** This block's JSON — the document's one serializer (`facade.blockJSON`). */
213
250
  get value() {
251
+ // Its subtree's: every commit re-runs a reactive reader.
252
+ if ($effect.tracking())
253
+ void this.edytor.valueRevision;
214
254
  if (!this.isRoot)
215
255
  return this.edytor.facade.blockJSON(this.id);
216
256
  const { data = {}, children } = this.edytor.facade.toJSON();
@@ -294,7 +334,20 @@ export class Block {
294
334
  pushContentIntoBlock = batch('pushContentIntoBlock', pushContentIntoBlock);
295
335
  removeInlineBlock = batch('removeInlineBlock', removeInlineBlock, prepareRemoveInline);
296
336
  patchData = batch('patchData', patchData, preparePatch);
297
- addInlineBlock = batch('addInlineBlock', addInlineBlock, undefined, textAfterAtom);
337
+ #addInline = batch('addInlineBlock', addInlineBlock, undefined, textAfterAtom);
338
+ /**
339
+ * Insert an inline atom: at `offset` of the block's content (block
340
+ * offsets, an inline atom counting 1; a caret's), or at `index` of the
341
+ * text segment `text`. One `addInlineBlock` operation (its payload names
342
+ * the segment). Answers the text segment right after the atom, where a
343
+ * caret goes (`null` when it was not written, `undefined` when refused).
344
+ */
345
+ addInlineBlock = (payload) => {
346
+ if (!('offset' in payload))
347
+ return this.#addInline(payload);
348
+ const at = this.textAtOffset(Math.max(0, payload.offset));
349
+ return at ? this.#addInline({ index: at.offset, text: at.text, block: payload.block }) : null;
350
+ };
298
351
  normalizeContent = batch('normalizeContent', normalizeContent);
299
352
  normalizeChildren = batch('normalizeChildren', normalizeChildren);
300
353
  /** @deprecated `edytor.suggestions.add({ end: block.id }, …)`. */
@@ -385,6 +438,8 @@ export class Block {
385
438
  node.setAttribute(name, value);
386
439
  this.node = node;
387
440
  const release = this.edytor.surface.register(node, 'block', this.id);
441
+ // A block laid out again with no commit moves the chrome beside it (the overlay measures).
442
+ const unobserve = this.edytor.overlay.observe(node);
388
443
  const onDestroy = this.edytor.plugins.flatMap((plugin) => {
389
444
  const action = plugin.onBlockAttached?.({ node, block: this });
390
445
  return typeof action === 'function' ? [action] : [];
@@ -395,6 +450,7 @@ export class Block {
395
450
  if (this.node === node)
396
451
  this.node = undefined;
397
452
  release();
453
+ unobserve();
398
454
  onDestroy.forEach((destroy) => destroy());
399
455
  }
400
456
  };
@@ -135,6 +135,19 @@ export type BlockOperations = {
135
135
  }[];
136
136
  replacement: string;
137
137
  };
138
+ /**
139
+ * A comment thread's anchor (`plugins/comments`): its `comment:<thread>`
140
+ * mark over each run of the text it was made on, one plan, one undo step
141
+ * (its steps: a `formatRange` per run).
142
+ */
143
+ addComment: {
144
+ thread: string;
145
+ runs: {
146
+ block: string;
147
+ offset: number;
148
+ length: number;
149
+ }[];
150
+ };
138
151
  deleteContentAtRange: {
139
152
  start: [number, number];
140
153
  end: [number, number];
@@ -146,6 +159,30 @@ export type BlockOperations = {
146
159
  flow: Flow;
147
160
  target: FlowTarget;
148
161
  };
162
+ /**
163
+ * A text range dragged inside the editor and dropped at `to` (block
164
+ * offsets): its content placed at `to`, then the range deleted — or,
165
+ * with `copy` (Alt), only placed. Both are prepared before any write:
166
+ * hooks see the placement's planned steps and the deletion's, and a
167
+ * veto or a refusal of either writes nothing.
168
+ */
169
+ moveText: {
170
+ from: {
171
+ start: {
172
+ block: string;
173
+ offset: number;
174
+ };
175
+ end: {
176
+ block: string;
177
+ offset: number;
178
+ };
179
+ };
180
+ to: {
181
+ block: string;
182
+ offset: number;
183
+ };
184
+ copy: boolean;
185
+ };
149
186
  deleteBlocks: {
150
187
  blocks: Block[];
151
188
  };
@@ -157,6 +194,38 @@ export type BlockOperations = {
157
194
  };
158
195
  /** A divider at the caret: its steps are the conversion, insertion or split it plans. */
159
196
  insertDivider: {};
197
+ /** A table's row at `index`, one empty cell per column (`table.insert-row`). */
198
+ insertTableRow: {
199
+ index: number;
200
+ };
201
+ /** A table's rows, with their cells (`table.delete-row`). */
202
+ deleteTableRows: {
203
+ rows: Block[];
204
+ };
205
+ /** A table's column at `index`, an empty cell in every row (`table.insert-column`). */
206
+ insertTableColumn: {
207
+ index: number;
208
+ width?: number;
209
+ };
210
+ /** A table's column, by id or position, with its cells (`table.delete-column`). */
211
+ deleteTableColumn: {
212
+ column: string | number;
213
+ };
214
+ /** A table's column moved to position `to` (`table.move-column`). */
215
+ moveTableColumn: {
216
+ column: string | number;
217
+ to: number;
218
+ };
219
+ /** A table's rows moved to position `to` among its rows (`table.move-row`). */
220
+ moveTableRows: {
221
+ rows: Block[];
222
+ to: number;
223
+ };
224
+ /** The cell a row shows none of in `column`, created (`table.pad`). */
225
+ fillTableCell: {
226
+ row: string;
227
+ column: string | number;
228
+ };
160
229
  };
161
230
  /**
162
231
  * Bind an operation onto its wrapper: every call is dispatched as a command
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Block colours (Notion's "Color" in the block menu): a block's text colour
3
+ * and background, by palette name, in two data leaves, `data.color` and
4
+ * `data.background`. Each is one property of the block, so two people
5
+ * colouring it at once keep one value each (per-leaf last writer), and
6
+ * Turn into keeps them (a retype sets only the leaves it names).
7
+ *
8
+ * The core renders a valid name as `data-edytor-color` and
9
+ * `data-edytor-background` on the block element (`Block.svelte`, owned by
10
+ * the attribute table), and its stylesheet paints the bundled names from
11
+ * theme tokens (`--edytor-color-<name>`, `--edytor-background-<name>`).
12
+ */
13
+ import type { Block } from './block.svelte.js';
14
+ import type { Edytor } from '../edytor.svelte.js';
15
+ /** Notion's palette: the colour names a block may hold, in menu order ("Default" is none). */
16
+ export declare const BLOCK_COLORS: readonly ["gray", "brown", "orange", "yellow", "green", "blue", "purple", "pink", "red"];
17
+ /**
18
+ * Notion's light values of the palette: the fallbacks of the theme tokens
19
+ * (`--edytor-color-<name>`, `--edytor-background-<name>`), as the core's
20
+ * stylesheet (`Block.svelte`) and the Notion theme write them.
21
+ */
22
+ export declare const BLOCK_PALETTE: Record<(typeof BLOCK_COLORS)[number], {
23
+ color: string;
24
+ background: string;
25
+ }>;
26
+ /** A block's colour fields: its text colour and its background. */
27
+ export type BlockColorField = 'color' | 'background';
28
+ /** `value` as a colour name, or `undefined`. */
29
+ export declare const colorName: (value: unknown) => string | undefined;
30
+ /** The block element's colour attributes for `data` (absent when it holds none). */
31
+ export declare const colorAttributes: (data: Readonly<Record<string, unknown>> | undefined) => {
32
+ 'data-edytor-color': string | undefined;
33
+ 'data-edytor-background': string | undefined;
34
+ };
35
+ /**
36
+ * Whether `block` takes a colour: a block showing its own text (a
37
+ * paragraph, a heading, a list item, a toggle, a callout), not a void (a
38
+ * divider, an image), an island (a code block) or one of its lines.
39
+ */
40
+ export declare const colorable: (block: Block) => boolean;
41
+ /**
42
+ * Set `field` of every colourable block of `blocks` to `value` (`null`
43
+ * removes it: the default), as one command and one undo step; each block
44
+ * is its own data write (`patchData`), so an extension vetoing one keeps
45
+ * that block as it was. Answers whether any block changed.
46
+ */
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
+ };
@@ -0,0 +1,106 @@
1
+ /** Notion's palette: the colour names a block may hold, in menu order ("Default" is none). */
2
+ export const BLOCK_COLORS = [
3
+ 'gray',
4
+ 'brown',
5
+ 'orange',
6
+ 'yellow',
7
+ 'green',
8
+ 'blue',
9
+ 'purple',
10
+ 'pink',
11
+ 'red'
12
+ ];
13
+ /**
14
+ * Notion's light values of the palette: the fallbacks of the theme tokens
15
+ * (`--edytor-color-<name>`, `--edytor-background-<name>`), as the core's
16
+ * stylesheet (`Block.svelte`) and the Notion theme write them.
17
+ */
18
+ export const BLOCK_PALETTE = {
19
+ gray: { color: '#7d7a75', background: '#f0efed' },
20
+ brown: { color: '#9f765a', background: '#f5ede9' },
21
+ orange: { color: '#d27b2d', background: '#fbebde' },
22
+ yellow: { color: '#cb9434', background: '#f9f3dc' },
23
+ green: { color: '#50946e', background: '#e8f1ec' },
24
+ blue: { color: '#387dc9', background: '#e5f2fc' },
25
+ purple: { color: '#9a6bb4', background: '#f3ebf9' },
26
+ pink: { color: '#c14c8a', background: '#fae9f1' },
27
+ red: { color: '#cf5148', background: '#fce9e7' }
28
+ };
29
+ /**
30
+ * A colour name the core renders: lowercase letters, digits and hyphens,
31
+ * starting with a letter (an app's own name, such as `teal`, renders too,
32
+ * and its stylesheet paints it). Anything else renders nothing.
33
+ */
34
+ const NAME = /^[a-z][a-z0-9-]{0,31}$/;
35
+ /** `value` as a colour name, or `undefined`. */
36
+ export const colorName = (value) => typeof value === 'string' && NAME.test(value) ? value : undefined;
37
+ /** The block element's colour attributes for `data` (absent when it holds none). */
38
+ export const colorAttributes = (data) => ({
39
+ 'data-edytor-color': colorName(data?.color),
40
+ 'data-edytor-background': colorName(data?.background)
41
+ });
42
+ /**
43
+ * Whether `block` takes a colour: a block showing its own text (a
44
+ * paragraph, a heading, a list item, a toggle, a callout), not a void (a
45
+ * divider, an image), an island (a code block) or one of its lines.
46
+ */
47
+ export const colorable = (block) => {
48
+ const { facade } = block.edytor;
49
+ const line = block.parent && !block.parent.isRoot && facade.isLines(block.parent.id);
50
+ return (!block.isRoot &&
51
+ block.rendersContent &&
52
+ !facade.isVoid(block.id) &&
53
+ !facade.isIsland(block.id) &&
54
+ !line);
55
+ };
56
+ /**
57
+ * Set `field` of every colourable block of `blocks` to `value` (`null`
58
+ * removes it: the default), as one command and one undo step; each block
59
+ * is its own data write (`patchData`), so an extension vetoing one keeps
60
+ * that block as it was. Answers whether any block changed.
61
+ */
62
+ export const setBlockColor = (edytor, blocks, field, value) => {
63
+ const name = value === null ? undefined : colorName(value);
64
+ if (value !== null && name === undefined)
65
+ return false;
66
+ const painted = [...blocks].filter((block) => colorable(block) && edytor.facade.blockDataOf(block.id)?.[field] !== name);
67
+ if (!painted.length)
68
+ return false;
69
+ const applied = edytor.dispatcher.each('setBlockColor', painted, (block) => {
70
+ block.patchData({ ops: [{ path: [field], value: name }] });
71
+ return edytor.dispatcher.last?.status === 'applied';
72
+ });
73
+ return applied.some(Boolean);
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 {
@@ -67,7 +67,40 @@ const extractBlockRange = (edytor) => {
67
67
  return value;
68
68
  });
69
69
  };
70
- export const createEdytorClipboardFragment = (edytor) => {
70
+ /**
71
+ * `fragment` without the marks whose record says `copy: false` (a
72
+ * comment's anchor, `comment:<id>`: Notion copies the text, not the
73
+ * comment): one rule for copy, cut and the internal paste they feed.
74
+ */
75
+ const withoutUncopied = (edytor, fragment) => {
76
+ if (!fragment)
77
+ return fragment;
78
+ const strip = (content) => {
79
+ for (const part of content ?? []) {
80
+ if (!('text' in part) || !part.marks)
81
+ continue;
82
+ for (const key of Object.keys(part.marks))
83
+ if (edytor.marks.get(key)?.copy === false)
84
+ delete part.marks[key];
85
+ if (Object.keys(part.marks).length === 0)
86
+ delete part.marks;
87
+ }
88
+ };
89
+ const walk = (blocks) => {
90
+ for (const block of blocks) {
91
+ strip(block.content);
92
+ if (block.children)
93
+ walk(block.children);
94
+ }
95
+ };
96
+ if (fragment.kind === 'blocks')
97
+ walk(fragment.blocks);
98
+ else
99
+ strip(fragment.content);
100
+ return fragment;
101
+ };
102
+ export const createEdytorClipboardFragment = (edytor) => withoutUncopied(edytor, fragmentOf(edytor));
103
+ const fragmentOf = (edytor) => {
71
104
  // A layout the block selection covers whole is copied as the layout (D3).
72
105
  const selectedBlocks = selectedMembers(edytor, liftLayouts(edytor.selection.selectedBlocks));
73
106
  if (selectedBlocks.length > 0) {
@@ -2,8 +2,8 @@ import type { Edytor } from '../edytor.svelte.js';
2
2
  import type { Flow } from '../crdt/flow.js';
3
3
  import type { BlockDefinition } from '../plugins.js';
4
4
  import { type SerializableContent } from '../utils/json.js';
5
- /** What HTML import reads: the kind and mark records, and the document's default child. */
6
- export type ImportKinds = Pick<Edytor, 'blocks' | 'marks'> & {
5
+ /** What HTML import reads: the kind, mark and atom records, and the document's default child. */
6
+ export type ImportKinds = Pick<Edytor, 'blocks' | 'marks'> & Partial<Pick<Edytor, 'inlineBlocks'>> & {
7
7
  document: Pick<Edytor['document'], 'defaultChild'>;
8
8
  };
9
9
  type Values = Record<string, SerializableContent>;
@@ -17,7 +17,9 @@ export declare const tagOf: (type: string, kind: BlockDefinition, data: Values)
17
17
  * `tag`, and each record's `parse` hook first (aliases, sanitized values).
18
18
  * A void kind with a `parse` hook (an image, an embed, a video) is found
19
19
  * by its hook only, and a void takes only its `figcaption`'s text; an
20
- * `iframe`, `video` or `audio` no hook claims carries nothing. Unknown
20
+ * `iframe`, `video` or `audio` no hook claims carries nothing. An atom
21
+ * kind's `parse` hook claims inline elements (an equation's `<math>`): the
22
+ * atom, never its text. Unknown
21
23
  * elements degrade to text runs; whitespace collapses as HTML renders it. `null` when the HTML carries nothing (`flow.shape`, F-P10).
22
24
  */
23
25
  export declare const flowOfHtml: (kinds: ImportKinds, html: string | undefined) => Flow | null;