@prosekit/extensions 0.11.4 → 0.11.5

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 (383) 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-dB9rZn8e.js → drop-indicator-D1eHOhSi.js} +4 -4
  5. package/dist/drop-indicator-D1eHOhSi.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/gap-cursor/style.css +2 -0
  9. package/dist/gap-cursor/style.css.map +1 -0
  10. package/dist/gap-cursor/style.js +1 -0
  11. package/dist/{input-rule-Gji4N7Oe.js → input-rule-B17tpW4m.js} +3 -3
  12. package/dist/input-rule-B17tpW4m.js.map +1 -0
  13. package/dist/list/style.css +2 -0
  14. package/dist/list/style.css.map +1 -0
  15. package/dist/list/style.js +1 -0
  16. package/dist/loro/style.css +2 -0
  17. package/dist/loro/style.css.map +1 -0
  18. package/dist/loro/style.js +1 -0
  19. package/dist/{mark-rule-D7zaa32n.js → mark-rule-BCqIZMDu.js} +3 -3
  20. package/dist/mark-rule-BCqIZMDu.js.map +1 -0
  21. package/dist/{paste-rule-Cca3n5TA.js → paste-rule-DIEJKIje.js} +5 -15
  22. package/dist/paste-rule-DIEJKIje.js.map +1 -0
  23. package/dist/placeholder/style.css +2 -0
  24. package/dist/placeholder/style.css.map +1 -0
  25. package/dist/placeholder/style.js +1 -0
  26. package/dist/prosekit-extensions-autocomplete.d.ts +2 -1
  27. package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -0
  28. package/dist/prosekit-extensions-autocomplete.js +2 -9
  29. package/dist/prosekit-extensions-autocomplete.js.map +1 -0
  30. package/dist/prosekit-extensions-blockquote.d.ts +2 -1
  31. package/dist/prosekit-extensions-blockquote.d.ts.map +1 -0
  32. package/dist/prosekit-extensions-blockquote.js +4 -4
  33. package/dist/prosekit-extensions-blockquote.js.map +1 -0
  34. package/dist/prosekit-extensions-bold.d.ts +2 -1
  35. package/dist/prosekit-extensions-bold.d.ts.map +1 -0
  36. package/dist/prosekit-extensions-bold.js +3 -2
  37. package/dist/prosekit-extensions-bold.js.map +1 -0
  38. package/dist/prosekit-extensions-code-block.d.ts +2 -1
  39. package/dist/prosekit-extensions-code-block.d.ts.map +1 -0
  40. package/dist/prosekit-extensions-code-block.js +5 -6
  41. package/dist/prosekit-extensions-code-block.js.map +1 -0
  42. package/dist/prosekit-extensions-code.d.ts +2 -1
  43. package/dist/prosekit-extensions-code.d.ts.map +1 -0
  44. package/dist/prosekit-extensions-code.js +3 -2
  45. package/dist/prosekit-extensions-code.js.map +1 -0
  46. package/dist/prosekit-extensions-commit.d.ts +2 -1
  47. package/dist/prosekit-extensions-commit.d.ts.map +1 -0
  48. package/dist/prosekit-extensions-commit.js +11 -13
  49. package/dist/prosekit-extensions-commit.js.map +1 -0
  50. package/dist/prosekit-extensions-doc.d.ts +2 -1
  51. package/dist/prosekit-extensions-doc.d.ts.map +1 -0
  52. package/dist/prosekit-extensions-doc.js +2 -1
  53. package/dist/prosekit-extensions-doc.js.map +1 -0
  54. package/dist/prosekit-extensions-drop-cursor.d.ts +2 -1
  55. package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -0
  56. package/dist/prosekit-extensions-drop-cursor.js +2 -1
  57. package/dist/prosekit-extensions-drop-cursor.js.map +1 -0
  58. package/dist/prosekit-extensions-drop-indicator.d.ts +2 -1
  59. package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -0
  60. package/dist/prosekit-extensions-drop-indicator.js +1 -1
  61. package/dist/prosekit-extensions-enter-rule.d.ts +2 -1
  62. package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -0
  63. package/dist/prosekit-extensions-file.d.ts +2 -1
  64. package/dist/prosekit-extensions-file.d.ts.map +1 -0
  65. package/dist/prosekit-extensions-file.js +4 -16
  66. package/dist/prosekit-extensions-file.js.map +1 -0
  67. package/dist/prosekit-extensions-gap-cursor.d.ts +2 -2
  68. package/dist/prosekit-extensions-gap-cursor.d.ts.map +1 -0
  69. package/dist/prosekit-extensions-gap-cursor.js +2 -1
  70. package/dist/prosekit-extensions-gap-cursor.js.map +1 -0
  71. package/dist/prosekit-extensions-hard-break.d.ts +2 -1
  72. package/dist/prosekit-extensions-hard-break.d.ts.map +1 -0
  73. package/dist/prosekit-extensions-hard-break.js +2 -1
  74. package/dist/prosekit-extensions-hard-break.js.map +1 -0
  75. package/dist/prosekit-extensions-heading.d.ts +2 -1
  76. package/dist/prosekit-extensions-heading.d.ts.map +1 -0
  77. package/dist/prosekit-extensions-heading.js +5 -6
  78. package/dist/prosekit-extensions-heading.js.map +1 -0
  79. package/dist/prosekit-extensions-horizontal-rule.d.ts +2 -1
  80. package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -0
  81. package/dist/prosekit-extensions-horizontal-rule.js +5 -6
  82. package/dist/prosekit-extensions-horizontal-rule.js.map +1 -0
  83. package/dist/prosekit-extensions-image.d.ts +2 -1
  84. package/dist/prosekit-extensions-image.d.ts.map +1 -0
  85. package/dist/prosekit-extensions-image.js +3 -3
  86. package/dist/prosekit-extensions-image.js.map +1 -0
  87. package/dist/prosekit-extensions-input-rule.d.ts +2 -1
  88. package/dist/prosekit-extensions-input-rule.d.ts.map +1 -0
  89. package/dist/prosekit-extensions-input-rule.js +1 -1
  90. package/dist/prosekit-extensions-italic.d.ts +2 -1
  91. package/dist/prosekit-extensions-italic.d.ts.map +1 -0
  92. package/dist/prosekit-extensions-italic.js +3 -2
  93. package/dist/prosekit-extensions-italic.js.map +1 -0
  94. package/dist/prosekit-extensions-link.d.ts +2 -1
  95. package/dist/prosekit-extensions-link.d.ts.map +1 -0
  96. package/dist/prosekit-extensions-link.js +6 -5
  97. package/dist/prosekit-extensions-link.js.map +1 -0
  98. package/dist/prosekit-extensions-list.d.ts +22 -21
  99. package/dist/prosekit-extensions-list.d.ts.map +1 -0
  100. package/dist/prosekit-extensions-list.js +6 -7
  101. package/dist/prosekit-extensions-list.js.map +1 -0
  102. package/dist/prosekit-extensions-loro.d.ts +14 -13
  103. package/dist/prosekit-extensions-loro.d.ts.map +1 -0
  104. package/dist/prosekit-extensions-loro.js +2 -1
  105. package/dist/prosekit-extensions-loro.js.map +1 -0
  106. package/dist/prosekit-extensions-mark-rule.d.ts +2 -1
  107. package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -0
  108. package/dist/prosekit-extensions-mark-rule.js +1 -1
  109. package/dist/prosekit-extensions-mention.d.ts +2 -1
  110. package/dist/prosekit-extensions-mention.d.ts.map +1 -0
  111. package/dist/prosekit-extensions-mention.js +2 -1
  112. package/dist/prosekit-extensions-mention.js.map +1 -0
  113. package/dist/prosekit-extensions-mod-click-prevention.d.ts +2 -1
  114. package/dist/prosekit-extensions-mod-click-prevention.d.ts.map +1 -0
  115. package/dist/prosekit-extensions-mod-click-prevention.js +2 -1
  116. package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -0
  117. package/dist/prosekit-extensions-paragraph.d.ts +2 -1
  118. package/dist/prosekit-extensions-paragraph.d.ts.map +1 -0
  119. package/dist/prosekit-extensions-paragraph.js +2 -1
  120. package/dist/prosekit-extensions-paragraph.js.map +1 -0
  121. package/dist/prosekit-extensions-paste-rule.d.ts +2 -1
  122. package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -0
  123. package/dist/prosekit-extensions-paste-rule.js +1 -1
  124. package/dist/prosekit-extensions-placeholder.d.ts +2 -1
  125. package/dist/prosekit-extensions-placeholder.d.ts.map +1 -0
  126. package/dist/prosekit-extensions-placeholder.js +5 -5
  127. package/dist/prosekit-extensions-placeholder.js.map +1 -0
  128. package/dist/prosekit-extensions-readonly.d.ts +2 -1
  129. package/dist/prosekit-extensions-readonly.d.ts.map +1 -0
  130. package/dist/prosekit-extensions-readonly.js +2 -1
  131. package/dist/prosekit-extensions-readonly.js.map +1 -0
  132. package/dist/prosekit-extensions-search.d.ts +2 -1
  133. package/dist/prosekit-extensions-search.d.ts.map +1 -0
  134. package/dist/prosekit-extensions-search.js +3 -3
  135. package/dist/prosekit-extensions-search.js.map +1 -0
  136. package/dist/prosekit-extensions-strike.d.ts +2 -1
  137. package/dist/prosekit-extensions-strike.d.ts.map +1 -0
  138. package/dist/prosekit-extensions-strike.js +3 -2
  139. package/dist/prosekit-extensions-strike.js.map +1 -0
  140. package/dist/prosekit-extensions-table.d.ts +47 -114
  141. package/dist/prosekit-extensions-table.d.ts.map +1 -0
  142. package/dist/prosekit-extensions-table.js +2 -2
  143. package/dist/prosekit-extensions-text-align.d.ts +2 -1
  144. package/dist/prosekit-extensions-text-align.d.ts.map +1 -0
  145. package/dist/prosekit-extensions-text-align.js +2 -1
  146. package/dist/prosekit-extensions-text-align.js.map +1 -0
  147. package/dist/prosekit-extensions-text.d.ts +2 -1
  148. package/dist/prosekit-extensions-text.d.ts.map +1 -0
  149. package/dist/prosekit-extensions-text.js +2 -1
  150. package/dist/prosekit-extensions-text.js.map +1 -0
  151. package/dist/prosekit-extensions-underline.d.ts +2 -1
  152. package/dist/prosekit-extensions-underline.d.ts.map +1 -0
  153. package/dist/prosekit-extensions-underline.js +2 -1
  154. package/dist/prosekit-extensions-underline.js.map +1 -0
  155. package/dist/prosekit-extensions-virtual-selection.d.ts +2 -1
  156. package/dist/prosekit-extensions-virtual-selection.d.ts.map +1 -0
  157. package/dist/prosekit-extensions-virtual-selection.js +3 -3
  158. package/dist/prosekit-extensions-virtual-selection.js.map +1 -0
  159. package/dist/prosekit-extensions-yjs.d.ts +2 -1
  160. package/dist/prosekit-extensions-yjs.d.ts.map +1 -0
  161. package/dist/prosekit-extensions-yjs.js +2 -1
  162. package/dist/prosekit-extensions-yjs.js.map +1 -0
  163. package/dist/prosekit-extensions.d.ts +1 -1
  164. package/dist/prosekit-extensions.js +1 -0
  165. package/dist/search/style.css +2 -0
  166. package/dist/search/style.css.map +1 -0
  167. package/dist/search/style.js +1 -0
  168. package/dist/shiki-highlighter-chunk-DSPM0T27.d.ts +2 -1
  169. package/dist/shiki-highlighter-chunk-DSPM0T27.d.ts.map +1 -0
  170. package/dist/shiki-highlighter-chunk.js +3 -5
  171. package/dist/shiki-highlighter-chunk.js.map +1 -0
  172. package/dist/table/style.css +2 -0
  173. package/dist/table/style.css.map +1 -0
  174. package/dist/table/style.js +1 -0
  175. package/dist/table-Bi7WsMI3.js +297 -0
  176. package/dist/table-Bi7WsMI3.js.map +1 -0
  177. package/dist/virtual-selection/style.css +2 -0
  178. package/dist/virtual-selection/style.css.map +1 -0
  179. package/dist/virtual-selection/style.js +1 -0
  180. package/dist/yjs/style.css +2 -0
  181. package/dist/yjs/style.css.map +1 -0
  182. package/dist/yjs/style.js +1 -0
  183. package/package.json +10 -9
  184. package/src/autocomplete/autocomplete-helpers.ts +74 -0
  185. package/src/autocomplete/autocomplete-plugin.ts +186 -0
  186. package/src/autocomplete/autocomplete-rule.ts +117 -0
  187. package/src/autocomplete/autocomplete.spec.ts +132 -0
  188. package/src/autocomplete/autocomplete.ts +29 -0
  189. package/src/autocomplete/index.ts +9 -0
  190. package/src/blockquote/blockquote-commands.ts +32 -0
  191. package/src/blockquote/blockquote-input-rule.ts +14 -0
  192. package/src/blockquote/blockquote-keymap.spec.ts +45 -0
  193. package/src/blockquote/blockquote-keymap.ts +31 -0
  194. package/src/blockquote/blockquote-spec.ts +24 -0
  195. package/src/blockquote/blockquote.ts +34 -0
  196. package/src/blockquote/index.ts +14 -0
  197. package/src/bold/bold-commands.ts +23 -0
  198. package/src/bold/bold-input-rule.spec.ts +51 -0
  199. package/src/bold/bold-input-rule.ts +18 -0
  200. package/src/bold/bold-keymap.ts +14 -0
  201. package/src/bold/bold-spec.ts +53 -0
  202. package/src/bold/bold.ts +32 -0
  203. package/src/bold/index.ts +14 -0
  204. package/src/code/code-commands.ts +23 -0
  205. package/src/code/code-input-rule.ts +18 -0
  206. package/src/code/code-keymap.ts +14 -0
  207. package/src/code/code-spec.ts +28 -0
  208. package/src/code/code.ts +32 -0
  209. package/src/code/index.ts +14 -0
  210. package/src/code-block/code-block-commands.ts +44 -0
  211. package/src/code-block/code-block-highlight.ts +40 -0
  212. package/src/code-block/code-block-input-rule.ts +36 -0
  213. package/src/code-block/code-block-keymap.ts +61 -0
  214. package/src/code-block/code-block-shiki.ts +58 -0
  215. package/src/code-block/code-block-spec.spec.ts +164 -0
  216. package/src/code-block/code-block-spec.ts +71 -0
  217. package/src/code-block/code-block-types.ts +8 -0
  218. package/src/code-block/code-block.ts +46 -0
  219. package/src/code-block/index.ts +32 -0
  220. package/src/code-block/shiki-bundle.ts +8 -0
  221. package/src/code-block/shiki-highlighter-chunk.ts +84 -0
  222. package/src/code-block/shiki-highlighter.ts +22 -0
  223. package/src/code-block/shiki-parser.ts +36 -0
  224. package/src/commit/index.ts +330 -0
  225. package/src/commit/style.css +7 -0
  226. package/src/doc/index.ts +21 -0
  227. package/src/drop-cursor/drop-cursor.ts +46 -0
  228. package/src/drop-cursor/index.ts +5 -0
  229. package/src/drop-indicator/drop-indicator-facet.ts +84 -0
  230. package/src/drop-indicator/drop-indicator-plugin.ts +147 -0
  231. package/src/drop-indicator/drop-indicator.ts +37 -0
  232. package/src/drop-indicator/drop-target.ts +168 -0
  233. package/src/drop-indicator/index.ts +14 -0
  234. package/src/drop-indicator/types.ts +90 -0
  235. package/src/enter-rule/index.ts +241 -0
  236. package/src/file/file-drop-handler.ts +75 -0
  237. package/src/file/file-paste-handler.spec.ts +95 -0
  238. package/src/file/file-paste-handler.ts +59 -0
  239. package/src/file/file-upload.ts +119 -0
  240. package/src/file/helpers.ts +39 -0
  241. package/src/file/index.ts +16 -0
  242. package/src/gap-cursor/gap-cursor.ts +28 -0
  243. package/src/gap-cursor/index.ts +4 -0
  244. package/src/gap-cursor/style.css +25 -0
  245. package/src/hard-break/hard-break-commands.ts +31 -0
  246. package/src/hard-break/hard-break-keymap.spec.ts +45 -0
  247. package/src/hard-break/hard-break-keymap.ts +16 -0
  248. package/src/hard-break/hard-break-spec.ts +31 -0
  249. package/src/hard-break/hard-break.ts +32 -0
  250. package/src/hard-break/index.ts +13 -0
  251. package/src/heading/heading-commands.ts +37 -0
  252. package/src/heading/heading-input-rule.ts +22 -0
  253. package/src/heading/heading-keymap.spec.ts +53 -0
  254. package/src/heading/heading-keymap.ts +40 -0
  255. package/src/heading/heading-spec.ts +39 -0
  256. package/src/heading/heading-types.ts +3 -0
  257. package/src/heading/heading.ts +34 -0
  258. package/src/heading/index.ts +15 -0
  259. package/src/horizontal-rule/horizontal-rule-commands.spec.ts +61 -0
  260. package/src/horizontal-rule/horizontal-rule-commands.ts +37 -0
  261. package/src/horizontal-rule/horizontal-rule-input-rule.spec.ts +61 -0
  262. package/src/horizontal-rule/horizontal-rule-input-rule.ts +26 -0
  263. package/src/horizontal-rule/horizontal-rule-spec.ts +21 -0
  264. package/src/horizontal-rule/horizontal-rule.ts +29 -0
  265. package/src/horizontal-rule/index.ts +14 -0
  266. package/src/image/image-commands.ts +27 -0
  267. package/src/image/image-spec.ts +72 -0
  268. package/src/image/image.ts +25 -0
  269. package/src/image/index.ts +13 -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/table-CPI9ZxbK.js +0 -760
