edytor 0.1.0-next.32 → 0.1.0-next.36

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 (348) hide show
  1. package/README.md +10 -6
  2. package/dist/block/block.svelte.d.ts +34 -38
  3. package/dist/block/block.svelte.js +24 -8
  4. package/dist/block/block.utils.d.ts +19 -1
  5. package/dist/block/block.utils.js +2 -1
  6. package/dist/block/colors.d.ts +47 -0
  7. package/dist/block/colors.js +74 -0
  8. package/dist/block/inlineBlock.svelte.d.ts +1 -4
  9. package/dist/block/inlineBlock.svelte.js +2 -1
  10. package/dist/clipboard/htmlFlow.d.ts +4 -2
  11. package/dist/clipboard/htmlFlow.js +101 -17
  12. package/dist/cloudflare/DocumentRoom.d.ts +164 -486
  13. package/dist/cloudflare/DocumentRoom.js +219 -3276
  14. package/dist/cloudflare/history.d.ts +4 -4
  15. package/dist/cloudflare/history.js +3 -3
  16. package/dist/cloudflare/index.d.ts +3 -3
  17. package/dist/cloudflare/index.js +2 -2
  18. package/dist/cloudflare/locks.d.ts +1 -1
  19. package/dist/cloudflare/locks.js +1 -1
  20. package/dist/cloudflare/move.d.ts +11 -1
  21. package/dist/cloudflare/move.js +8 -3
  22. package/dist/cloudflare/room/access.d.ts +31 -0
  23. package/dist/cloudflare/room/access.js +226 -0
  24. package/dist/cloudflare/room/admission.d.ts +117 -0
  25. package/dist/cloudflare/room/admission.js +559 -0
  26. package/dist/cloudflare/room/context.d.ts +790 -0
  27. package/dist/cloudflare/room/context.js +293 -0
  28. package/dist/cloudflare/room/forged.d.ts +50 -0
  29. package/dist/cloudflare/room/forged.js +250 -0
  30. package/dist/cloudflare/room/frames.d.ts +24 -0
  31. package/dist/cloudflare/room/frames.js +37 -0
  32. package/dist/cloudflare/room/history.d.ts +100 -0
  33. package/dist/cloudflare/room/history.js +500 -0
  34. package/dist/cloudflare/room/moves.d.ts +60 -0
  35. package/dist/cloudflare/room/moves.js +419 -0
  36. package/dist/cloudflare/room/presence.d.ts +64 -0
  37. package/dist/cloudflare/room/presence.js +202 -0
  38. package/dist/cloudflare/room/purge.d.ts +16 -0
  39. package/dist/cloudflare/room/purge.js +114 -0
  40. package/dist/cloudflare/room/replicas.d.ts +51 -0
  41. package/dist/cloudflare/room/replicas.js +145 -0
  42. package/dist/cloudflare/room/scheduler.d.ts +39 -0
  43. package/dist/cloudflare/room/scheduler.js +122 -0
  44. package/dist/cloudflare/room/storage.d.ts +153 -0
  45. package/dist/cloudflare/room/storage.js +758 -0
  46. package/dist/cloudflare/room/updates.d.ts +89 -0
  47. package/dist/cloudflare/room/updates.js +328 -0
  48. package/dist/cloudflare/room/validation.d.ts +61 -0
  49. package/dist/cloudflare/room/validation.js +227 -0
  50. package/dist/cloudflare/routeDocumentSocket.d.ts +29 -5
  51. package/dist/cloudflare/routeDocumentSocket.js +32 -10
  52. package/dist/collaboration/awarenessSelection.d.ts +2 -2
  53. package/dist/collaboration/awarenessSelection.js +2 -2
  54. package/dist/collaboration/history/HistoryPanel.svelte +531 -0
  55. package/dist/collaboration/history/HistoryPanel.svelte.d.ts +7 -0
  56. package/dist/collaboration/history/VersionHighlights.svelte +103 -0
  57. package/dist/collaboration/history/VersionHighlights.svelte.d.ts +9 -0
  58. package/dist/collaboration/history/client.d.ts +75 -0
  59. package/dist/collaboration/history/client.js +50 -0
  60. package/dist/collaboration/history/diff.d.ts +42 -0
  61. package/dist/collaboration/history/diff.js +99 -0
  62. package/dist/collaboration/history/index.d.ts +9 -0
  63. package/dist/collaboration/history/index.js +9 -0
  64. package/dist/collaboration/history/panel.d.ts +89 -0
  65. package/dist/collaboration/history/panel.js +28 -0
  66. package/dist/collaboration/history/versionHighlights.d.ts +9 -0
  67. package/dist/collaboration/history/versionHighlights.js +17 -0
  68. package/dist/collaboration/index.d.ts +1 -1
  69. package/dist/collaboration/index.js +1 -1
  70. package/dist/collaboration/providers.d.ts +0 -3
  71. package/dist/collaboration/providers.js +6 -11
  72. package/dist/components/Announcer.svelte +28 -0
  73. package/dist/components/Announcer.svelte.d.ts +7 -0
  74. package/dist/components/Block.svelte +78 -0
  75. package/dist/components/Edytor.svelte +59 -9
  76. package/dist/components/Edytor.svelte.d.ts +27 -4
  77. package/dist/components/Suggestion.svelte +1 -1
  78. package/dist/crdt/attribution/attribution.d.ts +3 -3
  79. package/dist/crdt/data.d.ts +11 -0
  80. package/dist/crdt/data.js +62 -12
  81. package/dist/crdt/doc/anchors.d.ts +17 -0
  82. package/dist/crdt/doc/anchors.js +83 -0
  83. package/dist/crdt/doc/capability.d.ts +56 -0
  84. package/dist/crdt/doc/capability.js +199 -0
  85. package/dist/crdt/doc/content.d.ts +12 -0
  86. package/dist/crdt/doc/content.js +75 -0
  87. package/dist/crdt/doc/delete.d.ts +14 -0
  88. package/dist/crdt/doc/delete.js +91 -0
  89. package/dist/crdt/doc/events.d.ts +9 -0
  90. package/dist/crdt/doc/events.js +63 -0
  91. package/dist/crdt/doc/funnel.d.ts +50 -0
  92. package/dist/crdt/doc/funnel.js +227 -0
  93. package/dist/crdt/doc/gate.d.ts +106 -0
  94. package/dist/crdt/doc/gate.js +118 -0
  95. package/dist/crdt/doc/history.d.ts +27 -0
  96. package/dist/crdt/doc/history.js +207 -0
  97. package/dist/crdt/doc/layout.d.ts +10 -0
  98. package/dist/crdt/doc/layout.js +190 -0
  99. package/dist/crdt/doc/meta.d.ts +19 -0
  100. package/dist/crdt/doc/meta.js +215 -0
  101. package/dist/crdt/doc/moves.d.ts +21 -0
  102. package/dist/crdt/doc/moves.js +254 -0
  103. package/dist/crdt/doc/plan.d.ts +28 -0
  104. package/dist/crdt/doc/plan.js +77 -0
  105. package/dist/crdt/doc/reads.d.ts +61 -0
  106. package/dist/crdt/doc/reads.js +240 -0
  107. package/dist/crdt/doc/seed.d.ts +38 -0
  108. package/dist/crdt/doc/seed.js +107 -0
  109. package/dist/crdt/doc/split-merge.d.ts +12 -0
  110. package/dist/crdt/doc/split-merge.js +180 -0
  111. package/dist/crdt/doc/steps.d.ts +57 -0
  112. package/dist/crdt/doc/steps.js +370 -0
  113. package/dist/crdt/doc/types.d.ts +302 -0
  114. package/dist/crdt/doc/types.js +1 -0
  115. package/dist/crdt/document.d.ts +31 -49
  116. package/dist/crdt/document.js +38 -53
  117. package/dist/crdt/edytor-doc.d.ts +32 -520
  118. package/dist/crdt/edytor-doc.js +82 -2468
  119. package/dist/crdt/engine-api.d.ts +4 -5
  120. package/dist/crdt/flow.d.ts +1 -1
  121. package/dist/crdt/index.d.ts +42 -58
  122. package/dist/crdt/index.js +33 -54
  123. package/dist/crdt/migration/migrate.d.ts +5 -5
  124. package/dist/crdt/nodes.d.ts +2 -2
  125. package/dist/crdt/placement/display.d.ts +106 -0
  126. package/dist/crdt/placement/display.js +339 -0
  127. package/dist/crdt/placement/model.d.ts +16 -177
  128. package/dist/crdt/placement/model.js +7 -558
  129. package/dist/crdt/placement/resolve.d.ts +38 -0
  130. package/dist/crdt/placement/resolve.js +169 -0
  131. package/dist/crdt/placement/source.d.ts +43 -0
  132. package/dist/crdt/placement/source.js +66 -0
  133. package/dist/crdt/protocol.d.ts +44 -0
  134. package/dist/crdt/protocol.js +62 -0
  135. package/dist/crdt/protocols/envelope.d.ts +1 -1
  136. package/dist/crdt/providers/bound.d.ts +2 -0
  137. package/dist/crdt/providers/bound.js +9 -0
  138. package/dist/crdt/providers/index.d.ts +6 -6
  139. package/dist/crdt/providers/indexeddb.d.ts +6 -6
  140. package/dist/crdt/providers/indexeddb.js +1 -1
  141. package/dist/crdt/providers/room.d.ts +19 -3
  142. package/dist/crdt/providers/room.js +54 -34
  143. package/dist/crdt/providers/websocket.d.ts +3 -4
  144. package/dist/crdt/rangeDelete.d.ts +1 -1
  145. package/dist/crdt/semantics.d.ts +145 -12
  146. package/dist/crdt/semantics.js +191 -14
  147. package/dist/crdt/text/delete-index.d.ts +145 -0
  148. package/dist/crdt/text/delete-index.js +368 -0
  149. package/dist/crdt/text/deletes.d.ts +49 -0
  150. package/dist/crdt/text/deletes.js +2 -379
  151. package/dist/crdt/text/index/anchored.d.ts +17 -0
  152. package/dist/crdt/text/index/anchored.js +196 -0
  153. package/dist/crdt/text/index/cache.d.ts +16 -0
  154. package/dist/crdt/text/index/cache.js +171 -0
  155. package/dist/crdt/text/index/checks.d.ts +15 -0
  156. package/dist/crdt/text/index/checks.js +156 -0
  157. package/dist/crdt/text/index/claims.d.ts +18 -0
  158. package/dist/crdt/text/index/claims.js +213 -0
  159. package/dist/crdt/text/index/fold.d.ts +22 -0
  160. package/dist/crdt/text/index/fold.js +496 -0
  161. package/dist/crdt/text/index/layout.d.ts +21 -0
  162. package/dist/crdt/text/index/layout.js +124 -0
  163. package/dist/crdt/text/index/placement.d.ts +39 -0
  164. package/dist/crdt/text/index/placement.js +450 -0
  165. package/dist/crdt/text/index/records.d.ts +13 -0
  166. package/dist/crdt/text/index/records.js +140 -0
  167. package/dist/crdt/text/index/report.d.ts +18 -0
  168. package/dist/crdt/text/index/report.js +338 -0
  169. package/dist/crdt/text/index/shared.d.ts +64 -0
  170. package/dist/crdt/text/index/shared.js +102 -0
  171. package/dist/crdt/text/index/state.d.ts +213 -0
  172. package/dist/crdt/text/index/state.js +113 -0
  173. package/dist/crdt/text/index/streams.d.ts +20 -0
  174. package/dist/crdt/text/index/streams.js +197 -0
  175. package/dist/crdt/text/items.d.ts +8 -0
  176. package/dist/crdt/text/items.js +2 -0
  177. package/dist/crdt/text/model.d.ts +7 -53
  178. package/dist/crdt/text/model.js +7 -227
  179. package/dist/crdt/text/ranges.d.ts +20 -0
  180. package/dist/crdt/text/ranges.js +82 -0
  181. package/dist/crdt/text/runs.d.ts +32 -28
  182. package/dist/crdt/text/runs.js +39 -2469
  183. package/dist/crdt/text/streams.d.ts +45 -0
  184. package/dist/crdt/text/streams.js +138 -0
  185. package/dist/edytor.svelte.d.ts +37 -164
  186. package/dist/edytor.svelte.js +104 -50
  187. package/dist/events/beforeInputCommands.js +8 -6
  188. package/dist/events/onBeforeInput.js +6 -6
  189. package/dist/events/onCopy.js +2 -2
  190. package/dist/events/onDrop.js +2 -2
  191. package/dist/events/onKeyDown.js +4 -3
  192. package/dist/events/onPaste.js +5 -4
  193. package/dist/index.d.ts +30 -24
  194. package/dist/index.js +32 -23
  195. package/dist/kinds.d.ts +15 -3
  196. package/dist/kinds.js +22 -4
  197. package/dist/labels.d.ts +340 -0
  198. package/dist/labels.js +334 -0
  199. package/dist/plugins/blockHandles/BlockHandle.svelte +16 -7
  200. package/dist/plugins/blockHandles/BlockHandleController.svelte.d.ts +15 -3
  201. package/dist/plugins/blockHandles/BlockHandleController.svelte.js +19 -3
  202. package/dist/plugins/blockHandles/blockHandlesPlugin.d.ts +6 -1
  203. package/dist/plugins/blockHandles/blockHandlesPlugin.js +4 -2
  204. package/dist/plugins/blockMenu/BlockMenu.svelte +133 -32
  205. package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +51 -9
  206. package/dist/plugins/blockMenu/BlockMenuController.svelte.js +102 -18
  207. package/dist/plugins/code/CodeHeader.svelte +68 -0
  208. package/dist/plugins/code/CodeHeader.svelte.d.ts +9 -0
  209. package/dist/plugins/code/CodePlugin.svelte +227 -224
  210. package/dist/plugins/code/CodePlugin.svelte.d.ts +10 -0
  211. package/dist/plugins/code/code.css +27 -8
  212. package/dist/plugins/code/languages.d.ts +65 -0
  213. package/dist/plugins/code/languages.js +192 -0
  214. package/dist/plugins/columns/ColumnResize.svelte +24 -2
  215. package/dist/plugins/columns/ColumnsPlugin.svelte +32 -9
  216. package/dist/plugins/columns/ColumnsPlugin.svelte.d.ts +8 -0
  217. package/dist/plugins/columns/resize.svelte.d.ts +40 -2
  218. package/dist/plugins/columns/resize.svelte.js +98 -24
  219. package/dist/plugins/find/FindBar.svelte +170 -0
  220. package/dist/plugins/find/FindBar.svelte.d.ts +9 -0
  221. package/dist/plugins/find/FindController.svelte.d.ts +67 -0
  222. package/dist/plugins/find/FindController.svelte.js +247 -0
  223. package/dist/plugins/find/FindHighlights.svelte +75 -0
  224. package/dist/plugins/find/FindHighlights.svelte.d.ts +9 -0
  225. package/dist/plugins/find/findPlugin.d.ts +28 -0
  226. package/dist/plugins/find/findPlugin.js +56 -0
  227. package/dist/plugins/find/search.d.ts +18 -0
  228. package/dist/plugins/find/search.js +41 -0
  229. package/dist/plugins/icons.js +17 -1
  230. package/dist/plugins/image/ImageChrome.svelte +213 -0
  231. package/dist/plugins/image/ImageChrome.svelte.d.ts +7 -0
  232. package/dist/plugins/image/ImageEmpty.svelte +54 -20
  233. package/dist/plugins/image/ImageEmpty.svelte.d.ts +4 -0
  234. package/dist/plugins/image/ImagePlugin.svelte +213 -40
  235. package/dist/plugins/image/ImagePlugin.svelte.d.ts +25 -4
  236. package/dist/plugins/image/controls.svelte.d.ts +116 -0
  237. package/dist/plugins/image/controls.svelte.js +289 -0
  238. package/dist/plugins/image/image.d.ts +24 -1
  239. package/dist/plugins/image/image.js +34 -1
  240. package/dist/plugins/image/uploads.svelte.d.ts +50 -0
  241. package/dist/plugins/image/uploads.svelte.js +111 -0
  242. package/dist/plugins/index.d.ts +18 -4
  243. package/dist/plugins/index.js +15 -3
  244. package/dist/plugins/markdownShortcuts.js +99 -67
  245. package/dist/plugins/media/AudioPlugin.svelte +92 -0
  246. package/dist/plugins/media/AudioPlugin.svelte.d.ts +28 -0
  247. package/dist/plugins/media/BookmarkPlugin.svelte +194 -0
  248. package/dist/plugins/media/BookmarkPlugin.svelte.d.ts +50 -0
  249. package/dist/plugins/media/EmbedPlugin.svelte +159 -0
  250. package/dist/plugins/media/EmbedPlugin.svelte.d.ts +42 -0
  251. package/dist/plugins/media/FilePlugin.svelte +119 -0
  252. package/dist/plugins/media/FilePlugin.svelte.d.ts +28 -0
  253. package/dist/plugins/media/MediaEmpty.svelte +108 -0
  254. package/dist/plugins/media/MediaEmpty.svelte.d.ts +16 -0
  255. package/dist/plugins/media/UrlPasteMenu.svelte +83 -0
  256. package/dist/plugins/media/UrlPasteMenu.svelte.d.ts +7 -0
  257. package/dist/plugins/media/VideoPlugin.svelte +101 -0
  258. package/dist/plugins/media/VideoPlugin.svelte.d.ts +29 -0
  259. package/dist/plugins/media/media.d.ts +82 -0
  260. package/dist/plugins/media/media.js +225 -0
  261. package/dist/plugins/media/urlPaste.svelte.d.ts +81 -0
  262. package/dist/plugins/media/urlPaste.svelte.js +201 -0
  263. package/dist/plugins/mention/MentionPlugin.svelte +163 -31
  264. package/dist/plugins/mention/MentionPlugin.svelte.d.ts +32 -2
  265. package/dist/plugins/page/PageLink.svelte +117 -0
  266. package/dist/plugins/page/PageLink.svelte.d.ts +11 -0
  267. package/dist/plugins/page/PagePlugin.svelte +112 -0
  268. package/dist/plugins/page/PagePlugin.svelte.d.ts +43 -0
  269. package/dist/plugins/page/page.d.ts +54 -0
  270. package/dist/plugins/page/page.js +42 -0
  271. package/dist/plugins/pageLink/PageLinkPlugin.svelte +169 -0
  272. package/dist/plugins/pageLink/PageLinkPlugin.svelte.d.ts +58 -0
  273. package/dist/plugins/richtext/RichTextPlugin.svelte +255 -76
  274. package/dist/plugins/richtext/RichTextPlugin.svelte.d.ts +23 -2
  275. package/dist/plugins/richtext/TodoCheckbox.svelte +35 -0
  276. package/dist/plugins/richtext/TodoCheckbox.svelte.d.ts +11 -0
  277. package/dist/plugins/richtext/labels.d.ts +5 -0
  278. package/dist/plugins/richtext/labels.js +3 -0
  279. package/dist/plugins/richtext/richTextOperations.d.ts +43 -3
  280. package/dist/plugins/richtext/richTextOperations.js +71 -1
  281. package/dist/plugins/slashMenu/SlashMenu.svelte +109 -46
  282. package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +27 -24
  283. package/dist/plugins/slashMenu/SlashMenuController.svelte.js +48 -138
  284. package/dist/plugins/slashMenu/slashMenuPlugin.d.ts +5 -0
  285. package/dist/plugins/slashMenu/slashMenuPlugin.js +7 -25
  286. package/dist/plugins/suggestions/SuggestionBars.svelte +12 -6
  287. package/dist/plugins/suggestions/SuggestionBars.svelte.d.ts +2 -0
  288. package/dist/plugins/suggestions/suggestionsPlugin.d.ts +3 -0
  289. package/dist/plugins/suggestions/suggestionsPlugin.js +3 -1
  290. package/dist/plugins/toc/TableOfContents.svelte +83 -0
  291. package/dist/plugins/toc/TableOfContents.svelte.d.ts +7 -0
  292. package/dist/plugins/toc/TocPlugin.svelte +71 -0
  293. package/dist/plugins/toc/TocPlugin.svelte.d.ts +32 -0
  294. package/dist/plugins/toc/toc.d.ts +29 -0
  295. package/dist/plugins/toc/toc.js +10 -0
  296. package/dist/plugins/toolbar/LinkCard.svelte +118 -0
  297. package/dist/plugins/toolbar/LinkCard.svelte.d.ts +7 -0
  298. package/dist/plugins/toolbar/Toolbar.svelte +80 -21
  299. package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +48 -3
  300. package/dist/plugins/toolbar/ToolbarController.svelte.js +131 -4
  301. package/dist/plugins/toolbar/toolbarPlugin.d.ts +8 -0
  302. package/dist/plugins/toolbar/toolbarPlugin.js +83 -1
  303. package/dist/plugins/triggers/TriggerController.svelte.d.ts +131 -0
  304. package/dist/plugins/triggers/TriggerController.svelte.js +333 -0
  305. package/dist/plugins/triggers/TriggerMenu.svelte +144 -0
  306. package/dist/plugins/triggers/TriggerMenu.svelte.d.ts +7 -0
  307. package/dist/plugins/triggers/place.d.ts +15 -0
  308. package/dist/plugins/triggers/place.js +37 -0
  309. package/dist/plugins/triggers/triggers.d.ts +12 -0
  310. package/dist/plugins/triggers/triggers.js +87 -0
  311. package/dist/plugins.d.ts +169 -44
  312. package/dist/selection/replaceSelection.d.ts +7 -1
  313. package/dist/selection/replaceSelection.js +20 -9
  314. package/dist/selection/selection.svelte.d.ts +33 -121
  315. package/dist/selection/selection.svelte.js +63 -15
  316. package/dist/session/announcer.svelte.d.ts +28 -0
  317. package/dist/session/announcer.svelte.js +40 -0
  318. package/dist/session/bindings.js +3 -1
  319. package/dist/session/commands.d.ts +46 -16
  320. package/dist/session/commands.js +138 -32
  321. package/dist/session/editing/text.d.ts +1 -1
  322. package/dist/session/history.d.ts +8 -1
  323. package/dist/session/history.js +10 -3
  324. package/dist/session/inputRules.d.ts +20 -0
  325. package/dist/session/inputRules.js +128 -0
  326. package/dist/session/keymap.d.ts +1 -1
  327. package/dist/session/keymap.js +2 -2
  328. package/dist/session/moves.d.ts +3 -2
  329. package/dist/session/moves.js +6 -2
  330. package/dist/session/navigation.js +1 -1
  331. package/dist/session/selection.d.ts +3 -3
  332. package/dist/session/suggestions.svelte.d.ts +0 -2
  333. package/dist/session/virtual.js +3 -2
  334. package/dist/surface/attributes.d.ts +13 -0
  335. package/dist/surface/attributes.js +24 -0
  336. package/dist/surface/cells.d.ts +1 -1
  337. package/dist/surface/popups.svelte.d.ts +28 -0
  338. package/dist/surface/popups.svelte.js +32 -0
  339. package/dist/surface/projector.svelte.js +8 -1
  340. package/dist/text/text.svelte.d.ts +2 -5
  341. package/dist/text/text.svelte.js +3 -2
  342. package/dist/text/text.utils.js +2 -1
  343. package/dist/themes/notion.css +301 -16
  344. package/dist/utils/json.d.ts +2 -0
  345. package/dist/utils/json.js +15 -0
  346. package/dist/utils.d.ts +10 -1
  347. package/dist/utils.js +22 -2
  348. package/package.json +14 -4
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  <p>A collaborative block editor for Svelte 5, on a Yjs v14 engine</p>
5
5
 
