@prosekit/extensions 0.11.4 → 0.11.6

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 (384) hide show
  1. package/dist/commit/style.css +2 -0
  2. package/dist/commit/style.css.map +1 -0
  3. package/dist/commit/style.js +1 -0
  4. package/dist/drop-indicator-E7nCfdnR.js +58 -0
  5. package/dist/drop-indicator-E7nCfdnR.js.map +1 -0
  6. package/dist/enter-rule-RdhEA900.js +2 -1
  7. package/dist/enter-rule-RdhEA900.js.map +1 -0
  8. package/dist/file-DVUhe5KJ.js +134 -0
  9. package/dist/file-DVUhe5KJ.js.map +1 -0
  10. package/dist/gap-cursor/style.css +2 -0
  11. package/dist/gap-cursor/style.css.map +1 -0
  12. package/dist/gap-cursor/style.js +1 -0
  13. package/dist/index-DY6lIIYV.d.ts +134 -0
  14. package/dist/index-DY6lIIYV.d.ts.map +1 -0
  15. package/dist/{input-rule-Gji4N7Oe.js → input-rule-B17tpW4m.js} +3 -3
  16. package/dist/input-rule-B17tpW4m.js.map +1 -0
  17. package/dist/list/style.css +2 -0
  18. package/dist/list/style.css.map +1 -0
  19. package/dist/list/style.js +1 -0
  20. package/dist/loro/style.css +2 -0
  21. package/dist/loro/style.css.map +1 -0
  22. package/dist/loro/style.js +1 -0
  23. package/dist/{mark-rule-D7zaa32n.js → mark-rule-CGmswjQ_.js} +3 -3
  24. package/dist/mark-rule-CGmswjQ_.js.map +1 -0
  25. package/dist/{paste-rule-Cca3n5TA.js → paste-rule-BIztzELg.js} +5 -15
  26. package/dist/paste-rule-BIztzELg.js.map +1 -0
  27. package/dist/placeholder/style.css +2 -0
  28. package/dist/placeholder/style.css.map +1 -0
  29. package/dist/placeholder/style.js +1 -0
  30. package/dist/prosekit-extensions-autocomplete.d.ts +2 -1
  31. package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -0
  32. package/dist/prosekit-extensions-autocomplete.js +2 -9
  33. package/dist/prosekit-extensions-autocomplete.js.map +1 -0
  34. package/dist/prosekit-extensions-blockquote.d.ts +2 -1
  35. package/dist/prosekit-extensions-blockquote.d.ts.map +1 -0
  36. package/dist/prosekit-extensions-blockquote.js +4 -4
  37. package/dist/prosekit-extensions-blockquote.js.map +1 -0
  38. package/dist/prosekit-extensions-bold.d.ts +2 -1
  39. package/dist/prosekit-extensions-bold.d.ts.map +1 -0
  40. package/dist/prosekit-extensions-bold.js +3 -2
  41. package/dist/prosekit-extensions-bold.js.map +1 -0
  42. package/dist/prosekit-extensions-code-block.d.ts +3 -2
  43. package/dist/prosekit-extensions-code-block.d.ts.map +1 -0
  44. package/dist/prosekit-extensions-code-block.js +5 -6
  45. package/dist/prosekit-extensions-code-block.js.map +1 -0
  46. package/dist/prosekit-extensions-code.d.ts +2 -1
  47. package/dist/prosekit-extensions-code.d.ts.map +1 -0
  48. package/dist/prosekit-extensions-code.js +3 -2
  49. package/dist/prosekit-extensions-code.js.map +1 -0
  50. package/dist/prosekit-extensions-commit.d.ts +2 -1
  51. package/dist/prosekit-extensions-commit.d.ts.map +1 -0
  52. package/dist/prosekit-extensions-commit.js +11 -13
  53. package/dist/prosekit-extensions-commit.js.map +1 -0
  54. package/dist/prosekit-extensions-doc.d.ts +2 -1
  55. package/dist/prosekit-extensions-doc.d.ts.map +1 -0
  56. package/dist/prosekit-extensions-doc.js +2 -1
  57. package/dist/prosekit-extensions-doc.js.map +1 -0
  58. package/dist/prosekit-extensions-drop-cursor.d.ts +2 -1
  59. package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -0
  60. package/dist/prosekit-extensions-drop-cursor.js +2 -1
  61. package/dist/prosekit-extensions-drop-cursor.js.map +1 -0
  62. package/dist/prosekit-extensions-drop-indicator.d.ts +5 -107
  63. package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -0
  64. package/dist/prosekit-extensions-drop-indicator.js +1 -1
  65. package/dist/prosekit-extensions-enter-rule.d.ts +2 -1
  66. package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -0
  67. package/dist/prosekit-extensions-file.d.ts +2 -125
  68. package/dist/prosekit-extensions-file.js +1 -139
  69. package/dist/prosekit-extensions-gap-cursor.d.ts +2 -2
  70. package/dist/prosekit-extensions-gap-cursor.d.ts.map +1 -0
  71. package/dist/prosekit-extensions-gap-cursor.js +2 -1
  72. package/dist/prosekit-extensions-gap-cursor.js.map +1 -0
  73. package/dist/prosekit-extensions-hard-break.d.ts +2 -5
  74. package/dist/prosekit-extensions-hard-break.d.ts.map +1 -0
  75. package/dist/prosekit-extensions-hard-break.js +2 -1
  76. package/dist/prosekit-extensions-hard-break.js.map +1 -0
  77. package/dist/prosekit-extensions-heading.d.ts +2 -1
  78. package/dist/prosekit-extensions-heading.d.ts.map +1 -0
  79. package/dist/prosekit-extensions-heading.js +5 -6
  80. package/dist/prosekit-extensions-heading.js.map +1 -0
  81. package/dist/prosekit-extensions-horizontal-rule.d.ts +2 -1
  82. package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -0
  83. package/dist/prosekit-extensions-horizontal-rule.js +5 -6
  84. package/dist/prosekit-extensions-horizontal-rule.js.map +1 -0
  85. package/dist/prosekit-extensions-image.d.ts +80 -3
  86. package/dist/prosekit-extensions-image.d.ts.map +1 -0
  87. package/dist/prosekit-extensions-image.js +90 -10
  88. package/dist/prosekit-extensions-image.js.map +1 -0
  89. package/dist/prosekit-extensions-input-rule.d.ts +2 -1
  90. package/dist/prosekit-extensions-input-rule.d.ts.map +1 -0
  91. package/dist/prosekit-extensions-input-rule.js +1 -1
  92. package/dist/prosekit-extensions-italic.d.ts +2 -1
  93. package/dist/prosekit-extensions-italic.d.ts.map +1 -0
  94. package/dist/prosekit-extensions-italic.js +3 -2
  95. package/dist/prosekit-extensions-italic.js.map +1 -0
  96. package/dist/prosekit-extensions-link.d.ts +2 -1
  97. package/dist/prosekit-extensions-link.d.ts.map +1 -0
  98. package/dist/prosekit-extensions-link.js +6 -5
  99. package/dist/prosekit-extensions-link.js.map +1 -0
  100. package/dist/prosekit-extensions-list.d.ts +22 -21
  101. package/dist/prosekit-extensions-list.d.ts.map +1 -0
  102. package/dist/prosekit-extensions-list.js +7 -8
  103. package/dist/prosekit-extensions-list.js.map +1 -0
  104. package/dist/prosekit-extensions-loro.d.ts +14 -13
  105. package/dist/prosekit-extensions-loro.d.ts.map +1 -0
  106. package/dist/prosekit-extensions-loro.js +2 -1
  107. package/dist/prosekit-extensions-loro.js.map +1 -0
  108. package/dist/prosekit-extensions-mark-rule.d.ts +2 -1
  109. package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -0
  110. package/dist/prosekit-extensions-mark-rule.js +1 -1
  111. package/dist/prosekit-extensions-mention.d.ts +2 -1
  112. package/dist/prosekit-extensions-mention.d.ts.map +1 -0
  113. package/dist/prosekit-extensions-mention.js +2 -1
  114. package/dist/prosekit-extensions-mention.js.map +1 -0
  115. package/dist/prosekit-extensions-mod-click-prevention.d.ts +2 -1
  116. package/dist/prosekit-extensions-mod-click-prevention.d.ts.map +1 -0
  117. package/dist/prosekit-extensions-mod-click-prevention.js +2 -1
  118. package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -0
  119. package/dist/prosekit-extensions-paragraph.d.ts +2 -5
  120. package/dist/prosekit-extensions-paragraph.d.ts.map +1 -0
  121. package/dist/prosekit-extensions-paragraph.js +2 -1
  122. package/dist/prosekit-extensions-paragraph.js.map +1 -0
  123. package/dist/prosekit-extensions-paste-rule.d.ts +2 -1
  124. package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -0
  125. package/dist/prosekit-extensions-paste-rule.js +1 -1
  126. package/dist/prosekit-extensions-placeholder.d.ts +2 -1
  127. package/dist/prosekit-extensions-placeholder.d.ts.map +1 -0
  128. package/dist/prosekit-extensions-placeholder.js +5 -5
  129. package/dist/prosekit-extensions-placeholder.js.map +1 -0
  130. package/dist/prosekit-extensions-readonly.d.ts +2 -1
  131. package/dist/prosekit-extensions-readonly.d.ts.map +1 -0
  132. package/dist/prosekit-extensions-readonly.js +2 -1
  133. package/dist/prosekit-extensions-readonly.js.map +1 -0
  134. package/dist/prosekit-extensions-search.d.ts +2 -1
  135. package/dist/prosekit-extensions-search.d.ts.map +1 -0
  136. package/dist/prosekit-extensions-search.js +3 -3
  137. package/dist/prosekit-extensions-search.js.map +1 -0
  138. package/dist/prosekit-extensions-strike.d.ts +2 -1
  139. package/dist/prosekit-extensions-strike.d.ts.map +1 -0
  140. package/dist/prosekit-extensions-strike.js +3 -2
  141. package/dist/prosekit-extensions-strike.js.map +1 -0
  142. package/dist/prosekit-extensions-table.d.ts +47 -114
  143. package/dist/prosekit-extensions-table.d.ts.map +1 -0
  144. package/dist/prosekit-extensions-table.js +2 -2
  145. package/dist/prosekit-extensions-text-align.d.ts +2 -1
  146. package/dist/prosekit-extensions-text-align.d.ts.map +1 -0
  147. package/dist/prosekit-extensions-text-align.js +2 -1
  148. package/dist/prosekit-extensions-text-align.js.map +1 -0
  149. package/dist/prosekit-extensions-text.d.ts +2 -1
  150. package/dist/prosekit-extensions-text.d.ts.map +1 -0
  151. package/dist/prosekit-extensions-text.js +2 -1
  152. package/dist/prosekit-extensions-text.js.map +1 -0
  153. package/dist/prosekit-extensions-underline.d.ts +2 -1
  154. package/dist/prosekit-extensions-underline.d.ts.map +1 -0
  155. package/dist/prosekit-extensions-underline.js +2 -1
  156. package/dist/prosekit-extensions-underline.js.map +1 -0
  157. package/dist/prosekit-extensions-virtual-selection.d.ts +2 -1
  158. package/dist/prosekit-extensions-virtual-selection.d.ts.map +1 -0
  159. package/dist/prosekit-extensions-virtual-selection.js +3 -3
  160. package/dist/prosekit-extensions-virtual-selection.js.map +1 -0
  161. package/dist/prosekit-extensions-yjs.d.ts +2 -1
  162. package/dist/prosekit-extensions-yjs.d.ts.map +1 -0
  163. package/dist/prosekit-extensions-yjs.js +2 -1
  164. package/dist/prosekit-extensions-yjs.js.map +1 -0
  165. package/dist/prosekit-extensions.js +1 -0
  166. package/dist/search/style.css +2 -0
  167. package/dist/search/style.css.map +1 -0
  168. package/dist/search/style.js +1 -0
  169. package/dist/{shiki-highlighter-chunk-DSPM0T27.d.ts → shiki-highlighter-chunk-Cwu1Jr9o.d.ts} +2 -1
  170. package/dist/shiki-highlighter-chunk-Cwu1Jr9o.d.ts.map +1 -0
  171. package/dist/shiki-highlighter-chunk.d.ts +1 -1
  172. package/dist/shiki-highlighter-chunk.js +3 -5
  173. package/dist/shiki-highlighter-chunk.js.map +1 -0
  174. package/dist/table/style.css +2 -0
  175. package/dist/table/style.css.map +1 -0
  176. package/dist/table/style.js +1 -0
  177. package/dist/table-BNwuK7xg.js +297 -0
  178. package/dist/table-BNwuK7xg.js.map +1 -0
  179. package/dist/virtual-selection/style.css +2 -0
  180. package/dist/virtual-selection/style.css.map +1 -0
  181. package/dist/virtual-selection/style.js +1 -0
  182. package/dist/yjs/style.css +2 -0
  183. package/dist/yjs/style.css.map +1 -0
  184. package/dist/yjs/style.js +1 -0
  185. package/package.json +12 -10
  186. package/src/autocomplete/autocomplete-helpers.ts +74 -0
  187. package/src/autocomplete/autocomplete-plugin.ts +186 -0
  188. package/src/autocomplete/autocomplete-rule.ts +117 -0
  189. package/src/autocomplete/autocomplete.spec.ts +132 -0
  190. package/src/autocomplete/autocomplete.ts +29 -0
  191. package/src/autocomplete/index.ts +9 -0
  192. package/src/blockquote/blockquote-commands.ts +32 -0
  193. package/src/blockquote/blockquote-input-rule.ts +14 -0
  194. package/src/blockquote/blockquote-keymap.spec.ts +45 -0
  195. package/src/blockquote/blockquote-keymap.ts +31 -0
  196. package/src/blockquote/blockquote-spec.ts +24 -0
  197. package/src/blockquote/blockquote.ts +34 -0
  198. package/src/blockquote/index.ts +14 -0
  199. package/src/bold/bold-commands.ts +23 -0
  200. package/src/bold/bold-input-rule.spec.ts +51 -0
  201. package/src/bold/bold-input-rule.ts +18 -0
  202. package/src/bold/bold-keymap.ts +14 -0
  203. package/src/bold/bold-spec.ts +53 -0
  204. package/src/bold/bold.ts +32 -0
  205. package/src/bold/index.ts +14 -0
  206. package/src/code/code-commands.ts +23 -0
  207. package/src/code/code-input-rule.ts +18 -0
  208. package/src/code/code-keymap.ts +14 -0
  209. package/src/code/code-spec.ts +28 -0
  210. package/src/code/code.ts +32 -0
  211. package/src/code/index.ts +14 -0
  212. package/src/code-block/code-block-commands.ts +44 -0
  213. package/src/code-block/code-block-highlight.ts +40 -0
  214. package/src/code-block/code-block-input-rule.ts +36 -0
  215. package/src/code-block/code-block-keymap.ts +61 -0
  216. package/src/code-block/code-block-shiki.ts +58 -0
  217. package/src/code-block/code-block-spec.spec.ts +164 -0
  218. package/src/code-block/code-block-spec.ts +71 -0
  219. package/src/code-block/code-block-types.ts +8 -0
  220. package/src/code-block/code-block.ts +46 -0
  221. package/src/code-block/index.ts +32 -0
  222. package/src/code-block/shiki-bundle.ts +8 -0
  223. package/src/code-block/shiki-highlighter-chunk.ts +84 -0
  224. package/src/code-block/shiki-highlighter.ts +22 -0
  225. package/src/code-block/shiki-parser.ts +36 -0
  226. package/src/commit/index.ts +330 -0
  227. package/src/commit/style.css +7 -0
  228. package/src/doc/index.ts +21 -0
  229. package/src/drop-cursor/drop-cursor.ts +46 -0
  230. package/src/drop-cursor/index.ts +5 -0
  231. package/src/drop-indicator/drop-indicator-facet.ts +62 -0
  232. package/src/drop-indicator/drop-indicator.ts +35 -0
  233. package/src/drop-indicator/index.ts +14 -0
  234. package/src/enter-rule/index.ts +241 -0
  235. package/src/file/file-drop-handler.ts +75 -0
  236. package/src/file/file-paste-handler.spec.ts +95 -0
  237. package/src/file/file-paste-handler.ts +59 -0
  238. package/src/file/file-upload.ts +140 -0
  239. package/src/file/helpers.ts +39 -0
  240. package/src/file/index.ts +16 -0
  241. package/src/gap-cursor/gap-cursor.ts +28 -0
  242. package/src/gap-cursor/index.ts +4 -0
  243. package/src/gap-cursor/style.css +25 -0
  244. package/src/hard-break/hard-break-commands.ts +31 -0
  245. package/src/hard-break/hard-break-keymap.spec.ts +45 -0
  246. package/src/hard-break/hard-break-keymap.ts +16 -0
  247. package/src/hard-break/hard-break-spec.ts +31 -0
  248. package/src/hard-break/hard-break.ts +32 -0
  249. package/src/hard-break/index.ts +13 -0
  250. package/src/heading/heading-commands.ts +37 -0
  251. package/src/heading/heading-input-rule.ts +22 -0
  252. package/src/heading/heading-keymap.spec.ts +53 -0
  253. package/src/heading/heading-keymap.ts +40 -0
  254. package/src/heading/heading-spec.ts +39 -0
  255. package/src/heading/heading-types.ts +3 -0
  256. package/src/heading/heading.ts +34 -0
  257. package/src/heading/index.ts +15 -0
  258. package/src/horizontal-rule/horizontal-rule-commands.spec.ts +61 -0
  259. package/src/horizontal-rule/horizontal-rule-commands.ts +37 -0
  260. package/src/horizontal-rule/horizontal-rule-input-rule.spec.ts +61 -0
  261. package/src/horizontal-rule/horizontal-rule-input-rule.ts +26 -0
  262. package/src/horizontal-rule/horizontal-rule-spec.ts +21 -0
  263. package/src/horizontal-rule/horizontal-rule.ts +29 -0
  264. package/src/horizontal-rule/index.ts +14 -0
  265. package/src/image/image-commands.ts +36 -0
  266. package/src/image/image-spec.ts +72 -0
  267. package/src/image/image-upload-handler.ts +156 -0
  268. package/src/image/image.ts +25 -0
  269. package/src/image/index.ts +22 -0
  270. package/src/index.ts +1 -0
  271. package/src/input-rule/index.ts +237 -0
  272. package/src/italic/index.ts +14 -0
  273. package/src/italic/italic-commands.spec.ts +75 -0
  274. package/src/italic/italic-commands.ts +23 -0
  275. package/src/italic/italic-input-rule.spec.ts +25 -0
  276. package/src/italic/italic-input-rule.ts +18 -0
  277. package/src/italic/italic-keymap.ts +14 -0
  278. package/src/italic/italic-spec.ts +35 -0
  279. package/src/italic/italic.ts +34 -0
  280. package/src/link/index.spec.ts +88 -0
  281. package/src/link/index.ts +156 -0
  282. package/src/link/link-paste-rule.spec.ts +194 -0
  283. package/src/link/link-paste-rule.ts +22 -0
  284. package/src/link/link-regex.spec.ts +82 -0
  285. package/src/link/link-regex.ts +79 -0
  286. package/src/link/link-types.ts +8 -0
  287. package/src/list/index.ts +25 -0
  288. package/src/list/list-commands.ts +61 -0
  289. package/src/list/list-drop-indicator.ts +37 -0
  290. package/src/list/list-input-rules.ts +14 -0
  291. package/src/list/list-keymap.spec.ts +39 -0
  292. package/src/list/list-keymap.ts +48 -0
  293. package/src/list/list-plugins.ts +35 -0
  294. package/src/list/list-serializer.ts +38 -0
  295. package/src/list/list-spec.ts +60 -0
  296. package/src/list/list-types.spec.ts +10 -0
  297. package/src/list/list-types.ts +23 -0
  298. package/src/list/list.spec.ts +134 -0
  299. package/src/list/list.ts +38 -0
  300. package/src/list/style.css +128 -0
  301. package/src/loro/index.ts +17 -0
  302. package/src/loro/loro-commands.ts +27 -0
  303. package/src/loro/loro-cursor-plugin.ts +28 -0
  304. package/src/loro/loro-keymap.ts +23 -0
  305. package/src/loro/loro-sync-plugin.ts +14 -0
  306. package/src/loro/loro-undo-plugin.ts +12 -0
  307. package/src/loro/loro.ts +75 -0
  308. package/src/loro/style.css +33 -0
  309. package/src/mark-rule/apply.ts +129 -0
  310. package/src/mark-rule/index.ts +2 -0
  311. package/src/mark-rule/mark-rule.spec.ts +123 -0
  312. package/src/mark-rule/mark-rule.ts +48 -0
  313. package/src/mark-rule/range.ts +107 -0
  314. package/src/mark-rule/types.ts +30 -0
  315. package/src/mention/index.ts +90 -0
  316. package/src/mod-click-prevention/index.ts +35 -0
  317. package/src/paragraph/index.ts +7 -0
  318. package/src/paragraph/paragraph-commands.ts +29 -0
  319. package/src/paragraph/paragraph-keymap.ts +15 -0
  320. package/src/paragraph/paragraph-spec.ts +31 -0
  321. package/src/paragraph/paragraph.ts +37 -0
  322. package/src/paste-rule/index.ts +10 -0
  323. package/src/paste-rule/mark-paste-rule.spec.ts +112 -0
  324. package/src/paste-rule/mark-paste-rule.ts +194 -0
  325. package/src/paste-rule/paste-rule-plugin.ts +53 -0
  326. package/src/paste-rule/paste-rule.spec.ts +96 -0
  327. package/src/paste-rule/paste-rule.ts +60 -0
  328. package/src/paste-rule/split-text-by-regex.spec.ts +97 -0
  329. package/src/paste-rule/split-text-by-regex.ts +44 -0
  330. package/src/placeholder/index.ts +113 -0
  331. package/src/placeholder/style.css +7 -0
  332. package/src/readonly/index.ts +22 -0
  333. package/src/search/index.ts +140 -0
  334. package/src/search/style.css +13 -0
  335. package/src/strike/index.ts +101 -0
  336. package/src/table/index.ts +53 -0
  337. package/src/table/style.css +42 -0
  338. package/src/table/table-commands/delete-cell-selection.spec.ts +41 -0
  339. package/src/table/table-commands/delete-cell-selection.ts +1 -0
  340. package/src/table/table-commands/exit-table.spec.ts +45 -0
  341. package/src/table/table-commands/exit-table.ts +49 -0
  342. package/src/table/table-commands/insert-table.spec.ts +39 -0
  343. package/src/table/table-commands/insert-table.ts +80 -0
  344. package/src/table/table-commands/move-table-column.spec.ts +618 -0
  345. package/src/table/table-commands/move-table-column.ts +4 -0
  346. package/src/table/table-commands/move-table-row.spec.ts +380 -0
  347. package/src/table/table-commands/move-table-row.ts +4 -0
  348. package/src/table/table-commands/select-table-cell.spec.ts +34 -0
  349. package/src/table/table-commands/select-table-cell.ts +35 -0
  350. package/src/table/table-commands/select-table-column.spec.ts +33 -0
  351. package/src/table/table-commands/select-table-column.ts +39 -0
  352. package/src/table/table-commands/select-table-row.spec.ts +32 -0
  353. package/src/table/table-commands/select-table-row.ts +39 -0
  354. package/src/table/table-commands/select-table.spec.ts +36 -0
  355. package/src/table/table-commands/select-table.ts +50 -0
  356. package/src/table/table-commands.ts +110 -0
  357. package/src/table/table-drop-indicator.ts +40 -0
  358. package/src/table/table-plugins.ts +15 -0
  359. package/src/table/table-spec.spec.ts +113 -0
  360. package/src/table/table-spec.ts +109 -0
  361. package/src/table/table-utils.ts +16 -0
  362. package/src/table/table.ts +49 -0
  363. package/src/table/test-utils.ts +28 -0
  364. package/src/testing/clipboard.ts +58 -0
  365. package/src/testing/format-html.ts +5 -0
  366. package/src/testing/index.ts +161 -0
  367. package/src/testing/keyboard.ts +36 -0
  368. package/src/testing/markdown.ts +23 -0
  369. package/src/text/index.ts +24 -0
  370. package/src/text-align/index.ts +133 -0
  371. package/src/types/assert-type-equal.ts +8 -0
  372. package/src/underline/index.ts +83 -0
  373. package/src/virtual-selection/index.ts +100 -0
  374. package/src/virtual-selection/style.css +5 -0
  375. package/src/yjs/index.ts +22 -0
  376. package/src/yjs/style.css +31 -0
  377. package/src/yjs/yjs-commands.ts +27 -0
  378. package/src/yjs/yjs-cursor-plugin.ts +25 -0
  379. package/src/yjs/yjs-keymap.ts +23 -0
  380. package/src/yjs/yjs-sync-plugin.ts +23 -0
  381. package/src/yjs/yjs-undo-plugin.ts +87 -0
  382. package/src/yjs/yjs.ts +84 -0
  383. package/dist/drop-indicator-dB9rZn8e.js +0 -267
  384. package/dist/table-CPI9ZxbK.js +0 -760