@@ -0,0 +1,297 @@
1
+ import { defineDropIndicator } from "./drop-indicator-D1eHOhSi.js";
2
+ import { defaultBlockAt, defineCommands, defineNodeSpec, definePlugin, getNodeType, insertNode, union } from "@prosekit/core";
3
+ import { TextSelection } from "@prosekit/pm/state";
4
+ import { CellSelection, TableMap, addColumnAfter, addColumnBefore, addRowAfter, addRowBefore, columnResizing, deleteCellSelection, deleteColumn, deleteRow, deleteTable, findCellPos, findCellRange, findTable, mergeCells, moveTableColumn, moveTableRow, splitCell, tableEditing, tableNodes } from "prosemirror-tables";
5
+
6
+ //#region src/table/table-commands/exit-table.ts
7
+ /**
8
+ * When the selection is in a table node, create a default block after the table
9
+ * table, and move the cursor there.
10
+ *
11
+ * @public
12
+ */
13
+ const exitTable = (state, dispatch) => {
14
+ const { $head, $anchor } = state.selection;
15
+ if (!$head.sameParent($anchor)) return false;
16
+ let tableStart = -1;
17
+ let tableDepth = -1;
18
+ for (let depth = $head.depth; depth >= 0; depth--) if ($head.node(depth).type.spec.tableRole === "table") {
19
+ tableStart = $head.before(depth);
20
+ tableDepth = depth;
21
+ }
22
+ if (tableStart < 0 || tableDepth <= 0) return false;
23
+ const above = $head.node(tableDepth - 1);
24
+ const after = $head.indexAfter(tableDepth - 1);
25
+ const type = defaultBlockAt(above.contentMatchAt(after));
26
+ const node = type?.createAndFill();
27
+ if (!type || !node || !above.canReplaceWith(after, after, type)) return false;
28
+ if (dispatch) {
29
+ const pos = $head.after(tableDepth);
30
+ const tr = state.tr.replaceWith(pos, pos, node);
31
+ tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1));
32
+ dispatch(tr.scrollIntoView());
33
+ }
34
+ return true;
35
+ };
36
+
37
+ //#endregion
38
+ //#region src/table/table-commands/insert-table.ts
39
+ function createEmptyTable(schema, row, col, header) {
40
+ const tableType = getNodeType(schema, "table");
41
+ const tableRowType = getNodeType(schema, "tableRow");
42
+ const tableCellType = getNodeType(schema, "tableCell");
43
+ const tableHeaderCellType = getNodeType(schema, "tableHeaderCell");
44
+ if (header) {
45
+ const headerCell = tableHeaderCellType.createAndFill();
46
+ const headerCells = repeat(headerCell, col);
47
+ const headerRow = tableRowType.createAndFill(null, headerCells);
48
+ const bodyCell = tableCellType.createAndFill();
49
+ const bodyCells = repeat(bodyCell, col);
50
+ const bodyRow = tableRowType.createAndFill(null, bodyCells);
51
+ const bodyRows = repeat(bodyRow, row - 1);
52
+ return tableType.createAndFill(null, [headerRow, ...bodyRows]);
53
+ } else {
54
+ const bodyCell = tableCellType.createAndFill();
55
+ const bodyCells = repeat(bodyCell, col);
56
+ const bodyRow = tableRowType.createAndFill(null, bodyCells);
57
+ const bodyRows = repeat(bodyRow, row);
58
+ return tableType.createAndFill(null, bodyRows);
59
+ }
60
+ }
61
+ function repeat(node, length) {
62
+ return Array(length).fill(node);
63
+ }
64
+ /**
65
+ * Insert a table node with the given number of rows and columns, and optionally
66
+ * a header row.
67
+ *
68
+ * @param options
69
+ *
70
+ * @public
71
+ */
72
+ function insertTable(options) {
73
+ return (state, dispatch, view) => {
74
+ const { row, col, header = false } = options;
75
+ const table = createEmptyTable(state.schema, row, col, header);
76
+ return insertNode({ node: table })(state, dispatch, view);
77
+ };
78
+ }
79
+
80
+ //#endregion
81
+ //#region src/table/table-utils.ts
82
+ /**
83
+ * Checks if the given object is a `CellSelection` instance.
84
+ *
85
+ * @public
86
+ */
87
+ function isCellSelection(value) {
88
+ return value instanceof CellSelection;
89
+ }
90
+
91
+ //#endregion
92
+ //#region src/table/table-commands/select-table.ts
93
+ /**
94
+ * @public
95
+ */
96
+ function selectTable(options) {
97
+ return (state, dispatch) => {
98
+ const $pos = options?.pos ? state.doc.resolve(options.pos) : state.selection.$anchor;
99
+ const table = findTable($pos);
100
+ if (!table) return false;
101
+ const map = TableMap.get(table.node);
102
+ if (map.map.length === 0) return false;
103
+ if (dispatch) {
104
+ let tr = state.tr;
105
+ const firstCellPosInTable = map.map[0];
106
+ const lastCellPosInTable = map.map[map.map.length - 1];
107
+ const firstCellPos = table.pos + firstCellPosInTable + 1;
108
+ const lastCellPos = table.pos + lastCellPosInTable + 1;
109
+ const $firstCellPos = tr.doc.resolve(firstCellPos);
110
+ const $lastCellPos = tr.doc.resolve(lastCellPos);
111
+ const selection = new CellSelection($firstCellPos, $lastCellPos);
112
+ tr = tr.setSelection(selection);
113
+ dispatch?.(tr);
114
+ }
115
+ return true;
116
+ };
117
+ }
118
+
119
+ //#endregion
120
+ //#region src/table/table-commands/select-table-cell.ts
121
+ /**
122
+ * @public
123
+ */
124
+ function selectTableCell(options) {
125
+ return (state, dispatch) => {
126
+ const $cellPos = findCellPos(state.doc, options?.pos ?? state.selection.anchor);
127
+ if (!$cellPos) return false;
128
+ if (dispatch) {
129
+ const selection = new CellSelection($cellPos);
130
+ dispatch(state.tr.setSelection(selection));
131
+ }
132
+ return true;
133
+ };
134
+ }
135
+
136
+ //#endregion
137
+ //#region src/table/table-commands/select-table-column.ts
138
+ /**
139
+ * @public
140
+ */
141
+ function selectTableColumn(options) {
142
+ return (state, dispatch) => {
143
+ const range = findCellRange(state.selection, options?.anchor, options?.head);
144
+ if (!range) return false;
145
+ if (dispatch) {
146
+ const [$anchorCell, $headCell] = range;
147
+ const selection = CellSelection.colSelection($anchorCell, $headCell);
148
+ dispatch(state.tr.setSelection(selection));
149
+ }
150
+ return true;
151
+ };
152
+ }
153
+
154
+ //#endregion
155
+ //#region src/table/table-commands/select-table-row.ts
156
+ /**
157
+ * @public
158
+ */
159
+ function selectTableRow(options) {
160
+ return (state, dispatch) => {
161
+ const range = findCellRange(state.selection, options?.anchor, options?.head);
162
+ if (!range) return false;
163
+ if (dispatch) {
164
+ const [$anchorCell, $headCell] = range;
165
+ const selection = CellSelection.rowSelection($anchorCell, $headCell);
166
+ dispatch(state.tr.setSelection(selection));
167
+ }
168
+ return true;
169
+ };
170
+ }
171
+
172
+ //#endregion
173
+ //#region src/table/table-commands.ts
174
+ /**
175
+ * Adds commands for working with `table` nodes.
176
+ *
177
+ * @public
178
+ */
179
+ function defineTableCommands() {
180
+ return defineCommands({
181
+ insertTable,
182
+ exitTable: () => exitTable,
183
+ selectTable,
184
+ selectTableCell,
185
+ selectTableColumn,
186
+ selectTableRow,
187
+ addTableColumnBefore: () => addColumnBefore,
188
+ addTableColumnAfter: () => addColumnAfter,
189
+ addTableRowAbove: () => addRowBefore,
190
+ addTableRowBelow: () => addRowAfter,
191
+ deleteTable: () => deleteTable,
192
+ deleteTableColumn: () => deleteColumn,
193
+ deleteTableRow: () => deleteRow,
194
+ deleteCellSelection: () => deleteCellSelection,
195
+ mergeTableCells: () => mergeCells,
196
+ splitTableCell: () => splitCell,
197
+ moveTableRow,
198
+ moveTableColumn
199
+ });
200
+ }
201
+
202
+ //#endregion
203
+ //#region src/table/table-drop-indicator.ts
204
+ /**
205
+ * Hides the drop indicator when dragging a table column or row by using the
206
+ * table handle.
207
+ *
208
+ * @internal
209
+ */
210
+ function defineTableDropIndicator() {
211
+ return defineDropIndicator({ onDrag });
212
+ }
213
+ const matchMap = /* @__PURE__ */ new WeakMap();
214
+ const onDrag = ({ event }) => {
215
+ const dataTransfer = event.dataTransfer;
216
+ if (!dataTransfer) return true;
217
+ let match;
218
+ if (matchMap.has(dataTransfer)) match = matchMap.get(dataTransfer);
219
+ else {
220
+ match = dataTransfer.types.includes("application/x-prosekit-table-handle-drag");
221
+ matchMap.set(dataTransfer, match);
222
+ }
223
+ return !match;
224
+ };
225
+
226
+ //#endregion
227
+ //#region src/table/table-plugins.ts
228
+ /**
229
+ * @public
230
+ */
231
+ function defineTablePlugins() {
232
+ return definePlugin([tableEditing(), columnResizing()]);
233
+ }
234
+
235
+ //#endregion
236
+ //#region src/table/table-spec.ts
237
+ const cellContent = "block+";
238
+ const cellAttrs = {
239
+ colspan: { default: 1 },
240
+ rowspan: { default: 1 },
241
+ colwidth: { default: null }
242
+ };
243
+ const specs = tableNodes({
244
+ tableGroup: "block",
245
+ cellContent,
246
+ cellAttributes: {}
247
+ });
248
+ /**
249
+ * @internal
250
+ */
251
+ function defineTableSpec() {
252
+ return defineNodeSpec({
253
+ ...specs["table"],
254
+ content: "tableRow+",
255
+ name: "table"
256
+ });
257
+ }
258
+ /**
259
+ * @internal
260
+ */
261
+ function defineTableRowSpec() {
262
+ return defineNodeSpec({
263
+ ...specs["table_row"],
264
+ content: "(tableCell | tableHeaderCell)*",
265
+ name: "tableRow"
266
+ });
267
+ }
268
+ /**
269
+ * @internal
270
+ */
271
+ function defineTableCellSpec() {
272
+ return defineNodeSpec({
273
+ ...specs["table_cell"],
274
+ name: "tableCell",
275
+ attrs: cellAttrs
276
+ });
277
+ }
278
+ function defineTableHeaderCellSpec() {
279
+ return defineNodeSpec({
280
+ ...specs["table_header"],
281
+ name: "tableHeaderCell",
282
+ attrs: cellAttrs
283
+ });
284
+ }
285
+
286
+ //#endregion
287
+ //#region src/table/table.ts
288
+ /**
289
+ * @public
290
+ */
291
+ function defineTable() {
292
+ return union(defineTableSpec(), defineTableRowSpec(), defineTableCellSpec(), defineTableHeaderCellSpec(), defineTablePlugins(), defineTableCommands(), defineTableDropIndicator());
293
+ }
294
+
295
+ //#endregion
296
+ export { defineTable, defineTableCellSpec, defineTableCommands, defineTableDropIndicator, defineTableHeaderCellSpec, defineTablePlugins, defineTableRowSpec, defineTableSpec, exitTable, findTable, insertTable, isCellSelection, moveTableColumn, moveTableRow, selectTable, selectTableCell, selectTableColumn, selectTableRow };
297
+ //# sourceMappingURL=table-Bi7WsMI3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-Bi7WsMI3.js","names":["exitTable: Command","onDrag: DragEventHandler","match: boolean"],"sources":["../src/table/table-commands/exit-table.ts","../src/table/table-commands/insert-table.ts","../src/table/table-utils.ts","../src/table/table-commands/select-table.ts","../src/table/table-commands/select-table-cell.ts","../src/table/table-commands/select-table-column.ts","../src/table/table-commands/select-table-row.ts","../src/table/table-commands.ts","../src/table/table-drop-indicator.ts","../src/table/table-plugins.ts","../src/table/table-spec.ts","../src/table/table.ts"],"sourcesContent":["import { defaultBlockAt } from '@prosekit/core'\nimport { TextSelection } from '@prosekit/pm/state'\nimport type { Command } from '@prosekit/pm/state'\nimport type { TableRole } from 'prosemirror-tables'\n\n/**\n * When the selection is in a table node, create a default block after the table\n * table, and move the cursor there.\n *\n * @public\n */\nexport const exitTable: Command = (state, dispatch) => {\n const { $head, $anchor } = state.selection\n\n if (!$head.sameParent($anchor)) {\n return false\n }\n\n let tableStart = -1\n let tableDepth = -1\n for (let depth = $head.depth; depth >= 0; depth--) {\n const node = $head.node(depth)\n if ((node.type.spec.tableRole as TableRole) === 'table') {\n tableStart = $head.before(depth)\n tableDepth = depth\n }\n }\n\n if (tableStart < 0 || tableDepth <= 0) {\n return false\n }\n\n const above = $head.node(tableDepth - 1)\n const after = $head.indexAfter(tableDepth - 1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n const node = type?.createAndFill()\n\n if (!type || !node || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n if (dispatch) {\n const pos = $head.after(tableDepth)\n const tr = state.tr.replaceWith(pos, pos, node)\n tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1))\n dispatch(tr.scrollIntoView())\n }\n return true\n}\n","import {\n getNodeType,\n insertNode,\n} from '@prosekit/core'\nimport type { Schema } from '@prosekit/pm/model'\nimport type { Command } from '@prosekit/pm/state'\n\nfunction createEmptyTable(\n schema: Schema,\n row: number,\n col: number,\n header: boolean,\n) {\n const tableType = getNodeType(schema, 'table')\n const tableRowType = getNodeType(schema, 'tableRow')\n const tableCellType = getNodeType(schema, 'tableCell')\n const tableHeaderCellType = getNodeType(schema, 'tableHeaderCell')\n\n if (header) {\n const headerCell = tableHeaderCellType.createAndFill()!\n const headerCells = repeat(headerCell, col)\n const headerRow = tableRowType.createAndFill(null, headerCells)!\n\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row - 1)\n\n return tableType.createAndFill(null, [headerRow, ...bodyRows])!\n } else {\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row)\n\n return tableType.createAndFill(null, bodyRows)!\n }\n}\n\nfunction repeat<T>(node: T, length: number): T[] {\n return Array<T>(length).fill(node)\n}\n\n/**\n * @public\n */\nexport interface InsertTableOptions {\n /**\n * The number of rows in the table.\n */\n row: number\n\n /**\n * The number of columns in the table.\n */\n col: number\n\n /**\n * Whether the table has a header row.\n *\n * @default false\n */\n header?: boolean\n}\n\n/**\n * Insert a table node with the given number of rows and columns, and optionally\n * a header row.\n *\n * @param options\n *\n * @public\n */\nexport function insertTable(options: InsertTableOptions): Command {\n return (state, dispatch, view) => {\n const { row, col, header = false } = options\n const table = createEmptyTable(state.schema, row, col, header)\n return insertNode({ node: table })(state, dispatch, view)\n }\n}\n","import { CellSelection } from 'prosemirror-tables'\n\nexport {\n findCellPos,\n findCellRange,\n findTable,\n} from 'prosemirror-tables'\n\n/**\n * Checks if the given object is a `CellSelection` instance.\n *\n * @public\n */\nexport function isCellSelection(value: unknown): value is CellSelection {\n return value instanceof CellSelection\n}\n","import type { Command } from '@prosekit/pm/state'\nimport {\n CellSelection,\n TableMap,\n} from 'prosemirror-tables'\n\nimport { findTable } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableOptions {\n /**\n * A hit position of the table to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTable(options?: SelectTableOptions): Command {\n return (state, dispatch) => {\n const $pos = options?.pos\n ? state.doc.resolve(options.pos)\n : state.selection.$anchor\n const table = findTable($pos)\n if (!table) {\n return false\n }\n const map = TableMap.get(table.node)\n if (map.map.length === 0) {\n return false\n }\n if (dispatch) {\n let tr = state.tr\n const firstCellPosInTable = map.map[0]\n const lastCellPosInTable = map.map[map.map.length - 1]\n const firstCellPos = table.pos + firstCellPosInTable + 1\n const lastCellPos = table.pos + lastCellPosInTable + 1\n const $firstCellPos = tr.doc.resolve(firstCellPos)\n const $lastCellPos = tr.doc.resolve(lastCellPos)\n const selection = new CellSelection($firstCellPos, $lastCellPos)\n tr = tr.setSelection(selection)\n dispatch?.(tr)\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellPos } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableCellOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTableCell(options?: SelectTableCellOptions): Command {\n return (state, dispatch) => {\n const $cellPos = findCellPos(\n state.doc,\n options?.pos ?? state.selection.anchor,\n )\n if (!$cellPos) {\n return false\n }\n if (dispatch) {\n const selection = new CellSelection($cellPos)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableColumnOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableColumn(options?: SelectTableColumnOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.colSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableRowOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableRow(options?: SelectTableRowOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.rowSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n addColumnAfter,\n addColumnBefore,\n addRowAfter,\n addRowBefore,\n deleteColumn,\n deleteRow,\n deleteTable,\n mergeCells,\n splitCell,\n} from 'prosemirror-tables'\n\nimport { deleteCellSelection } from './table-commands/delete-cell-selection'\nimport { exitTable } from './table-commands/exit-table'\nimport {\n insertTable,\n type InsertTableOptions,\n} from './table-commands/insert-table'\nimport {\n moveTableColumn,\n type MoveTableColumnOptions,\n} from './table-commands/move-table-column'\nimport {\n moveTableRow,\n type MoveTableRowOptions,\n} from './table-commands/move-table-row'\nimport {\n selectTable,\n type SelectTableOptions,\n} from './table-commands/select-table'\nimport {\n selectTableCell,\n type SelectTableCellOptions,\n} from './table-commands/select-table-cell'\nimport {\n selectTableColumn,\n type SelectTableColumnOptions,\n} from './table-commands/select-table-column'\nimport {\n selectTableRow,\n type SelectTableRowOptions,\n} from './table-commands/select-table-row'\n\n/**\n * @internal\n */\nexport type TableCommandsExtension = Extension<{\n Commands: {\n insertTable: [options: InsertTableOptions]\n exitTable: []\n\n selectTable: [options?: SelectTableOptions]\n selectTableCell: [options?: SelectTableCellOptions]\n selectTableColumn: [options?: SelectTableColumnOptions]\n selectTableRow: [options?: SelectTableRowOptions]\n\n addTableColumnBefore: []\n addTableColumnAfter: []\n addTableRowAbove: []\n addTableRowBelow: []\n\n deleteTable: []\n deleteTableColumn: []\n deleteTableRow: []\n deleteCellSelection: []\n\n mergeTableCells: []\n splitTableCell: []\n\n moveTableRow: [options: MoveTableRowOptions]\n moveTableColumn: [options: MoveTableColumnOptions]\n }\n}>\n\n/**\n * Adds commands for working with `table` nodes.\n *\n * @public\n */\nexport function defineTableCommands(): TableCommandsExtension {\n return defineCommands({\n insertTable,\n exitTable: () => exitTable,\n\n selectTable,\n selectTableCell,\n selectTableColumn,\n selectTableRow,\n\n addTableColumnBefore: () => addColumnBefore,\n addTableColumnAfter: () => addColumnAfter,\n addTableRowAbove: () => addRowBefore,\n addTableRowBelow: () => addRowAfter,\n\n deleteTable: () => deleteTable,\n deleteTableColumn: () => deleteColumn,\n deleteTableRow: () => deleteRow,\n deleteCellSelection: () => deleteCellSelection,\n\n mergeTableCells: () => mergeCells,\n splitTableCell: () => splitCell,\n\n moveTableRow,\n moveTableColumn,\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport type { DragEventHandler } from '../drop-indicator'\nimport { defineDropIndicator } from '../drop-indicator'\n\n/**\n * Hides the drop indicator when dragging a table column or row by using the\n * table handle.\n *\n * @internal\n */\nexport function defineTableDropIndicator(): PlainExtension {\n return defineDropIndicator({\n onDrag,\n })\n}\n\nconst matchMap = new WeakMap<DataTransfer, boolean>()\n\nconst onDrag: DragEventHandler = ({ event }): boolean => {\n const dataTransfer = event.dataTransfer\n if (!dataTransfer) return true\n\n let match: boolean\n\n if (matchMap.has(dataTransfer)) {\n match = matchMap.get(dataTransfer)!\n } else {\n // On Safari, accessing `dataTransfer.types` is more than 10x slower than in\n // Chrome. This becomes a bottleneck when `onDrag` is called frequently, so\n // we cache the result in a WeakMap.\n const types = dataTransfer.types\n match = types.includes('application/x-prosekit-table-handle-drag')\n matchMap.set(dataTransfer, match)\n }\n\n // Don't show the drop indicator when the drag event has\n // \"application/x-prosekit-table-handle-drag\" type.\n return !match\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n columnResizing,\n tableEditing,\n} from 'prosemirror-tables'\n\n/**\n * @public\n */\nexport function defineTablePlugins(): PlainExtension {\n return definePlugin([tableEditing(), columnResizing()])\n}\n","import {\n defineNodeSpec,\n type Extension,\n} from '@prosekit/core'\nimport type {\n AttributeSpec,\n Attrs,\n} from '@prosekit/pm/model'\nimport { tableNodes } from 'prosemirror-tables'\n\nconst cellContent = 'block+'\n\n/**\n * @public\n */\nexport interface CellAttrs {\n colspan?: number\n rowspan?: number\n colwidth?: number[] | null\n}\n\nconst cellAttrs = {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n colwidth: { default: null },\n} satisfies Record<string, AttributeSpec>\n\n/**\n * @internal\n */\nexport type TableSpecExtension = Extension<{\n Nodes: {\n table: Attrs\n }\n}>\n\nconst specs = tableNodes({\n tableGroup: 'block',\n cellContent,\n cellAttributes: {},\n})\n\n/**\n * @internal\n */\nexport function defineTableSpec(): TableSpecExtension {\n return defineNodeSpec({\n ...specs['table'],\n content: 'tableRow+',\n name: 'table',\n })\n}\n\n/**\n * @internal\n */\nexport type TableRowSpecExtension = Extension<{\n Nodes: {\n tableRow: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableRowSpec(): TableRowSpecExtension {\n return defineNodeSpec({\n ...specs['table_row'],\n content: '(tableCell | tableHeaderCell)*',\n name: 'tableRow',\n })\n}\n\n/**\n * @internal\n */\nexport type TableCellSpecExtension = Extension<{\n Nodes: {\n tableCell: CellAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableCellSpec(): TableCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_cell'],\n name: 'tableCell',\n attrs: cellAttrs,\n })\n}\n\n/**\n * @internal\n */\nexport type TableHeaderCellSpecExtension = Extension<{\n Nodes: {\n tableHeaderCell: CellAttrs\n }\n}>\n\nexport function defineTableHeaderCellSpec(): TableHeaderCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_header'],\n name: 'tableHeaderCell',\n attrs: cellAttrs,\n })\n}\n","import {\n union,\n type Union,\n} from '@prosekit/core'\n\nimport {\n defineTableCommands,\n type TableCommandsExtension,\n} from './table-commands'\nimport { defineTableDropIndicator } from './table-drop-indicator'\nimport { defineTablePlugins } from './table-plugins'\nimport {\n defineTableCellSpec,\n defineTableHeaderCellSpec,\n defineTableRowSpec,\n defineTableSpec,\n type TableCellSpecExtension,\n type TableHeaderCellSpecExtension,\n type TableRowSpecExtension,\n type TableSpecExtension,\n} from './table-spec'\n\n/**\n * @internal\n */\nexport type TableExtension = Union<\n [\n TableSpecExtension,\n TableRowSpecExtension,\n TableCellSpecExtension,\n TableHeaderCellSpecExtension,\n TableCommandsExtension,\n ]\n>\n\n/**\n * @public\n */\nexport function defineTable(): TableExtension {\n return union(\n defineTableSpec(),\n defineTableRowSpec(),\n defineTableCellSpec(),\n defineTableHeaderCellSpec(),\n defineTablePlugins(),\n defineTableCommands(),\n defineTableDropIndicator(),\n )\n}\n"],"mappings":"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"}
@@ -4,3 +4,5 @@
4
4
  box-shadow: 0 0 0 2px #8888884d;