6
+ [![CI](https://github.com/beynar/edytor/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/beynar/edytor/actions/workflows/ci.yml)
6
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
8
  [![Svelte v5](https://img.shields.io/badge/Svelte-v5-FF3E00.svg)](https://svelte.dev)
8
9
 
@@ -15,13 +16,16 @@
15
16
 
16
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.
17
18
 
18
- > **Work in progress.** Edytor is a pre-release (`0.1.0-next.32`, `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.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
20
 
20
21
  ## Features
21
22
 
22
- - **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)).
23
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
+ - **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)).
24
27
  - **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
+ - **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)).
25
29
  - **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.
26
30
  - **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)).
27
31
  - **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.
@@ -38,7 +42,7 @@ The pre-release is on npm under the `next` tag. Name the tag: a bare `edytor` is
38
42
  pnpm add edytor@next
39
43
  ```
40
44
 
41
- `svelte@^5` is a peer dependency. Do not install `yjs`: the v14 engine is vendored (`edytor/crdt`). See [installation](https://edytor.dev/docs/getting-started).
45
+ `svelte@^5` is a peer dependency. Do not install `yjs`: the v14 engine is vendored (`edytor/crdt`). See [installation](https://edytor.dev/docs/getting-started) and [platform support](https://edytor.dev/docs/reference/platform-support) (Chrome, Edge, Firefox and Safari; real phones are not tested yet).
42
46
 
43
47
  ## Quick start
44
48
 
@@ -78,7 +82,7 @@ pnpm add edytor@next
78
82
  </div>
79
83
  ```
80
84
 
81
- `<Edytor>` adds the rich text, image, arrow-move and suggestions plugins after yours, and block handles. To collaborate, name a room and a server running the [`edytor/cloudflare` room](https://edytor.dev/docs/server/quick-start):
85
+ An editable editor is client-only: in SvelteKit, mount it once the page has hydrated ([quick start](https://edytor.dev/docs/getting-started/quick-start#mount-it-in-a-page)). `<Edytor>` adds the rich text, image, arrow-move and suggestions plugins after yours, and block handles. To collaborate, name a room and a server running the [`edytor/cloudflare` room](https://edytor.dev/docs/server/quick-start):
82
86
 
83
87
  ```svelte
84
88
  <Edytor
@@ -98,11 +102,11 @@ The [documentation site](https://edytor.dev/docs) is the single source for the A
98
102
  - [Editor](https://edytor.dev/docs/editor/edytor-component): the component, commands, selection, history, clipboard, readonly
99
103
  - [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)
100
104
  - [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
101
- - [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
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)
102
106
 
103
107
  ## Contributing
104
108
 
105
- `AGENTS.md` describes the architecture (one owner per fact), where to fix what, and the test lanes. The docs live in `site/content/docs`; a change to public behavior updates them in the same commit.
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.
106
110
 
107
111
  ```bash
108
112
  pnpm install
@@ -45,18 +45,16 @@ export declare class Block {
45
45
  setData: (data: Record<string, unknown>) => void;
46
46
  get selected(): boolean;
47
47
  get focused(): boolean;
48
- /** May this block move at all — R5 `canPlace` without a destination (drag handles). */
48
+ /** May this block move at all: `canPlace` without a destination (drag handles). */
49
49
  get movable(): boolean;
50
50
  /**
51
51
  * May text-level structural commands (convert, markdown shortcut, slash
52
52
  * menu) apply: the block is movable — or the virtual paragraph of an
53
53
  * emptied document, which a conversion creates with its kind
54
- * (SW10-lists-3) — has no role of its own and renders its own content —
55
- * a container (a list) is never converted, its items are (ZW-02).
54
+ * — has no role of its own and renders its own content —
55
+ * a container (a list) is never converted, its items are.
56
56
  */
57
57
  get convertible(): boolean;
58
- get firstEditableText(): Text | undefined;
59
- get lastEditableText(): Text | undefined;
60
58
  get index(): number;
61
59
  get depth(): number;
62
60
  get path(): number[];
@@ -79,14 +77,14 @@ export declare class Block {
79
77
  /** It holds nothing: no content and no children (the emptiness Turn into reads, `holdsNothing`). */
80
78
  get isEmpty(): boolean;
81
79
  get isNested(): boolean;
82
- /** This block's JSON — the document's one serializer (`facade.blockJSON`, L14). */
80
+ /** This block's JSON — the document's one serializer (`facade.blockJSON`). */
83
81
  get value(): JSONBlock;
84
82
  isChildOf(block: Block): boolean;
85
- /** Whether this kind renders its own content slot — the adopted capability (R5, O22). */
83
+ /** Whether this kind renders its own content slot — the adopted capability. */
86
84
  get rendersContent(): boolean;
87
85
  /**
88
86
  * A container: it shows only its children (a list), neither void nor an
89
- * island — the document's container rule (YW-02). Its items hold what it
87
+ * island — the document's container rule. Its items hold what it
90
88
  * shows; it is never converted (`convertible`).
91
89
  */
92
90
  get isContainer(): boolean;
@@ -100,7 +98,7 @@ export declare class Block {
100
98
  /**
101
99
  * The list this block shows in: its container when it is an item
102
100
  * (`isListItem`), or — an item outdented out of a nested list into the
103
- * item holding it (SW8-roles-4) — the list of the items of its kind it
101
+ * item holding it — the list of the items of its kind it
104
102
  * sits under. <kbd>Enter</kbd> in an empty one outdents it; the menus
105
103
  * name it by the list's `itemKind`.
106
104
  */
@@ -114,58 +112,64 @@ export declare class Block {
114
112
  get firstText(): Text | undefined;
115
113
  /** The last text of this block's own content (see {@link firstText}). */
116
114
  get lastText(): Text | undefined;
117
- addChildBlock: (args_0: {
115
+ addChildBlock: (payload: {
118
116
  block: JSONBlock;
119
117
  index: number;
120
118
  }) => Block;
121
- addChildBlocks: (args_0: {
119
+ addChildBlocks: (payload: {
122
120
  blocks: JSONBlock[];
123
121
  index: number;
124
122
  }) => Block[];
125
123
  insertBlockAfter: (payload: {
126
124
  block: JSONBlock;
127
- }, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
125
+ }) => Block | null | undefined;
128
126
  insertBlockBefore: (payload: {
129
127
  block: JSONBlock;
130
- }, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
128
+ }) => Block | null | undefined;
131
129
  splitBlock: (payload: {
132
130
  index: number;
133
131
  text: Text;
134
- }, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
135
- duplicateBlock: (_?: {} | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
132
+ }) => Block | null | undefined;
133
+ duplicateBlock: (payload?: {} | undefined) => Block | null | undefined;
136
134
  removeBlock: (payload?: {
137
135
  keepChildren?: boolean;
138
- } | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => void;
139
- unNestBlock: (this: Block, _?: {} | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null;
140
- mergeBlockBackward: (_?: {} | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
141
- mergeBlockForward: (_?: {} | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null | undefined;
142
- nestBlock: (this: Block, _?: {} | undefined, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null;
136
+ } | undefined) => void;
137
+ unNestBlock: (this: Block, payload?: {} | undefined) => Block | null;
138
+ mergeBlockBackward: (payload?: {} | undefined) => Block | null | undefined;
139
+ mergeBlockForward: (payload?: {} | undefined) => Block | null | undefined;
140
+ nestBlock: (this: Block, payload?: {} | undefined) => Block | null;
143
141
  setBlock: (payload: {
144
142
  value: Partial<JSONBlock>;
145
- }, plan?: import("../crdt/index.js").Prepared | undefined) => void;
143
+ }) => void;
146
144
  moveBlock: (this: Block, payload: {
147
145
  path: number[];
148
146
  beside?: import("./block.utils.js").BlockBeside;
149
- }, plan?: import("../crdt/index.js").Prepared | undefined) => Block | null;
147
+ }) => Block | null;
150
148
  moveBlocks: (this: Block, payload: {
151
149
  blocks: Block[];
152
150
  path: number[];
153
151
  beside?: import("./block.utils.js").BlockBeside;
154
- }, plan?: import("../crdt/index.js").Prepared | undefined) => Block[];
155
- pushContentIntoBlock: (args_0: {
152
+ }) => Block[];
153
+ pushContentIntoBlock: (payload: {
156
154
  value: (Text | InlineBlock)[];
157
155
  }) => void;
158
156
  removeInlineBlock: (payload: {
159
157
  index: number;
160
- }, plan?: import("../crdt/index.js").Prepared | undefined) => void;
158
+ }) => void;
161
159
  patchData: (payload: {
162
160
  ops: import("../crdt/index.js").DataPatch[];
163
161
  atom?: string;
164
- }, plan?: import("../crdt/index.js").Prepared | undefined) => void;
165
- addInlineBlock: (args_0: {
166
- index: number;
162
+ }) => void;
163
+ /**
164
+ * Insert an inline atom: at `offset` of the block's content (block
165
+ * offsets, an inline atom counting 1; a caret's), or at `index` of the
166
+ * text segment `text`. One `addInlineBlock` operation (its payload names
167
+ * the segment). Answers the text segment right after the atom, where a
168
+ * caret goes (`null` when it was not written, `undefined` when refused).
169
+ */
170
+ addInlineBlock: (payload: BlockOperations["addInlineBlock"] | {
171
+ offset: number;
167
172
  block: JSONInlineBlock;
168
- text: Text;
169
173
  }) => Text | null | undefined;
170
174
  normalizeContent: () => void;
171
175
  normalizeChildren: () => void;
@@ -176,7 +180,7 @@ export declare class Block {
176
180
  deleteContentAtRange: (payload: {
177
181
  start: [number, number];
178
182
  end: [number, number];
179
- }, plan?: import("../crdt/index.js").Prepared | undefined) => void;
183
+ }) => void;
180
184
  /** Mark an element inside the block's markup as non-editable chrome (a header, a caption bar). */
181
185
  void: (node: HTMLElement) => void;
182
186
  /**
@@ -201,12 +205,4 @@ export declare class Block {
201
205
  * each entry is a text's runs or an atom, as JSON.
202
206
  */
203
207
  insertParts: (index: number, parts: (JSONText[] | JSONInlineBlock)[]) => void;
204
- /**
205
- * Register the element the core rendered for this block (O45) and run the
206
- * attach hooks. A re-rendered block (moved, re-parented) keeps its declared
207
- * view state (R11): an open toggle stays open.
208
- */
209
- attach: (node: HTMLElement) => {
210
- destroy: () => void;
211
- };
212
208
  }
@@ -94,7 +94,7 @@ export class Block {
94
94
  get focused() {
95
95
  return this.edytor.selection.focusedBlocks.has(this) && !this.selected;
96
96
  }
97
- /** May this block move at all — R5 `canPlace` without a destination (drag handles). */
97
+ /** May this block move at all: `canPlace` without a destination (drag handles). */
98
98
  get movable() {
99
99
  return this.edytor.facade.canPlace([this.id]);
100
100
  }
@@ -102,14 +102,15 @@ export class Block {
102
102
  * May text-level structural commands (convert, markdown shortcut, slash
103
103
  * menu) apply: the block is movable — or the virtual paragraph of an
104
104
  * emptied document, which a conversion creates with its kind
105
- * (SW10-lists-3) — has no role of its own and renders its own content —
106
- * a container (a list) is never converted, its items are (ZW-02).
105
+ * — has no role of its own and renders its own content —
106
+ * a container (a list) is never converted, its items are.
107
107
  */
108
108
  get convertible() {
109
109
  const { facade } = this.edytor;
110
110
  const placeable = this.movable || facade.virtual() === this.id;
111
111
  return placeable && this.rendersContent && !facade.isVoid(this.id) && !facade.isIsland(this.id);
112
112
  }
113
+ /** @internal */
113
114
  get firstEditableText() {
114
115
  // Only a RENDERED text part is editable — a container's phantom
115
116
  // content slot holds a Text with no `node`. Scan ALL children: the
@@ -125,6 +126,7 @@ export class Block {
125
126
  }
126
127
  return undefined;
127
128
  }
129
+ /** @internal */
128
130
  get lastEditableText() {
129
131
  const own = this.content.findLast((part) => part instanceof Text && part.node != null);
130
132
  if (own)
@@ -207,7 +209,7 @@ export class Block {
207
209
  get isNested() {
208
210
  return (this.parent && this.parent.type !== 'root') || false;
209
211
  }
210
- /** This block's JSON — the document's one serializer (`facade.blockJSON`, L14). */
212
+ /** This block's JSON — the document's one serializer (`facade.blockJSON`). */
211
213
  get value() {
212
214
  if (!this.isRoot)
213
215
  return this.edytor.facade.blockJSON(this.id);
@@ -220,13 +222,13 @@ export class Block {
220
222
  return true;
221
223
  return false;
222
224
  }
223
- /** Whether this kind renders its own content slot — the adopted capability (R5, O22). */
225
+ /** Whether this kind renders its own content slot — the adopted capability. */
224
226
  get rendersContent() {
225
227
  return this.edytor.document.rendersContent(this.type);
226
228
  }
227
229
  /**
228
230
  * A container: it shows only its children (a list), neither void nor an
229
- * island — the document's container rule (YW-02). Its items hold what it
231
+ * island — the document's container rule. Its items hold what it
230
232
  * shows; it is never converted (`convertible`).
231
233
  */
232
234
  get isContainer() {
@@ -249,7 +251,7 @@ export class Block {
249
251
  /**
250
252
  * The list this block shows in: its container when it is an item
251
253
  * (`isListItem`), or — an item outdented out of a nested list into the
252
- * item holding it (SW8-roles-4) — the list of the items of its kind it
254
+ * item holding it — the list of the items of its kind it
253
255
  * sits under. <kbd>Enter</kbd> in an empty one outdents it; the menus
254
256
  * name it by the list's `itemKind`.
255
257
  */
@@ -292,7 +294,20 @@ export class Block {
292
294
  pushContentIntoBlock = batch('pushContentIntoBlock', pushContentIntoBlock);
293
295
  removeInlineBlock = batch('removeInlineBlock', removeInlineBlock, prepareRemoveInline);
294
296
  patchData = batch('patchData', patchData, preparePatch);
295
- addInlineBlock = batch('addInlineBlock', addInlineBlock, undefined, textAfterAtom);
297
+ #addInline = batch('addInlineBlock', addInlineBlock, undefined, textAfterAtom);
298
+ /**
299
+ * Insert an inline atom: at `offset` of the block's content (block
300
+ * offsets, an inline atom counting 1; a caret's), or at `index` of the
301
+ * text segment `text`. One `addInlineBlock` operation (its payload names
302
+ * the segment). Answers the text segment right after the atom, where a
303
+ * caret goes (`null` when it was not written, `undefined` when refused).
304
+ */
305
+ addInlineBlock = (payload) => {
306
+ if (!('offset' in payload))
307
+ return this.#addInline(payload);
308
+ const at = this.textAtOffset(Math.max(0, payload.offset));
309
+ return at ? this.#addInline({ index: at.offset, text: at.text, block: payload.block }) : null;
310
+ };
296
311
  normalizeContent = batch('normalizeContent', normalizeContent);
297
312
  normalizeChildren = batch('normalizeChildren', normalizeChildren);
298
313
  /** @deprecated `edytor.suggestions.add({ end: block.id }, …)`. */
@@ -373,6 +388,7 @@ export class Block {
373
388
  * Register the element the core rendered for this block (O45) and run the
374
389
  * attach hooks. A re-rendered block (moved, re-parented) keeps its declared
375
390
  * view state (R11): an open toggle stays open.
391
+ * @internal
376
392
  */
377
393
  attach = (node) => {
378
394
  const names = this.definition.viewState ?? [];
@@ -122,6 +122,19 @@ export type BlockOperations = {
122
122
  content: readonly JSONBlock[];
123
123
  };
124
124
  };
125
+ /**
126
+ * Find and replace (`plugins/find`): each match's text replaced by
127
+ * `replacement`, one plan, one undo step (its steps: a
128
+ * `deleteContentAtRange` and an `insertText` per match).
129
+ */
130
+ replaceMatches: {
131
+ matches: {
132
+ block: string;
133
+ offset: number;
134
+ length: number;
135
+ }[];
136
+ replacement: string;
137
+ };
125
138
  deleteContentAtRange: {
126
139
  start: [number, number];
127
140
  end: [number, number];
@@ -153,7 +166,12 @@ export type BlockOperations = {
153
166
  * and answers the op's document result; `resolve` turns it into wrappers
154
167
  * after the commit patched them.
155
168
  */
156
- export declare function batch<T extends (...args: any[]) => any, O extends keyof BlockOperations, R = ReturnType<T>>(operation: O, func: T, prepare?: (payload: BlockOperations[O]) => Prepared, resolve?: (this: any, out: ReturnType<T> | undefined, payload: Parameters<T>[0]) => R): (...args: Parameters<T>) => R;
169
+ export declare function batch<T extends (...args: any[]) => any, O extends keyof BlockOperations, R = ReturnType<T>>(operation: O, func: T, prepare?: (payload: BlockOperations[O]) => Prepared, resolve?: (this: any, out: ReturnType<T> | undefined, payload: Parameters<T>[0]) => R): (...args: PayloadOf<Parameters<T>>) => R;
170
+ /**
171
+ * A mutator's public parameters: its payload alone (optional when the op's
172
+ * is). The plan the dispatcher passes the op is not the caller's.
173
+ */
174
+ export type PayloadOf<A extends unknown[]> = A extends [] ? [] : A extends [infer P, ...unknown[]] ? [payload: P] : A extends [(infer P)?, ...unknown[]] ? [payload?: P] : [];
157
175
  /**
158
176
  * The handle of block `id` (null: refused at preparation, or gone; undefined:
159
177
  * the command did not run). Inside an outer transaction too: the index shows
@@ -12,7 +12,8 @@ import { InlineBlock } from './inlineBlock.svelte.js';
12
12
  export function batch(operation, func, prepare, resolve) {
13
13
  return function (...[payload]) {
14
14
  const out = this.edytor.dispatcher.dispatch(operation, payload, { block: this }, (p, plan) => func.call(this, p, plan), prepare && ((p) => prepare.call(this, p)));
15
- return resolve ? resolve.call(this, out, payload) : out;
15
+ const value = resolve ? resolve.call(this, out, payload) : out;
16
+ return this.edytor.dispatcher.answer(value);
16
17
  };
17
18
  }
18
19
  /**
@@ -0,0 +1,47 @@
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;
@@ -0,0 +1,74 @@
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
+ };
@@ -3,7 +3,7 @@ import type { InlineBlockDefinition } from '../plugins.js';
3
3
  import type { JSONInlineBlock } from '../utils/json.js';
4
4
  import type { Block } from './block.svelte.js';
5
5
  /**
6
- * An id-only inline-atom handle (§2.4 "Handles", R4): atom `id`, shown in
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
8
  * that renders it (a Surface fact).
9
9
  */
@@ -31,7 +31,4 @@ export declare class InlineBlock {
31
31
  /** The atom is shown by a live block. */
32
32
  get isInDocument(): boolean;
33
33
  get value(): JSONInlineBlock;
34
- attach: (node: HTMLElement) => {
35
- destroy: () => void;
36
- };
37
34
  }
@@ -3,7 +3,7 @@ import { propsProxy } from '../session/props.js';
3
3
  const INLINE_EDGE_CARET_THRESHOLD_PX = 4;
4
4
  const isTextPart = (part) => part !== undefined && !(part instanceof InlineBlock);
5
5
  /**
6
- * An id-only inline-atom handle (§2.4 "Handles", R4): atom `id`, shown in
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
8
  * that renders it (a Surface fact).
9
9
  */
@@ -61,6 +61,7 @@ export class InlineBlock {
61
61
  get value() {
62
62
  return { id: this.id, type: this.type, data: { ...this.#item?.data } };
63
63
  }
64
+ /** @internal */
64
65
  attach = (node) => {
65
66
  node.setAttribute('contenteditable', 'false');
66
67
  node.dataset.edytorId = this.id;
@@ -15,8 +15,10 @@ export declare const tagOf: (type: string, kind: BlockDefinition, data: Values)
15
15
  * catalogue kind's tag per preset (a content-less container takes its
16
16
  * default child's tag, one child per text line), a value-less mark's
17
17
  * `tag`, and each record's `parse` hook first (aliases, sanitized values).
18
- * Unknown elements degrade to text runs; whitespace collapses as HTML
19
- * renders it. `null` when the HTML carries nothing (`flow.shape`, F-P10).
18
+ * A void kind with a `parse` hook (an image, an embed, a video) is found
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
21
+ * elements degrade to text runs; whitespace collapses as HTML renders it. `null` when the HTML carries nothing (`flow.shape`, F-P10).
20
22
  */
21
23
  export declare const flowOfHtml: (kinds: ImportKinds, html: string | undefined) => Flow | null;
22
24
  export {};