@@ -0,0 +1,53 @@
1
+ import {
2
+ defineFacet,
3
+ defineFacetPayload,
4
+ pluginFacet,
5
+ type PlainExtension,
6
+ type PluginPayload,
7
+ } from '@prosekit/core'
8
+ import type { Slice } from '@prosekit/pm/model'
9
+ import {
10
+ PluginKey,
11
+ ProseMirrorPlugin,
12
+ } from '@prosekit/pm/state'
13
+ import type { EditorView } from '@prosekit/pm/view'
14
+
15
+ type PasteRulePayload = (options: { slice: Slice; view: EditorView; plain: boolean }) => Slice
16
+
17
+ /**
18
+ * @internal
19
+ */
20
+ const pasteRuleFacet = defineFacet<PasteRulePayload, PluginPayload>({
21
+ reduce: () => {
22
+ let handlers: PasteRulePayload[] = []
23
+
24
+ const transformPasted = (slice: Slice, view: EditorView, plain: boolean): Slice => {
25
+ for (const handler of handlers) {
26
+ slice = handler({ slice, view, plain })
27
+ }
28
+ return slice
29
+ }
30
+
31
+ const plugin = new ProseMirrorPlugin({
32
+ key: new PluginKey('prosekit-paste-rule'),
33
+ props: {
34
+ transformPasted,
35
+ },
36
+ })
37
+
38
+ return (inputs: PasteRulePayload[]) => {
39
+ // Last added rule (highest priority) is applied first
40
+ handlers = [...inputs].reverse()
41
+ return plugin
42
+ }
43
+ },
44
+ singleton: true,
45
+ parent: pluginFacet,
46
+ })
47
+
48
+ /**
49
+ * @internal
50
+ */
51
+ export function definePasteRulePlugin(payload: PasteRulePayload): PlainExtension {
52
+ return defineFacetPayload(pasteRuleFacet, [payload]) as PlainExtension
53
+ }
@@ -0,0 +1,96 @@
1
+ import {
2
+ Priority,
3
+ union,
4
+ withPriority,
5
+ type PlainExtension,
6
+ } from '@prosekit/core'
7
+ import type { ProseMirrorNode } from '@prosekit/pm/model'
8
+ import {
9
+ Fragment,
10
+ Slice,
11
+ } from '@prosekit/pm/model'
12
+ import {
13
+ describe,
14
+ expect,
15
+ it,
16
+ } from 'vitest'
17
+
18
+ import {
19
+ defineTestExtension,
20
+ setupTestFromExtension,
21
+ } from '../testing'
22
+
23
+ import { definePasteRule } from './paste-rule'
24
+
25
+ function replaceTextInSlice(slice: Slice, from: string, to: string): Slice {
26
+ return new Slice(
27
+ replaceTextInFragment(slice.content, from, to),
28
+ slice.openStart,
29
+ slice.openEnd,
30
+ )
31
+ }
32
+
33
+ function replaceTextInFragment(fragment: Fragment, from: string, to: string): Fragment {
34
+ return Fragment.fromArray(fragment.content.map(node => replaceTextInNode(node, from, to)))
35
+ }
36
+
37
+ function replaceTextInNode(node: ProseMirrorNode, from: string, to: string): ProseMirrorNode {
38
+ const text = node.text
39
+ if (text != null) {
40
+ return node.type.schema.text(text.replaceAll(from, to))
41
+ }
42
+ return node.copy(replaceTextInFragment(node.content, from, to))
43
+ }
44
+
45
+ function defineTextReplacePasteRule(from: string, to: string): PlainExtension {
46
+ return definePasteRule({
47
+ handler: ({ slice }) => {
48
+ return replaceTextInSlice(slice, from, to)
49
+ },
50
+ })
51
+ }
52
+
53
+ describe('paste rule', () => {
54
+ it('can transform pasted HTML', () => {
55
+ const extension = union(
56
+ defineTestExtension(),
57
+ defineTextReplacePasteRule('Foo', 'Bar'),
58
+ )
59
+ const { editor } = setupTestFromExtension(extension)
60
+ editor.view.pasteHTML('<div>Foo</div>')
61
+ expect(editor.getDocHTML()).not.toContain(`Foo`)
62
+ expect(editor.getDocHTML()).toContain(`Bar`)
63
+ })
64
+
65
+ it('can transform pasted text', () => {
66
+ const extension = union(
67
+ defineTestExtension(),
68
+ defineTextReplacePasteRule('Foo', 'Bar'),
69
+ )
70
+ const { editor } = setupTestFromExtension(extension)
71
+ editor.view.pasteText('Foo')
72
+ expect(editor.getDocHTML()).not.toContain(`Foo`)
73
+ expect(editor.getDocHTML()).toContain(`Bar`)
74
+ })
75
+
76
+ it('can order multiple paste rules', () => {
77
+ const extension = union(
78
+ defineTestExtension(),
79
+ withPriority(defineTextReplacePasteRule('Foo', 'Bar'), Priority.high),
80
+ withPriority(defineTextReplacePasteRule('Foo', 'Baz'), Priority.low),
81
+ )
82
+ const { editor } = setupTestFromExtension(extension)
83
+ editor.view.pasteText('Foo')
84
+ expect(editor.getDocHTML()).not.toContain(`Foo`)
85
+ expect(editor.getDocHTML()).toContain(`Bar`)
86
+ expect(editor.getDocHTML()).not.toContain(`Baz`)
87
+
88
+ editor.use(defineTextReplacePasteRule('Bar', 'Qux'))
89
+ editor.setContent('')
90
+ editor.view.pasteText('Foo')
91
+ expect(editor.getDocHTML()).not.toContain(`Foo`)
92
+ expect(editor.getDocHTML()).not.toContain(`Bar`)
93
+ expect(editor.getDocHTML()).not.toContain(`Baz`)
94
+ expect(editor.getDocHTML()).toContain(`Qux`)
95
+ })
96
+ })
@@ -0,0 +1,60 @@
1
+ import type { PlainExtension } from '@prosekit/core'
2
+ import type { Slice } from '@prosekit/pm/model'
3
+ import type { EditorView } from '@prosekit/pm/view'
4
+
5
+ import { definePasteRulePlugin } from './paste-rule-plugin'
6
+
7
+ /**
8
+ * @public
9
+ *
10
+ * Options for {@link PasteRuleHandler}.
11
+ */
12
+ export interface PasteRuleHandlerOptions {
13
+ /**
14
+ * The slice to be pasted.
15
+ */
16
+ slice: Slice
17
+
18
+ /**
19
+ * The editor view.
20
+ */
21
+ view: EditorView
22
+
23
+ /**
24
+ * Whether the pasted content is treated as plain text. This is true when the
25
+ * `Shift` key is held when pasting.
26
+ */
27
+ plain: boolean
28
+ }
29
+
30
+ /**
31
+ * @public
32
+ *
33
+ * Can be used to transform pasted or dragged-and-dropped content before it is
34
+ * applied to the document.
35
+ */
36
+ export type PasteRuleHandler = (options: PasteRuleHandlerOptions) => Slice
37
+
38
+ /**
39
+ * Options for {@link definePasteRule}.
40
+ *
41
+ * @public
42
+ */
43
+ export interface PasteRuleOptions {
44
+ /**
45
+ * A function to be called when a paste rule is triggered.
46
+ */
47
+ handler: PasteRuleHandler
48
+ }
49
+
50
+ /**
51
+ * Defines a paste rule. This rule allows you to modify pasted or dragged
52
+ * content before it is inserted into the document.
53
+ *
54
+ * @param options
55
+ *
56
+ * @public
57
+ */
58
+ export function definePasteRule({ handler }: PasteRuleOptions): PlainExtension {
59
+ return definePasteRulePlugin(handler)
60
+ }
@@ -0,0 +1,97 @@
1
+ import {
2
+ describe,
3
+ expect,
4
+ it,
5
+ } from 'vitest'
6
+
7
+ import { splitTextByRegex } from './split-text-by-regex'
8
+
9
+ describe('splitTextByRegex', () => {
10
+ it('should return undefined when no matches are found', () => {
11
+ const result = splitTextByRegex('hello world', /\d+/g)
12
+ expect(result).toBeUndefined()
13
+ })
14
+
15
+ it('should split text with single match', () => {
16
+ const result = splitTextByRegex('hello 123 world', /\d+/g)
17
+ expect(result).toEqual([
18
+ ['hello ', undefined],
19
+ ['123', expect.objectContaining({ 0: '123', index: 6 })],
20
+ [' world', undefined],
21
+ ])
22
+ })
23
+
24
+ it('should split text with multiple matches', () => {
25
+ const result = splitTextByRegex('abc 123 def 456 ghi', /\d+/g)
26
+ expect(result).toEqual([
27
+ ['abc ', undefined],
28
+ ['123', expect.objectContaining({ 0: '123', index: 4 })],
29
+ [' def ', undefined],
30
+ ['456', expect.objectContaining({ 0: '456', index: 12 })],
31
+ [' ghi', undefined],
32
+ ])
33
+ })
34
+
35
+ it('should handle match at the beginning', () => {
36
+ const result = splitTextByRegex('123 hello', /\d+/g)
37
+ expect(result).toEqual([
38
+ ['123', expect.objectContaining({ 0: '123', index: 0 })],
39
+ [' hello', undefined],
40
+ ])
41
+ })
42
+
43
+ it('should handle match at the end', () => {
44
+ const result = splitTextByRegex('hello 123', /\d+/g)
45
+ expect(result).toEqual([
46
+ ['hello ', undefined],
47
+ ['123', expect.objectContaining({ 0: '123', index: 6 })],
48
+ ])
49
+ })
50
+
51
+ it('should handle consecutive matches', () => {
52
+ const result = splitTextByRegex('123456', /\d/g)
53
+ expect(result).toEqual([
54
+ ['1', expect.objectContaining({ 0: '1', index: 0 })],
55
+ ['2', expect.objectContaining({ 0: '2', index: 1 })],
56
+ ['3', expect.objectContaining({ 0: '3', index: 2 })],
57
+ ['4', expect.objectContaining({ 0: '4', index: 3 })],
58
+ ['5', expect.objectContaining({ 0: '5', index: 4 })],
59
+ ['6', expect.objectContaining({ 0: '6', index: 5 })],
60
+ ])
61
+ })
62
+
63
+ it('should handle entire string match', () => {
64
+ const result = splitTextByRegex('123', /\d+/g)
65
+ expect(result).toEqual([
66
+ ['123', expect.objectContaining({ 0: '123', index: 0 })],
67
+ ])
68
+ })
69
+
70
+ it('should work with URL regex', () => {
71
+ const urlRegex = /https?:\/\/\S+/g
72
+ const result = splitTextByRegex('Visit https://example.com for more info', urlRegex)
73
+ expect(result).toEqual([
74
+ ['Visit ', undefined],
75
+ ['https://example.com', expect.objectContaining({ 0: 'https://example.com', index: 6 })],
76
+ [' for more info', undefined],
77
+ ])
78
+ })
79
+
80
+ it('should reset regex lastIndex', () => {
81
+ const regex = /\d+/g
82
+ regex.lastIndex = 5 // Set to non-zero
83
+ const result = splitTextByRegex('123 456', regex)
84
+ expect(result).toEqual([
85
+ ['123', expect.objectContaining({ 0: '123', index: 0 })],
86
+ [' ', undefined],
87
+ ['456', expect.objectContaining({ 0: '456', index: 4 })],
88
+ ])
89
+ expect(regex.lastIndex).toBe(0) // Should be reset
90
+ })
91
+
92
+ it('should return undefined for zero-width matches', () => {
93
+ const regex = /(?=b)/g
94
+ const result = splitTextByRegex('abc', regex)
95
+ expect(result).toBeUndefined()
96
+ })
97
+ })
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Splits text into chunks based on regex matches, preserving both matched and unmatched segments.
3
+ * Returns an array of tuples where each tuple contains a text segment and either the match data
4
+ * (for matched segments) or undefined (for unmatched segments).
5
+ */
6
+ export function splitTextByRegex(
7
+ text: string,
8
+ regex: RegExp,
9
+ ): Array<[string, RegExpExecArray | undefined]> | undefined {
10
+ regex.lastIndex = 0
11
+
12
+ const chunks: Array<[string, RegExpExecArray | undefined]> = []
13
+ let lastIndex = 0
14
+ let match: RegExpExecArray | null
15
+ let matched = false
16
+
17
+ while ((match = regex.exec(text))) {
18
+ const start = match.index
19
+ const end = regex.lastIndex
20
+
21
+ // Push the unmatched prefix, if any.
22
+ if (start > lastIndex) {
23
+ chunks.push([text.slice(lastIndex, start), undefined])
24
+ }
25
+
26
+ // Push the matched segment.
27
+ chunks.push([text.slice(start, end), match])
28
+ matched = true
29
+
30
+ if (lastIndex === end) {
31
+ // Safeguard against zero-width matches that would otherwise cause an infinite loop.
32
+ return
33
+ }
34
+ lastIndex = end
35
+ }
36
+
37
+ if (matched && lastIndex < text.length) {
38
+ chunks.push([text.slice(lastIndex), undefined])
39
+ }
40
+
41
+ regex.lastIndex = 0
42
+
43
+ return matched ? chunks : undefined
44
+ }
@@ -0,0 +1,113 @@
1
+ import {
2
+ definePlugin,
3
+ isInCodeBlock,
4
+ maybeRun,
5
+ type PlainExtension,
6
+ } from '@prosekit/core'
7
+ import type { ProseMirrorNode } from '@prosekit/pm/model'
8
+ import {
9
+ Plugin,
10
+ PluginKey,
11
+ type EditorState,
12
+ } from '@prosekit/pm/state'
13
+ import {
14
+ Decoration,
15
+ DecorationSet,
16
+ } from '@prosekit/pm/view'
17
+
18
+ import { findTable } from '../table'
19
+
20
+ export interface PlaceholderOptions {
21
+ /**
22
+ * The placeholder to use. It can be a static string or a function that
23
+ * receives the current editor state and returns a string.
24
+ */
25
+ placeholder: string | ((state: EditorState) => string)
26
+
27
+ /**
28
+ * By default, the placeholder text will be shown whenever the current text
29
+ * cursor is in an empty text node and it's not inside a code block or a
30
+ * table node.
31
+ *
32
+ * If you only want to show the placeholder when the whole doc is empty, you
33
+ * can set this option to 'doc'.
34
+ *
35
+ * You can also pass a function that receives the current editor state and
36
+ * returns a boolean value to determine whether the placeholder should be
37
+ * shown.
38
+ *
39
+ * @default 'block'
40
+ */
41
+ strategy?: 'doc' | 'block' | ((state: EditorState) => boolean)
42
+ }
43
+
44
+ /**
45
+ * Add a placeholder text to the editor when the current block or document is
46
+ * empty.
47
+ */
48
+ export function definePlaceholder(options: PlaceholderOptions): PlainExtension {
49
+ return definePlugin(createPlaceholderPlugin(options))
50
+ }
51
+
52
+ function createPlaceholderPlugin({
53
+ placeholder,
54
+ strategy = 'block',
55
+ }: PlaceholderOptions): Plugin {
56
+ return new Plugin({
57
+ key: new PluginKey('prosekit-placeholder'),
58
+ props: {
59
+ decorations: (state) => {
60
+ const strategyFn = typeof strategy === 'function'
61
+ ? strategy
62
+ : strategy === 'doc'
63
+ ? docStrategy
64
+ : defaultStrategy
65
+
66
+ if (!strategyFn(state)) {
67
+ return null
68
+ }
69
+
70
+ const placeholderText: string = maybeRun(placeholder, state)
71
+ const deco = createPlaceholderDecoration(state, placeholderText)
72
+ if (!deco) {
73
+ return null
74
+ }
75
+
76
+ return DecorationSet.create(state.doc, [deco])
77
+ },
78
+ },
79
+ })
80
+ }
81
+
82
+ function defaultStrategy(state: EditorState): boolean {
83
+ return !isInCodeBlock(state.selection) && !findTable(state.selection.$from)
84
+ }
85
+
86
+ function docStrategy(state: EditorState): boolean {
87
+ return isDocEmpty(state.doc) && defaultStrategy(state)
88
+ }
89
+
90
+ function isDocEmpty(doc: ProseMirrorNode) {
91
+ return doc.childCount <= 1 && !doc.firstChild?.content.size
92
+ }
93
+
94
+ function createPlaceholderDecoration(
95
+ state: EditorState,
96
+ placeholderText: string,
97
+ ): Decoration | null {
98
+ if (!placeholderText) return null
99
+
100
+ const { selection } = state
101
+ if (!selection.empty) return null
102
+
103
+ const $pos = selection.$anchor
104
+ const node = $pos.parent
105
+ if (node.content.size > 0) return null
106
+
107
+ const before = $pos.before()
108
+
109
+ return Decoration.node(before, before + node.nodeSize, {
110
+ 'class': 'prosekit-placeholder',
111
+ 'data-placeholder': placeholderText,
112
+ })
113
+ }
@@ -0,0 +1,7 @@
1
+ .prosekit-placeholder::before {
2
+ position: absolute;
3
+ height: 0;
4
+ content: attr(data-placeholder);
5
+ opacity: 30%;
6
+ pointer-events: none;
7
+ }
@@ -0,0 +1,22 @@
1
+ import {
2
+ definePlugin,
3
+ type PlainExtension,
4
+ } from '@prosekit/core'
5
+ import {
6
+ PluginKey,
7
+ ProseMirrorPlugin,
8
+ } from '@prosekit/pm/state'
9
+
10
+ /**
11
+ * Make the editor read-only.
12
+ */
13
+ export function defineReadonly(): PlainExtension {
14
+ return definePlugin(plugin)
15
+ }
16
+
17
+ const plugin = new ProseMirrorPlugin({
18
+ key: new PluginKey('prosekey-readonly'),
19
+ props: {
20
+ editable: () => false,
21
+ },
22
+ })
@@ -0,0 +1,140 @@
1
+ import {
2
+ defineCommands,
3
+ definePlugin,
4
+ type Extension,
5
+ type PlainExtension,
6
+ } from '@prosekit/core'
7
+ import type { Command } from '@prosekit/pm/state'
8
+ import type { EditorView } from '@prosekit/pm/view'
9
+ import {
10
+ findNext,
11
+ findNextNoWrap,
12
+ findPrev,
13
+ findPrevNoWrap,
14
+ replaceAll,
15
+ replaceCurrent,
16
+ replaceNext,
17
+ replaceNextNoWrap,
18
+ search,
19
+ SearchQuery,
20
+ } from 'prosemirror-search'
21
+
22
+ /**
23
+ * Options for {@link defineSearchQuery}
24
+ *
25
+ * @public
26
+ */
27
+ export interface SearchQueryOptions {
28
+ /**
29
+ * The search string (or regular expression).
30
+ */
31
+ search: string
32
+
33
+ /**
34
+ * The replace text.
35
+ */
36
+ replace?: string
37
+
38
+ /**
39
+ * Indicates whether the search is case-sensitive
40
+ *
41
+ * @default false
42
+ */
43
+ caseSensitive?: boolean
44
+
45
+ /**
46
+ * By default, string search will replace `\n`, `\r`, and `\t` in the query
47
+ * with newline, return, and tab characters. When this is set to true, that
48
+ * behavior is disabled.
49
+ *
50
+ * @default false
51
+ */
52
+ literal?: boolean
53
+
54
+ /**
55
+ * When true, the search string is interpreted as a regular expression.
56
+ *
57
+ * @default false
58
+ */
59
+ regexp?: boolean
60
+
61
+ /**
62
+ * Enable whole-word matching.
63
+ *
64
+ * @default false
65
+ */
66
+ wholeWord?: boolean
67
+ }
68
+
69
+ /**
70
+ * Defines an extension that stores a current search query and replace string.
71
+ *
72
+ * @public
73
+ */
74
+ export function defineSearchQuery(options: SearchQueryOptions): PlainExtension {
75
+ const query = new SearchQuery(options)
76
+ return definePlugin(search({ initialQuery: query }))
77
+ }
78
+
79
+ /**
80
+ * Scrolls the active search match into view.
81
+ */
82
+ function scrollActiveIntoView(view: EditorView) {
83
+ if (view.isDestroyed) return
84
+ const active = view.dom.querySelector('.ProseMirror-active-search-match')
85
+ active?.scrollIntoView({
86
+ block: 'nearest',
87
+ inline: 'nearest',
88
+ behavior: 'smooth',
89
+ })
90
+ }
91
+
92
+ /**
93
+ * Wraps a command and scrolls the active search match into view when the command
94
+ * is applied.
95
+ */
96
+ function withScrollActiveIntoView(command: Command): Command {
97
+ return (state, dispatch, view) => {
98
+ const result = command(state, dispatch, view)
99
+ if (result && dispatch && view) {
100
+ // Add a small delay because the command itself will handle scrolling if
101
+ // the view is focused.
102
+ setTimeout(() => scrollActiveIntoView(view), 50)
103
+ }
104
+ return result
105
+ }
106
+ }
107
+
108
+ /**
109
+ * @internal
110
+ */
111
+ export type SearchCommandsExtension = Extension<{
112
+ Commands: {
113
+ findNext: []
114
+ findPrev: []
115
+ findNextNoWrap: []
116
+ findPrevNoWrap: []
117
+ replaceNext: []
118
+ replaceNextNoWrap: []
119
+ replaceCurrent: []
120
+ replaceAll: []
121
+ }
122
+ }>
123
+
124
+ /**
125
+ * Defines commands for search and replace.
126
+ *
127
+ * @public
128
+ */
129
+ export function defineSearchCommands(): SearchCommandsExtension {
130
+ return defineCommands({
131
+ findNext: () => withScrollActiveIntoView(findNext),
132
+ findPrev: () => withScrollActiveIntoView(findPrev),
133
+ findNextNoWrap: () => withScrollActiveIntoView(findNextNoWrap),
134
+ findPrevNoWrap: () => withScrollActiveIntoView(findPrevNoWrap),
135
+ replaceNext: () => withScrollActiveIntoView(replaceNext),
136
+ replaceNextNoWrap: () => withScrollActiveIntoView(replaceNextNoWrap),
137
+ replaceCurrent: () => withScrollActiveIntoView(replaceCurrent),
138
+ replaceAll: () => withScrollActiveIntoView(replaceAll),
139
+ })
140
+ }
@@ -0,0 +1,13 @@
1
+ .ProseMirror-search-match {
2
+ border-radius: 2px;
3
+ background-color: #ffff0054;
4
+ box-shadow: 0 0 0 2px #ffff0054;
5
+ }
6
+
7
+ .ProseMirror.ProseMirror-focused .ProseMirror-active-search-match::selection,
8
+ .ProseMirror:not(.ProseMirror-focused) .ProseMirror-active-search-match {
9
+ border-radius: 2px;
10
+ background-color: #ff6a0054;
11
+ box-shadow: 0 0 0 2px #ff6a0054;
12
+ scroll-margin: 8px;
13
+ }