5
5
  }
6
6
 
7
+
8
+ /*# sourceMappingURL=style.css.map*/
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.css","names":[],"sources":["../../src/virtual-selection/style.css"],"sourcesContent":[".prosekit-virtual-selection {\n border-radius: 2px;\n background-color: #8888884d;\n box-shadow: 0 0 0 2px #8888884d;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA"}
@@ -0,0 +1 @@
1
+ export { };
@@ -30,3 +30,5 @@
30
30
  margin-top: 16px;
31
31
  }
32
32
 
33
+
34
+ /*# sourceMappingURL=style.css.map*/
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.css","names":[],"sources":["../../src/yjs/style.css"],"sourcesContent":[".ProseMirror .ProseMirror-yjs-cursor {\n position: absolute;\n height: 1em;\n border-left: black;\n border-left-width: 2px;\n border-left-style: solid;\n border-color: orange;\n word-break: normal;\n pointer-events: none;\n}\n\n.ProseMirror .ProseMirror-yjs-cursor > div {\n position: relative;\n top: -1.05em;\n padding-right: 2px;\n padding-left: 2px;\n background-color: rgb(250, 129, 0);\n color: white;\n font-style: normal;\n font-weight: normal;\n font-size: 13px;\n line-height: normal;\n font-family: serif;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.ProseMirror > .ProseMirror-yjs-cursor:first-child {\n margin-top: 16px;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
package/dist/yjs/style.js CHANGED
@@ -0,0 +1 @@
1
+ export { };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.11.4",
4
+ "version": "0.11.5",
5
5
  "private": false,
6
6
  "description": "A collection of common extensions for ProseKit",
7
7
  "author": {
@@ -203,7 +203,8 @@
203
203
  }
204
204
  },
205
205
  "files": [
206
- "dist"
206
+ "dist",
207
+ "src"
207
208
  ],
208
209
  "dependencies": {
209
210
  "@ocavue/utils": "^0.7.1",
@@ -213,10 +214,10 @@
213
214
  "prosemirror-gapcursor": "^1.3.2",
214
215
  "prosemirror-highlight": "^0.13.0",
215
216
  "prosemirror-search": "^1.1.0",
216
- "prosemirror-tables": "^1.7.1",
217
- "shiki": "^3.9.2",
218
- "@prosekit/core": "^0.8.3",
219
- "@prosekit/pm": "^0.1.11"
217
+ "prosemirror-tables": "^1.8.1",
218
+ "shiki": "^3.12.2",
219
+ "@prosekit/core": "^0.8.4",
220
+ "@prosekit/pm": "^0.1.12"
220
221
  },
221
222
  "peerDependencies": {
222
223
  "loro-crdt": ">= 0.16.7",
@@ -243,14 +244,14 @@
243
244
  "@vitest/browser": "^3.2.4",
244
245
  "diffable-html": "^6.0.1",
245
246
  "just-pick": "^4.2.0",
246
- "loro-crdt": "^1.5.10",
247
- "loro-prosemirror": "^0.2.3",
247
+ "loro-crdt": "^1.7.0",
248
+ "loro-prosemirror": "^0.3.1",
248
249
  "rehype-parse": "^9.0.1",
249
250
  "rehype-remark": "^10.0.1",
250
251
  "remark-html": "^16.0.1",
251
252
  "remark-parse": "^11.0.0",
252
253
  "remark-stringify": "^11.0.0",
253
- "tsdown": "^0.13.4",
254
+ "tsdown": "^0.14.2",
254
255
  "type-fest": "^4.41.0",
255
256
  "typescript": "~5.9.2",
256
257
  "unified": "^11.0.5",
@@ -0,0 +1,74 @@
1
+ import type { ResolvedPos } from '@prosekit/pm/model'
2
+ import {
3
+ PluginKey,
4
+ type EditorState,
5
+ type Transaction,
6
+ } from '@prosekit/pm/state'
7
+
8
+ import type { AutocompleteRule } from './autocomplete-rule'
9
+
10
+ export function defaultCanMatch({ state }: { state: EditorState }): boolean {
11
+ return state.selection.empty && !isInsideCode(state.selection.$from)
12
+ }
13
+
14
+ function isInsideCode($pos: ResolvedPos): boolean {
15
+ for (let d = $pos.depth; d > 0; d--) {
16
+ if ($pos.node(d).type.spec.code) {
17
+ return true
18
+ }
19
+ }
20
+
21
+ return $pos.marks().some((mark) => mark.type.name === 'code')
22
+ }
23
+
24
+ /**
25
+ * @internal
26
+ */
27
+ export interface PredictionPluginMatching {
28
+ rule: AutocompleteRule
29
+ from: number
30
+ to: number
31
+ match: RegExpExecArray
32
+ }
33
+
34
+ /**
35
+ * @internal
36
+ */
37
+ export interface PredictionPluginState {
38
+ /**
39
+ * The matching positions that should be ignored.
40
+ */
41
+ ignores: number[]
42
+
43
+ /**
44
+ * The current active matching.
45
+ */
46
+ matching: PredictionPluginMatching | null
47
+ }
48
+
49
+ /**
50
+ * @internal
51
+ */
52
+ interface PredictionTransactionMeta {
53
+ /**
54
+ * The from position that should be ignored.
55
+ */
56
+ ignore: number
57
+ }
58
+
59
+ export function getPluginState(state: EditorState): PredictionPluginState | undefined {
60
+ return pluginKey.getState(state)
61
+ }
62
+
63
+ export function getTrMeta(tr: Transaction): PredictionTransactionMeta | undefined {
64
+ return tr.getMeta(pluginKey) as PredictionTransactionMeta | undefined
65
+ }
66
+
67
+ export function setTrMeta(
68
+ tr: Transaction,
69
+ meta: PredictionTransactionMeta,
70
+ ): Transaction {
71
+ return tr.setMeta(pluginKey, meta)
72
+ }
73
+
74
+ export const pluginKey: PluginKey<PredictionPluginState> = new PluginKey<PredictionPluginState>('prosekit-autocomplete')
@@ -0,0 +1,186 @@
1
+ import { OBJECT_REPLACEMENT_CHARACTER } from '@prosekit/core'
2
+ import {
3
+ Plugin,
4
+ type EditorState,
5
+ type Transaction,
6
+ } from '@prosekit/pm/state'
7
+ import {
8
+ Decoration,
9
+ DecorationSet,
10
+ } from '@prosekit/pm/view'
11
+
12
+ import {
13
+ getPluginState,
14
+ getTrMeta,
15
+ pluginKey,
16
+ setTrMeta,
17
+ type PredictionPluginMatching,
18
+ type PredictionPluginState,
19
+ } from './autocomplete-helpers'
20
+ import type { AutocompleteRule } from './autocomplete-rule'
21
+
22
+ export function createAutocompletePlugin({
23
+ getRules,
24
+ }: {
25
+ getRules: () => AutocompleteRule[]
26
+ }): Plugin {
27
+ return new Plugin<PredictionPluginState>({
28
+ key: pluginKey,
29
+
30
+ state: {
31
+ init: (): PredictionPluginState => {
32
+ return { ignores: [], matching: null }
33
+ },
34
+ apply: (
35
+ tr: Transaction,
36
+ prevValue: PredictionPluginState,
37
+ oldState: EditorState,
38
+ newState: EditorState,
39
+ ): PredictionPluginState => {
40
+ const meta = getTrMeta(tr)
41
+
42
+ // No changes
43
+ if (
44
+ !tr.docChanged
45
+ && oldState.selection.eq(newState.selection)
46
+ && !meta
47
+ ) {
48
+ return prevValue
49
+ }
50
+
51
+ // Receiving a meta means that we are ignoring a match
52
+ if (meta) {
53
+ let ignores = prevValue.ignores
54
+ if (!ignores.includes(meta.ignore)) {
55
+ ignores = [...ignores, meta.ignore]
56
+ }
57
+ return { matching: null, ignores }
58
+ }
59
+
60
+ // Calculate the new ignores
61
+ const ignoreSet = new Set(prevValue.ignores.map(pos => tr.mapping.map(pos)))
62
+
63
+ // Calculate the new matching
64
+ let matching = calcPluginStateMatching(newState, getRules())
65
+
66
+ // Check if the matching should be ignored
67
+ if (matching && ignoreSet.has(matching.from)) {
68
+ matching = null
69
+ }
70
+
71
+ // Return the new matching and ignores
72
+ return { matching, ignores: Array.from(ignoreSet) }
73
+ },
74
+ },
75
+
76
+ view: () => ({
77
+ update: (view, prevState) => {
78
+ const prevValue = getPluginState(prevState)
79
+ const currValue = getPluginState(view.state)
80
+
81
+ if (
82
+ prevValue?.matching
83
+ && prevValue.matching.rule !== currValue?.matching?.rule
84
+ ) {
85
+ // Deactivate the previous rule
86
+ prevValue.matching.rule.onLeave?.()
87
+ }
88
+
89
+ if (
90
+ currValue?.matching
91
+ && !currValue.ignores.includes(currValue.matching.from)
92
+ ) {
93
+ // Activate the current rule
94
+
95
+ const { from, to, match, rule } = currValue.matching
96
+
97
+ const textContent = view.state.doc.textBetween(
98
+ from,
99
+ to,
100
+ null,
101
+ OBJECT_REPLACEMENT_CHARACTER,
102
+ )
103
+
104
+ const deleteMatch = () => {
105
+ if (
106
+ view.state.doc.textBetween(
107
+ from,
108
+ to,
109
+ null,
110
+ OBJECT_REPLACEMENT_CHARACTER,
111
+ ) === textContent
112
+ ) {
113
+ view.dispatch(view.state.tr.delete(from, to))
114
+ }
115
+ }
116
+
117
+ const ignoreMatch = () => {
118
+ view.dispatch(
119
+ setTrMeta(view.state.tr, { ignore: from }),
120
+ )
121
+ }
122
+
123
+ rule.onMatch({
124
+ state: view.state,
125
+ match,
126
+ from,
127
+ to,
128
+ deleteMatch,
129
+ ignoreMatch,
130
+ })
131
+ }
132
+ },
133
+ }),
134
+
135
+ props: {
136
+ decorations: (state: EditorState) => {
137
+ const pluginState = getPluginState(state)
138
+ if (pluginState?.matching) {
139
+ const { from, to } = pluginState.matching
140
+ const deco = Decoration.inline(from, to, {
141
+ class: 'prosemirror-prediction-match',
142
+ })
143
+ return DecorationSet.create(state.doc, [deco])
144
+ }
145
+ return null
146
+ },
147
+ },
148
+ })
149
+ }
150
+
151
+ const MAX_MATCH = 200
152
+
153
+ function calcPluginStateMatching(
154
+ state: EditorState,
155
+ rules: AutocompleteRule[],
156
+ ): PredictionPluginMatching | null {
157
+ const $pos = state.selection.$from
158
+
159
+ const parentOffset: number = $pos.parentOffset
160
+
161
+ const textBefore: string = $pos.parent.textBetween(
162
+ Math.max(0, parentOffset - MAX_MATCH),
163
+ parentOffset,
164
+ null,
165
+ OBJECT_REPLACEMENT_CHARACTER,
166
+ )
167
+
168
+ for (const rule of rules) {
169
+ if (!rule.canMatch({ state })) {
170
+ continue
171
+ }
172
+
173
+ rule.regex.lastIndex = 0
174
+ const match = rule.regex.exec(textBefore)
175
+ if (!match) {
176
+ continue
177
+ }
178
+
179
+ const to = $pos.pos
180
+ const from = to - textBefore.length + match.index
181
+
182
+ return { rule, match, from, to }
183
+ }
184
+
185
+ return null
186
+ }